I have a piece of code that takes a stream of images and writes them to a file using x264 to encode and avconv. The relevant bits are as follows
// Setup encoder
sprintf(cmd, "avconv -i pipe: -vcodec copy %s", filename);
fp = popen(cmd, "w");
x264_param_default_preset(¶ms, "ultrafast", "stillimage,zerolatency");
params.i_fps_num = fps;
params.i_fps_den = 1;
x264_picture_alloc(&in, X264_CSP_I420, width, height);
params.i_csp = X264_CSP_I420;
in.img.i_csp = X264_CSP_I420;
x.params.b_vfr_input = 0;
in.i_pts = -1;
out.i_pts = -1;
params.i_width = width;
params.i_height = height;
encoder = x264_encoder_open(¶ms);
in.img.i_plane = 1;
in.img.i_stride[0] = width;
ret = x264_encoder_headers(encoder, &nals, &nheader);
header_size = nals[0].i_payload + nals[1].i_payload + nals[2].i_payload;
fwrite(nals[0].p_payload, header_size, 1, fp);
...
// Loop body
++in.i_pts;
frame_size = x264_encoder_encode(encoder, &nals, &num_nals, &in, &out);
fwrite(nals[0].p_payload, frame_size, 1, fp);
I've left out error checking for clarity, but no error is ever returned. Indeed, until I upgraded my system to 14.04, this code worked perfectly (and continues to work perfectly for colleagues who've yet to upgrade).
Only now running Ubuntu 14.04, I get this output from avconv
[h264 @ 0x98dec0] Estimating duration from bitrate, this may be inaccurate
Input #0, h264, from 'pipe:'
Duration: N/A, bitrate: N/A
Stream #0.0: Video: h264 (Constrained Baseline), yuv420p, 640x480, 25 fps, 25 tbr, 25 tbn, 60 tbc
Output #0, mp4, to '../reel/test.mp4':
Metadata:
encoder : Lavf54.20.3
Stream #0.0: Video: libx264, yuv420p, 640x480, q=2-31, 25 tbn, 25 tbc
Stream mapping:
Stream #0:0 -> #0:0 (copy)
[mp4 @ 0x1347800] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 2 >= 2
av_interleaved_write_frame(): Invalid argument
Despite the error, out.i_dts
does monotonically increase over the whole duration of the video (it's always equal to in.i_pts
).
My general assumption is that newer versions of avconv are more strict with the parameters of the input stream, so while my choice of parameters may have worked before, they do not work now.
Another curiousity, which might be related, is avconv detecting that the stream is 25 FPS, even though x264 is configured with an input FPS of 30.
Edit: Some further information, the same dts error (2>=2
) happens regardless of the initial pts (with the output dts matching as expected).
In a moment of "I don't know why this should fix it, but does", changing -vcodec copy
to -vcodec libx264
(even though the source codec was already libx264) fixed the dts
error.