我现在想修改RTSP服务器,让其可以接受,编码后的一帧一帧数据,然后通过VLC实时直播。
现在问题是,我改完的后一直编译不通过。
有没有实例,可以供我参考一下呢?
是怎么改的?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我现在想修改RTSP服务器,让其可以接受,编码后的一帧一帧数据,然后通过VLC实时直播。
现在问题是,我改完的后一直编译不通过。
有没有实例,可以供我参考一下呢?
是怎么改的?
Juke,
IPNC代码 里面有使用live555来支持RTSP,请问你是否有使用的类似软件?
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的相关代码可以参考了。
你能给我一些建议吗?
JUKE CHEN 说:我尝试过live555。 我可以实现264文件的通过live555服务器,然后VLC播放。
你是在DM36x上尝试的live555么?这个功能和你要的功能有什么区别?
是的,我是在DM368开发板上尝试的live555, 这个需要把test.264文件放在可执行文件live555MediaServer同一目录。
然后执行的,然后再VLC上输入 rtsp://192.168.2.187/test.264.
然而这个不是我要的功能。它的test.264文件是已经编码好的文件。
而我需要的是实时播放的效果,需要一边摄像一边播放,可以实时监控。
Juke,
DM36x的IPNC参考设计利用live555实现的是实时视频发送给VLC,这是IPNC的基本功能啊
DM36x编码输出是可以告诉你该帧是什么类型的帧,请参考IVIDENC1_OutArgs.encodedFrameType.
kevin xie2
我的实时流播放是可以的, 是从encode 的writer.c 里将它获取的一帧数据当做了码流。
现在可以实现实时播放。
但是有个问题,当我在开发板上执行encode的时候,立即在WMPlayer播放器上输入网络地址。 是ok的。
但是当我在encode执行过程中,在WMPlayer播放器上输入网络地址,就不可以了。没有图像。
请问这个是什么原因呢? 这个与什么有关?