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;
73 prompt_audio_channels = 0;
75 prompt_video_compression = 0;
77 locked_compressor = 0;
81 FormatTools::~FormatTools()
92 if(aparams_button) delete aparams_button;
94 if(vparams_button) delete vparams_button;
96 if(aparams_thread) delete aparams_thread;
98 if(vparams_thread) delete vparams_thread;
102 void FormatTools::create_objects(
103 int &init_x, int &init_y,
104 int do_audio, int do_video, // Include support for audio, video
105 int prompt_audio, int prompt_video, // Include checkbox for audio, video
106 int prompt_audio_channels,
107 int prompt_video_compression,
108 const char *locked_compressor,
112 int horizontal_layout)
117 int margin = mwindow->theme->widget_border;
119 this->locked_compressor = locked_compressor;
120 this->recording = recording;
121 this->use_brender = brender;
122 this->do_audio = do_audio;
123 this->do_video = do_video;
124 this->prompt_audio = prompt_audio;
125 this->prompt_audio_channels = prompt_audio_channels;
126 this->prompt_video = prompt_video;
127 this->prompt_video_compression = prompt_video_compression;
128 this->file_per_label = file_per_label;
130 //printf("FormatTools::create_objects 1\n");
135 window->add_subwindow(path_textbox = new FormatPathText(px, y, this));
136 px += path_textbox->get_w() + 5;
137 path_recent = new BC_RecentList("PATH", mwindow->defaults,
138 path_textbox, 10, px, y, 300, 100);
139 window->add_subwindow(path_recent);
140 path_recent->load_items(File::formattostr(asset->format));
141 px += path_recent->get_w();
142 window->add_subwindow(path_button = new BrowseButton(
143 mwindow->theme, window, path_textbox, px, y, asset->path,
144 _("Output to file"), _("Select a file to write to:"), 0));
148 y += path_textbox->get_h() + 10;
157 window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
158 x += format_title->get_w() + margin;
159 window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1,
160 File::formattostr(asset->format)));
161 x += format_text->get_w() + margin;
162 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
163 window->add_subwindow(format_button = new FormatFormat(x, y, this));
164 format_button->create_objects();
165 x += format_button->get_w() + 5;
166 window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 70, 1, asset->fformat));
167 FFMPEG::set_asset_format(asset, asset->fformat);
168 x += ffmpeg_type->get_w();
169 window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
170 format_ffmpeg->create_objects();
172 y += format_button->get_h() + 10;
174 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT,
175 BC_WindowBase::get_resources()->audiovideo_color));
176 x += audio_title->get_w() + margin;
177 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
178 x += aparams_button->get_w() + margin;
180 window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
184 y += aparams_button->get_h() + 10;
186 //printf("FormatTools::create_objects 6\n");
187 aparams_thread = new FormatAThread(this);
190 //printf("FormatTools::create_objects 7\n");
192 if( horizontal_layout && do_audio ) {
197 //printf("FormatTools::create_objects 8\n");
198 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT,
199 BC_WindowBase::get_resources()->audiovideo_color));
200 x += video_title->get_w() + margin;
201 if(prompt_video_compression) {
202 window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
203 x += vparams_button->get_w() + margin;
206 //printf("FormatTools::create_objects 9\n");
208 window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
209 y += video_switch->get_h();
212 y += vparams_button->get_h();
215 //printf("FormatTools::create_objects 10\n");
217 vparams_thread = new FormatVThread(this);
220 //printf("FormatTools::create_objects 11\n");
223 if( file_per_label ) {
224 labeled_files = new FormatFilePerLabel(this, x, y, file_per_label);
225 window->add_subwindow(labeled_files);
226 y += labeled_files->get_h() + 10;
229 //printf("FormatTools::create_objects 12\n");
235 void FormatTools::update_driver(int driver)
237 this->video_driver = driver;
239 locked_compressor = 0;
243 case VIDEO4LINUX2MPEG:
244 // Just give the user information about how the stream is going to be
245 // stored but don't change the asset.
246 // Want to be able to revert to user settings.
247 if(asset->format == FILE_MPEG) break;
248 asset->format = FILE_MPEG;
249 format_text->update(File::formattostr(asset->format));
250 asset->audio_data = 1;
251 asset->video_data = 1;
252 audio_switch->update(1);
253 video_switch->update(1);
256 case CAPTURE_IEC61883:
257 case CAPTURE_FIREWIRE:
258 case VIDEO4LINUX2JPEG:
259 case CAPTURE_JPEG_WEBCAM:
260 asset->format = FILE_FFMPEG;
261 format_text->update(File::formattostr(asset->format));
264 case CAPTURE_IEC61883:
265 case CAPTURE_FIREWIRE:
266 locked_compressor = (char*)CODEC_TAG_DVSD;
269 case VIDEO4LINUX2JPEG:
270 locked_compressor = (char*)CODEC_TAG_MJPEG;
273 case CAPTURE_JPEG_WEBCAM:
274 locked_compressor = (char*)CODEC_TAG_JPEG;
277 if( locked_compressor )
278 strcpy(asset->vcodec, locked_compressor);
280 audio_switch->update(asset->audio_data);
281 video_switch->update(asset->video_data);
285 format_text->update(File::formattostr(asset->format));
286 audio_switch->update(asset->audio_data);
287 video_switch->update(asset->video_data);
290 close_format_windows();
294 void FormatTools::update_format()
296 if( do_audio && prompt_audio && audio_switch ) {
297 audio_switch->update(asset->audio_data);
298 if( File::renders_audio(asset) )
299 audio_switch->enable();
301 audio_switch->disable();
303 if( do_video && prompt_video && video_switch ) {
304 video_switch->update(asset->video_data);
305 if( File::renders_video(asset) )
306 video_switch->enable();
308 video_switch->disable();
310 if( asset->format == FILE_FFMPEG ) {
312 format_ffmpeg->show();
316 format_ffmpeg->hide();
320 int FormatTools::handle_event()
325 Asset* FormatTools::get_asset()
330 void FormatTools::update_extension()
332 const char *extension = File::get_tag(asset->format);
333 // split multiple extensions
334 ArrayList<const char*> extensions;
335 int len = !extension ? -1 : strlen(extension);
336 const char *extension_ptr = extension;
337 for(int i = 0; i <= len; i++)
339 if(extension[i] == '/' || extension[i] == 0)
341 extensions.append(extension_ptr);
342 extension_ptr = extension + i + 1;
346 if(extensions.size())
348 char *ptr = strrchr(asset->path, '.');
351 ptr = asset->path + strlen(asset->path);
356 // test for equivalent extension
357 int need_extension = 1;
358 //int extension_len = 0;
359 for(int i = 0; i < extensions.size() && need_extension; i++)
362 extension_ptr = extensions.get(i);
365 while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
367 if(tolower(*ptr1) != tolower(*extension_ptr))
377 *extension_ptr != 0 &&
378 *extension_ptr != '/')
382 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
387 extension_ptr = asset->format != FILE_FFMPEG ?
388 extensions.get(0) : asset->fformat;
389 while(*extension_ptr != 0 && *extension_ptr != '/')
390 *ptr1++ = *extension_ptr++;
394 int character1 = ptr - asset->path;
395 int character2 = strlen(asset->path);
396 // *(asset->path + character2) = 0;
399 path_textbox->update(asset->path);
400 path_textbox->set_selection(character1, character2, character2);
405 void FormatTools::update(Asset *asset, int *file_per_label)
408 this->file_per_label = file_per_label;
409 if( file_per_label ) labeled_files->update(file_per_label);
410 if( path_textbox ) path_textbox->update(asset->path);
411 format_text->update(File::formattostr(asset->format));
413 close_format_windows();
416 void FormatTools::close_format_windows()
418 // This is done in ~file
419 if( aparams_thread ) {
420 if( aparams_thread->running() )
421 aparams_thread->file->close_window();
422 aparams_thread->join();
424 if( vparams_thread ) {
425 if( vparams_thread->running() )
426 vparams_thread->file->close_window();
427 vparams_thread->join();
431 int FormatTools::get_w()
433 return asset->format != FILE_FFMPEG ? w :
434 format_ffmpeg->get_x() + format_ffmpeg->get_w();
437 void FormatTools::set_w(int w)
442 void FormatTools::reposition_window(int &init_x, int &init_y)
450 path_textbox->reposition_window(px, y);
451 px += path_textbox->get_w() + 5;
452 path_recent->reposition_window(px, y);
453 px += path_recent->get_w() + 8;
454 path_button->reposition_window(px, y);
455 y += path_textbox->get_h() + 10;
458 format_title->reposition_window(x, y);
460 format_text->reposition_window(x, y);
461 x += format_text->get_w();
462 format_button->reposition_window(x, y);
465 y += format_button->get_h() + 10;
469 audio_title->reposition_window(x, y);
471 aparams_button->reposition_window(x, y);
472 x += aparams_button->get_w() + 10;
473 if(prompt_audio) audio_switch->reposition_window(x, y);
476 y += aparams_button->get_h() + 10;
482 video_title->reposition_window(x, y);
484 if(prompt_video_compression)
486 vparams_button->reposition_window(x, y);
487 x += vparams_button->get_w() + 10;
492 video_switch->reposition_window(x, y);
493 y += video_switch->get_h();
497 y += vparams_button->get_h();
504 if( file_per_label ) {
505 labeled_files->reposition_window(x, y);
506 y += labeled_files->get_h() + 10;
513 int FormatTools::set_audio_options()
515 // if(video_driver == CAPTURE_DVB)
520 if(!aparams_thread->running())
522 aparams_thread->start();
526 aparams_thread->file->raise_window();
531 int FormatTools::set_video_options()
533 // if(video_driver == CAPTURE_DVB)
538 if(!vparams_thread->running())
540 vparams_thread->start();
544 vparams_thread->file->raise_window();
554 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
555 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
557 this->format = format;
558 set_tooltip(_("Configure audio compression"));
561 FormatAParams::~FormatAParams()
565 int FormatAParams::handle_event()
567 format->set_audio_options();
568 format->handle_event();
576 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
577 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
579 this->format = format;
580 set_tooltip(_("Configure video compression"));
583 FormatVParams::~FormatVParams()
587 int FormatVParams::handle_event()
589 format->set_video_options();
590 format->handle_event();
598 FormatAThread::FormatAThread(FormatTools *format)
601 this->format = format;
606 FormatAThread::~FormatAThread()
608 delete file; file = 0;
612 void FormatAThread::start()
620 void FormatAThread::run()
622 file->get_options(format, 1, 0);
628 FormatVThread::FormatVThread(FormatTools *format)
631 this->format = format;
636 FormatVThread::~FormatVThread()
638 delete file; file = 0;
642 void FormatVThread::start()
649 void FormatVThread::run()
651 file->get_options(format, 0, 1);
658 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
659 : BC_TextBox(x, y, format->w - x -
660 2*format->mwindow->theme->get_image_set("wrench")[0]->get_w() - 20, 1,
663 this->format = format;
666 FormatPathText::~FormatPathText()
669 int FormatPathText::handle_event()
671 calculate_suggestions();
672 strcpy(format->asset->path, get_text());
673 format->handle_event();
680 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
684 (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
686 this->format = format;
689 FormatAudio::~FormatAudio() {}
690 int FormatAudio::handle_event()
692 format->asset->audio_data = get_value();
693 format->handle_event();
698 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
702 (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
704 this->format = format;
707 FormatVideo::~FormatVideo() {}
708 int FormatVideo::handle_event()
710 format->asset->video_data = get_value();
711 format->handle_event();
718 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
719 : FormatPopup(x, y, format->do_audio, format->do_video, format->use_brender)
721 this->format = format;
724 FormatFormat::~FormatFormat()
728 int FormatFormat::handle_event()
730 BC_ListBoxItem *selection = get_selection(0, 0);
732 int new_format = File::strtoformat(get_selection(0, 0)->get_text());
733 // if(new_format != format->asset->format)
735 Asset *asset = format->asset;
736 asset->format = new_format;
737 asset->audio_data = File::renders_audio(asset);
738 asset->video_data = File::renders_video(asset);
739 asset->ff_audio_options[0] = 0;
740 asset->ff_video_options[0] = 0;
741 format->format_text->update(selection->get_text());
742 if( !format->use_brender )
743 format->update_extension();
744 format->close_format_windows();
745 if (format->path_recent) format->path_recent->
746 load_items(File::formattostr(format->asset->format));
747 format->update_format();
749 format->handle_event();
755 FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
756 : FFMPEGPopup(format->plugindb, x, y)
758 this->format = format;
761 FormatFFMPEG::~FormatFFMPEG()
765 int FormatFFMPEG::handle_event()
767 BC_ListBoxItem *selection = get_selection(0, 0);
769 char *text = get_selection(0, 0)->get_text();
770 format->ffmpeg_type->update(text);
771 format->asset->ff_audio_options[0] = 0;
772 format->asset->ff_video_options[0] = 0;
773 FFMPEG::set_asset_format(format->asset, text);
774 format->update_extension();
775 format->close_format_windows();
776 format->update_format();
777 format->handle_event();
783 FormatFilePerLabel::FormatFilePerLabel(FormatTools *format,
784 int x, int y, int *output)
785 : BC_CheckBox(x, y, *output, _("Create new file at each label"))
787 this->format = format;
788 this->output = output;
791 FormatFilePerLabel::~FormatFilePerLabel()
795 int FormatFilePerLabel::handle_event()
797 *output = get_value();
798 format->handle_event();
802 void FormatFilePerLabel::update(int *output)
804 this->output = output;
805 set_value(*output ? 1 : 0);