最新进展:
分辨率由原来320*240增加到640*480
流畅播放,但有延时约2秒不到,说明代码还得优化
马赛克消除,画质改善,但仍不是很清晰
两台笔记本可同时观看,说明组播已实现
ipad也可观看,手机不行,卡死,说明手机该换了
更正一下,上次出画面完全是偶然,因为第二天又不出画面了,全过程如下:
arm打印信息如下:
[1301] WebcamOndemandMediaSubsession ....
calling
using url
"rtsp://192.168.253.209:8554/webcam"
[1301] createNewStreamSource .... calling
[1301] WebcamFrameSource .... calling
Current input name: ov9650
field =1
nv12
fmt!
capture_open: using MEMORY_MMAP mode, buf
cnt=1
ImageSize[0] = 115200
support RGB-5-6-5
support RGB-8-8-8, unpacked 24 bpp
support YUV 4:2:2 packed, YCbYCr
support YUV 4:2:2 packed, CbYCrY
support YUV 4:2:2 packed, CrYCbY
support YUV 4:2:2 packed, YCrYCb
support YUV 4:2:2 planar, Y/Cb/Cr
support YUV 4:2:0 planar, Y/CbCr
support YUV 4:2:0 planar, Y/CbCr, Tiled
support YUV 4:2:0 planar, Y/CrCb
support YUV 4:2:2 planar, Y/CbCr
support YUV 4:2:2 planar, Y/CrCb
support YUV 4:2:0 planar, Y/Cb/Cr
support Encoded JPEG bitstream
support
support
Open Device OK!
StartStream OK!
MfcEncOpen succeeded
SsbSipMfcEncInit: Encode Init start
SsbSipMfcEncInit: H264 Encode
SsbSipMfcEncInit succeeded
SsbSipMfcEncGetOutBuf suceeded
headersize= 22
head=
SsbSipMfcEncGetInBuf succeeded
[1301] createNewRTPSink .... calling
[1301] getAuxSDPLine .... calling
startPlaying
[1301] chkForAuxSDPLine1 .... calling
after getting AuxSDPLine
[1301] getNextFrame1 .... call
capture_get_picture: DQ index=0
fFrameSize=22772 fMaxSize=150000
[1301] getNextFrame1 .... call
capture_get_picture: DQ index=0
fFrameSize=3781 fMaxSize=127228
[1301] getNextFrame1 .... call
capture_get_picture: DQ index=0
fFrameSize=21 fMaxSize=123447
[1301] getNextFrame1 .... call
capture_get_picture: DQ index=0
fFrameSize=12 fMaxSize=123426
[1301] getNextFrame1 .... call
capture_get_picture: DQ index=0
fFrameSize=12 fMaxSize=123414
[1301] chkForAuxSDPLine1 .... calling
chkForAuxSDPLine1 success !
after doEventLoop
getAuxSDPLine return mp_sdp_line= a=fmtp:96
packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=Z2QAKKzTBQfk,aOpAbywAAAAAAAAAAAAAAA……(此处省略几千个A)
[1301] ~WebcamFrameSource .... calling
SsbSipMfcEncClose Success!
Segmentation
fault
最后一个段错误上次通过释放header指针解决了,
但倒数第三句还在,就是析构了,然后终中断,pc看不到画面
同时从上面的几千个A看出,pps提取出错,sps倒是正确的
于是开始痛苦地研究live关于pps的代码,主要看 源码 + live官网 + http://blog.csdn.net/gavinr
这篇博客让人思路清晰
live官网提供所有文件、函数、class等等的查询,可以快速查找你想要找的函数,因为live的整个架构很复杂,
我一开始可能看一个代码花20分钟,找一个函数花半小时。。。
live555源码分析---- DESCRIBE命令处理 关于sps、pps在这篇文章里
大致流程就是:
void RTSPServer::RTSPClientSession ::handleCmd_DESCRIBE 处理DESCRIBE,其中调用下面的函数
sdpDescription = session->generateSDPDescription(); 获得SDP,SDP大部分都好获取,
但媒体描述部分不太容易获取,这部分要调用下面的函数
subsession->sdpLines() 这个函数定义在ServerMediaSubsession中的纯虚函数,在 数在 OnDemandServerMediaSubsession::sdpLines()中实现,实现过程为三步走:
第一步:实例化source
第二步:实例化RTPSink
第三步:调用下面的函数获取媒体部分的SDP,前两部是为第三步服务,因为这个函数的参数是前两个实例
void OnDemandServerMediaSubsession ::setSDPLinesFromRTPSink
媒体相关的描述大部分都好办,就是有一个可选的扩展属性,需要调用下面的函数获取
auxSDPLine() 这个函数是父类RTPSink的成员函数,返回空,需要在子类H264VideoRTPSink中重实现,如下:
H264VideoRTPSink::auxSDPLine() 此函数中调用下面的函数获得sps和pps
framerSource->getSPSandPPS(sps, spsSize, pps, ppsSize); 注意,这是老版本的live,在新版本中就这个函数改了个名
叫getVPSandSPSandPPS
新版本做了一些优化,但大差不差
这个函数getVPSandSPSandPPS 在哪?博主没有继续分析,我就自己找了,
此函数中就三行:
vps = fLastSeenVPS; vpsSize = fLastSeenVPSSize;
sps = fLastSeenSPS; spsSize = fLastSeenSPSSize;
pps = fLastSeenPPS; ppsSize = fLastSeenPPSSize;
fLastSeenPPSSize 哪来?下面来 :
void H264or5VideoStreamFramer::saveCopyOfPPS(u_int8_t* from, unsigned size)
{
if (from == NULL) return;
delete[] fLastSeenPPS;
fLastSeenPPS = new u_int8_t[size];
memmove(fLastSeenPPS, from, size);
fLastSeenPPSSize = size;
}
saveCopyOfPPS这个函数定义及调用均在这个文件里: H264or5VideoStreamFramer.cpp
调用:usingSource()->saveCopyOfPPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize);
其中fOutputStartCodeSize = 0 curFrameSize()竟然 = 7000
这就是为什么arm打印了几千个A,因为从源头上获取的pps的size就这么大,
当然正常情况下pps就几个字节,不会有7000的,所以:
要么是提取pps的算法有问题,
要么我传给live555的数据源本身就有问题
估计是数据源的问题,因为live555毕竟是公司做的软件
而且直播264文件没问题
数据源怎么有问题现在不知道!!!!!!!!!
我暂时只能这样处理:
加上一句:若size大于20,则让他等于20
毕竟动态分配20大小的空间要比分配7000要好
目前pc都能出画面了,但治标不治本,还是存在bug,问题没有从根本解决
另外说一下,最先送给live555的不是264的head,而是解码后的数据,
先送5帧编码后的数据,在这期间arm无法获取head , pc没有画面,
然后吧head送给live555,他就获取head了,pc慢慢就有画面了
也不一定非要十几帧,两三帧甚至直接给head都有可能行,我还没试
稍微总结一下:sps和pps属于 SDP的媒体相关部分 中的 可扩展属性 的一部分
最后再说一下怎么调试
我没用过 gdb 也不会用 也不想用
就在程序里加入很多打印信息函数fprintf(),可以有效跟踪程序的走向
对于一般的代码,这么调试足够了
对于live555 ,就比较困难了,很容易跟丢了
好在live提供DEBUG,就是在文件里宏定义DEBUG
就能输出很多打印信息
后面的工作:
看看我的264文件,数据源有什么问题,跟标准264文件对比一下
改善画质
串口终端怎么用