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;
72 prompt_audio_channels = 0;
74 prompt_video_compression = 0;
76 locked_compressor = 0;
80 FormatTools::~FormatTools()
91 if(aparams_button) delete aparams_button;
93 if(vparams_button) delete vparams_button;
95 if(aparams_thread) delete aparams_thread;
97 if(vparams_thread) delete vparams_thread;
101 void FormatTools::create_objects(
102 int &init_x, int &init_y,
103 int do_audio, int do_video, // Include support for audio, video
104 int prompt_audio, int prompt_video, // Include checkbox for audio, video
105 int prompt_audio_channels,
106 int prompt_video_compression,
107 const char *locked_compressor,
111 int horizontal_layout)
116 int margin = mwindow->theme->widget_border;
118 this->locked_compressor = locked_compressor;
119 this->recording = recording;
120 this->use_brender = brender;
121 this->do_audio = do_audio;
122 this->do_video = do_video;
123 this->prompt_audio = prompt_audio;
124 this->prompt_audio_channels = prompt_audio_channels;
125 this->prompt_video = prompt_video;
126 this->prompt_video_compression = prompt_video_compression;
127 this->file_per_label = file_per_label;
129 //printf("FormatTools::create_objects 1\n");
134 window->add_subwindow(path_textbox = new FormatPathText(px, y, this));
135 px += path_textbox->get_w() + 5;
136 path_recent = new BC_RecentList("PATH", mwindow->defaults,
137 path_textbox, 10, px, y, 300, 100);
138 window->add_subwindow(path_recent);
139 path_recent->load_items(File::formattostr(asset->format));
140 px += path_recent->get_w();
141 window->add_subwindow(path_button = new BrowseButton(
142 mwindow->theme, window, path_textbox, px, y, asset->path,
143 _("Output to file"), _("Select a file to write to:"), 0));
147 y += path_textbox->get_h() + 10;
156 window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
157 x += format_title->get_w() + margin;
158 window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1,
159 File::formattostr(asset->format)));
160 x += format_text->get_w() + margin;
161 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
162 window->add_subwindow(format_button = new FormatFormat(x, y, this));
163 format_button->create_objects();
164 x += format_button->get_w() + 5;
165 window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 70, 1, asset->fformat));
166 FFMPEG::set_asset_format(asset, mwindow->edl, asset->fformat);
167 x += ffmpeg_type->get_w();
168 window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
169 format_ffmpeg->create_objects();
171 y += format_button->get_h() + 10;
173 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT,
174 BC_WindowBase::get_resources()->audiovideo_color));
175 x += audio_title->get_w() + margin;
176 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
177 x += aparams_button->get_w() + margin;
179 window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
183 y += aparams_button->get_h() + 10;
185 //printf("FormatTools::create_objects 6\n");
186 aparams_thread = new FormatAThread(this);
189 //printf("FormatTools::create_objects 7\n");
191 if( horizontal_layout && do_audio ) {
196 //printf("FormatTools::create_objects 8\n");
197 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT,
198 BC_WindowBase::get_resources()->audiovideo_color));
199 x += video_title->get_w() + margin;
200 if(prompt_video_compression) {
201 window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
202 x += vparams_button->get_w() + margin;
205 //printf("FormatTools::create_objects 9\n");
207 window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
208 y += video_switch->get_h();
211 y += vparams_button->get_h();
214 //printf("FormatTools::create_objects 10\n");
216 vparams_thread = new FormatVThread(this);
219 //printf("FormatTools::create_objects 11\n");
222 if( file_per_label ) {
223 labeled_files = new FormatFilePerLabel(this, x, y, file_per_label);
224 window->add_subwindow(labeled_files);
225 y += labeled_files->get_h() + 10;
228 //printf("FormatTools::create_objects 12\n");
234 void FormatTools::update_driver(int driver)
236 this->video_driver = driver;
238 locked_compressor = 0;
242 case VIDEO4LINUX2MPEG:
243 // Just give the user information about how the stream is going to be
244 // stored but don't change the asset.
245 // Want to be able to revert to user settings.
246 if(asset->format == FILE_MPEG) break;
247 asset->format = FILE_MPEG;
248 format_text->update(File::formattostr(asset->format));
249 asset->audio_data = 1;
250 asset->video_data = 1;
251 audio_switch->update(1);
252 video_switch->update(1);
255 case CAPTURE_IEC61883:
256 case CAPTURE_FIREWIRE:
257 case VIDEO4LINUX2JPEG:
258 case CAPTURE_JPEG_WEBCAM:
259 asset->format = FILE_FFMPEG;
260 format_text->update(File::formattostr(asset->format));
263 case CAPTURE_IEC61883:
264 case CAPTURE_FIREWIRE:
265 locked_compressor = (char*)CODEC_TAG_DVSD;
268 case VIDEO4LINUX2JPEG:
269 locked_compressor = (char*)CODEC_TAG_MJPEG;
272 case CAPTURE_JPEG_WEBCAM:
273 locked_compressor = (char*)CODEC_TAG_JPEG;
276 if( locked_compressor )
277 strcpy(asset->vcodec, locked_compressor);
279 audio_switch->update(asset->audio_data);
280 video_switch->update(asset->video_data);
284 format_text->update(File::formattostr(asset->format));
285 audio_switch->update(asset->audio_data);
286 video_switch->update(asset->video_data);
289 close_format_windows();
293 void FormatTools::update_format()
295 if( do_audio && prompt_audio && audio_switch ) {
296 audio_switch->update(asset->audio_data);
297 if( File::renders_audio(asset) )
298 audio_switch->enable();
300 audio_switch->disable();
302 if( do_video && prompt_video && video_switch ) {
303 video_switch->update(asset->video_data);
304 if( File::renders_video(asset) )
305 video_switch->enable();
307 video_switch->disable();
309 if( asset->format == FILE_FFMPEG ) {
311 format_ffmpeg->show();
315 format_ffmpeg->hide();
319 int FormatTools::handle_event()
324 Asset* FormatTools::get_asset()
329 void FormatTools::update_extension()
331 const char *extension = File::get_tag(asset->format);
332 // split multiple extensions
333 ArrayList<const char*> extensions;
334 int len = !extension ? -1 : strlen(extension);
335 const char *extension_ptr = extension;
336 for(int i = 0; i <= len; i++)
338 if(extension[i] == '/' || extension[i] == 0)
340 extensions.append(extension_ptr);
341 extension_ptr = extension + i + 1;
345 if(extensions.size())
347 char *ptr = strrchr(asset->path, '.');
350 ptr = asset->path + strlen(asset->path);
355 // test for equivalent extension
356 int need_extension = 1;
357 //int extension_len = 0;
358 for(int i = 0; i < extensions.size() && need_extension; i++)
361 extension_ptr = extensions.get(i);
364 while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
366 if(tolower(*ptr1) != tolower(*extension_ptr))
376 *extension_ptr != 0 &&
377 *extension_ptr != '/')
381 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
386 extension_ptr = asset->format != FILE_FFMPEG ?
387 extensions.get(0) : asset->fformat;
388 while(*extension_ptr != 0 && *extension_ptr != '/')
389 *ptr1++ = *extension_ptr++;
393 int character1 = ptr - asset->path;
394 int character2 = strlen(asset->path);
395 // *(asset->path + character2) = 0;
398 path_textbox->update(asset->path);
399 path_textbox->set_selection(character1, character2, character2);
404 void FormatTools::update(Asset *asset, int *file_per_label)
407 this->file_per_label = file_per_label;
408 if( file_per_label ) labeled_files->update(file_per_label);
409 if( path_textbox ) path_textbox->update(asset->path);
410 format_text->update(File::formattostr(asset->format));
412 close_format_windows();
415 void FormatTools::close_format_windows()
417 // This is done in ~file
418 if( aparams_thread ) {
419 if( aparams_thread->running() )
420 aparams_thread->file->close_window();
421 aparams_thread->join();
423 if( vparams_thread ) {
424 if( vparams_thread->running() )
425 vparams_thread->file->close_window();
426 vparams_thread->join();
430 int FormatTools::get_w()
432 return asset->format != FILE_FFMPEG ? w :
433 format_ffmpeg->get_x() + format_ffmpeg->get_w();
436 void FormatTools::set_w(int w)
441 void FormatTools::reposition_window(int &init_x, int &init_y)
449 path_textbox->reposition_window(px, y);
450 px += path_textbox->get_w() + 5;
451 path_recent->reposition_window(px, y);
452 px += path_recent->get_w() + 8;
453 path_button->reposition_window(px, y);
454 y += path_textbox->get_h() + 10;
457 format_title->reposition_window(x, y);
459 format_text->reposition_window(x, y);
460 x += format_text->get_w();
461 format_button->reposition_window(x, y);
464 y += format_button->get_h() + 10;
468 audio_title->reposition_window(x, y);
470 aparams_button->reposition_window(x, y);
471 x += aparams_button->get_w() + 10;
472 if(prompt_audio) audio_switch->reposition_window(x, y);
475 y += aparams_button->get_h() + 10;
481 video_title->reposition_window(x, y);
483 if(prompt_video_compression)
485 vparams_button->reposition_window(x, y);
486 x += vparams_button->get_w() + 10;
491 video_switch->reposition_window(x, y);
492 y += video_switch->get_h();
496 y += vparams_button->get_h();
503 if( file_per_label ) {
504 labeled_files->reposition_window(x, y);
505 y += labeled_files->get_h() + 10;
512 int FormatTools::set_audio_options()
514 // if(video_driver == CAPTURE_DVB)
519 if(!aparams_thread->running())
521 aparams_thread->start();
525 aparams_thread->file->raise_window();
530 int FormatTools::set_video_options()
532 // if(video_driver == CAPTURE_DVB)
537 if(!vparams_thread->running())
539 vparams_thread->start();
543 vparams_thread->file->raise_window();
553 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
554 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
556 this->format = format;
557 set_tooltip(_("Configure audio compression"));
560 FormatAParams::~FormatAParams()
564 int FormatAParams::handle_event()
566 format->set_audio_options();
567 format->handle_event();
575 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
576 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
578 this->format = format;
579 set_tooltip(_("Configure video compression"));
582 FormatVParams::~FormatVParams()
586 int FormatVParams::handle_event()
588 format->set_video_options();
589 format->handle_event();
597 FormatAThread::FormatAThread(FormatTools *format)
600 this->format = format;
605 FormatAThread::~FormatAThread()
607 delete file; file = 0;
611 void FormatAThread::start()
619 void FormatAThread::run()
621 file->get_options(format, 1, 0);
627 FormatVThread::FormatVThread(FormatTools *format)
630 this->format = format;
635 FormatVThread::~FormatVThread()
637 delete file; file = 0;
641 void FormatVThread::start()
648 void FormatVThread::run()
650 file->get_options(format, 0, 1);
657 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
658 : BC_TextBox(x, y, format->w - x -
659 2*format->mwindow->theme->get_image_set("wrench")[0]->get_w() - 20, 1,
662 this->format = format;
665 FormatPathText::~FormatPathText()
668 int FormatPathText::handle_event()
670 calculate_suggestions();
671 strcpy(format->asset->path, get_text());
672 format->handle_event();
679 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
683 (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
685 this->format = format;
688 FormatAudio::~FormatAudio() {}
689 int FormatAudio::handle_event()
691 format->asset->audio_data = get_value();
692 format->handle_event();
697 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
701 (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
703 this->format = format;
706 FormatVideo::~FormatVideo() {}
707 int FormatVideo::handle_event()
709 format->asset->video_data = get_value();
710 format->handle_event();
717 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
718 : FormatPopup(x, y, format->do_audio, format->do_video, format->use_brender)
720 this->format = format;
723 FormatFormat::~FormatFormat()
727 int FormatFormat::handle_event()
729 BC_ListBoxItem *selection = get_selection(0, 0);
731 int new_format = File::strtoformat(get_selection(0, 0)->get_text());
732 // if(new_format != format->asset->format)
734 Asset *asset = format->asset;
735 asset->format = new_format;
736 asset->audio_data = File::renders_audio(asset);
737 asset->video_data = File::renders_video(asset);
738 asset->ff_audio_options[0] = 0;
739 asset->ff_video_options[0] = 0;
740 format->format_text->update(selection->get_text());
741 if( !format->use_brender )
742 format->update_extension();
743 format->close_format_windows();
744 if (format->path_recent) format->path_recent->
745 load_items(File::formattostr(format->asset->format));
746 format->update_format();
748 format->handle_event();
754 FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
757 this->format = format;
760 FormatFFMPEG::~FormatFFMPEG()
764 int FormatFFMPEG::handle_event()
766 BC_ListBoxItem *selection = get_selection(0, 0);
768 char *text = get_selection(0, 0)->get_text();
769 format->ffmpeg_type->update(text);
770 format->asset->ff_audio_options[0] = 0;
771 format->asset->ff_video_options[0] = 0;
772 FFMPEG::set_asset_format(format->asset, format->mwindow->edl, text);
773 format->update_extension();
774 format->close_format_windows();
775 format->update_format();
776 format->handle_event();
782 FormatFilePerLabel::FormatFilePerLabel(FormatTools *format,
783 int x, int y, int *output)
784 : BC_CheckBox(x, y, *output, _("Create new file at each label"))
786 this->format = format;
787 this->output = output;
790 FormatFilePerLabel::~FormatFilePerLabel()
794 int FormatFilePerLabel::handle_event()
796 *output = get_value();
797 format->handle_event();
801 void FormatFilePerLabel::update(int *output)
803 this->output = output;
804 set_value(*output ? 1 : 0);