我现在想修改RTSP服务器,让其可以接受,编码后的一帧一帧数据,然后通过VLC实时直播。
现在问题是,我改完的后一直编译不通过。
有没有实例,可以供我参考一下呢?
是怎么改的?
Chris Meng:
Juke,
IPNC代码 里面有使用live555来支持RTSP,请问你是否有使用的类似软件?
JUKE CHEN:
回复 Chris Meng:
Chris Meng,
我没有使用IPNC方案,
我尝试过live555。 我可以实现264文件的通过live555服务器,然后VLC播放。
但是这不是我想要的。我要做的的是将编码后的码流,通过RTSP,然后VLC实时播放。
这个我现在还没有弄好。
我现在使用的RTSP服务器的demo里,问题在于需要对每一帧数据进行判断IDR。
void OnH264FrameDataOK( DATA_CONTEXT * lpDataContext, unsigned char * lpDataBuf, unsigned long ulSize ){ if( lpDataContext && lpDataBuf && ulSize ) { if( !lpDataContext->nGetIDR ) { unsigned char * lpSPS = NULL; unsigned char * lpSPS_E = NULL; unsigned char * lpPPS = NULL; unsigned char * lpPPS_E = NULL;
unsigned int fNalType = 0;
if( ( 0 == *(lpDataBuf+0) ) && ( 0 == *(lpDataBuf+1) ) && ( 0 == *(lpDataBuf+2) ) && ( 1 == *(lpDataBuf+3) ) ) { fNalType = (0x01f&(*(lpDataBuf+4))); }
if( 7 == fNalType ) /*SPS*/ { unsigned char * pNextNal = lpDataBuf+4; unsigned char * pEnd = lpDataBuf+ulSize;
lpSPS = lpDataBuf;
while( pNextNal < pEnd ) { if( ( 0 == *(pNextNal+0) ) && ( 0 == *(pNextNal+1) ) && ( 0 == *(pNextNal+2) ) && ( 1 == *(pNextNal+3) ) ) { if( !lpSPS_E ) lpSPS_E = pNextNal;
fNalType = (0x01f&(*(pNextNal+4)));
if( 8 == fNalType ) /*PPS*/ { if( !lpPPS ) lpPPS = pNextNal; } else { if( lpPPS && !lpPPS_E ) lpPPS_E = pNextNal; }
if( lpPPS_E ) break; }
pNextNal++; }
if( lpSPS && lpSPS_E && lpPPS && lpPPS_E ) { char szSPS[128]; char szPPS[32]; unsigned int profile_level_id = 0x420029; unsigned char spsWEB[3];
live_base64encode( szSPS, lpSPS+5, lpSPS_E-lpSPS-5 ); live_base64encode( szPPS, lpPPS+5, lpPPS_E-lpPPS-5 );
// sprintf( szSPS, "%s", "Z00AKZpmA8ARPyzUBAQFAAADA+gAAMNQBA==" );// sprintf( szPPS, "%s", "aO48gA==" );
spsWEB[0] = *(lpSPS+5); spsWEB[1] = *(lpSPS+6); spsWEB[2] = *(lpSPS+7);
profile_level_id = (spsWEB[0]<<16) | (spsWEB[1]<<8) | spsWEB[2];
sprintf( lpDataContext->szVideoFmtp, "a=fmtp:%d packetization-mode=1;profile-level-id=%06X;sprop-parameter-sets=%s,%s", g_nVideoPayloadType, profile_level_id, szSPS, szPPS );
lpDataContext->nGetIDR = 1; } } }
需要检测264文件的帧。
void * ProcLiveStreamSeed( void * voidPtr ){ DATA_CONTEXT * lpDataContext = (DATA_CONTEXT*)voidPtr;
unsigned char * lpReadBuf; unsigned long ulRead = 0; unsigned char * lpFrameBuf = NULL; int nTotalFrames = 0; FILE * fd_H264;
//以二进制的方式打开文件或创建文件 if((fd_H264 = fopen( "test.264", "rb")) == NULL) { return NULL; }
lpReadBuf = (unsigned char*)malloc( 2*1024*1024+4 );
while( !lpDataContext->nSeedTerminal ) {
/***********************************************/ /* ENCODE DATA ARRIVING… */
int nRead = fread( lpReadBuf+ulRead, 1, 1, fd_H264 ); if( nRead <= 0 ) { fseek( fd_H264, 0, SEEK_SET ); ulRead = 0; lpFrameBuf = NULL;
continue; }
ulRead++;
if( ulRead >= 5 ) { if( 0 == *(lpReadBuf + ulRead – 5) && 0 == *(lpReadBuf + ulRead – 4) && 0 == *(lpReadBuf + ulRead – 3) && 1 == *(lpReadBuf + ulRead – 2) ) { if( NULL == lpFrameBuf ) lpFrameBuf = lpReadBuf + (ulRead – 5); else { int t = 0x1f &(*(lpReadBuf+ulRead-1)); if( t == 7 || t == 1 ) { nTotalFrames++; OnH264FrameDataOK( lpDataContext, lpFrameBuf, lpReadBuf + ulRead – 5 – lpFrameBuf );
lpReadBuf[0] = 0; lpReadBuf[1] = 0; lpReadBuf[2] = 0; lpReadBuf[3] = 1; lpReadBuf[4] = *(lpReadBuf+ulRead-1);
ulRead = 5;
lpFrameBuf = lpReadBuf;
#ifndef WIN32 usleep( 40*1000 );#else Sleep( 40 );#endif } } } }
/***********************************************/ }
free( lpReadBuf );
fclose(fd_H264);
return NULL;}
我编译OK,但是执行的时候,会没有图像。 我怀疑是264文件格式不对,或者是上面分离检测每一帧的方法不对。
但是我没有其他OK的相关代码可以参考了。
你能给我一些建议吗?
Chris Meng:
回复 JUKE CHEN:
JUKE CHEN我尝试过live555。 我可以实现264文件的通过live555服务器,然后VLC播放。
你是在DM36x上尝试的live555么?这个功能和你要的功能有什么区别?
JUKE CHEN:
回复 Chris Meng:
是的,我是在DM368开发板上尝试的live555, 这个需要把test.264文件放在可执行文件live555MediaServer同一目录。
然后执行的,然后再VLC上输入 rtsp://192.168.2.187/test.264.
然而这个不是我要的功能。它的test.264文件是已经编码好的文件。
而我需要的是实时播放的效果,需要一边摄像一边播放,可以实时监控。
Chris Meng:
回复 JUKE CHEN:
Juke,
DM36x的IPNC参考设计利用live555实现的是实时视频发送给VLC,这是IPNC的基本功能啊
DM36x编码输出是可以告诉你该帧是什么类型的帧,请参考IVIDENC1_OutArgs.encodedFrameType.
JUKE CHEN:
回复 Chris Meng:
我用的是DVSDK 4.02 使用dvsdk-demos_4_02_00_01 里的encode捕获视频图像的。
那我这个需要怎么改呢?
kevin xie2:
回复 JUKE CHEN:
想要实现实时码流播放,需要修改LIVE555的数据来源类,你要扩展出自己的数据源类文件,实现从你的encode里拿码流
JUKE CHEN:
回复 kevin xie2:
kevin xie2
我的实时流播放是可以的, 是从encode 的writer.c 里将它获取的一帧数据当做了码流。
现在可以实现实时播放。
但是有个问题,当我在开发板上执行encode的时候,立即在WMPlayer播放器上输入网络地址。 是ok的。
但是当我在encode执行过程中,在WMPlayer播放器上输入网络地址,就不可以了。没有图像。
请问这个是什么原因呢? 这个与什么有关?
TI中文支持网

