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;
76 prompt_audio_channels = 0;
78 prompt_video_compression = 0;
80 locked_compressor = 0;
84 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;
106 void FormatTools::create_objects(
107 int &init_x, int &init_y,
108 int do_audio, int do_video, // Include support for audio, video
109 int prompt_audio, int prompt_video, // Include checkbox for audio, video
110 int prompt_audio_channels,
111 int prompt_video_compression,
112 const char *locked_compressor,
116 int horizontal_layout)
121 int margin = mwindow->theme->widget_border;
123 this->locked_compressor = locked_compressor;
124 this->recording = recording;
125 this->use_brender = brender;
126 this->do_audio = do_audio;
127 this->do_video = do_video;
128 this->prompt_audio = prompt_audio;
129 this->prompt_audio_channels = prompt_audio_channels;
130 this->prompt_video = prompt_video;
131 this->prompt_video_compression = prompt_video_compression;
132 this->file_per_label = file_per_label;
134 //printf("FormatTools::create_objects 1\n");
139 window->add_subwindow(path_textbox = new FormatPathText(px, y, this));
140 px += path_textbox->get_w() + 5;
141 path_recent = new BC_RecentList("PATH", mwindow->defaults,
142 path_textbox, 10, px, y, 300, 100);
143 window->add_subwindow(path_recent);
144 path_recent->load_items(File::formattostr(asset->format));
145 px += path_recent->get_w();
146 window->add_subwindow(path_button = new BrowseButton(
147 mwindow->theme, window, path_textbox, px, y, asset->path,
148 _("Output to file"), _("Select a file to write to:"), 0));
152 y += path_textbox->get_h() + 10;
161 window->add_subwindow(format_title = new BC_Title(x, y, _("File Format:")));
162 x += format_title->get_w() + margin;
163 window->add_subwindow(format_text = new BC_TextBox(x, y, 160, 1,
164 File::formattostr(asset->format)));
165 x += format_text->get_w() + margin;
166 //printf("FormatTools::create_objects %d %p\n", __LINE__, window);
167 window->add_subwindow(format_button = new FormatFormat(x, y, this));
168 format_button->create_objects();
169 x += format_button->get_w() + 5;
170 window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 70, 1, asset->fformat));
171 FFMPEG::set_asset_format(asset, asset->fformat);
172 x += ffmpeg_type->get_w();
173 window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
174 format_ffmpeg->create_objects();
176 y += format_button->get_h() + 10;
178 window->add_subwindow(audio_title = new BC_Title(x, y, _("Audio:"), LARGEFONT,
179 BC_WindowBase::get_resources()->audiovideo_color));
180 x += audio_title->get_w() + margin;
181 window->add_subwindow(aparams_button = new FormatAParams(mwindow, this, x, y));
182 x += aparams_button->get_w() + margin;
184 window->add_subwindow(audio_switch = new FormatAudio(x, y, this, asset->audio_data));
188 y += aparams_button->get_h() + 10;
190 // Audio channels only used for recording.
191 // if(prompt_audio_channels)
193 // window->add_subwindow(channels_title = new BC_Title(x, y, _("Number of audio channels to record:")));
195 // window->add_subwindow(channels_button = new FormatChannels(x, y, this));
196 // x += channels_button->get_w() + 5;
197 // window->add_subwindow(channels_tumbler = new BC_ITumbler(channels_button, 1, MAXCHANNELS, x, y));
198 // y += channels_button->get_h() + 20;
202 //printf("FormatTools::create_objects 6\n");
203 aparams_thread = new FormatAThread(this);
206 //printf("FormatTools::create_objects 7\n");
208 if( horizontal_layout && do_audio ) {
213 //printf("FormatTools::create_objects 8\n");
214 window->add_subwindow(video_title = new BC_Title(x, y, _("Video:"), LARGEFONT,
215 BC_WindowBase::get_resources()->audiovideo_color));
216 x += video_title->get_w() + margin;
217 if(prompt_video_compression) {
218 window->add_subwindow(vparams_button = new FormatVParams(mwindow, this, x, y));
219 x += vparams_button->get_w() + margin;
222 //printf("FormatTools::create_objects 9\n");
224 window->add_subwindow(video_switch = new FormatVideo(x, y, this, asset->video_data));
225 y += video_switch->get_h();
228 y += vparams_button->get_h();
231 //printf("FormatTools::create_objects 10\n");
233 vparams_thread = new FormatVThread(this);
236 //printf("FormatTools::create_objects 11\n");
239 if( file_per_label ) {
240 multiple_files = new FormatMultiple(mwindow, x, y, file_per_label);
241 window->add_subwindow(multiple_files);
242 y += multiple_files->get_h() + 10;
245 //printf("FormatTools::create_objects 12\n");
251 void FormatTools::update_driver(int driver)
253 this->video_driver = driver;
255 locked_compressor = 0;
259 case VIDEO4LINUX2MPEG:
260 // Just give the user information about how the stream is going to be
261 // stored but don't change the asset.
262 // Want to be able to revert to user settings.
263 if(asset->format == FILE_MPEG) break;
264 asset->format = FILE_MPEG;
265 format_text->update(File::formattostr(asset->format));
266 asset->audio_data = 1;
267 asset->video_data = 1;
268 audio_switch->update(1);
269 video_switch->update(1);
272 case CAPTURE_IEC61883:
273 case CAPTURE_FIREWIRE:
274 case VIDEO4LINUX2JPEG:
275 case CAPTURE_JPEG_WEBCAM:
276 asset->format = FILE_FFMPEG;
277 format_text->update(File::formattostr(asset->format));
280 case CAPTURE_IEC61883:
281 case CAPTURE_FIREWIRE:
282 locked_compressor = (char*)CODEC_TAG_DVSD;
285 case VIDEO4LINUX2JPEG:
286 locked_compressor = (char*)CODEC_TAG_MJPEG;
289 case CAPTURE_JPEG_WEBCAM:
290 locked_compressor = (char*)CODEC_TAG_JPEG;
293 if( locked_compressor )
294 strcpy(asset->vcodec, locked_compressor);
296 audio_switch->update(asset->audio_data);
297 video_switch->update(asset->video_data);
301 format_text->update(File::formattostr(asset->format));
302 audio_switch->update(asset->audio_data);
303 video_switch->update(asset->video_data);
306 close_format_windows();
310 void FormatTools::update_format()
312 if( do_audio && prompt_audio && audio_switch ) {
313 audio_switch->update(asset->audio_data);
314 if( File::renders_audio(asset) )
315 audio_switch->enable();
317 audio_switch->disable();
319 if( do_video && prompt_video && video_switch ) {
320 video_switch->update(asset->video_data);
321 if( File::renders_video(asset) )
322 video_switch->enable();
324 video_switch->disable();
326 if( asset->format == FILE_FFMPEG ) {
328 format_ffmpeg->show();
332 format_ffmpeg->hide();
336 int FormatTools::handle_event()
341 Asset* FormatTools::get_asset()
346 void FormatTools::update_extension()
348 const char *extension = File::get_tag(asset->format);
349 // split multiple extensions
350 ArrayList<const char*> extensions;
351 int len = !extension ? -1 : strlen(extension);
352 const char *extension_ptr = extension;
353 for(int i = 0; i <= len; i++)
355 if(extension[i] == '/' || extension[i] == 0)
357 extensions.append(extension_ptr);
358 extension_ptr = extension + i + 1;
362 if(extensions.size())
364 char *ptr = strrchr(asset->path, '.');
367 ptr = asset->path + strlen(asset->path);
372 // test for equivalent extension
373 int need_extension = 1;
374 //int extension_len = 0;
375 for(int i = 0; i < extensions.size() && need_extension; i++)
378 extension_ptr = extensions.get(i);
381 while(*ptr1 != 0 && *extension_ptr != 0 && *extension_ptr != '/')
383 if(tolower(*ptr1) != tolower(*extension_ptr))
393 *extension_ptr != 0 &&
394 *extension_ptr != '/')
398 //printf("FormatTools::update_extension %d %d\n", __LINE__, need_extension);
403 extension_ptr = asset->format != FILE_FFMPEG ?
404 extensions.get(0) : asset->fformat;
405 while(*extension_ptr != 0 && *extension_ptr != '/')
406 *ptr1++ = *extension_ptr++;
410 int character1 = ptr - asset->path;
411 int character2 = strlen(asset->path);
412 // *(asset->path + character2) = 0;
415 path_textbox->update(asset->path);
416 path_textbox->set_selection(character1, character2, character2);
421 void FormatTools::update(Asset *asset, int *file_per_label)
424 this->file_per_label = file_per_label;
425 if( file_per_label ) multiple_files->update(file_per_label);
426 if( path_textbox ) path_textbox->update(asset->path);
427 format_text->update(File::formattostr(asset->format));
429 close_format_windows();
432 void FormatTools::close_format_windows()
434 // This is done in ~file
435 if( aparams_thread ) {
436 if( aparams_thread->running() )
437 aparams_thread->file->close_window();
438 aparams_thread->join();
440 if( vparams_thread ) {
441 if( vparams_thread->running() )
442 vparams_thread->file->close_window();
443 vparams_thread->join();
447 int FormatTools::get_w()
449 return asset->format != FILE_FFMPEG ? w :
450 format_ffmpeg->get_x() + format_ffmpeg->get_w();
453 void FormatTools::set_w(int w)
458 void FormatTools::reposition_window(int &init_x, int &init_y)
466 path_textbox->reposition_window(px, y);
467 px += path_textbox->get_w() + 5;
468 path_recent->reposition_window(px, y);
469 px += path_recent->get_w() + 8;
470 path_button->reposition_window(px, y);
471 y += path_textbox->get_h() + 10;
474 format_title->reposition_window(x, y);
476 format_text->reposition_window(x, y);
477 x += format_text->get_w();
478 format_button->reposition_window(x, y);
481 y += format_button->get_h() + 10;
485 audio_title->reposition_window(x, y);
487 aparams_button->reposition_window(x, y);
488 x += aparams_button->get_w() + 10;
489 if(prompt_audio) audio_switch->reposition_window(x, y);
492 y += aparams_button->get_h() + 10;
493 if(prompt_audio_channels)
495 channels_title->reposition_window(x, y);
497 channels_button->reposition_window(x, y);
498 x += channels_button->get_w() + 5;
499 channels_tumbler->reposition_window(x, y);
500 y += channels_button->get_h() + 20;
508 video_title->reposition_window(x, y);
510 if(prompt_video_compression)
512 vparams_button->reposition_window(x, y);
513 x += vparams_button->get_w() + 10;
518 video_switch->reposition_window(x, y);
519 y += video_switch->get_h();
523 y += vparams_button->get_h();
530 if( file_per_label ) {
531 multiple_files->reposition_window(x, y);
532 y += multiple_files->get_h() + 10;
539 int FormatTools::set_audio_options()
541 // if(video_driver == CAPTURE_DVB)
546 if(!aparams_thread->running())
548 aparams_thread->start();
552 aparams_thread->file->raise_window();
557 int FormatTools::set_video_options()
559 // if(video_driver == CAPTURE_DVB)
564 if(!vparams_thread->running())
566 vparams_thread->start();
570 vparams_thread->file->raise_window();
580 FormatAParams::FormatAParams(MWindow *mwindow, FormatTools *format, int x, int y)
581 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
583 this->format = format;
584 set_tooltip(_("Configure audio compression"));
587 FormatAParams::~FormatAParams()
591 int FormatAParams::handle_event()
593 format->set_audio_options();
601 FormatVParams::FormatVParams(MWindow *mwindow, FormatTools *format, int x, int y)
602 : BC_Button(x, y, mwindow->theme->get_image_set("wrench"))
604 this->format = format;
605 set_tooltip(_("Configure video compression"));
608 FormatVParams::~FormatVParams()
612 int FormatVParams::handle_event()
614 format->set_video_options();
622 FormatAThread::FormatAThread(FormatTools *format)
625 this->format = format;
630 FormatAThread::~FormatAThread()
632 delete file; file = 0;
636 void FormatAThread::start()
644 void FormatAThread::run()
646 file->get_options(format, 1, 0);
652 FormatVThread::FormatVThread(FormatTools *format)
655 this->format = format;
660 FormatVThread::~FormatVThread()
662 delete file; file = 0;
666 void FormatVThread::start()
673 void FormatVThread::run()
675 file->get_options(format, 0, 1);
682 FormatPathText::FormatPathText(int x, int y, FormatTools *format)
683 : BC_TextBox(x, y, format->w - x -
684 2*format->mwindow->theme->get_image_set("wrench")[0]->get_w() - 20, 1,
687 this->format = format;
690 FormatPathText::~FormatPathText()
693 int FormatPathText::handle_event()
695 calculate_suggestions();
696 strcpy(format->asset->path, get_text());
697 format->handle_event();
704 FormatAudio::FormatAudio(int x, int y, FormatTools *format, int default_)
708 (char*)(format->recording ? _("Record audio tracks") : _("Render audio tracks")))
710 this->format = format;
713 FormatAudio::~FormatAudio() {}
714 int FormatAudio::handle_event()
716 format->asset->audio_data = get_value();
721 FormatVideo::FormatVideo(int x, int y, FormatTools *format, int default_)
725 (char*)(format->recording ? _("Record video tracks") : _("Render video tracks")))
727 this->format = format;
730 FormatVideo::~FormatVideo() {}
731 int FormatVideo::handle_event()
733 format->asset->video_data = get_value();
740 FormatFormat::FormatFormat(int x, int y, FormatTools *format)
741 : FormatPopup(x, y, format->do_audio, format->do_video, format->use_brender)
743 this->format = format;
746 FormatFormat::~FormatFormat()
750 int FormatFormat::handle_event()
752 BC_ListBoxItem *selection = get_selection(0, 0);
754 int new_format = File::strtoformat(get_selection(0, 0)->get_text());
755 // if(new_format != format->asset->format)
757 Asset *asset = format->asset;
758 asset->format = new_format;
759 asset->audio_data = File::renders_audio(asset);
760 asset->video_data = File::renders_video(asset);
761 asset->ff_audio_options[0] = 0;
762 asset->ff_video_options[0] = 0;
763 format->format_text->update(selection->get_text());
764 if( !format->use_brender )
765 format->update_extension();
766 format->close_format_windows();
767 if (format->path_recent) format->path_recent->
768 load_items(File::formattostr(format->asset->format));
769 format->update_format();
776 FormatFFMPEG::FormatFFMPEG(int x, int y, FormatTools *format)
777 : FFMPEGPopup(format->plugindb, x, y)
779 this->format = format;
782 FormatFFMPEG::~FormatFFMPEG()
786 int FormatFFMPEG::handle_event()
788 BC_ListBoxItem *selection = get_selection(0, 0);
790 char *text = get_selection(0, 0)->get_text();
791 format->ffmpeg_type->update(text);
792 format->asset->ff_audio_options[0] = 0;
793 format->asset->ff_video_options[0] = 0;
794 FFMPEG::set_asset_format(format->asset, text);
795 format->update_extension();
796 format->close_format_windows();
797 format->update_format();
805 FormatChannels::FormatChannels(int x, int y, FormatTools *format)
806 : BC_TextBox(x, y, 100, 1, format->asset->channels)
808 this->format = format;
811 FormatChannels::~FormatChannels()
815 int FormatChannels::handle_event()
817 format->asset->channels = atol(get_text());
822 FormatToTracks::FormatToTracks(int x, int y, int *output)
823 : BC_CheckBox(x, y, *output, _("Overwrite project with output"))
825 this->output = output;
828 FormatToTracks::~FormatToTracks()
832 int FormatToTracks::handle_event()
834 *output = get_value();
839 FormatMultiple::FormatMultiple(MWindow *mwindow, int x, int y, int *output)
840 : BC_CheckBox(x, y, *output, _("Create new file at each label"))
842 this->output = output;
843 this->mwindow = mwindow;
846 FormatMultiple::~FormatMultiple()
850 int FormatMultiple::handle_event()
852 *output = get_value();
856 void FormatMultiple::update(int *output)
858 this->output = output;
859 set_value(*output ? 1 : 0);