如何实现live555中接收的视频数据是完整帧

柒号华仔
2022年度博客之星评选前沿技术领域TOP 1
2012-07-09 03:49:00
实现了摄像头采集视频并以RTSP流发送出去,用vlc是可以播放这个RTSP流的,现在可以基于live555接收RTSP视频流保存为一个264文件,并基于ffmpeg解码这个文件在浏览器上显示出来。现在需要不保存为文件,直接取出一帧数据传给ffmpeg解码。
在FileSink的addData中fwrite函数写入数据到文件,但是strlen传给fwrite的data数据时大时小,小的时候为零,大的时候10000多;
可以看出afterGettingFrame中的adddata调用写入了图像数据,因为注销这个adddata,过10几秒写出的文件只有几K,不注销时写出的有10M左右,但是它写入的fBuffer也是时大时小,小的时候为零,大的时候10000多。
同时continuePlaying中fSource->getNextFrame函数,fBuffer也是跟上面一样,时大时小。

这三个个地方的data和fBuffer传过去解码,在解码函数avcodec_decode_video中都显示:[h264 @ 65E8EAC0] no frame!看起来是没有得到完整的一帧数据。

现在怎么样在这里得到完整的一帧图像数据,以便传过去解码,求指导,不胜感激。
...全文
2628 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
smilestone322 2014-02-11
  • 打赏
  • 举报
回复
live555 的sink中有 // Request the next frame of data from our input source. "afterGettingFrame()" will get called later, when it arrives: fSource->getNextFrame(fReceiveBuffer, RTPMEDAA_SINK_RECEIVE_BUFFER_SIZE, afterGettingFrame, this, onSourceClosure, this); fReceiveBuffer中就是Buff,如果服务端sps,pps,i帧 是分开发包的话,客户端要自己组包,组成一帧,如果不是分开发,直接加00 00 00 01 ,就是一帧完整数据,交给ffmpeg解码就行,具体看我的博客; http://blog.csdn.net/smilestone_322?viewmode=contents
37度的阳光 2013-08-16
  • 打赏
  • 举报
回复
buf的最大容量为20000,读取数据时就会用这个buf来接收,每接收一次buf的容量就会变小,如果你每次都打印fMaxSize的值,你就会发现它是递减的,fMaxSize其实就是buf的剩余容量,所以它递减,每次也是依据这个容量来接收数据,当buf满了之后,会把这个满的buf中的数据放到待处理链表中,同时分配一个新的buf,大小依然是20000.所以每次读取的数据并不能保证是完整的一帧。 avcodec_decode_video解码的结果为no frame是正常的,你只需要把这些还未解码成功的数据数据保存下来,和下次到达的数据再一起传给解码器,解码器就会自己查找是否有完整帧,若无,继续上面的操作,直到有完整帧,删掉那一帧的数据,接下来重复就可以了。 如果你想手动判定h264的一帧也可以,只需要寻找数据里的00 00 00 01,对于P帧,都是以00 00 00 01开头,到下一个00 00 00 01结束(这是下一帧的开头),然后把这部分数据拿出来传给解码器解码也是可以的。
huangwutao1987 2013-08-14
  • 打赏
  • 举报
回复
楼主现在解决了吗?我也很想知道。
柒号华仔 2012-07-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

filesink获取的就是1帧数据,h264编码,live555没加0 0 0 1
[/Quote]

我在adddata的fBuffer前加上了0x00,0x00,0x00,0x01,传过去一样的情况,主要是adddata进去的数据有时大小只有几十,有时又有10000多;
尝试根据struct timeval presentationTime来判断时间,把几次接收到presentationTime相同的数据写入同一个buffer然后解码,还是说no frame
柒号华仔 2012-07-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

在fileSink的afternextframe()中,通过adddata()把buffer写到指定的文件中。
afternextframe()中的就是一个完整的帧数据。
[/Quote]

我在linux下grep了一下,live555里面没有afternextframe这个函数,getnextframe倒是有的,不过这里的fBuffer也是一会基本为零,一会10000多,有点困惑
ArcRain 2012-07-10
  • 打赏
  • 举报
回复
数据大小怎么能用strlen来取呢?遇到0x00就截断了。
cll131421 2012-07-09
  • 打赏
  • 举报
回复
在fileSink的afternextframe()中,通过adddata()把buffer写到指定的文件中。
afternextframe()中的就是一个完整的帧数据。
rightorwrong 2012-07-09
  • 打赏
  • 举报
回复
filesink获取的就是1帧数据,h264编码,live555没加0 0 0 1

2,542

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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