如何解决FFmpeg中的“ PES数据包大小不匹配”错误?

时间:2019-02-14 23:43:48

标签: ffmpeg

如何解决FFmpeg中的错误 PES数据包大小不匹配-

我要回答我自己的问题,因为在与ffmpeg有关的帖子中经常出现 PES数据包大小不匹配短语,但是我没有一个令人满意的解决方案。

通常会涉及一个涉及.TS传输流文件的问题:要么与此类文件串联在一起,要么与它们重新混合(从.ts到.mp4)有关。在ffmpeg的输出中,致命的短语数据包大小不匹配将突然开始重复。

一种解决方案是将它们串联为.ts文件(即原始格式为 ),然后将输出的.ts文件分割为视频文件(.ts)和音频文件(.ts),然后使用“ itsoffset”选项将它们重新混合(.ts或.mp4)。即使使用流复制,输出到.mp4也会带来比保留.ts格式差的图片质量。

以下代码可以做到这一点,输出.mp4视频或.ts视频(将代码复制到简单的.bat 批处理文件,然后运行该文件)-

:: Program Location
SET ffmpeg="C:\Program Files\FFmpeg\ffmpeg.exe" -hide_banner  


::  STEP 1 -

::  Create File List
IF EXIST mylist.txt DEL mylist.txt
FOR %%i IN (*.ts) DO ECHO file '%%i'>> mylist.txt

::  Concatenate Files : TS
%ffmpeg%  -f concat  -safe 0  -i mylist.txt  -c copy  -threads 1  out.ts


::  STEP 2 -

::  Extract Video stream
%ffmpeg%  -i out.ts  -vcodec copy  -an  -sn  -threads 1  video.ts

::  Extract Audio stream
%ffmpeg%  -i out.ts  -acodec copy  -vn  -sn  -threads 1  audio.ts


::  STEP 3 -

::  Combine Video and Audio streams (with .MP4 options)
SET mapping=-i video.ts -itsoffset -0  -i audio.ts   -map 0:v -map 1:a
SET options=-flags global_header  -movflags faststart  -threads 1
%ffmpeg%  %mapping%  -c:v copy -c:a copy  %options%  output.mp4

::  Combine Video and Audio streams (with .TS options)
SET mapping=-i video.ts -itsoffset -0  -i audio.ts  -map 0:v -map 1:a
SET options=-threads 1
%ffmpeg%  %mapping%  -c:v copy -c:a copy  %options%  output.ts

附录

关于我建议的解决方案似乎存在一些争议,如下面的评论中所述。似乎有人说我的解决方案忽略了源文件中数据丢失的事实。

我认为我唯一能做的就是承认,由于ffmpeg正在报告源文件中的错误,并带有“数据包大小不匹配”警告,因此注释中提出的异议可能是有效的。

但是,即使数据丢失,我建议的例程也至少会为您提供一个可以在大多数媒体播放器中播放的文件。在许多情况下,报告的错误中指定的连接点甚至不会出现听觉或视觉故障。

很难看到丢失的数据将如何恢复,但请务必提出建议。必须有改进我的脚本的余地,因为以前很少注意这种类型的错误。

令人高兴的是,这种错误似乎不会导致声音与图片失去同步。因此,即使连接处缺少某些数据,连接点之后的音频也不会不同步。

1 个答案:

答案 0 :(得分:1)

PES 数据包大小不匹配

错误信息(视频文件):

<块引用>

PES 数据包大小不匹配

.

错误分析

单个 PES 数据包只能包含三种可能的帧类型之一, 即 I、B 或 P。单个 PES 数据包存储一对 DTS/PTS。

多路复用器所做的是将帧(无论是 I、B 还是 P)打包成一个 PES 数据包,然后向该数据包添加 DTS 和 PTS 时间戳,仅此而已。 下一帧将被打包成一个单独的 PES 数据包。

有时,取决于编码器和多路复用器,当帧非常大时(例如 作为高清视频中的 I 帧)它被打包成多个 PES 数据包 具有相同的 DTS/PTS 时间戳。

h264 流的 SPS 和 PPS 与 I 帧一起打包的地方, 成单个 PES 数据包,如果该数据包(包含 SPS 和 PPS)丢失, 解码器将不得不等到下一个 SPS 和 PPS 被传输—— 因为没有它们就无法解码流。

MPEG-2 视频中的帧类型:

  • 帧类型 001:帧内编码 (I) - “i 帧”

  • 帧类型 010:预测编码 (P) - “p 帧”

  • 帧类型 011:双向预测编码 (B) - “b 帧”

在直播流中,所有电视台都将 H264 视频流的 PES 长度设置为零, 由于 PES 长度是 16 位值,因此最大大小为 65,535 字节 (MPEG2 视频的旧标准)。这对于大多数 H264 PES 数据包来说太小了, 所以它应该设置为零(即“任意长度”)。

如果视频流的 PES 长度不为零,则会出现问题。 FFMPEG 确实如此 似乎无法应对。看来 FFMPEG 要求流是 明确标记为“任意长度”(即设置为零)。

如果我下载原始 .ts 文件并通过 TS_Doctor 运行它,分析器会抱怨:

<块引用>

"检测到视频流上的 PES 长度。这可能有问题! 将视频流上的 PES 长度修补为安全值 - 是/否。"

如果我点击“否”,然后通过 FFMPEG 运行输出,则会报告一个问题 声音不同步。如果我点击“是”,然后通过 FFMPEG 运行输出, 没有问题。这表明输出文件之间的唯一区别 是 PES 长度修正。

PES 数据包长度为零的值只能在 PES 数据包 有效载荷是一个视频流。

.

解决方法

一个可能的解决方案是连接 .ts 文件,然后获取输出 .ts 文件, 将其拆分为视频文件 (.m4v) 和音频文件 (.m4a),然后重新混合它们 (仍为 .ts 格式)使用“itsoffset”选项。

然后应该可以将生成的 .ts 文件转换为 .mp4 或 .mkv 而不需要 任何错误。

不理想,但通常有效。