4 * Copyright (C) 2010-2013 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "bcsignals.h"
27 #include "filesystem.h"
28 #include "formattools.h"
30 #include "maxchannels.h"
32 #include "preferences.h"
33 #include "quicktime.h"
35 #include "videodevice.inc"
41 FormatTools::FormatTools(MWindow *mwindow,
42 BC_WindowBase *window,
45 this->mwindow = mwindow;
46 this->window = window;
48 this->plugindb = mwindow->plugindb;
77 prompt_audio_channels = 0;
79 prompt_video_compression = 0;
81 locked_compressor = 0;
85 FormatTools::~FormatTools()
95 if(aparams_button) delete aparams_button;
97 if(vparams_button) delete vparams_button;
99 if(aparams_thread) delete aparams_thread;
101 if(vparams_thread) delete vparams_thread;
103 if(channels_tumbler) delete channels_tumbler;
107 file_entries->remove_all_objects();
112 void FormatTools::create_objects(int &init_x,
114 int do_audio, // Include support for audio
115 int do_video, // Include support for video
116 int prompt_audio, // Include checkbox for audio
118 int prompt_audio_channels,
119 int prompt_video_compression,
120 char *locked_compressor,
128 this->locked_compressor = locked_compressor;
129 this->recording = recording;
130 this->use_brender = brender;
131 this->do_audio = do_audio;
132 this->do_video = do_video;
133 this->prompt_audio = prompt_audio;
134 this->prompt_audio_channels = prompt_audio_channels;
135 this->prompt_video = prompt_video;
136 this->prompt_video_compression = prompt_video_compression;
137 this->strategy = strategy;
140 file_entries = new ArrayList<BC_ListBoxItem*>;
142 char string[BCTEXTLEN];
143 // Load current directory
144 fs.update(getcwd(string, BCTEXTLEN));
145 for(int i = 0; i < fs.total_files(); i++)
147 file_entries->append(
149 fs.get_entry(i)->get_name()));
152 //printf("FormatTools::create_objects 1\n");
154 // Modify strategy depending on render farm
157 if(mwindow->preferences->use_renderfarm)
159 if(*strategy == FILE_PER_LABEL)
160 *strategy = FILE_PER_LABEL_FARM;
162 if(*strategy == SINGLE_PASS)
163 *strategy = SINGLE_PASS_FARM;
167 if(*strategy == FILE_PER_LABEL_FARM)
168 *strategy = FILE_PER_LABEL;
170 if(*strategy == SINGLE_PASS_FARM)
171 *strategy = SINGLE_PASS;
177 window->add_subwindow(path_textbox = new FormatPathText(x, y, this));
178 x += path_textbox->get_w() + 5;
179 window->add_subwindow(path_button = new BrowseButton(
187 _("Select a file to write to:"),
192 // w = x + path_button->get_w() + 5;
193 x -= path_textbox->get_w() + 5;
202 window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
204 window->add_subwindow(format_text = new BC_TextBox(x, y, 180, 1,
205 File::formattostr(asset->format)));
206 x += format_text->get_w();
207 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
208 window->add_subwindow(format_button = new FormatFormat(x, y, this));
209 format_button->create_objects();
210 x += format_button->get_w() + 5;
211 window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 50, 1, asset->fformat));
212 x += ffmpeg_type->get_w();
213 window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
214 format_ffmpeg->create_objects();
217 y += format_button->get_h() + 10;
220 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT, RED));
222 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
223 x += aparams_button->get_w() + 10;
226 window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
229 y += aparams_button->get_h() + 10;
231 // Audio channels only used for recording.
232 // if(prompt_audio_channels)
234 // window->add_subwindow(channels_title = new BC_Title(x, y, _("Number of audio channels to record:")));
236 // window->add_subwindow(channels_button = new FormatChannels(x, y, this));
237 // x += channels_button->get_w() + 5;
238 // window->add_subwindow(channels_tumbler = new BC_ITumbler(channels_button, 1, MAXCHANNELS, x, y));
239 // y += channels_button->get_h() + 20;
243 //printf("FormatTools::create_objects 6\n");
244 aparams_thread = new FormatAThread(this);
247 //printf("FormatTools::create_objects 7\n");
251 //printf("FormatTools::create_objects 8\n");
252 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT, RED));
254 if(prompt_video_compression)
256 window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
257 x += vparams_button->get_w() + 10;
260 //printf("FormatTools::create_objects 9\n");
263 window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
264 y += video_switch->get_h();
268 y += vparams_button->get_h();
271 //printf("FormatTools::create_objects 10\n");
273 vparams_thread = new FormatVThread(this);
276 //printf("FormatTools::create_objects 11\n");
281 window->add_subwindow(multiple_files = new FormatMultiple(mwindow, x, y, strategy));
282 y += multiple_files->get_h() + 10;
285 //printf("FormatTools::create_objects 12\n");
291 void FormatTools::update_driver(int driver)
293 this->video_driver = driver;
298 case VIDEO4LINUX2MPEG:
299 // Just give the user information about how the stream is going to be
300 // stored but don't change the asset.
301 // Want to be able to revert to user settings.
302 if(asset->format != FILE_MPEG)
304 format_text->update(_("MPEG stream"));
305 asset->format = FILE_MPEG;
307 locked_compressor = 0;
308 audio_switch->update(1);
309 video_switch->update(1);
312 case CAPTURE_IEC61883:
313 case CAPTURE_FIREWIRE:
315 case VIDEO4LINUX2JPEG:
316 case CAPTURE_JPEG_WEBCAM:
317 if(asset->format != FILE_AVI &&
318 asset->format != FILE_MOV)
320 format_text->update(MOV_NAME);
321 asset->format = FILE_MOV;
324 format_text->update(File::formattostr(asset->format));
328 case CAPTURE_IEC61883:
329 case CAPTURE_FIREWIRE:
330 locked_compressor = (char*)QUICKTIME_DVSD;
331 strcpy(asset->vcodec, QUICKTIME_DVSD);
335 case VIDEO4LINUX2JPEG:
336 locked_compressor = (char*)QUICKTIME_MJPA;
337 strcpy(asset->vcodec, QUICKTIME_MJPA);
340 case CAPTURE_JPEG_WEBCAM:
341 locked_compressor = (char*)QUICKTIME_JPEG;
342 strcpy(asset->vcodec, QUICKTIME_JPEG);
346 audio_switch->update(asset->audio_data);
347 video_switch->update(asset->video_data);
355 format_text->update(File::formattostr(asset->format));
356 locked_compressor = 0;
357 audio_switch->update(asset->audio_data);
358 video_switch->update(asset->video_data);
361 close_format_windows();
364 void FormatTools::update_format()
366 if( do_audio && prompt_audio && audio_switch ) {
367 asset->audio_data = File::supports_audio(asset->format);
368 audio_switch->update(asset->audio_data);
369 if( !asset->audio_data )
370 audio_switch->disable();
372 audio_switch->enable();
374 if( do_video && prompt_video && video_switch ) {
375 asset->video_data = File::supports_video(asset->format);
376 video_switch->update(asset->video_data);
377 if( !asset->video_data )
378 video_switch->disable();
380 video_switch->enable();
382 if( asset->format == FILE_FFMPEG ) {
384 format_ffmpeg->show();
388 format_ffmpeg->hide();
392 int FormatTools::handle_event()
397 Asset* FormatTools::get_asset()
402 void FormatTools::update_extension()
404 const char *extension = File::get_tag(asset->format);
405 // split multiple extensions
406 ArrayList<const char*> extensions;
407 int len = strlen(extension);
408 const char *extension_ptr = extension;
409 for(int i = 0; i <= len; i++)
411 if(extension[i] == '/' || extension[i] == 0)
413 extensions.append(extension_ptr);
414 extension_ptr = extension + i + 1;
418 if(extensions.size())
420 char *ptr = strrchr(asset->path, '.');
423 ptr = asset->path + strlen(asset->path);
429 // test for equivalent extension
430 int need_extension = 1;
431 //int extension_len = 0;
432 for(int i = 0; i < extensions.size() && need_extension; i++)
435 extension_ptr = extensions.get(i);
438 while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
440 if(tolower(*ptr1) != tolower(*extension_ptr))
450 *extension_ptr != 0 &&
451 *extension_ptr != '/')
455 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
460 extension_ptr = asset->format != FILE_FFMPEG ?
461 extensions.get(0) : asset->fformat;
462 while(*extension_ptr != 0 && *extension_ptr != '/')
463 *ptr1++ = *extension_ptr++;
467 int character1 = ptr - asset->path;
468 int character2 = strlen(asset->path);
469 // *(asset->path + character2) = 0;
472 path_textbox->update(asset->path);
473 path_textbox->set_selection(character1, character2, character2);
478 void FormatTools::update(Asset *asset, int *strategy)
481 this->strategy = strategy;
484 path_textbox->update(asset->path);
485 format_text->update(File::formattostr(plugindb, asset->format));
486 if(do_audio && prompt_audio && audio_switch)
487 audio_switch->update(asset->audio_data);
488 if(do_video && prompt_video && video_switch)
489 video_switch->update(asset->video_data);
492 multiple_files->update(strategy);
494 close_format_windows();
497 void FormatTools::close_format_windows()
499 // This is done in ~file
500 if(aparams_thread && aparams_thread->running())
502 aparams_thread->file->close_window();
503 aparams_thread->join();
505 if(vparams_thread && vparams_thread->running())
507 vparams_thread->file->close_window();
508 vparams_thread->join();
512 int FormatTools::get_w()
517 void FormatTools::set_w(int w)
522 void FormatTools::reposition_window(int &init_x, int &init_y)
529 path_textbox->reposition_window(x, y);
530 x += path_textbox->get_w() + 5;
531 path_button->reposition_window(x, y);
532 x -= path_textbox->get_w() + 5;
536 format_title->reposition_window(x, y);
538 format_text->reposition_window(x, y);
539 x += format_text->get_w();
540 format_button->reposition_window(x, y);
543 y += format_button->get_h() + 10;
547 audio_title->reposition_window(x, y);
549 aparams_button->reposition_window(x, y);
550 x += aparams_button->get_w() + 10;
551 if(prompt_audio) audio_switch->reposition_window(x, y);
554 y += aparams_button->get_h() + 20;
555 if(prompt_audio_channels)
557 channels_title->reposition_window(x, y);
559 channels_button->reposition_window(x, y);
560 x += channels_button->get_w() + 5;
561 channels_tumbler->reposition_window(x, y);
562 y += channels_button->get_h() + 20;
570 video_title->reposition_window(x, y);
572 if(prompt_video_compression)
574 vparams_button->reposition_window(x, y);
575 x += vparams_button->get_w() + 10;
580 video_switch->reposition_window(x, y);
581 y += video_switch->get_h();
585 y += vparams_button->get_h();
594 multiple_files->reposition_window(x, y);
595 y += multiple_files->get_h() + 10;
602 int FormatTools::set_audio_options()
604 // if(video_driver == CAPTURE_DVB)
609 if(!aparams_thread->running())
611 aparams_thread->start();
615 aparams_thread->file->raise_window();
620 int FormatTools::set_video_options()
622 // if(video_driver == CAPTURE_DVB)
627 if(!vparams_thread->running())
629 vparams_thread->start();
633 vparams_thread->file->raise_window();
643 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
644 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
646 this->format = format;
647 set_tooltip(_("Configure audio compression"));
650 FormatAParams::~FormatAParams()
654 int FormatAParams::handle_event()
656 format->set_audio_options();
664 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
665 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
667 this->format = format;
668 set_tooltip(_("Configure video compression"));
671 FormatVParams::~FormatVParams()
675 int FormatVParams::handle_event()
677 format->set_video_options();
685 FormatAThread::FormatAThread(FormatTools *format)
688 this->format = format;
693 FormatAThread::~FormatAThread()
700 void FormatAThread::start()
708 void FormatAThread::run()
710 file->get_options(format, 1, 0);
716 FormatVThread::FormatVThread(FormatTools *format)
719 this->format = format;
724 FormatVThread::~FormatVThread()
731 void FormatVThread::start()
738 void FormatVThread::run()
740 file->get_options(format, 0, 1);
747 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
751 format->mwindow->theme->get_image_set("wrench")[0]->get_w() -
756 this->format = format;
759 FormatPathText::~FormatPathText()
762 int FormatPathText::handle_event()
765 calculate_suggestions(format->file_entries);
769 strcpy(format->asset->path, get_text());
770 format->handle_event();
778 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
782 (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
784 this->format = format;
787 FormatAudio::~FormatAudio() {}
788 int FormatAudio::handle_event()
790 format->asset->audio_data = get_value();
795 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
799 (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
801 this->format = format;
804 FormatVideo::~FormatVideo() {}
805 int FormatVideo::handle_event()
807 format->asset->video_data = get_value();
814 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
815 : FormatPopup(format->plugindb, x, y, format->use_brender)
817 this->format = format;
820 FormatFormat::~FormatFormat()
824 int FormatFormat::handle_event()
826 BC_ListBoxItem *selection = get_selection(0, 0);
828 int new_format = File::strtoformat(format->plugindb, get_selection(0, 0)->get_text());
829 // if(new_format != format->asset->format)
831 format->asset->format = new_format;
832 format->format_text->update(selection->get_text());
833 format->update_extension();
834 format->close_format_windows();
835 format->update_format();
842 FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
843 : FFMPEGPopup(format->plugindb, x, y)
845 this->format = format;
848 FormatFFMPEG::~FormatFFMPEG()
852 int FormatFFMPEG::handle_event()
854 BC_ListBoxItem *selection = get_selection(0, 0);
856 char *text = get_selection(0, 0)->get_text();
857 format->ffmpeg_type->update(text);
858 strcpy(format->asset->fformat, text);
859 strcpy(format->asset->ff_audio_options, "");
860 strcpy(format->asset->ff_video_options, "");
861 format->update_extension();
862 format->close_format_windows();
863 format->update_format();
871 FormatChannels::FormatChannels(int x, int y, FormatTools *format)
872 : BC_TextBox(x, y, 100, 1, format->asset->channels)
874 this->format = format;
877 FormatChannels::~FormatChannels()
881 int FormatChannels::handle_event()
883 format->asset->channels = atol(get_text());
888 FormatToTracks::FormatToTracks(int x, int y, int *output)
889 : BC_CheckBox(x, y, *output, _("Overwrite project with output"))
891 this->output = output;
894 FormatToTracks::~FormatToTracks()
898 int FormatToTracks::handle_event()
900 *output = get_value();
905 FormatMultiple::FormatMultiple(MWindow *mwindow, int x, int y, int *output)
908 (*output == FILE_PER_LABEL) || (*output == FILE_PER_LABEL_FARM),
909 _("Create new file at each label"))
911 this->output = output;
912 this->mwindow = mwindow;
915 FormatMultiple::~FormatMultiple()
919 int FormatMultiple::handle_event()
923 if(mwindow->preferences->use_renderfarm)
924 *output = FILE_PER_LABEL_FARM;
926 *output = FILE_PER_LABEL;
930 if(mwindow->preferences->use_renderfarm)
931 *output = SINGLE_PASS_FARM;
933 *output = SINGLE_PASS;
938 void FormatMultiple::update(int *output)
940 this->output = output;
941 if(*output == FILE_PER_LABEL_FARM ||
942 *output ==FILE_PER_LABEL)