ffmpeg如何判读一帧(AVPacket)不完整

haotianmai 2010-12-01 10:37:35
现在手上有个程序用ffmpeg从网络接收TS流, 然后通过av_read_frame()分离出一帧帧的音视频帧(TS术语中叫ES),保存在一个个的AVPacket中, 再通过av_decode_video把AVpacket中的数据解码到 AVFrame中,再把AVFrame中的yuv420数据渲染到屏幕上。

因为网络会丢包,可能会丢掉几个TS包,这样av_read_frame分离出来的帧数据就会不完整。
问题是:我现在能知道一个AVpacket中的实际大小,但我不知道这个AVPacket应该是多大,因此我无法判断这个AVPacket到底完整不?
补充:理论上PES包头有这个ES的总大小,但TS官方文档说这个pes_packet_size数据段也可能为0。那么我通过什么方法知道这个AVPacket(ES)丢失了数据,不完整呢。
不胜感激!
...全文
4130 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
happylifer 2013-01-30
  • 打赏
  • 举报
回复
mark...好帖,说不定以后用的上。
rain_2011_kai 2012-05-28
  • 打赏
  • 举报
回复
楼主,我现在也正在做接收网络流的工作,请问你怎样实现的接收网络流并判断视频格式呢,恳请指导?
wgx20120504 2012-05-14
  • 打赏
  • 举报
回复
用ffmpeg从网络接收TS流的程序可以发给我看看嘛?
我的邮箱是510056105@qq.com
码记 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
现在手上有个程序用ffmpeg从网络接收TS流, 然后通过av_read_frame()分离出一帧帧的音视频帧(TS术语中叫ES),保存在一个个的AVPacket中, 再通过av_decode_video把AVpacket中的数据解码到 AVFrame中,再把AVFrame中的yuv420数据渲染到屏幕上。

因为网络会丢包,可能会丢掉几个TS包,这样av_read_frame分离出来的帧数据……
[/Quote]
楼主,你的ffmpeg读取TS流后如何调用av_read_frame 来分离帧呢?
av_read_frame的第一个参数我实在不知道该如何设置。望楼主指点一下。谢谢。
yezeguo 2010-12-04
  • 打赏
  • 举报
回复
都是牛人,学习中
wy2001wy 2010-12-03
  • 打赏
  • 举报
回复
如果不考虑流畅的问题应该可以,我对这东西也不是很了解
haotianmai 2010-12-02
  • 打赏
  • 举报
回复
换个差不多的问题问吧:
ffmpeg有没有错误处理的模式,能使花屏的帧(h264格式的)不显示出来?
haotianmai 2010-12-02
  • 打赏
  • 举报
回复
To wy2001wy
I帧不错误的话直接跳到下一个I帧。
流畅不考虑,只要不花就行了。

To hdusunny44
服务端是不会传的,服务端只管把TS流传过来

haotianmai 2010-12-02
  • 打赏
  • 举报
回复
郁闷!
你们要再不回帖,我都没法发了: CSDN不让一个人连续发帖超过3次,刚实在是发不了帖子。

看来问题只能这样解决了,现在还要多测测,防止产生新的问题。目前来看,对现有代码没有影响,花屏的帧直接屏蔽掉了。

思路:
问了下机顶盒方面h264解码的,他们用的是硬件解码,他们做到不花屏的方法就是简单的设置了一个硬件解码提供的接口:设置了错误处理模式。
我想这个错误处理模式肯定对那些错误的帧直接屏蔽掉了,这样显示到屏幕上就不花了。

因此,就有了上面的问题:ffmpeg有没有错误处理的模式,能使花屏的帧(h264格式的)不显示出来?
查了些资料,没找到。

PS:各位如果知道的话,请留个言。

我假定ffmpeg没有这个模式,十有八九没有。我就用我的方法模拟一个错误处理模式。
在AVFrame(FF_COMMON_FRAME)里添加一个变量,datadamage.
这个变量为0时,表示这个frame没有错误;反之,为1时,表示有错误。

怎么用呢?
当av_decode_video()解出一帧后,判断这个标志:
为1。就不渲染,屏蔽掉。如果当前帧是关键帧,且标志为1,到下一个关键帧之前的所有帧都屏蔽掉。
为0就正常渲染。

现在的问题就变成了这个标志什么时候置的问题。
首先我们要知道一个frame(h264)什么时候开始解码的.知道了什么时候开始,也就知道了什么时候结束。(下一帧开始解码的时候,上一帧当然结束了)。
这里有个依据,current_mb_slice == 0时,表示一帧开始。
当然也可以用第2个方法:ff_h264_frame_start()这就是一帧开始了。

那么我们怎么判断这帧错误呢?
我用的方法是:
因为h264一帧由slice MB这些单位,当解这帧的任意slice或任意MB出现错误时,只要有一个错误,这帧就置错误标志。
另h264每帧之前还有些相应信息,SPS PPS.这些出现错误的话,理论上应该到下一个SPS或PPS之间的帧都要置错误标志,这个还没做(目前没什么影响)。再后面几天测试的时候可能要仔细考虑下。

上面就是目前的方案,也是想到的唯一方案,目前为止能屏蔽掉花屏的帧。
等到完全测试成功,再说吧。

这个方案中有什么好的建议的,请大家提出来。不胜感激

hdusunny44 2010-12-02
  • 打赏
  • 举报
回复
把帧大小传到客户端进行比较?
wy2001wy 2010-12-02
  • 打赏
  • 举报
回复
我觉得吧,把不完整的包扔了也一样会花屏,除非你直接跳到下个I帧,那样不花了,但是也不流畅了。
haotianmai 2010-12-01
  • 打赏
  • 举报
回复
没人碰到过类似问题吗?
继续查资料中....
呵呵,期待着人品大爆发
haotianmai 2010-12-01
  • 打赏
  • 举报
回复
我下周就要把 “通过丢帧来实现不花屏” 完成,现在打算先找到哪帧不完整,就直接丢掉不送去解码。另如果是关键帧,就连带后续的PB帧也同时丢掉。
问题是我对于如何判断一帧是否完整没法判断出来。
一点眉目也没,正在狂找资料中。
有谁能提供个思路,分享下好吗
就想叫yoko 2010-12-01
  • 打赏
  • 举报
回复
最近手上也在搞FFMPEG,帮顶下楼主了

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧