#include "fileffmpeg.h"
#include "filesystem.h"
#include "indexfile.h"
+#include "language.h"
#include "mainerror.h"
#include "mainprogress.h"
#include "mutex.h"
FFMpegConfigNum::FFMpegConfigNum(BC_Window *window,
int x, int y, char *title_text, int *output)
- : BC_TumbleTextBox(window, (int64_t)*output,
- (int64_t)-1, (int64_t)25000000, 100, y, 100)
+ : BC_TumbleTextBox(window, *output, -1, INT_MAX, 100, y, 100)
{
this->window = window;
this->x = x; this->y = y;
BC_TumbleTextBox::create_objects();
}
+int FFMpegConfigNum::update_param(const char *param, const char *opts)
+{
+ char value[BCTEXTLEN];
+ if( !FileFFMPEG::get_ff_option(param, opts, value) ) {
+ if( (*output = atoi(value)) < 0 ) {
+ disable(1);
+ return 0;
+ }
+ }
+ BC_TumbleTextBox::update((int64_t)*output);
+ enable();
+ return 1;
+}
+
int FFMpegConfigNum::handle_event()
{
- *output = atol(get_text());
+ *output = atoi(get_text());
return 1;
}
{
int ret = FFMpegVideoNum::handle_event();
Asset *asset = window()->asset;
- if( asset->ff_video_bitrate )
+ if( asset->ff_video_bitrate > 0 )
window()->quality->disable();
- else
+ else if( !window()->quality->get_textbox()->is_hidden() )
window()->quality->enable();
return ret;
}
{
int ret = FFMpegVideoNum::handle_event();
Asset *asset = window()->asset;
- if( asset->ff_video_quality )
+ if( asset->ff_video_quality >= 0 )
window()->bitrate->disable();
- else
+ else if( !window()->bitrate->get_textbox()->is_hidden() )
window()->bitrate->enable();
return ret;
}
+void FileFFMPEG::set_parameters(char *cp, int len, const char *bp)
+{
+ char *ep = cp + len-2, ch = 0;
+ while( cp < ep && *bp != 0 ) { ch = *bp++; *cp++ = ch; }
+ if( ch != '\n' ) *cp++ = '\n';
+ *cp = 0;
+}
+
void FileFFMPEG::get_parameters(BC_WindowBase *parent_window,
Asset *asset, BC_WindowBase *&format_window,
int audio_options, int video_options)
format_window = window;
window->create_objects();
if( !window->run_window() )
- strcpy(asset->ff_audio_options, window->audio_options->get_text());
+ set_parameters(asset->ff_audio_options, sizeof(asset->ff_audio_options),
+ window->audio_options->get_text());
delete window;
}
else if(video_options) {
format_window = window;
window->create_objects();
if( !window->run_window() )
- strcpy(asset->ff_video_options, window->video_options->get_text());
+ set_parameters(asset->ff_video_options, sizeof(asset->ff_video_options),
+ window->video_options->get_text());
delete window;
}
}
if( !ff || !asset->video_data ) return 1;
asset->width = ff->ff_video_width(vstream);
asset->height = ff->ff_video_height(vstream);
- asset->video_length = ff->ff_video_frames(vstream);
if( (asset->video_length = ff->ff_video_frames(vstream)) < 2 )
asset->video_length = asset->video_length < 0 ? 0 : -1;
asset->frame_rate = ff->ff_frame_rate(vstream);
asset->channels = audio_channels;
asset->sample_rate = ff->ff_sample_rate(0);
asset->audio_length = ff->ff_audio_samples(0);
+ strcpy(asset->acodec, ff->ff_audio_format(0));
}
int video_layers = ff->ff_total_video_layers();
if( video_layers > 0 ) {
(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));
}
IndexState *index_state = asset->index_state;
index_state->read_markers(file->preferences->index_directory, asset->path);
return colormodel;
}
+
+int FileFFMPEG::get_best_colormodel(int driver, int vstream)
+{
+ if( vstream < 0 ) vstream = 0;
+ int is_mpeg = !ff ? 0 : ff->ff_video_mpeg_color_range(vstream);
+
+ switch(driver) {
+ case PLAYBACK_X11:
+ case PLAYBACK_X11_GL: return is_mpeg ? BC_YUV888 : BC_RGB888;
+ case PLAYBACK_X11_XV: return BC_YUV420P;
+ }
+
+ return BC_RGB888;
+}
+
int FileFFMPEG::get_best_colormodel(Asset *asset, int driver)
{
switch(driver) {
- case PLAYBACK_X11: return BC_RGB888;
- case PLAYBACK_X11_GL: return BC_YUV888;
+// the direct X11 color model requires scaling in the codec
+ case SCREENCAPTURE:
+ case PLAYBACK_X11:
+ case PLAYBACK_X11_GL: return BC_RGB888;
+ case PLAYBACK_X11_XV: return BC_YUV420P;
}
+
return BC_YUV420P;
}
+int FileFFMPEG::can_render(const char *fformat, const char *type)
+{
+ FileSystem fs;
+ char option_path[BCTEXTLEN];
+ FFMPEG::set_option_path(option_path, type);
+ fs.update(option_path);
+ int total_files = fs.total_files();
+ for( int i=0; i<total_files; ++i ) {
+ const char *name = fs.get_entry(i)->get_name();
+ const char *ext = strrchr(name,'.');
+ if( !ext ) continue;
+ if( !strcmp(fformat, ++ext) ) return 1;
+ }
+ return 0;
+}
+
+int FileFFMPEG::get_ff_option(const char *nm, const char *options, char *value)
+{
+ for( const char *cp=options; *cp!=0; ) {
+ char line[BCTEXTLEN], *bp = line, *ep = bp+sizeof(line)-1;
+ while( bp < ep && *cp && *cp!='\n' ) *bp++ = *cp++;
+ if( *cp ) ++cp;
+ *bp = 0;
+ if( !line[0] || line[0] == '#' || line[0] == ';' ) continue;
+ char key[BCSTRLEN], val[BCTEXTLEN];
+ if( FFMPEG::scan_option_line(line, key, val) ) continue;
+ if( !strcmp(key, nm) ) {
+ strcpy(value, val);
+ return 0;
+ }
+ }
+ return 1;
+}
+
//======
FFMPEGConfigAudio::FFMPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
bitrate = new FFMpegAudioBitrate(this, x, y, _("Bitrate:"), &asset->ff_audio_bitrate);
bitrate->create_objects();
bitrate->set_increment(1000);
+ bitrate->set_boundaries((int64_t)0, (int64_t)INT_MAX);
y += bitrate->get_h() + 10;
BC_Title *title = new BC_Title(x, y, _("Audio Options:"));
audio_options->create_objects();
add_subwindow(new BC_OKButton(this));
add_subwindow(new BC_CancelButton(this));
-
show_window(1);
- bitrate->handle_event();
+
+ bitrate->update_param("cin_bitrate", asset->ff_audio_options);
+
unlock_window();
}
this->audio_popup = audio_popup;
}
-int FFAudioOptions::handle_event()
-{
- strcpy(audio_popup->asset->ff_audio_options, get_text());
- return 1;
-}
-
FFMPEGConfigAudioPopup::FFMPEGConfigAudioPopup(FFMPEGConfigAudio *popup, int x, int y)
: BC_PopupTextBox(popup, &popup->presets, popup->asset->acodec, x, y, 300, 300)
{
strcpy(popup->asset->acodec, get_text());
Asset *asset = popup->asset;
+ asset->ff_audio_bitrate = 0;
char option_path[BCTEXTLEN];
FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec);
FFMPEG::load_options(option_path, asset->ff_audio_options,
sizeof(asset->ff_audio_options));
popup->audio_options->update(asset->ff_audio_options);
+ popup->audio_options->set_text_row(0);
+
+ popup->bitrate->update_param("cin_bitrate", asset->ff_audio_options);
return 1;
}
preset_popup = new FFMPEGConfigVideoPopup(this, x, y);
preset_popup->create_objects();
- if( asset->ff_video_bitrate && asset->ff_video_quality ) {
- asset->ff_video_bitrate = 0;
- asset->ff_video_quality = 0;
+ if( asset->ff_video_bitrate > 0 && asset->ff_video_quality >= 0 ) {
+ asset->ff_video_bitrate = 0; asset->ff_video_quality = -1;
}
y += 50;
bitrate = new FFMpegVideoBitrate(this, x, y, _("Bitrate:"), &asset->ff_video_bitrate);
bitrate->create_objects();
bitrate->set_increment(100000);
+ bitrate->set_boundaries((int64_t)0, (int64_t)INT_MAX);
y += bitrate->get_h() + 5;
quality = new FFMpegVideoQuality(this, x, y, _("Quality:"), &asset->ff_video_quality);
quality->create_objects();
quality->set_increment(1);
- quality->set_boundaries((int64_t)0, (int64_t)31);
+ quality->set_boundaries((int64_t)-1, (int64_t)51);
y += quality->get_h() + 10;
BC_Title *title = new BC_Title(x, y, _("Video Options:"));
video_options->create_objects();
add_subwindow(new BC_OKButton(this));
add_subwindow(new BC_CancelButton(this));
-
show_window(1);
- if( asset->ff_video_bitrate )
- quality->disable();
- if( asset->ff_video_quality )
- bitrate->disable();
+
+ bitrate->update_param("cin_bitrate", asset->ff_video_options);
+ quality->update_param("cin_quality", asset->ff_video_options);
+
+ if( asset->ff_video_bitrate > 0 ) quality->disable();
+ else if( asset->ff_video_quality >= 0 ) bitrate->disable();
unlock_window();
}
this->video_popup = video_popup;
}
-int FFVideoOptions::handle_event()
-{
- strcpy(video_popup->asset->ff_video_options, get_text());
- return 1;
-}
-
FFMPEGConfigVideoPopup::FFMPEGConfigVideoPopup(FFMPEGConfigVideo *popup, int x, int y)
: BC_PopupTextBox(popup, &popup->presets, popup->asset->vcodec, x, y, 300, 300)
strcpy(popup->asset->vcodec, get_text());
Asset *asset = popup->asset;
char option_path[BCTEXTLEN];
+ asset->ff_video_bitrate = 0; asset->ff_video_quality = -1;
FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec);
FFMPEG::load_options(option_path, asset->ff_video_options,
sizeof(asset->ff_video_options));
popup->video_options->update(asset->ff_video_options);
+ popup->video_options->set_text_row(0);
+
+ popup->bitrate->update_param("cin_bitrate", asset->ff_video_options);
+ popup->quality->update_param("cin_quality", asset->ff_video_options);
return 1;
}
void FFOptions_OptPanel::create_objects()
{
- const char *cols[] = { "option", "value", };
+ const char *cols[] = { _("option"), _("value"), };
const int col1_w = 150;
int wids[] = { col1_w, get_w()-col1_w };
BC_ListBox::update(&items[0], &cols[0], &wids[0], sizeof(items)/sizeof(items[0]));
void FFOptionsKind::set(int k)
{
this->kind = k;
- set_text(kinds[k]);
+ set_text(_(kinds[k]));
}
FFOptionsText::
if( dupl ) continue;
FFOptions_Opt *fopt = new FFOptions_Opt(this, opt, opt->name);
append(fopt);
+ AVDictionaryEntry *elem = av_dict_get(win->dialog->ff_opts,
+ opt->name, 0, AV_DICT_IGNORE_SUFFIX);
+ if( elem && elem->value ) fopt->set(elem->value);
char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val));
fopt->item_value->update(vp);
}
{
const char *cp = "";
if( opt ) switch (opt->type) {
- case AV_OPT_TYPE_FLAGS: cp = "<flags>"; break;
- case AV_OPT_TYPE_INT: cp = "<int>"; break;
- case AV_OPT_TYPE_INT64: cp = "<int64>"; break;
- case AV_OPT_TYPE_DOUBLE: cp = "<double>"; break;
- case AV_OPT_TYPE_FLOAT: cp = "<float>"; break;
- case AV_OPT_TYPE_STRING: cp = "<string>"; break;
- case AV_OPT_TYPE_RATIONAL: cp = "<rational>"; break;
- case AV_OPT_TYPE_BINARY: cp = "<binary>"; break;
- case AV_OPT_TYPE_IMAGE_SIZE: cp = "<image_size>"; break;
- case AV_OPT_TYPE_VIDEO_RATE: cp = "<video_rate>"; break;
- case AV_OPT_TYPE_PIXEL_FMT: cp = "<pix_fmt>"; break;
- case AV_OPT_TYPE_SAMPLE_FMT: cp = "<sample_fmt>"; break;
- case AV_OPT_TYPE_DURATION: cp = "<duration>"; break;
- case AV_OPT_TYPE_COLOR: cp = "<color>"; break;
- case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = "<channel_layout>"; break;
- case AV_OPT_TYPE_BOOL: cp = "<bool>"; break;
- default: cp = "<undef>"; break;
+ case AV_OPT_TYPE_FLAGS: cp = N_("<flags>"); break;
+ case AV_OPT_TYPE_INT: cp = N_("<int>"); break;
+ case AV_OPT_TYPE_INT64: cp = N_("<int64>"); break;
+ case AV_OPT_TYPE_DOUBLE: cp = N_("<double>"); break;
+ case AV_OPT_TYPE_FLOAT: cp = N_("<float>"); break;
+ case AV_OPT_TYPE_STRING: cp = N_("<string>"); break;
+ case AV_OPT_TYPE_RATIONAL: cp = N_("<rational>"); break;
+ case AV_OPT_TYPE_BINARY: cp = N_("<binary>"); break;
+ case AV_OPT_TYPE_IMAGE_SIZE: cp = N_("<image_size>"); break;
+ case AV_OPT_TYPE_VIDEO_RATE: cp = N_("<video_rate>"); break;
+ case AV_OPT_TYPE_PIXEL_FMT: cp = N_("<pix_fmt>"); break;
+ case AV_OPT_TYPE_SAMPLE_FMT: cp = N_("<sample_fmt>"); break;
+ case AV_OPT_TYPE_DURATION: cp = N_("<duration>"); break;
+ case AV_OPT_TYPE_COLOR: cp = N_("<color>"); break;
+ case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = N_("<channel_layout>"); break;
+ case AV_OPT_TYPE_BOOL: cp = N_("<bool>"); break;
+ default: cp = N_("<undef>"); break;
}
- return sprintf(rp, "%s", cp);
+ return sprintf(rp, "%s", _(cp));
}
int FFOptions_Opt::scalar(double d, char *rp)
{
FFOptionsWindow::FFOptionsWindow(FFOptionsDialog *dialog)
- : BC_Window(PROGRAM_NAME ": Options", 60, 30, 640, 400)
+ : BC_Window(_(PROGRAM_NAME ": Options"), 60, 30, 640, 400)
{
this->dialog = dialog;
this->selected = 0;