在14.04上从libx264传输数据并将其串接时,avconv会报错“非单调递增的DTS到复用器流”。

12

我有一段代码,它使用x264进行编码并使用avconv将图像流写入文件。相关的部分如下:

// Setup encoder
sprintf(cmd, "avconv -i pipe: -vcodec copy %s", filename);
fp = popen(cmd, "w");
x264_param_default_preset(&params, "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(&params);

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);

为了清晰起见,我省略了错误检查,但从未返回过任何错误。事实上,在我将系统升级到14.04之前,此代码完美运行(对于尚未升级的同事而言,它仍然完美运行)。

只有现在运行Ubuntu 14.04,我从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
尽管出现错误,out.i_dts在整个视频持续时间内单调递增(它始终等于 in.i_pts )。
我一般的假设是,较新版本的avconv对输入流的参数更为严格,因此虽然以前我的参数选择可能有效,但现在它们无法工作。
另一个有趣的问题可能与此相关,即avconv检测到流的帧速率为25 FPS,即使x264配置了30 FPS的输入。
编辑:进一步的信息是,无论初始pts如何,同样的dts错误( 2> = 2 )都会发生(输出dts如预期匹配)。

在FFMPEG出现错误后,我在DDG找到了这个问题。问题是由于非法的字幕文件引起的。某个字幕时间戳早于前一个时间戳。我只需在文本编辑器中编辑VTT文件并删除它。无效的字幕恰好位于文件开头。我认为错误的时间戳是由x >= x给出的,其中x表示毫秒。 - Chloe
1个回答

10
在“我不知道为什么这样能解决问题,但它确实可以”的时刻,将-vcodec copy更改为-vcodec libx264(即使源编解码器已经是libx264)解决了dts错误。

8
可以,这样做是有效的。但现在的ffmpeg可能不仅仅是转存流,而是重新编码了它。 - lefterav
3
使用FFmpeg时,我遇到了一个错误(只在mp2文件中出现),我的解决方法是通过在FFmpeg命令行中添加以下内容来删除文件开头部分(即删除前几毫秒),以便该文件下载时不包括前0.015秒的内容(但可能需要根据实际情况尝试不同的数值,因为我怀疑不同文件的情况不同,所以第一步应该是将值从0.015增加到某个较大的数字):-ss 0.015。 - Ed999

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接