在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!看起来是没有得到完整的一帧数据。
现在怎么样在这里得到完整的一帧图像数据,以便传过去解码,求指导,不胜感激。
9 个解决方案
#1
filesink获取的就是1帧数据,h264编码,live555没加0 0 0 1
#2
在fileSink的afternextframe()中,通过adddata()把buffer写到指定的文件中。
afternextframe()中的就是一个完整的帧数据。
afternextframe()中的就是一个完整的帧数据。
#3
我在linux下grep了一下,live555里面没有afternextframe这个函数,getnextframe倒是有的,不过这里的fBuffer也是一会基本为零,一会10000多,有点困惑
#4
我在adddata的fBuffer前加上了0x00,0x00,0x00,0x01,传过去一样的情况,主要是adddata进去的数据有时大小只有几十,有时又有10000多;
尝试根据struct timeval presentationTime来判断时间,把几次接收到presentationTime相同的数据写入同一个buffer然后解码,还是说no frame
#5
数据大小怎么能用strlen来取呢?遇到0x00就截断了。
#6
楼主现在解决了吗?我也很想知道。
#7
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结束(这是下一帧的开头),然后把这部分数据拿出来传给解码器解码也是可以的。
avcodec_decode_video解码的结果为no frame是正常的,你只需要把这些还未解码成功的数据数据保存下来,和下次到达的数据再一起传给解码器,解码器就会自己查找是否有完整帧,若无,继续上面的操作,直到有完整帧,删掉那一帧的数据,接下来重复就可以了。
如果你想手动判定h264的一帧也可以,只需要寻找数据里的00 00 00 01,对于P帧,都是以00 00 00 01开头,到下一个00 00 00 01结束(这是下一帧的开头),然后把这部分数据拿出来传给解码器解码也是可以的。
#8
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
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
#9
#1
filesink获取的就是1帧数据,h264编码,live555没加0 0 0 1
#2
在fileSink的afternextframe()中,通过adddata()把buffer写到指定的文件中。
afternextframe()中的就是一个完整的帧数据。
afternextframe()中的就是一个完整的帧数据。
#3
我在linux下grep了一下,live555里面没有afternextframe这个函数,getnextframe倒是有的,不过这里的fBuffer也是一会基本为零,一会10000多,有点困惑
#4
我在adddata的fBuffer前加上了0x00,0x00,0x00,0x01,传过去一样的情况,主要是adddata进去的数据有时大小只有几十,有时又有10000多;
尝试根据struct timeval presentationTime来判断时间,把几次接收到presentationTime相同的数据写入同一个buffer然后解码,还是说no frame
#5
数据大小怎么能用strlen来取呢?遇到0x00就截断了。
#6
楼主现在解决了吗?我也很想知道。
#7
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结束(这是下一帧的开头),然后把这部分数据拿出来传给解码器解码也是可以的。
avcodec_decode_video解码的结果为no frame是正常的,你只需要把这些还未解码成功的数据数据保存下来,和下次到达的数据再一起传给解码器,解码器就会自己查找是否有完整帧,若无,继续上面的操作,直到有完整帧,删掉那一帧的数据,接下来重复就可以了。
如果你想手动判定h264的一帧也可以,只需要寻找数据里的00 00 00 01,对于P帧,都是以00 00 00 01开头,到下一个00 00 00 01结束(这是下一帧的开头),然后把这部分数据拿出来传给解码器解码也是可以的。
#8
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
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