当前位置: 技术问答>linux和unix
求教各路高手 jrtplib库在arm与pc机之间通信 组网点播H.264时花屏
来源: 互联网 发布时间:2016-09-09
本文导语: 网络播放器 架构如下:在局域网中有多个ARM板 发送视频流,每个ARM板有一个IP。所有的ARM板通过交换机与PC机相连。PC机通过给不同的IP发送指令来点播或结束视频。PC部分软件将从交换机中获得的数据进行3894解包...
网络播放器
架构如下:在局域网中有多个ARM板 发送视频流,每个ARM板有一个IP。所有的ARM板通过交换机与PC机相连。PC机通过给不同的IP发送指令来点播或结束视频。PC部分软件将从交换机中获得的数据进行3894解包,加时间戳变成标准的H.264视频格式发送到DIRECTSHOW缓冲区中。,由directshow进行播放。
现在的问题是。当切换点播时,会出现花屏,或者画面长时间的不响应,此时停止播放。再进行播放即可正常播放。通过抓包软件看,数据流其实已经全部过来了,只是应用软在接收线程中端使用GoToFirstSourceWithData总是返回0即检测不到数据源。
我切换播放的过程如下:发送停止当前视频->清空缓冲区->重新进行SOCKET连接->发送播放命令->得到响应后,开始播放。
接受线程如下:
DWORD WINAPI CSourceFilter::ReceivingThrd(void * pParam)
{
CSourceFilter * pFilter = (CSourceFilter *) pParam;
if (pFilter)
{
pFilter->m_RtspClient->PlayRTSP();//start play!通知RTSP服务器,此时可以发送视频流了。
while(1)
{
pFilter->m_RtpSession->BeginDataAccess();
if(pFilter->m_RtpSession->GotoFirstSourceWithData())
{
do
{
RTPPacket *pack;
while ((pack = pFilter->m_RtpSession->GetNextPacket()) != NULL)
{//收到一包RTP
size_t length=0;
size_t decode_length=0;
char endFlag=0;
uint8_t *PlayloadData;
PlayloadData=pack->GetPayloadData();
length = pack->GetPayloadLength();
//对数据包进行解码。
decode_length=pFilter->m_DecoderRFC3984.DecodeRFC3984(PlayloadData,(pFilter->m_DecodeH264Buffer+pFilter->m_CurrentDecodeBufferIn),length,&endFlag);
if( endFlag == 0x40 )//NAL is end
{
//存到缓冲区中,有pin类的 fillbuff 函数调用。
pFilter->m_pDataList->MoveDataToBuffer((char *)pFilter->m_DecodeH264Buffer,pFilter->m_CurrentDecodeBufferIn+decode_length);
pFilter->ClearDecodeH264Buffer();
}
else
{
pFilter->m_CurrentDecodeBufferIn += decode_length;
}
pFilter->m_RtpSession->DeletePacket(pack); }
} while(pFilter->m_RtpSession->GotoNextSourceWithData());
}
pFilter->m_RtpSession->EndDataAccess();
Sleep(1);
}
}
return 0;
}
架构如下:在局域网中有多个ARM板 发送视频流,每个ARM板有一个IP。所有的ARM板通过交换机与PC机相连。PC机通过给不同的IP发送指令来点播或结束视频。PC部分软件将从交换机中获得的数据进行3894解包,加时间戳变成标准的H.264视频格式发送到DIRECTSHOW缓冲区中。,由directshow进行播放。
现在的问题是。当切换点播时,会出现花屏,或者画面长时间的不响应,此时停止播放。再进行播放即可正常播放。通过抓包软件看,数据流其实已经全部过来了,只是应用软在接收线程中端使用GoToFirstSourceWithData总是返回0即检测不到数据源。
我切换播放的过程如下:发送停止当前视频->清空缓冲区->重新进行SOCKET连接->发送播放命令->得到响应后,开始播放。
接受线程如下:
DWORD WINAPI CSourceFilter::ReceivingThrd(void * pParam)
{
CSourceFilter * pFilter = (CSourceFilter *) pParam;
if (pFilter)
{
pFilter->m_RtspClient->PlayRTSP();//start play!通知RTSP服务器,此时可以发送视频流了。
while(1)
{
pFilter->m_RtpSession->BeginDataAccess();
if(pFilter->m_RtpSession->GotoFirstSourceWithData())
{
do
{
RTPPacket *pack;
while ((pack = pFilter->m_RtpSession->GetNextPacket()) != NULL)
{//收到一包RTP
size_t length=0;
size_t decode_length=0;
char endFlag=0;
uint8_t *PlayloadData;
PlayloadData=pack->GetPayloadData();
length = pack->GetPayloadLength();
//对数据包进行解码。
decode_length=pFilter->m_DecoderRFC3984.DecodeRFC3984(PlayloadData,(pFilter->m_DecodeH264Buffer+pFilter->m_CurrentDecodeBufferIn),length,&endFlag);
if( endFlag == 0x40 )//NAL is end
{
//存到缓冲区中,有pin类的 fillbuff 函数调用。
pFilter->m_pDataList->MoveDataToBuffer((char *)pFilter->m_DecodeH264Buffer,pFilter->m_CurrentDecodeBufferIn+decode_length);
pFilter->ClearDecodeH264Buffer();
}
else
{
pFilter->m_CurrentDecodeBufferIn += decode_length;
}
pFilter->m_RtpSession->DeletePacket(pack); }
} while(pFilter->m_RtpSession->GotoNextSourceWithData());
}
pFilter->m_RtpSession->EndDataAccess();
Sleep(1);
}
}
return 0;
}
|
你可以试试重载 RTPSession 类,里面有个什么 OnRTPPacketReceive(RTPDataSource*data),
不知道会不会解决 返回0 的问题。
另外,如果返回0,说明远端已经掉线,RTPSession 自动维护连接。如果掉线会在OnRemoveDataSource 里检测到,你可以在里面看下IP,进一步进行调试。
不知道会不会解决 返回0 的问题。
另外,如果返回0,说明远端已经掉线,RTPSession 自动维护连接。如果掉线会在OnRemoveDataSource 里检测到,你可以在里面看下IP,进一步进行调试。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。