X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffileffmpeg.C;h=a6437242ddd633973252b2fcac7a9f9f4bab9e84;hb=83b70dd60863377cb281e6be5206304e10373e30;hp=f7ad943934f153ca70f73cd414ae96a73d530c90;hpb=a0d43979126b586d50b2de48056ae48fa8d0bb1d;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C index f7ad9439..a6437242 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.C +++ b/cinelerra-5.1/cinelerra/fileffmpeg.C @@ -18,6 +18,7 @@ #include "fileffmpeg.h" #include "filesystem.h" #include "indexfile.h" +#include "interlacemodes.h" #include "language.h" #include "mainerror.h" #include "mainprogress.h" @@ -45,7 +46,7 @@ FileFFMPEG::~FileFFMPEG() FFMpegConfigNum::FFMpegConfigNum(BC_Window *window, int x, int y, char *title_text, int *output) - : BC_TumbleTextBox(window, *output, -1, INT_MAX, 100, y, 100) + : BC_TumbleTextBox(window, *output, -1, INT_MAX, xS(100), y, xS(100)) { this->window = window; this->x = x; this->y = y; @@ -158,7 +159,7 @@ void FFMpegPixelFormat::update_formats() pixfmts.remove_all_objects(); char video_codec[BCSTRLEN]; video_codec[0] = 0; const char *vcodec = vid_config->asset->vcodec; - AVCodec *av_codec = !FFMPEG::get_codec(video_codec, "video", vcodec) ? + const AVCodec *av_codec = !FFMPEG::get_codec(video_codec, "video", vcodec) ? avcodec_find_encoder_by_name(video_codec) : 0; const AVPixelFormat *pix_fmts = av_codec ? av_codec->pix_fmts : 0; if( pix_fmts ) { @@ -189,7 +190,7 @@ void FFMpegSampleFormat::update_formats() samplefmts.remove_all_objects(); char audio_codec[BCSTRLEN]; audio_codec[0] = 0; const char *acodec = aud_config->asset->acodec; - AVCodec *av_codec = !FFMPEG::get_codec(audio_codec, "audio", acodec) ? + const AVCodec *av_codec = !FFMPEG::get_codec(audio_codec, "audio", acodec) ? avcodec_find_encoder_by_name(audio_codec) : 0; const AVSampleFormat *sample_fmts = av_codec ? av_codec->sample_fmts : 0; if( sample_fmts ) { @@ -215,8 +216,11 @@ void FileFFMPEG::get_parameters(BC_WindowBase *parent_window, { Asset *ff_asset = new Asset(); ff_asset->copy_from(asset, 0); + int wx, wy; + parent_window->get_pop_cursor(wx, wy); if( audio_options ) { - FFMPEGConfigAudio *window = new FFMPEGConfigAudio(parent_window, ff_asset, edl); + FFMPEGConfigAudio *window = new FFMPEGConfigAudio(parent_window, + wx, wy, ff_asset, edl); format_window = window; window->create_objects(); if( !window->run_window() ) { @@ -228,7 +232,8 @@ void FileFFMPEG::get_parameters(BC_WindowBase *parent_window, delete window; } else if( video_options ) { - FFMPEGConfigVideo *window = new FFMPEGConfigVideo(parent_window, ff_asset, edl); + FFMPEGConfigVideo *window = new FFMPEGConfigVideo(parent_window, + wx, wy, ff_asset, edl); format_window = window; window->create_objects(); if( !window->run_window() ) { @@ -321,7 +326,7 @@ int FileFFMPEG::open_file(int rd, int wr) int result = 0; if( ff ) return 1; ff = new FFMPEG(this); - + if( rd ) { result = ff->init_decoder(asset->path); if( !result ) result = ff->open_decoder(); @@ -337,6 +342,12 @@ int FileFFMPEG::open_file(int rd, int wr) int video_layers = ff->ff_total_video_layers(); if( video_layers > 0 ) { asset->video_data = 1; + asset->aspect_ratio = ff->ff_aspect_ratio(0); + if (!asset->interlace_mode) asset->interlace_mode = ff->ff_interlace(0); + if ( ff->ff_video_frames(0) > 1 ) { +// ff->video_probe(1); + if (!asset->interlace_mode && (ff->interlace_from_codec) ) asset->interlace_mode = ff->video_probe(1); + } if( !asset->layers ) asset->layers = video_layers; asset->actual_width = ff->ff_video_width(0); asset->actual_height = ff->ff_video_height(0); @@ -346,7 +357,11 @@ int FileFFMPEG::open_file(int rd, int wr) (asset->video_length = ff->ff_video_frames(0)) < 2 ) asset->video_length = asset->video_length < 0 ? 0 : -1; if( !asset->frame_rate ) asset->frame_rate = ff->ff_frame_rate(0); - strcpy(asset->vcodec, ff->ff_video_format(0)); + if( asset->ff_color_range < 0 ) + asset->ff_color_range = ff->ff_color_range(0); + if( asset->ff_color_space < 0 ) + asset->ff_color_space = ff->ff_color_space(0); + strcpy(asset->vcodec, ff->ff_video_codec(0)); } IndexState *index_state = asset->index_state; index_state->read_markers(file->preferences->index_directory, asset->path); @@ -455,33 +470,78 @@ int FileFFMPEG::get_best_colormodel(Asset *asset, int driver) return BC_YUV420P; } -//====== -FFMPEGConfigAudio::FFMPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset, EDL *edl) - : BC_Window(_(PROGRAM_NAME ": Audio Preset"), - parent_window->get_abs_cursor_x(1), - parent_window->get_abs_cursor_y(1), - 420, 420) +FFMPEGConfigWindow::FFMPEGConfigWindow(const char *title, + BC_WindowBase *parent_window, + int x, int y, int w, int h, + Asset *asset, EDL *edl) + : BC_Window(title, x, y, w, h) { this->parent_window = parent_window; this->asset = asset; this->edl = edl; - preset_popup = 0; + avctx = 0; + fmt_ctx = 0; + ff_options_dialog = 0; + format_name = 0; + codec_name = 0; +} +FFMPEGConfigWindow::~FFMPEGConfigWindow() +{ + delete ff_options_dialog; +} + +void FFMPEGConfigWindow::start(AVCodecContext *avctx) +{ + this->avctx = avctx; + ff_options_dialog->start(); +} + +void FFMPEGConfigWindow::start(AVFormatContext *fmt_ctx) +{ + this->fmt_ctx = fmt_ctx; + ff_options_dialog->start(); +} + +//====== + +FFMPEGConfigAudio::FFMPEGConfigAudio(BC_WindowBase *parent_window, + int x, int y, Asset *asset, EDL *edl) + : FFMPEGConfigWindow(_(PROGRAM_NAME ": Audio Preset"), parent_window, x, y, + xS(420), yS(420), asset, edl) +{ + preset_popup = 0; bitrate = 0; audio_options = 0; - ff_options_dialog = 0; + format_name = asset->fformat; + codec_name = asset->acodec; +// *** CONTEXT_HELP *** + context_help_set_keyword("Options for Render with FFmpeg"); } FFMPEGConfigAudio::~FFMPEGConfigAudio() { - delete ff_options_dialog; lock_window("FFMPEGConfigAudio::~FFMPEGConfigAudio"); delete preset_popup; presets.remove_all_objects(); + delete audio_options; unlock_window(); } +void FFMPEGConfigAudio::read_options() +{ + const char *options = audio_options->get_text(); + int options_len = strlen(options); + ff_options_dialog->load_options(options, options_len); +} +void FFMPEGConfigAudio::save_options() +{ + char options[BCTEXTLEN]; + ff_options_dialog->store_options(options, sizeof(options)-1); + audio_options->update(options); +} + void FFMPEGConfigAudio::load_options() { FFMPEG::load_audio_options(asset, edl); @@ -489,7 +549,7 @@ void FFMPEGConfigAudio::load_options() void FFMPEGConfigAudio::create_objects() { - int x = 10, y = 10; + int x = xS(10), y = yS(10); lock_window("FFMPEGConfigAudio::create_objects"); FileSystem fs; @@ -517,11 +577,11 @@ void FFMPEGConfigAudio::create_objects() strcpy(asset->acodec, presets[0]->get_text()); add_tool(new BC_Title(x, y, _("Preset:"))); - y += 25; + y += yS(25); preset_popup = new FFMPEGConfigAudioPopup(this, x, y); preset_popup->create_objects(); - y += 50; + y += yS(50); bitrate = new FFMpegAudioBitrate(this, x, y, _("Bitrate:"), &asset->ff_audio_bitrate); bitrate->create_objects(); bitrate->set_increment(1000); @@ -531,10 +591,10 @@ void FFMPEGConfigAudio::create_objects() quality->create_objects(); quality->set_increment(1); quality->set_boundaries((int64_t)-1, (int64_t)51); - y += quality->get_h() + 10; + y += quality->get_h() + yS(10); add_subwindow(new BC_Title(x, y, _("Samples:"))); - sample_format = new FFMpegSampleFormat(this, x+90, y, 100, 120); + sample_format = new FFMpegSampleFormat(this, x+xS(90), y, xS(100), yS(120)); sample_format->create_objects(); if( asset->acodec[0] ) { sample_format->update_formats(); @@ -543,17 +603,20 @@ void FFMPEGConfigAudio::create_objects() } if( !asset->ff_sample_format[0] ) strcpy(asset->ff_sample_format, _("None")); sample_format->update(asset->ff_sample_format); - y += sample_format->get_h() + 10; + y += sample_format->get_h() + yS(10); BC_Title *title = new BC_Title(x, y, _("Audio Options:")); add_subwindow(title); ff_options_dialog = new FFOptionsAudioDialog(this); - int x1 = x + title->get_w() + 8; - add_subwindow(new FFOptionsViewAudio(this, x1, y, _("view"))); - - y += 25; - audio_options = new FFAudioOptions(this, x, y, get_w()-x-20, 8, + int x1 = x + title->get_w() + xS(8); + add_subwindow(view_audio = new FFOptionsViewAudio(this, x1, y, _("view"))); + x1 += x + view_audio->get_w() + xS(20); + view_format = new FFOptionsViewFormat(this, edl, asset, x1, y, _("format")); + add_subwindow(view_format); + + y += yS(25); + audio_options = new FFAudioOptions(this, x, y, get_w()-x-xS(20), 8, sizeof(asset->ff_audio_options)-1, asset->ff_audio_options); audio_options->create_objects(); add_subwindow(new BC_OKButton(this)); @@ -584,7 +647,7 @@ FFAudioOptions::FFAudioOptions(FFMPEGConfigAudio *audio_popup, FFMPEGConfigAudioPopup::FFMPEGConfigAudioPopup(FFMPEGConfigAudio *popup, int x, int y) - : BC_PopupTextBox(popup, &popup->presets, popup->asset->acodec, x, y, 300, 300) + : BC_PopupTextBox(popup, &popup->presets, popup->asset->acodec, x, y, xS(300), yS(300)) { this->popup = popup; } @@ -605,50 +668,48 @@ int FFMPEGConfigAudioPopup::handle_event() return 1; } - -FFMPEGConfigAudioToggle::FFMPEGConfigAudioToggle(FFMPEGConfigAudio *popup, - char *title_text, int x, int y, int *output) - : BC_CheckBox(x, y, *output, title_text) -{ - this->popup = popup; - this->output = output; -} -int FFMPEGConfigAudioToggle::handle_event() -{ - *output = get_value(); - return 1; -} - //====== -FFMPEGConfigVideo::FFMPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset, EDL *edl) - : BC_Window(_(PROGRAM_NAME ": Video Preset"), - parent_window->get_abs_cursor_x(1), - parent_window->get_abs_cursor_y(1), - 420, 420) +FFMPEGConfigVideo::FFMPEGConfigVideo(BC_WindowBase *parent_window, + int x, int y, Asset *asset, EDL *edl) + : FFMPEGConfigWindow(_(PROGRAM_NAME ": Video Preset"), parent_window, x, y, + xS(420), yS(420), asset, edl) { - this->parent_window = parent_window; - this->asset = asset; - this->edl = edl; preset_popup = 0; - ff_options_dialog = 0; pixel_format = 0; + format_name = asset->fformat; + codec_name = asset->vcodec; bitrate = 0; quality = 0; video_options = 0; +// *** CONTEXT_HELP *** + context_help_set_keyword("Options for Render with FFmpeg"); } FFMPEGConfigVideo::~FFMPEGConfigVideo() { lock_window("FFMPEGConfigVideo::~FFMPEGConfigVideo"); - delete ff_options_dialog; - delete pixel_format; delete preset_popup; + delete pixel_format; + delete video_options; presets.remove_all_objects(); unlock_window(); } +void FFMPEGConfigVideo::read_options() +{ + const char *options = video_options->get_text(); + int options_len = strlen(options); + ff_options_dialog->load_options(options, options_len); +} +void FFMPEGConfigVideo::save_options() +{ + char options[BCTEXTLEN]; + ff_options_dialog->store_options(options, sizeof(options)-1); + video_options->update(options); +} + void FFMPEGConfigVideo::load_options() { FFMPEG::load_video_options(asset, edl); @@ -656,11 +717,11 @@ void FFMPEGConfigVideo::load_options() void FFMPEGConfigVideo::create_objects() { - int x = 10, y = 10; + int x = xS(10), y = yS(10); lock_window("FFMPEGConfigVideo::create_objects"); add_subwindow(new BC_Title(x, y, _("Compression:"))); - y += 25; + y += yS(25); FileSystem fs; char option_path[BCTEXTLEN]; @@ -693,7 +754,7 @@ void FFMPEGConfigVideo::create_objects() asset->ff_video_bitrate = 0; asset->ff_video_quality = -1; } - y += 50; + y += yS(50); bitrate = new FFMpegVideoBitrate(this, x, y, _("Bitrate:"), &asset->ff_video_bitrate); bitrate->create_objects(); bitrate->set_increment(100000); @@ -703,10 +764,10 @@ void FFMPEGConfigVideo::create_objects() quality->create_objects(); quality->set_increment(1); quality->set_boundaries((int64_t)-1, (int64_t)51); - y += quality->get_h() + 10; + y += quality->get_h() + yS(10); add_subwindow(new BC_Title(x, y, _("Pixels:"))); - pixel_format = new FFMpegPixelFormat(this, x+90, y, 100, 120); + pixel_format = new FFMpegPixelFormat(this, x+xS(90), y, xS(100), yS(120)); pixel_format->create_objects(); if( asset->vcodec[0] ) { pixel_format->update_formats(); @@ -715,17 +776,20 @@ void FFMPEGConfigVideo::create_objects() } if( !asset->ff_pixel_format[0] ) strcpy(asset->ff_pixel_format, _("None")); pixel_format->update(asset->ff_pixel_format); - y += pixel_format->get_h() + 10; + y += pixel_format->get_h() + yS(10); BC_Title *title = new BC_Title(x, y, _("Video Options:")); add_subwindow(title); ff_options_dialog = new FFOptionsVideoDialog(this); int x1 = x + title->get_w() + 8; - add_subwindow(new FFOptionsViewVideo(this, x1, y, _("view"))); + add_subwindow(view_video = new FFOptionsViewVideo(this, x1, y, _("view"))); + x1 += x + view_video->get_w() + xS(20); + view_format = new FFOptionsViewFormat(this, edl, asset, x1, y, _("format")); + add_subwindow(view_format); - y += 25; - video_options = new FFVideoOptions(this, x, y, get_w()-x-20, 8, + y += yS(25); + video_options = new FFVideoOptions(this, x, y, get_w()-x-xS(20), 8, sizeof(asset->ff_video_options)-1, asset->ff_video_options); video_options->create_objects(); add_subwindow(new BC_OKButton(this)); @@ -755,7 +819,7 @@ FFVideoOptions::FFVideoOptions(FFMPEGConfigVideo *video_popup, FFMPEGConfigVideoPopup::FFMPEGConfigVideoPopup(FFMPEGConfigVideo *popup, int x, int y) - : BC_PopupTextBox(popup, &popup->presets, popup->asset->vcodec, x, y, 300, 300) + : BC_PopupTextBox(popup, &popup->presets, popup->asset->vcodec, x, y, xS(300), yS(300)) { this->popup = popup; } @@ -776,20 +840,97 @@ int FFMPEGConfigVideoPopup::handle_event() return 1; } +//====== -FFMPEGConfigVideoToggle::FFMPEGConfigVideoToggle(FFMPEGConfigVideo *popup, - char *title_text, int x, int y, int *output) - : BC_CheckBox(x, y, *output, title_text) +FFMPEGConfigFormat::FFMPEGConfigFormat(FFOptionsFormatViewDialog *view_dialog, + int x, int y, Asset *asset, EDL *edl) + : FFMPEGConfigWindow(_(PROGRAM_NAME ": Format Preset"), + view_dialog->view_format, x, y, xS(420), yS(300), asset, edl) { - this->popup = popup; - this->output = output; + this->view_dialog = view_dialog; + format_options = 0; + format_name = asset->fformat; + codec_name = 0; +// *** CONTEXT_HELP *** + context_help_set_keyword("Modifying FFmpeg Format Options"); +} + +FFMPEGConfigFormat::~FFMPEGConfigFormat() +{ + lock_window("FFMPEGConfigFormat::~FFMPEGConfigFormat"); + delete format_options; + unlock_window(); +} + +void FFMPEGConfigFormat::read_options() +{ + const char *options = format_options->get_text(); + int options_len = strlen(options); + ff_options_dialog->load_options(options, options_len); +} +void FFMPEGConfigFormat::save_options() +{ + char options[BCTEXTLEN]; + ff_options_dialog->store_options(options, sizeof(options)-1); + format_options->update(options); +} +void FFMPEGConfigFormat::save_changes() +{ + read_options(); + char *options = asset->ff_format_options; + int options_len = sizeof(asset->ff_format_options)-1; + ff_options_dialog->store_options(options, options_len); +} + +void FFMPEGConfigFormat::load_options() +{ + Asset *asset = view_dialog->view_format->asset; + EDL *edl = view_dialog->view_format->edl; + FFMPEG::load_format_options(asset, edl); } -int FFMPEGConfigVideoToggle::handle_event() + +void FFMPEGConfigFormat::create_objects() +{ + int x = xS(10), y = yS(10); + lock_window("FFMPEGConfigFormat::create_objects"); + Asset *asset = view_dialog->view_format->asset; + BC_Title *title; + add_subwindow(title = new BC_Title(x, y, _("Format:"))); + int x1 = x + title->get_w() + 8; + add_subwindow(new BC_Title(x1, y, asset->fformat)); + y += yS(25); + + add_subwindow(title = new BC_Title(x, y, _("Format Options:"))); + + ff_options_dialog = new FFOptionsFormatDialog(this); + x1 = x + title->get_w() + 8; + add_subwindow(new FFOptionsFormatView(this, x1, y, _("view"))); + + y += yS(25); + format_options = new FFFormatOptions(this, x, y, get_w()-x-xS(20), 8, + sizeof(asset->ff_format_options)-1, asset->ff_format_options); + format_options->create_objects(); + add_subwindow(new BC_OKButton(this)); + add_subwindow(new BC_CancelButton(this)); + show_window(1); + unlock_window(); +} + +int FFMPEGConfigFormat::close_event() { - *output = get_value(); + set_done(1); return 1; } +FFFormatOptions::FFFormatOptions(FFMPEGConfigFormat *format_popup, + int x, int y, int w, int rows, int size, char *text) + : BC_ScrollTextBox(format_popup, x, y, w, rows, text, size) +{ + this->format_popup = format_popup; +} + +//====== + FFMPEGScanProgress::FFMPEGScanProgress(IndexFile *index_file, MainProgressBar *progress_bar, const char *title, int64_t length, int64_t *position, int *canceled) : Thread(1, 0, 0) @@ -889,7 +1030,7 @@ FFOptions_OptPanel:: void FFOptions_OptPanel::create_objects() { const char *cols[] = { _("option"), _("value"), }; - const int col1_w = 150; + const int col1_w = xS(150); int wids[] = { col1_w, get_w()-col1_w }; BC_ListBox::update(&items[0], &cols[0], &wids[0], sizeof(items)/sizeof(items[0])); } @@ -967,7 +1108,7 @@ char *FFOptions_Opt::get(char *vp, int sz) void *obj = (void *)options->obj; uint8_t *bp = 0; if( av_opt_get(obj, opt->name, 0, &bp) >= 0 && bp != 0 ) { - const char *val = (const char *)bp; + const char *val = (const char *)bp; if( opt->unit && *val ) { int id = atoi(val); const char *uid = unit_name(id); @@ -1005,12 +1146,14 @@ int FFOptionsKindItem::handle_event() FFOptionsWindow *fwin = kind->fwin; FFOptions &options = fwin->options; options.initialize(fwin, idx); + kind->set_text(get_text()); fwin->draw(); return 1; } const char *FFOptionsKind::kinds[] = { N_("codec"), // FF_KIND_CODEC + N_("format"), // FF_KIND_FORMAT N_("ffmpeg"), // FF_KIND_FFMPEG }; @@ -1028,8 +1171,8 @@ FFOptionsKind:: void FFOptionsKind::create_objects() { - for( int i=0; i<(int)(sizeof(kinds)/sizeof(kinds[0])); ++i ) - add_item(new FFOptionsKindItem(this, _(kinds[i]), i)); + add_item(new FFOptionsKindItem(this, _(kinds[FF_KIND_CODEC]), FF_KIND_CODEC)); + add_item(new FFOptionsKindItem(this, _(kinds[FF_KIND_FFMPEG]), FF_KIND_FFMPEG)); } int FFOptionsKind::handle_event() @@ -1114,14 +1257,12 @@ int FFOptionsApply::handle_event() FFOptions::FFOptions() { - avctx = 0; obj = 0; } FFOptions::~FFOptions() { remove_all_objects(); - avcodec_free_context(&avctx); } int FFOptions::cmpr(const void *a, const void *b) @@ -1136,21 +1277,21 @@ int FFOptions::cmpr(const void *a, const void *b) void FFOptions::initialize(FFOptionsWindow *win, int kind) { remove_all_objects(); - this->win = win; win->selected = 0; - obj = 0; - if( !avctx ) - avctx = avcodec_alloc_context3(win->dialog->codec); - + const void *obj = 0; switch( kind ) { case FF_KIND_CODEC: - obj = (const void *)avctx->priv_data; + obj = (const void *)win->dialog->cfg_window->avctx->priv_data; break; case FF_KIND_FFMPEG: - obj = (const void *)avctx; + obj = (const void *)win->dialog->cfg_window->avctx; + break; + case FF_KIND_FORMAT: + obj = (const void *)win->dialog->cfg_window->fmt_ctx->priv_data; break; } - + this->win = win; + this->obj = obj; if( obj ) { FFOptions &conf = *this; const AVOption *opt = 0; @@ -1175,10 +1316,8 @@ void FFOptions::initialize(FFOptionsWindow *win, int kind) char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val)); fopt->item_value->update(vp); } + qsort(&values[0],size(),sizeof(values[0]),cmpr); } - - qsort(&values[0],size(),sizeof(values[0]),cmpr); - win->kind->set(kind); win->panel->update(); win->panel->set_yposition(0); } @@ -1454,11 +1593,14 @@ const char *FFOptions_Opt::tip() } -FFOptionsWindow::FFOptionsWindow(FFOptionsDialog *dialog) - : BC_Window(_(PROGRAM_NAME ": Options"), 60, 30, 640, 400) +FFOptionsWindow::FFOptionsWindow(FFOptionsDialog *dialog, int x, int y) + : BC_Window(_(PROGRAM_NAME ": Options"), x, y, xS(640), yS(400)) { this->dialog = dialog; this->selected = 0; + this->kind = 0; +// *** CONTEXT_HELP *** + context_help_set_keyword("Modifying FFmpeg Format Options"); } FFOptionsWindow::~FFOptionsWindow() @@ -1467,50 +1609,59 @@ FFOptionsWindow::~FFOptionsWindow() void FFOptionsWindow::create_objects() { + int xs8 = xS(8), xs10 = xS(10); + int ys10 = yS(10); lock_window("FFOptionsWindow::create_objects"); BC_Title *title; - int x0 = 10, y0 = 10; + const char *format_name = dialog->cfg_window->format_name; + const char *codec_name = dialog->cfg_window->codec_name; + int x0 = xs10, y0 = ys10; int x = x0, y = y0; add_subwindow(title = new BC_Title(x, y, _("Format: "))); x += title->get_w(); - add_subwindow(new BC_Title(x, y, dialog->format_name)); - x = x0 + 150; - add_subwindow(title = new BC_Title(x, y, _("Codec: "))); - x += title->get_w(); - add_subwindow(new BC_Title(x, y, dialog->codec_name)); - - x = x0; y += title->get_h() + 10; y0 = y; + add_subwindow(new BC_Title(x, y, format_name)); + if( codec_name ) { + x = x0 + xS(150); + add_subwindow(title = new BC_Title(x, y, _("Codec: "))); + x += title->get_w(); + add_subwindow(new BC_Title(x, y, codec_name)); + } + x = x0; y += title->get_h() + ys10; y0 = y; add_subwindow(title = new BC_Title(x, y, _("Type: "))); - x += title->get_w() + 8; + x += title->get_w() + xs8; add_subwindow(type = new BC_Title(x, y, (char *)"")); - x = x0 + 150; + x = x0 + xS(150); add_subwindow(title = new BC_Title(x, y, _("Range: "))); - x += title->get_w() + 8; + x += title->get_w() + xs8; add_subwindow(range = new BC_Title(x, y, (char *)"")); - x = x0; y += title->get_h() + 10; - add_subwindow(units = new FFOptionsUnits(this, x, y, 120)); - x += units->get_w() + 8; - int x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - 8; - add_subwindow(text = new FFOptionsText(this, x, y, x1-x - 8)); + x = x0; y += title->get_h() + ys10; + add_subwindow(units = new FFOptionsUnits(this, x, y, xS(120))); + x += units->get_w() + xs8; + int x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - xs8; + add_subwindow(text = new FFOptionsText(this, x, y, x1-x - xs8)); add_subwindow(apply = new FFOptionsApply(this, x1, y)); - y += units->get_h() + 10; - add_subwindow(kind = new FFOptionsKind(this, x1, y0, apply->get_w())); - kind->create_objects(); - const char *kind_text = _("Kind:"); - x1 -= BC_Title::calculate_w(this, kind_text) + 8; - add_subwindow(kind_title = new BC_Title(x1, y0, kind_text)); + y += units->get_h() + ys10; + if( codec_name ) { + add_subwindow(kind = new FFOptionsKind(this, x1, y0, apply->get_w())); + kind->create_objects(); + const char *kind_text = _("Kind:"); + x1 -= BC_Title::calculate_w(this, kind_text) + xs8; + add_subwindow(kind_title = new BC_Title(x1, y0, kind_text)); + } y0 = y; - panel_x = x0; panel_y = y0; - panel_w = get_w()-10 - panel_x; - panel_h = get_h()-10 - panel_y - BC_OKButton::calculate_h(); + panel_w = get_w()-xs10 - panel_x; + panel_h = get_h()-ys10 - panel_y - BC_OKButton::calculate_h(); panel = new FFOptions_OptPanel(this, panel_x, panel_y, panel_w, panel_h); add_subwindow(panel); add_subwindow(new BC_OKButton(this)); add_subwindow(new BC_CancelButton(this)); panel->create_objects(); - options.initialize(this, FF_KIND_CODEC); + int k = codec_name ? FF_KIND_CODEC : FF_KIND_FORMAT; + options.initialize(this, k); + if( kind ) + kind->set(k); draw(); show_window(1); unlock_window(); @@ -1523,41 +1674,44 @@ void FFOptionsWindow::draw() int FFOptionsWindow::resize_event(int w, int h) { - int x1 = w - 8 - kind->get_w(); - int y = kind->get_y(); - kind->reposition_window(x1, y); - x1 -= kind_title->get_w() + 8; - kind_title->reposition_window(x1,y); - x1 = get_w() - apply->get_w() - 8; + int xs8 = xS(8), xs10 = xS(10); + int ys10 = yS(10); + if( kind ) { + int x0 = w - xs8 - kind->get_w(); + int y0 = kind->get_y(); + kind->reposition_window(x0, y0); + x0 -= kind_title->get_w() + xs8; + kind_title->reposition_window(x0, y0); + } + int x1 = get_w() - apply->get_w() - xs8; int y1 = units->get_y(); apply->reposition_window(x1, y1); - int x0 = units->get_x() + units->get_w() + 8; + int x0 = units->get_x() + units->get_w() + xs8; int y0 = units->get_y(); - text->reposition_window(x0,y0, x1-x0-8); - panel_w = get_w()-10 - panel_x; - panel_h = get_h()-10 - panel_y; + text->reposition_window(x0,y0, x1-x0-xs8); + panel_w = get_w()-xs10 - panel_x; + panel_h = get_h()-ys10 - panel_y - BC_OKButton::calculate_h(); panel->reposition_window(panel_x,panel_y, panel_w, panel_h); return 1; } -FFOptionsDialog::FFOptionsDialog() +FFOptionsDialog::FFOptionsDialog(FFMPEGConfigWindow *cfg_window) : BC_DialogThread() { - this->options_window = 0; - this->codec_name = 0; - this->codec = 0; - this->ff_opts = 0; - this->ff_len = 0; + this->cfg_window = cfg_window; + options_window = 0; + ff_opts = 0; } FFOptionsDialog::~FFOptionsDialog() { close_window(); - delete [] codec_name; + av_dict_free(&ff_opts); } void FFOptionsDialog::load_options(const char *bp, int len) { + av_dict_free(&ff_opts); char line[BCTEXTLEN]; char key[BCSTRLEN], val[BCTEXTLEN]; const char *dp = bp + len-1; @@ -1592,8 +1746,8 @@ void FFOptionsDialog::store_options(char *cp, int len) *cp = 0; } -void FFOptionsDialog::start(const char *format_name, const char *codec_name, - AVCodec *codec, const char *options, int len) + +void FFOptionsDialog::start() { if( options_window ) { options_window->lock_window("FFOptionsDialog::start"); @@ -1601,20 +1755,14 @@ void FFOptionsDialog::start(const char *format_name, const char *codec_name, options_window->unlock_window(); return; } - - this->format_name = cstrdup(format_name); - this->codec_name = cstrdup(codec_name); - this->codec = codec; - this->ff_opts = 0; - this->ff_len = len; - load_options(options, len); - + cfg_window->get_pop_cursor(wx, wy); + cfg_window->read_options(); BC_DialogThread::start(); } BC_Window* FFOptionsDialog::new_gui() { - options_window = new FFOptionsWindow(this); + options_window = new FFOptionsWindow(this, wx, wy); options_window->create_objects(); return options_window; } @@ -1622,17 +1770,15 @@ BC_Window* FFOptionsDialog::new_gui() void FFOptionsDialog::handle_done_event(int result) { if( !result ) { - char options[ff_len]; - store_options(options, ff_len); - update_options(options); + cfg_window->lock_window("FFMPEGConfigFormat::save_options"); + cfg_window->save_options(); + cfg_window->unlock_window(); } options_window = 0; - delete [] format_name; format_name = 0; - delete [] codec_name; codec_name = 0; - av_dict_free(&ff_opts); } FFOptionsAudioDialog::FFOptionsAudioDialog(FFMPEGConfigAudio *aud_config) + : FFOptionsDialog(aud_config) { this->aud_config = aud_config; } @@ -1644,10 +1790,13 @@ FFOptionsAudioDialog::~FFOptionsAudioDialog() void FFOptionsAudioDialog::update_options(const char *options) { + aud_config->lock_window("FFOptionsAudioDialog::update_options"); aud_config->audio_options->update(options); + aud_config->unlock_window(); } FFOptionsVideoDialog::FFOptionsVideoDialog(FFMPEGConfigVideo *vid_config) + : FFOptionsDialog(vid_config) { this->vid_config = vid_config; } @@ -1659,65 +1808,197 @@ FFOptionsVideoDialog::~FFOptionsVideoDialog() void FFOptionsVideoDialog::update_options(const char *options) { + vid_config->lock_window("FFOptionsVideoDialog::update_options"); vid_config->video_options->update(options); + vid_config->unlock_window(); } +FFOptionsFormatDialog::FFOptionsFormatDialog(FFMPEGConfigFormat *fmt_config) + : FFOptionsDialog(fmt_config) +{ + this->fmt_config = fmt_config; +} -FFOptionsViewAudio::FFOptionsViewAudio(FFMPEGConfigAudio *aud_config, int x, int y, const char *text) +FFOptionsFormatDialog::~FFOptionsFormatDialog() +{ + close_window(); +} + +void FFOptionsFormatDialog::update_options(const char *options) +{ + fmt_config->lock_window("FFOptionsFormatDialog::update_options"); + fmt_config->format_options->update(options); + fmt_config->unlock_window(); +} + + +FFOptionsViewAudio::FFOptionsViewAudio(FFMPEGConfigAudio *aud_config, + int x, int y, const char *text) : BC_GenericButton(x, y, text) { this->aud_config = aud_config; + avctx = 0; } FFOptionsViewAudio::~FFOptionsViewAudio() { + avcodec_free_context(&avctx); } int FFOptionsViewAudio::handle_event() { - char audio_format[BCSTRLEN]; audio_format[0] = 0; - char audio_codec[BCSTRLEN]; audio_codec[0] = 0; - AVCodec *codec = 0; + int ret = 0; Asset *asset = aud_config->asset; const char *name = asset->acodec; - if( !FFMPEG::get_format(audio_format, "audio", name) && - !FFMPEG::get_codec(audio_codec, "audio", name) ) - codec = avcodec_find_encoder_by_name(audio_codec); - if( !codec ) { + char audio_format[BCSTRLEN]; audio_format[0] = 0; + char audio_codec[BCSTRLEN]; audio_codec[0] = 0; + const AVCodec *codec = !ret && + !FFMPEG::get_format(audio_format, "audio", name) && + !FFMPEG::get_codec(audio_codec, "audio", name) ? + avcodec_find_encoder_by_name(audio_codec) : 0; + if( !ret && !codec ) { eprintf(_("no codec named: %s: %s"), name, audio_codec); - return 1; + ret = 1; + } + avcodec_free_context(&avctx); + if( !ret && !(avctx = avcodec_alloc_context3(codec)) ) { + eprintf(_("no codec context: %s: %s"), name, audio_codec); + ret = 1; } - aud_config->ff_options_dialog->start(audio_format, audio_codec, codec, - asset->ff_audio_options, sizeof(asset->ff_audio_options)); + if( !ret ) + aud_config->start(avctx); return 1; } -FFOptionsViewVideo::FFOptionsViewVideo(FFMPEGConfigVideo *vid_config, int x, int y, const char *text) +FFOptionsViewVideo::FFOptionsViewVideo(FFMPEGConfigVideo *vid_config, + int x, int y, const char *text) : BC_GenericButton(x, y, text) { this->vid_config = vid_config; + avctx = 0; } FFOptionsViewVideo::~FFOptionsViewVideo() { + avcodec_free_context(&avctx); } int FFOptionsViewVideo::handle_event() { - char video_format[BCSTRLEN]; video_format[0] = 0; - char video_codec[BCSTRLEN]; video_codec[0] = 0; - AVCodec *codec = 0; + int ret = 0; Asset *asset = vid_config->asset; const char *name = asset->vcodec; - if( !FFMPEG::get_format(video_format, "video", name) && - !FFMPEG::get_codec(video_codec, "video", name) ) - codec = avcodec_find_encoder_by_name(video_codec); - if( !codec ) { + char video_format[BCSTRLEN]; video_format[0] = 0; + char video_codec[BCSTRLEN]; video_codec[0] = 0; + const AVCodec *codec = !ret && + !FFMPEG::get_format(video_format, "video", name) && + !FFMPEG::get_codec(video_codec, "video", name) ? + avcodec_find_encoder_by_name(video_codec) : 0; + if( !ret && !codec ) { eprintf(_("no codec named: %s: %s"), name, video_codec); - return 1; + ret = 1; } - vid_config->ff_options_dialog->start(video_format, video_codec, codec, - asset->ff_video_options, sizeof(asset->ff_video_options)); + avcodec_free_context(&avctx); + if( !ret && !(avctx = avcodec_alloc_context3(codec)) ) { + eprintf(_("no codec context: %s: %s"), name, video_codec); + ret = 1; + } + + if( !ret ) + vid_config->start(avctx); + return 1; +} + +FFOptionsViewFormat::FFOptionsViewFormat(FFMPEGConfigWindow *cfg_window, + EDL *edl, Asset *asset, int x, int y, const char *text) + : BC_GenericButton(x, y, text) +{ + this->cfg_window = cfg_window; + this->edl = edl; + this->asset = asset; + format_dialog = 0; +} + +FFOptionsViewFormat::~FFOptionsViewFormat() +{ + delete format_dialog; +} + +int FFOptionsViewFormat::handle_event() +{ + delete format_dialog; + int wx, wy; + get_pop_cursor(wx, wy); + format_dialog = new FFOptionsFormatViewDialog(this, wx, wy); + format_dialog->start(); + return 1; +} + + +FFOptionsFormatView::FFOptionsFormatView(FFMPEGConfigFormat *fmt_config, + int x, int y, const char *text) + : BC_GenericButton(x, y, text) +{ + this->fmt_config = fmt_config; + fmt_ctx = 0; +} + +FFOptionsFormatView::~FFOptionsFormatView() +{ + avformat_free_context(fmt_ctx); +} + +int FFOptionsFormatView::handle_event() +{ + Asset *asset = fmt_config->asset; + char *format_name = asset->fformat; + char replace_name0[] = "mov"; + char replace_name1[] = "mpegts"; + char replace_name2[] = "matroska"; + if (!strcmp(format_name, "qt")) + format_name = replace_name0; // fixup + if (!strcmp(format_name, "m2ts")) + format_name = replace_name1; // fixup + if (!strcmp(format_name, "mkv")) + format_name = replace_name2; // fixup + avformat_free_context(fmt_ctx); fmt_ctx = 0; + int ret = avformat_alloc_output_context2(&fmt_ctx, 0, format_name, 0); + if( ret || !fmt_ctx ) { + eprintf(_("no format named: %s"), format_name); + ret = 1; + } + if( !ret ) + fmt_config->start(fmt_ctx); return 1; } +FFOptionsFormatViewDialog::FFOptionsFormatViewDialog(FFOptionsViewFormat *view_format, + int wx, int wy) +{ + this->view_format = view_format; + this->wx = wx; + this->wy = wy; + cfg_window = 0; +} + +FFOptionsFormatViewDialog::~FFOptionsFormatViewDialog() +{ + close_window(); +} + +BC_Window *FFOptionsFormatViewDialog::new_gui() +{ + cfg_window = new FFMPEGConfigFormat(this, wx, wy, + view_format->asset, view_format->edl); + cfg_window->create_objects(); + cfg_window->read_options(); + return cfg_window; +} + +void FFOptionsFormatViewDialog::handle_done_event(int result) +{ + if( !result ) + cfg_window->save_changes(); + cfg_window = 0; +} +