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"
32 #include "maxchannels.h"
34 #include "preferences.h"
36 #include "videodevice.inc"
42 FormatTools::FormatTools(MWindow *mwindow,
43 BC_WindowBase *window,
46 this->mwindow = mwindow;
47 this->window = window;
49 this->plugindb = mwindow->plugindb;
78 prompt_audio_channels = 0;
80 prompt_video_compression = 0;
82 locked_compressor = 0;
86 FormatTools::~FormatTools()
97 if(aparams_button) delete aparams_button;
99 if(vparams_button) delete vparams_button;
101 if(aparams_thread) delete aparams_thread;
103 if(vparams_thread) delete vparams_thread;
105 if(channels_tumbler) delete channels_tumbler;
108 void FormatTools::create_objects(int &init_x,
110 int do_audio, // Include support for audio
111 int do_video, // Include support for video
112 int prompt_audio, // Include checkbox for audio
114 int prompt_audio_channels,
115 int prompt_video_compression,
116 const char *locked_compressor,
120 int horizontal_layout)
126 this->locked_compressor = locked_compressor;
127 this->recording = recording;
128 this->use_brender = brender;
129 this->do_audio = do_audio;
130 this->do_video = do_video;
131 this->prompt_audio = prompt_audio;
132 this->prompt_audio_channels = prompt_audio_channels;
133 this->prompt_video = prompt_video;
134 this->prompt_video_compression = prompt_video_compression;
135 this->strategy = strategy;
137 //printf("FormatTools::create_objects 1\n");
139 // Modify strategy depending on render farm
142 if(mwindow->preferences->use_renderfarm)
144 if(*strategy == FILE_PER_LABEL)
145 *strategy = FILE_PER_LABEL_FARM;
147 if(*strategy == SINGLE_PASS)
148 *strategy = SINGLE_PASS_FARM;
152 if(*strategy == FILE_PER_LABEL_FARM)
153 *strategy = FILE_PER_LABEL;
155 if(*strategy == SINGLE_PASS_FARM)
156 *strategy = SINGLE_PASS;
163 window->add_subwindow(path_textbox = new FormatPathText(px, y, this));
164 px += path_textbox->get_w() + 5;
165 path_recent = new BC_RecentList("PATH", mwindow->defaults,
166 path_textbox, 10, px, y, 300, 100);
167 window->add_subwindow(path_recent);
168 path_recent->load_items(File::formattostr(asset->format));
169 px += path_recent->get_w();
170 window->add_subwindow(path_button = new BrowseButton(
171 mwindow->theme, window, path_textbox, px, y, asset->path,
172 _("Output to file"), _("Select a file to write to:"), 0));
176 y += path_textbox->get_h() + 10;
185 window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
187 window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1,
188 File::formattostr(asset->format)));
189 x += format_text->get_w();
190 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
191 window->add_subwindow(format_button = new FormatFormat(x, y, this));
192 format_button->create_objects();
193 x += format_button->get_w() + 5;
194 window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 64, 1, asset->fformat));
195 FFMPEG::set_asset_format(asset, asset->fformat);
196 x += ffmpeg_type->get_w();
197 window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
198 format_ffmpeg->create_objects();
200 y += format_button->get_h() + 10;
203 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT, BC_WindowBase::get_resources()->audiovideo_color));
205 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
206 x += aparams_button->get_w() + 10;
209 window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
213 y += aparams_button->get_h() + 10;
215 // Audio channels only used for recording.
216 // if(prompt_audio_channels)
218 // window->add_subwindow(channels_title = new BC_Title(x, y, _("Number of audio channels to record:")));
220 // window->add_subwindow(channels_button = new FormatChannels(x, y, this));
221 // x += channels_button->get_w() + 5;
222 // window->add_subwindow(channels_tumbler = new BC_ITumbler(channels_button, 1, MAXCHANNELS, x, y));
223 // y += channels_button->get_h() + 20;
227 //printf("FormatTools::create_objects 6\n");
228 aparams_thread = new FormatAThread(this);
231 //printf("FormatTools::create_objects 7\n");
234 if(horizontal_layout && do_audio){
239 //printf("FormatTools::create_objects 8\n");
240 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT, BC_WindowBase::get_resources()->audiovideo_color));
242 if(prompt_video_compression)
244 window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
245 x += vparams_button->get_w() + 10;
248 //printf("FormatTools::create_objects 9\n");
251 window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
252 y += video_switch->get_h();
256 y += vparams_button->get_h();
259 //printf("FormatTools::create_objects 10\n");
261 vparams_thread = new FormatVThread(this);
264 //printf("FormatTools::create_objects 11\n");
269 window->add_subwindow(multiple_files = new FormatMultiple(mwindow, x, y, strategy));
270 y += multiple_files->get_h() + 10;
273 //printf("FormatTools::create_objects 12\n");
279 void FormatTools::update_driver(int driver)
281 this->video_driver = driver;
283 locked_compressor = 0;
287 case VIDEO4LINUX2MPEG:
288 // Just give the user information about how the stream is going to be
289 // stored but don't change the asset.
290 // Want to be able to revert to user settings.
291 if(asset->format == FILE_MPEG) break;
292 asset->format = FILE_MPEG;
293 format_text->update(File::formattostr(asset->format));
294 asset->audio_data = 1;
295 asset->video_data = 1;
296 audio_switch->update(1);
297 video_switch->update(1);
300 case CAPTURE_IEC61883:
301 case CAPTURE_FIREWIRE:
302 case VIDEO4LINUX2JPEG:
303 case CAPTURE_JPEG_WEBCAM:
304 asset->format = FILE_FFMPEG;
305 format_text->update(File::formattostr(asset->format));
308 case CAPTURE_IEC61883:
309 case CAPTURE_FIREWIRE:
310 locked_compressor = (char*)CODEC_TAG_DVSD;
313 case VIDEO4LINUX2JPEG:
314 locked_compressor = (char*)CODEC_TAG_MJPEG;
317 case CAPTURE_JPEG_WEBCAM:
318 locked_compressor = (char*)CODEC_TAG_JPEG;
321 if( locked_compressor )
322 strcpy(asset->vcodec, locked_compressor);
324 audio_switch->update(asset->audio_data);
325 video_switch->update(asset->video_data);
329 format_text->update(File::formattostr(asset->format));
330 audio_switch->update(asset->audio_data);
331 video_switch->update(asset->video_data);
334 close_format_windows();
338 void FormatTools::update_format()
340 if( do_audio && prompt_audio && audio_switch ) {
341 audio_switch->update(asset->audio_data);
342 if( !asset->audio_data )
343 audio_switch->disable();
345 audio_switch->enable();
347 if( do_video && prompt_video && video_switch ) {
348 video_switch->update(asset->video_data);
349 if( !asset->video_data )
350 video_switch->disable();
352 video_switch->enable();
354 if( asset->format == FILE_FFMPEG ) {
356 format_ffmpeg->show();
360 format_ffmpeg->hide();
364 int FormatTools::handle_event()
369 Asset* FormatTools::get_asset()
374 void FormatTools::update_extension()
376 const char *extension = File::get_tag(asset->format);
377 // split multiple extensions
378 ArrayList<const char*> extensions;
379 int len = !extension ? -1 : strlen(extension);
380 const char *extension_ptr = extension;
381 for(int i = 0; i <= len; i++)
383 if(extension[i] == '/' || extension[i] == 0)
385 extensions.append(extension_ptr);
386 extension_ptr = extension + i + 1;
390 if(extensions.size())
392 char *ptr = strrchr(asset->path, '.');
395 ptr = asset->path + strlen(asset->path);
400 // test for equivalent extension
401 int need_extension = 1;
402 //int extension_len = 0;
403 for(int i = 0; i < extensions.size() && need_extension; i++)
406 extension_ptr = extensions.get(i);
409 while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
411 if(tolower(*ptr1) != tolower(*extension_ptr))
421 *extension_ptr != 0 &&
422 *extension_ptr != '/')
426 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
431 extension_ptr = asset->format != FILE_FFMPEG ?
432 extensions.get(0) : asset->fformat;
433 while(*extension_ptr != 0 && *extension_ptr != '/')
434 *ptr1++ = *extension_ptr++;
438 int character1 = ptr - asset->path;
439 int character2 = strlen(asset->path);
440 // *(asset->path + character2) = 0;
443 path_textbox->update(asset->path);
444 path_textbox->set_selection(character1, character2, character2);
449 void FormatTools::update(Asset *asset, int *strategy)
452 this->strategy = strategy;
455 path_textbox->update(asset->path);
456 format_text->update(File::formattostr(plugindb, asset->format));
457 if(do_audio && prompt_audio && audio_switch)
458 audio_switch->update(asset->audio_data);
459 if(do_video && prompt_video && video_switch)
460 video_switch->update(asset->video_data);
463 multiple_files->update(strategy);
465 close_format_windows();
468 void FormatTools::close_format_windows()
470 // This is done in ~file
471 if( aparams_thread ) {
472 if( aparams_thread->running() )
473 aparams_thread->file->close_window();
474 aparams_thread->join();
476 if( vparams_thread ) {
477 if( vparams_thread->running() )
478 vparams_thread->file->close_window();
479 vparams_thread->join();
483 int FormatTools::get_w()
485 return asset->format != FILE_FFMPEG ? w :
486 format_ffmpeg->get_x() + format_ffmpeg->get_w();
489 void FormatTools::set_w(int w)
494 void FormatTools::reposition_window(int &init_x, int &init_y)
502 path_textbox->reposition_window(px, y);
503 px += path_textbox->get_w() + 5;
504 path_recent->reposition_window(px, y);
505 px += path_recent->get_w() + 8;
506 path_button->reposition_window(px, y);
507 y += path_textbox->get_h() + 10;
510 format_title->reposition_window(x, y);
512 format_text->reposition_window(x, y);
513 x += format_text->get_w();
514 format_button->reposition_window(x, y);
517 y += format_button->get_h() + 10;
521 audio_title->reposition_window(x, y);
523 aparams_button->reposition_window(x, y);
524 x += aparams_button->get_w() + 10;
525 if(prompt_audio) audio_switch->reposition_window(x, y);
528 y += aparams_button->get_h() + 10;
529 if(prompt_audio_channels)
531 channels_title->reposition_window(x, y);
533 channels_button->reposition_window(x, y);
534 x += channels_button->get_w() + 5;
535 channels_tumbler->reposition_window(x, y);
536 y += channels_button->get_h() + 20;
544 video_title->reposition_window(x, y);
546 if(prompt_video_compression)
548 vparams_button->reposition_window(x, y);
549 x += vparams_button->get_w() + 10;
554 video_switch->reposition_window(x, y);
555 y += video_switch->get_h();
559 y += vparams_button->get_h();
568 multiple_files->reposition_window(x, y);
569 y += multiple_files->get_h() + 10;
576 int FormatTools::set_audio_options()
578 // if(video_driver == CAPTURE_DVB)
583 if(!aparams_thread->running())
585 aparams_thread->start();
589 aparams_thread->file->raise_window();
594 int FormatTools::set_video_options()
596 // if(video_driver == CAPTURE_DVB)
601 if(!vparams_thread->running())
603 vparams_thread->start();
607 vparams_thread->file->raise_window();
617 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
618 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
620 this->format = format;
621 set_tooltip(_("Configure audio compression"));
624 FormatAParams::~FormatAParams()
628 int FormatAParams::handle_event()
630 format->set_audio_options();
638 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
639 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
641 this->format = format;
642 set_tooltip(_("Configure video compression"));
645 FormatVParams::~FormatVParams()
649 int FormatVParams::handle_event()
651 format->set_video_options();
659 FormatAThread::FormatAThread(FormatTools *format)
662 this->format = format;
667 FormatAThread::~FormatAThread()
669 delete file; file = 0;
673 void FormatAThread::start()
681 void FormatAThread::run()
683 file->get_options(format, 1, 0);
689 FormatVThread::FormatVThread(FormatTools *format)
692 this->format = format;
697 FormatVThread::~FormatVThread()
699 delete file; file = 0;
703 void FormatVThread::start()
710 void FormatVThread::run()
712 file->get_options(format, 0, 1);
719 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
720 : BC_TextBox(x, y, format->w - x -
721 2*format->mwindow->theme->get_image_set("wrench")[0]->get_w() - 20, 1,
724 this->format = format;
727 FormatPathText::~FormatPathText()
730 int FormatPathText::handle_event()
732 calculate_suggestions();
733 strcpy(format->asset->path, get_text());
734 format->handle_event();
741 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
745 (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
747 this->format = format;
750 FormatAudio::~FormatAudio() {}
751 int FormatAudio::handle_event()
753 format->asset->audio_data = get_value();
758 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
762 (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
764 this->format = format;
767 FormatVideo::~FormatVideo() {}
768 int FormatVideo::handle_event()
770 format->asset->video_data = get_value();
777 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
778 : FormatPopup(format->plugindb, x, y, format->use_brender)
780 this->format = format;
783 FormatFormat::~FormatFormat()
787 int FormatFormat::handle_event()
789 BC_ListBoxItem *selection = get_selection(0, 0);
791 int new_format = File::strtoformat(format->plugindb, get_selection(0, 0)->get_text());
792 // if(new_format != format->asset->format)
794 Asset *asset = format->asset;
795 asset->format = new_format;
796 asset->audio_data = File::supports_audio(asset->format);
797 asset->video_data = File::supports_video(asset->format);
798 asset->ff_audio_options[0] = 0;
799 asset->ff_video_options[0] = 0;
800 format->format_text->update(selection->get_text());
801 format->update_extension();
802 format->close_format_windows();
803 if (format->path_recent) format->path_recent->
804 load_items(File::formattostr(format->asset->format));
805 format->update_format();
812 FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
813 : FFMPEGPopup(format->plugindb, x, y)
815 this->format = format;
818 FormatFFMPEG::~FormatFFMPEG()
822 int FormatFFMPEG::handle_event()
824 BC_ListBoxItem *selection = get_selection(0, 0);
826 char *text = get_selection(0, 0)->get_text();
827 format->ffmpeg_type->update(text);
828 format->asset->ff_audio_options[0] = 0;
829 format->asset->ff_video_options[0] = 0;
830 FFMPEG::set_asset_format(format->asset, text);
831 format->update_extension();
832 format->close_format_windows();
833 format->update_format();
841 FormatChannels::FormatChannels(int x, int y, FormatTools *format)
842 : BC_TextBox(x, y, 100, 1, format->asset->channels)
844 this->format = format;
847 FormatChannels::~FormatChannels()
851 int FormatChannels::handle_event()
853 format->asset->channels = atol(get_text());
858 FormatToTracks::FormatToTracks(int x, int y, int *output)
859 : BC_CheckBox(x, y, *output, _("Overwrite project with output"))
861 this->output = output;
864 FormatToTracks::~FormatToTracks()
868 int FormatToTracks::handle_event()
870 *output = get_value();
875 FormatMultiple::FormatMultiple(MWindow *mwindow, int x, int y, int *output)
878 (*output == FILE_PER_LABEL) || (*output == FILE_PER_LABEL_FARM),
879 _("Create new file at each label"))
881 this->output = output;
882 this->mwindow = mwindow;
885 FormatMultiple::~FormatMultiple()
889 int FormatMultiple::handle_event()
893 if(mwindow->preferences->use_renderfarm)
894 *output = FILE_PER_LABEL_FARM;
896 *output = FILE_PER_LABEL;
900 if(mwindow->preferences->use_renderfarm)
901 *output = SINGLE_PASS_FARM;
903 *output = SINGLE_PASS;
908 void FormatMultiple::update(int *output)
910 this->output = output;
911 if(*output == FILE_PER_LABEL_FARM ||
912 *output ==FILE_PER_LABEL)