summaryrefslogtreecommitdiff
path: root/gtk2_ardour/transcode_ffmpeg.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2013-03-29 11:07:20 +0100
committerRobin Gareus <robin@gareus.org>2013-03-29 12:36:08 +0100
commit47ee22d91dbfa35b45c7cef8b825b4a7685c71c8 (patch)
treef0d1670c96d7a4eb3b23552a074e5e3aa195ab01 /gtk2_ardour/transcode_ffmpeg.cc
parent9274b870abcebe2605d118a394ab23dd8ce3eef4 (diff)
vtl: update ffprobe csv parsing
Diffstat (limited to 'gtk2_ardour/transcode_ffmpeg.cc')
-rw-r--r--gtk2_ardour/transcode_ffmpeg.cc179
1 files changed, 83 insertions, 96 deletions
diff --git a/gtk2_ardour/transcode_ffmpeg.cc b/gtk2_ardour/transcode_ffmpeg.cc
index 57121e257d..e886c64f64 100644
--- a/gtk2_ardour/transcode_ffmpeg.cc
+++ b/gtk2_ardour/transcode_ffmpeg.cc
@@ -98,8 +98,8 @@ TranscodeFfmpeg::probe ()
char **argp;
argp=(char**) calloc(7,sizeof(char*));
argp[0] = strdup(ffprobe_exe.c_str());
- argp[1] = strdup("-print_format"); // "-of" ; new version and avprobe compat but avprobe does not yet support csv
- argp[2] = strdup("csv"); // TODO use "csv=nk=0" and parse key/value pairs -> ffprobe version agnostic or parse XML or JSON key/value
+ argp[1] = strdup("-print_format");
+ argp[2] = strdup("csv=nk=0");
argp[3] = strdup("-show_format");
argp[4] = strdup("-show_streams");
argp[5] = strdup(infile.c_str());
@@ -123,113 +123,100 @@ TranscodeFfmpeg::probe ()
m_codec.clear();
m_audio.clear();
+#define PARSE_FRACTIONAL_FPS \
+ { \
+ std::string::size_type pos; \
+ m_fps = atof(value.c_str()); \
+ pos = value.find_first_of('/'); \
+ if (pos != std::string::npos) { \
+ m_fps = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str()); \
+ } \
+ }
+
for (std::vector<std::vector<std::string> >::iterator i = lines.begin(); i != lines.end(); ++i) {
if (i->at(0) == X_("format")) {
/* format,filename,#streams,format-name,format-long-name,start-time,duration,size,bitrate */
} else
if (i->at(0) == X_("stream")) {
- /*--------- Stream format
- * stream,index,codec-name,codec-name-long,PROFILE,
- * codec_time_base,codec_tag_string,codec_tag[hex],
- * VIDEO:
- * width,height,has_b_frames,sample_aspect_ratio,display_aspect_ratio
- * pix_fmt,level,
- * timecode
- * AUDIO:
- * sample_fmt,sample_rate,channels,bits_per_sample
- *
- * all cont'd;
- * r_frame_rate,avg_frame_rate,time_base,start_time,duration,
- * bit_rate,nb_frames,nb_read_frames,nb_read_packets
- *
- *---------- Example
- * stream,0,mpeg2video,MPEG-2 video,video,1/50,[0][0][0][0],0x0000,720,576,1,16:15,4:3,yuv420p,8,00:02:30:00,0x1e0,25/1,25/1,1/90000,0.360000,N/A,7000000,N/A,N/A,N/A
- * stream,1,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,6,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x80,0/0,0/0,1/90000,0.280000,312.992000,448000,N/A,N/A,N/A
- * stream,2,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,2,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x82,0/0,0/0,1/90000,0.280000,312.992000,384000,N/A,N/A,N/A
- * stream,3,ac3,ATSC A/52A (AC-3),audio,1/48000,[0][0][0][0],0x0000,s16,48000,2,0,-1,-1.000000,-1.000000,-1.000000,-1.000000,0x81,0/0,0/0,1/90000,0.280000,312.992000,192000,N/A,N/A,N/A
- */
- if (i->at(4) == X_("video") && m_width == 0) {
- std::string::size_type pos;
-
- m_width = atoi(i->at(8).c_str());
- m_height = atoi(i->at(9).c_str());
- m_codec = i->at(3) + " -- " + i->at(2);
- m_fps = atof(i->at(17).c_str());
-
- pos = i->at(17).find_first_of('/');
- if (pos != std::string::npos) {
- m_fps = atof(i->at(17).substr(0, pos).c_str()) / atof(i->at(17).substr(pos+1).c_str());
+ if (i->at(5) == X_("codec_type=video") && m_width == 0) {
+
+ for (std::vector<std::string>::iterator kv = i->begin(); kv != i->end(); ++kv) {
+ const size_t kvsep = kv->find('=');
+ if(kvsep == std::string::npos) continue;
+ std::string key = kv->substr(0, kvsep);
+ std::string value = kv->substr(kvsep + 1);
+
+ if (key == X_("width")) {
+ m_width = atoi(value.c_str());
+ } else if (key == X_("height")) {
+ m_height = atoi(value.c_str());
+ } else if (key == X_("codec_name")) {
+ if (!m_codec.empty()) m_codec += " ";
+ m_codec += value;
+ } else if (key == X_("codec_long_name")) {
+ if (!m_codec.empty()) m_codec += " ";
+ m_codec += "[" + value + "]";
+ } else if (key == X_("codec_tag_string")) {
+ if (!m_codec.empty()) m_codec += " ";
+ m_codec += "(" + value + ")";
+ } else if (key == X_("r_frame_rate")) {
+ PARSE_FRACTIONAL_FPS
+ } else if (key == X_("time_base") && m_fps == 0) {
+ PARSE_FRACTIONAL_FPS
+ } else if (key == X_("timecode") && m_duration == 0) {
+ int h,m,s; char f[7];
+ if (sscanf(i->at(16).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
+ m_duration = (ARDOUR::framecnt_t) floor(m_fps * (
+ h * 3600.0
+ + m * 60.0
+ + s * 1.0
+ + atoi(f) / pow(10, strlen(f))
+ ));
+ }
+ } else if (key == X_("duration_ts")) {
+ m_duration = atof(value.c_str());
+ } else if (key == X_("duration") && m_duration == 0 && m_fps != 0) {
+ m_duration = atof(value.c_str()) * m_fps;
+ } else if (key == X_("display_aspect_ratio")) {
+ std::string::size_type pos;
+ pos = value.find_first_of(':');
+ if (pos != std::string::npos && atof(value.substr(pos+1).c_str()) != 0) {
+ m_aspect = atof(value.substr(0, pos).c_str()) / atof(value.substr(pos+1).c_str());
+ }
+ }
}
- pos = i->at(12).find_first_of(':');
- m_aspect = 0;
- if (pos != std::string::npos && atof(i->at(12).substr(pos+1).c_str()) != 0) {
- m_aspect = atof(i->at(12).substr(0, pos).c_str()) / atof(i->at(12).substr(pos+1).c_str());
- }
if (m_aspect == 0) {
m_aspect = (double)m_width / (double)m_height;
}
- int h,m,s; char f[7];
- if (sscanf(i->at(15).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
- m_duration = (ARDOUR::framecnt_t) floor(m_fps * (
- h * 3600.0
- + m * 60.0
- + s * 1.0
- + atoi(f) / pow(10, strlen(f))
- ));
- } else {
- m_duration = atof(i->at(21).c_str()) * m_fps;
- }
-
- } else if (i->at(4) == X_("audio")) {
+ } else if (i->at(5) == X_("codec_type=audio")) { /* new ffprobe */
AudioStream as;
- as.name = i->at(3) + " " + i->at(2) + " " + i->at(8) + " " + i->at(9);
- as.stream_id = i->at(1);
- as.channels = atoi(i->at(10).c_str());
- m_audio.push_back(as);
-
- } else if (i->at(5) == X_("video") && m_width == 0) { /* new ffprobe */
- std::string::size_type pos;
-
- m_width = atoi(i->at(9).c_str());
- m_height = atoi(i->at(10).c_str());
- m_codec = i->at(3) + " -- " + i->at(2);
- m_fps = atof(i->at(18).c_str());
-
- pos = i->at(18).find_first_of('/');
- if (pos != std::string::npos) {
- m_fps = atof(i->at(18).substr(0, pos).c_str()) / atof(i->at(18).substr(pos+1).c_str());
- }
+ for (std::vector<std::string>::iterator kv = i->begin(); kv != i->end(); ++kv) {
+ const size_t kvsep = kv->find('=');
+ if(kvsep == std::string::npos) continue;
+ std::string key = kv->substr(0, kvsep);
+ std::string value = kv->substr(kvsep + 1);
+
+ if (key == X_("channels")) {
+ as.channels = atoi(value.c_str());
+ } else if (key == X_("index")) {
+ as.stream_id = value;
+ } else if (key == X_("codec_long_name")) {
+ if (!as.name.empty()) as.name += " ";
+ as.name += value;
+ } else if (key == X_("codec_name")) {
+ if (!as.name.empty()) as.name += " ";
+ as.name += value;
+ } else if (key == X_("sample_fmt")) {
+ if (!as.name.empty()) as.name += " ";
+ as.name += "FMT:" + value;
+ } else if (key == X_("sample_rate")) {
+ if (!as.name.empty()) as.name += " ";
+ as.name += "SR:" + value;
+ }
- pos = i->at(13).find_first_of(':');
- m_aspect = 0;
- if (pos != std::string::npos && atof(i->at(13).substr(pos+1).c_str()) != 0) {
- m_aspect = atof(i->at(13).substr(0, pos).c_str()) / atof(i->at(13).substr(pos+1).c_str());
}
- if (m_aspect == 0) {
- m_aspect = (double)m_width / (double)m_height;
- }
-
- int h,m,s; char f[7];
- if (sscanf(i->at(17).c_str(), "%d:%d:%d:%s",&h,&m,&s,f) == 4) {
- m_duration = (ARDOUR::framecnt_t) floor(m_fps * (
- h * 3600.0
- + m * 60.0
- + s * 1.0
- + atoi(f) / pow(10, strlen(f))
- ));
- } else if (atof(i->at(23).c_str()) != 0) {
- m_duration = atof(i->at(23).c_str());
- } else {
- m_duration = atof(i->at(24).c_str()) * m_fps;
- }
-
- } else if (i->at(5) == X_("audio")) { /* new ffprobe */
- AudioStream as;
- as.name = i->at(3) + " " + i->at(2) + " " + i->at(9) + " " + i->at(10);
- as.stream_id = i->at(1);
- as.channels = atoi(i->at(11).c_str());
m_audio.push_back(as);
}
}
@@ -241,7 +228,7 @@ TranscodeFfmpeg::probe ()
while (ffcmd && --timeout) usleep (1000); // wait until 'ffprobe' terminated.
if (timeout == 0) return false;
-#if 0 /* DEBUG */
+#if 1 /* DEBUG */
printf("FPS: %f\n", m_fps);
printf("Duration: %lu frames\n",(unsigned long)m_duration);
printf("W/H: %ix%i\n",m_width, m_height);