vtl: ffmpeg interaction:

* use ardour/SRC to resample audio on import
* parse framerate via codec-timebase if available
* update encoder parameters
* add vpx/webm as codec option
This commit is contained in:
Robin Gareus 2013-03-31 19:34:05 +02:00
parent 6f78b82452
commit ab3040f789
2 changed files with 53 additions and 35 deletions

View file

@ -229,7 +229,7 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
audio_codec_combo.set_name ("PaddedButton"); audio_codec_combo.set_name ("PaddedButton");
audio_codec_combo.append_text("ac3"); audio_codec_combo.append_text("ac3");
audio_codec_combo.append_text("libfaac"); audio_codec_combo.append_text("aac");
audio_codec_combo.append_text("libmp3lame"); audio_codec_combo.append_text("libmp3lame");
audio_codec_combo.append_text("libvorbis"); audio_codec_combo.append_text("libvorbis");
audio_codec_combo.append_text("mp2"); audio_codec_combo.append_text("mp2");
@ -242,8 +242,9 @@ ExportVideoDialog::ExportVideoDialog (PublicEditor& ed, Session* s)
video_codec_combo.append_text("mjpeg"); video_codec_combo.append_text("mjpeg");
video_codec_combo.append_text("mpeg2video"); video_codec_combo.append_text("mpeg2video");
video_codec_combo.append_text("mpeg4"); video_codec_combo.append_text("mpeg4");
video_codec_combo.append_text("x264 (default)"); video_codec_combo.append_text("x264 (baseline)");
video_codec_combo.append_text("x264 (hq)"); video_codec_combo.append_text("x264 (hq)");
video_codec_combo.append_text("vpx (webm)");
video_codec_combo.append_text("copy"); video_codec_combo.append_text("copy");
video_codec_combo.set_active(4); video_codec_combo.set_active(4);
@ -566,19 +567,27 @@ ExportVideoDialog::encode_pass (int pass)
ffs["-b:v"] = video_bitrate_combo.get_active_text(); ffs["-b:v"] = video_bitrate_combo.get_active_text();
} }
ffs["-b:a"] = audio_bitrate_combo.get_active_text(); ffs["-b:a"] = audio_bitrate_combo.get_active_text();
if (audio_codec_combo.get_active_text() == "aac" ) {
ffs["-strict"] = "-2";
}
if (video_codec_combo.get_active_text() == "x264 (hq)" ) { if (video_codec_combo.get_active_text() == "x264 (hq)" ) {
ffs["-vcodec"] = "libx264"; ffs["-vcodec"] = "libx264";
ffs["-vpre"] = "slow"; ffs["-vprofile"] = "high";
} }
else if (video_codec_combo.get_active_text() == "x264 (default)" ) { else if (video_codec_combo.get_active_text() == "x264 (baseline)" ) {
ffs["-vcodec"] = "libx264"; ffs["-vcodec"] = "libx264";
ffs["-vpre"] = "medium"; ffs["-vpre"] = "baseline";
}
else if (video_codec_combo.get_active_text() == "vpx (webm)" ) {
ffs["-vcodec"] = "libvpx";
ffs["-g"] = "120";
ffs["-qmin"] = "11";
ffs["-qmax"] = "51";
} }
if (optimizations_checkbox.get_active()) { if (optimizations_checkbox.get_active()) {
/* TODO: define these smartly in a header-file so that they can be
* merged for printing as label and used here easyly
*/
if (video_codec_combo.get_active_text() == "mpeg2video") { if (video_codec_combo.get_active_text() == "mpeg2video") {
ffs["-mbd"] = "rd"; ffs["-mbd"] = "rd";
ffs["-trellis"] = "2"; ffs["-trellis"] = "2";
@ -587,7 +596,7 @@ ExportVideoDialog::encode_pass (int pass)
} }
else if (video_codec_combo.get_active_text() == "mpeg4") { else if (video_codec_combo.get_active_text() == "mpeg4") {
ffs["-mbd"] = "rd"; ffs["-mbd"] = "rd";
ffs["-flags"] = "+4mv+aic"; ffs["-flags"] = "+mv4+aic";
ffs["-trellis"] = "2"; ffs["-trellis"] = "2";
ffs["-cmp"] = "2"; ffs["-cmp"] = "2";
ffs["-subcmp"] = "2"; ffs["-subcmp"] = "2";
@ -603,7 +612,10 @@ ExportVideoDialog::encode_pass (int pass)
} }
} }
if (bframes_checkbox.get_active()) { if (bframes_checkbox.get_active() && (
video_codec_combo.get_active_text() == "mpeg2video"
|| video_codec_combo.get_active_text() == "mpeg4"
)) {
ffs["-bf"] = "2"; ffs["-bf"] = "2";
} }
@ -757,7 +769,7 @@ ExportVideoDialog::video_codec_combo_changed ()
if (video_codec_combo.get_active_text() == "mpeg2video") { if (video_codec_combo.get_active_text() == "mpeg2video") {
optimizations_label.set_text("-mbd rd -trellis 2 -cmp 2 -subcmp 2"); // mpeg2 optimizations_label.set_text("-mbd rd -trellis 2 -cmp 2 -subcmp 2"); // mpeg2
} else if (video_codec_combo.get_active_text() == "mpeg4") { } else if (video_codec_combo.get_active_text() == "mpeg4") {
optimizations_label.set_text("-mbd rd -flags +4mv+aic -trellis 2 -cmp 2 -subcmp 2 -g 300"); // mpeg4 optimizations_label.set_text("-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300"); // mpeg4
} else { } else {
optimizations_label.set_text("-mbd 2 -cmp 2 -subcmp 2 -trellis 2 -flags +aic+mv0+mv4 -g 160"); // flv optimizations_label.set_text("-mbd 2 -cmp 2 -subcmp 2 -trellis 2 -flags +aic+mv0+mv4 -g 160"); // flv
} }

View file

@ -117,19 +117,20 @@ TranscodeFfmpeg::probe ()
std::vector<std::vector<std::string> > lines; std::vector<std::vector<std::string> > lines;
ParseCSV(ffoutput, lines); ParseCSV(ffoutput, lines);
double timebase = 0;
m_width = m_height = 0; m_width = m_height = 0;
m_fps = m_aspect = 0; m_fps = m_aspect = 0;
m_duration = 0; m_duration = 0;
m_codec.clear(); m_codec.clear();
m_audio.clear(); m_audio.clear();
#define PARSE_FRACTIONAL_FPS \ #define PARSE_FRACTIONAL_FPS(VAR) \
{ \ { \
std::string::size_type pos; \ std::string::size_type pos; \
m_fps = atof(value.c_str()); \ VAR = atof(value.c_str()); \
pos = value.find_first_of('/'); \ pos = value.find_first_of('/'); \
if (pos != std::string::npos) { \ if (pos != std::string::npos) { \
m_fps = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str()); \ VAR = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str()); \
} \ } \
} }
@ -160,9 +161,11 @@ TranscodeFfmpeg::probe ()
if (!m_codec.empty()) m_codec += " "; if (!m_codec.empty()) m_codec += " ";
m_codec += "(" + value + ")"; m_codec += "(" + value + ")";
} else if (key == X_("r_frame_rate")) { } else if (key == X_("r_frame_rate")) {
PARSE_FRACTIONAL_FPS PARSE_FRACTIONAL_FPS(m_fps)
} else if (key == X_("time_base") && m_fps == 0) { } else if (key == X_("avg_frame_rate") && m_fps == 0) {
PARSE_FRACTIONAL_FPS PARSE_FRACTIONAL_FPS(m_fps)
} else if (key == X_("time_base")) {
PARSE_FRACTIONAL_FPS(timebase)
} else if (key == X_("timecode") && m_duration == 0) { } else if (key == X_("timecode") && m_duration == 0) {
int h,m,s; char f[7]; int h,m,s; char f[7];
if (sscanf(i->at(16).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) { if (sscanf(i->at(16).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
@ -173,9 +176,9 @@ TranscodeFfmpeg::probe ()
+ atoi(f) / pow(10, strlen(f)) + atoi(f) / pow(10, strlen(f))
)); ));
} }
} else if (key == X_("duration_ts")) { } else if (key == X_("duration_ts") && m_fps == 0 && timebase !=0 ) {
m_duration = atof(value.c_str()); m_duration = atof(value.c_str()) * m_fps * timebase;
} else if (key == X_("duration") && m_duration == 0 && m_fps != 0) { } else if (key == X_("duration") && m_fps != 0 && m_duration == 0) {
m_duration = atof(value.c_str()) * m_fps; m_duration = atof(value.c_str()) * m_fps;
} else if (key == X_("display_aspect_ratio")) { } else if (key == X_("display_aspect_ratio")) {
std::string::size_type pos; std::string::size_type pos;
@ -357,23 +360,26 @@ TranscodeFfmpeg::extract_audio (std::string outfile, ARDOUR::framecnt_t samplera
if (stream >= m_audio.size()) return false; if (stream >= m_audio.size()) return false;
char **argp; char **argp;
int i = 0;
argp=(char**) calloc(15,sizeof(char*)); argp=(char**) calloc(15,sizeof(char*));
argp[0] = strdup(ffmpeg_exe.c_str()); argp[i++] = strdup(ffmpeg_exe.c_str());
argp[1] = strdup("-i"); argp[i++] = strdup("-i");
argp[2] = strdup(infile.c_str()); argp[i++] = strdup(infile.c_str());
argp[3] = strdup("-ar"); #if 0 // native samplerate -- use a3/SRC
argp[4] = (char*) calloc(7,sizeof(char)); snprintf(argp[4], 7, "%"PRId64, samplerate); argp[i++] = strdup("-ar");
argp[5] = strdup("-ac"); argp[i] = (char*) calloc(7,sizeof(char)); snprintf(argp[i++], 7, "%"PRId64, samplerate);
argp[6] = (char*) calloc(3,sizeof(char)); snprintf(argp[6], 3, "%i", m_audio.at(stream).channels); #endif
argp[7] = strdup("-map"); argp[i++] = strdup("-ac");
argp[8] = (char*) calloc(8,sizeof(char)); snprintf(argp[8], 8, "0:%s", m_audio.at(stream).stream_id.c_str()); argp[i] = (char*) calloc(3,sizeof(char)); snprintf(argp[i++], 3, "%i", m_audio.at(stream).channels);
argp[9] = strdup("-vn"); argp[i++] = strdup("-map");
argp[10] = strdup("-acodec"); argp[i] = (char*) calloc(8,sizeof(char)); snprintf(argp[i++], 8, "0:%s", m_audio.at(stream).stream_id.c_str());
argp[11] = strdup("pcm_f32le"); argp[i++] = strdup("-vn");
argp[12] = strdup("-y"); argp[i++] = strdup("-acodec");
argp[13] = strdup(outfile.c_str()); argp[i++] = strdup("pcm_f32le");
argp[14] = (char *)0; argp[i++] = strdup("-y");
argp[i++] = strdup(outfile.c_str());
argp[i++] = (char *)0;
/* Note: argp is free()d in ~SystemExec */ /* Note: argp is free()d in ~SystemExec */
#if 1 /* DEBUG */ #if 1 /* DEBUG */
if (debug_enable) { /* tentative debug mode */ if (debug_enable) { /* tentative debug mode */