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服务器问题!!



我现在想修改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.

  • 我用的是DVSDK 4.02   使用dvsdk-demos_4_02_00_01 里的encode捕获视频图像的。  

    那我这个需要怎么改呢?  

  • 想要实现实时码流播放,需要修改LIVE555的数据来源类,你要扩展出自己的数据源类文件,实现从你的encode里拿码流

  • kevin xie2

    我的实时流播放是可以的, 是从encode 的writer.c 里将它获取的一帧数据当做了码流。 

    现在可以实现实时播放。

    但是有个问题,当我在开发板上执行encode的时候,立即在WMPlayer播放器上输入网络地址。 是ok的。

    但是当我在encode执行过程中,在WMPlayer播放器上输入网络地址,就不可以了。没有图像。

    请问这个是什么原因呢?  这个与什么有关?