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.

IPNCRDK custom streaming server integration



I am using ipnc rdk 3.8, with DM388 IPNC. I wanted to use our custom streaming server. I am using GetAVData() method to get the encoded streams. However, I am stuck at LockFrame() function and it always returning RET_ERROR_OP or RET_OVERWRTE. I am using AV_OP_LOCK_MP4  to get H.264 stream . Is this correct?

pls check the relevant code below:

if(ApproDrvInit(BOA_MSG_TYPE)  < 0) {

      exit(1);

}

if (func_get_mem(NULL)) {

  ApproDrvExit();

  exit(1);

}

while (1)

{

    ret =  GetAVData(AV_OP_LOCK_MP4,1,&av_data);

    if (ret == SUCCESS)

   {

       GetAVData(AV_OP_UNLOCK_MP4,1,NULL);

       ......................

   }

   else if (ret == RET_NO_VALID_DATA)

   {

       printf("No Valid Data.\n");

   }

}

 

Is this the correct way to get H.264 frames in a different process?

Best Regards

JK

  • After digging  ipnc_app a little, I was able to deque encoded  frames from AV Server  using GetAVData() method.

    (See APPROInput.c)

    But , it looks all the frames are IDR frames , and only the first two frames are decodable. See attached  stream.

    void mainloop_h264()
    {
        FILE *pfd = NULL;
        AV_DATA vol_data;
        int vType = 0;
        int error_code = 0;
        int    SerialBook = -1;
        int    SerialLock = -1;
        int    ret = 0;
        int save_cnt = 5000;
        AV_DATA av_data;
        int Checkduration;
        unsigned fDurationInMicroseconds;
        unsigned fNumTruncatedBytes;
        unsigned fFrameSize;
        unsigned char* fTo; // in
        unsigned fMaxSize; // in
        int nal_state;
        struct timeval fPresentationTime;
        
        int IsStart;
        int StreamFlag = STREAM_GET_VOL;

        int offset = 0;
        int start = 0;
        int videoType = 7;
        //int *cmd = av_field[videoType];//2 for 1920x1080, 8 for MJPEG
    #ifdef FILE_WRITE    
        pfd = fopen("test.264","wb");
        if( pfd == NULL )
        {
            printf("open file error!!");
        }


        if( fseek( pfd, 0, SEEK_SET ) < 0)
        {
            printf("seek file error!!");
        }
    #endif
        
        if(ApproDrvInit(I2R_MSG_TYPE) < 0){
            printf("ApproDrvInit Error.\n");
            exit(1);
        }
        if (func_get_mem(NULL)) {
            ApproDrvExit();
            exit(1);
        }
        InitMp4File();
        int framecount=0;
        //while (framecount<1000)
        while (1)
        {
            offset = 0;
            int start = 0;
            int *cmd = av_field[videoType];
          
            //framecount++;
            if (StreamFlag & STREAM_GET_VOL) {
                
                
                AV_DATA vol_data;
                if(GetAVData(cmd[AV_LOCK_MP4_VOL], -1, &vol_data) != RET_SUCCESS) {
                    printf("Error on Get Vol data\n");
                    return -1;
                }
                if( (vol_data.size == 18) || (vol_data.size  >= (256 + 128))  ) // VA metadata size is 128 bytes
                {
                    GetAVData(cmd[AV_UNLOCK_MP4_VOL], -1, &vol_data);
                    printf("Stream %d is not avaliable~~~~~~~~\n",2);
                    sigterm(0);
                }
                //    printf("JK:111 Frame size = %d\n",vol_data.size);
                    
                    //memcpy(fTo+offset, vol_data.ptr, vol_data.size);
           
    #ifdef FILE_WRITE    
                    if( fwrite( vol_data.ptr,vol_data.size,1, pfd )  <= 0)
                    {
                        printf("save file error!!");

                    }
    #endif
                    offset += vol_data.size;
                    fFrameSize = 0;
                    nal_state = 5;
                

                GetAVData(cmd[AV_UNLOCK_MP4_VOL], -1, &vol_data);

                if( (vol_data.size == 18) || (vol_data.size  >= (256 + 128))  ) // VA metadata size is 128 bytes
                {
                    printf("Stream %d is not avaliable~~~~~~~~\n",2);
                    sigterm(0);
                }


                if( nal_state < 2 )
                {

                    fPresentationTime.tv_sec = av_data.timestamp/1000;
                    fPresentationTime.tv_usec = (av_data.timestamp%1000)*1000;

                    nal_state++;
                    return 1;
                }

                WaitVideoStart( videoType,300 );

                ret = GetAVData(cmd[AV_LOCK_MP4_IFRAME], -1, &av_data);
                SerialBook = av_data.serial;
                StreamFlag &= ~(STREAM_GET_VOL|STREAM_NEW_GOP);
            }
            else if (StreamFlag & STREAM_NEW_GOP) {
                
                
                WaitVideoStart( videoType,5000);

                ret = GetAVData(cmd[AV_LOCK_MP4_IFRAME], -1, &av_data );
                SerialBook = av_data.serial;
                StreamFlag &= ~STREAM_NEW_GOP;
            }
            else {
                
                ret = GetAVData(cmd[AV_LOCK_MP4], SerialBook, &av_data );
            }
            

            if (ret == RET_SUCCESS)
            {
                
                static int IscheckKey = 1;
                if( av_data.flags == AV_FLAGS_MP4_I_FRAME && IscheckKey == 1 )
                {
                    int serial_now;
                    serial_now = GetVideoSerial(videoType);
                    IscheckKey = 0;
                    //printf("serial_now = %d SerialBook = %d \n",serial_now,SerialBook);
                    if( (serial_now - SerialBook) > 30 )
                    {
                        GetAVData(cmd[AV_UNLOCK_MP4], SerialBook, &av_data);
                        StreamFlag |= STREAM_NEW_GOP;
                        return 0;
                    }
                }else{
                    IscheckKey = 1;
                }
            }
            
            if (ret == RET_SUCCESS)
            {
                
                
                char *dataPtr = (char *)av_data.ptr;
                
                /* If there is meta data at the start of the frame then consider it */
                if((dataPtr[0] == 'M') && (dataPtr[1] == 'E') && (dataPtr[2] == 'T') && (dataPtr[3] == 'S'))
                    start = 0;    
                else    
                    start = 4;    
            }
            
            if (ret == RET_SUCCESS) {
                

                fFrameSize = av_data.size - start;
    #if 0
                if (fFrameSize > fMaxSize) {
                    printf("Frame Truncated\n");
                    fNumTruncatedBytes = fFrameSize - fMaxSize;
                    fFrameSize = fMaxSize;
                }
                else {
                    fNumTruncatedBytes = 0;
                }
    #endif
            
                
                //memcpy(fTo, av_data.ptr+start, fFrameSize);
              
                //printf("width = %d height = %d  frame_type = %d framesize = %d\n",av_data.width,av_data.height,av_data.frameType,fFrameSize);
    #ifdef FILE_WRITE
                //printf("width = %d height = %d  frame_type = %d\n",av_data.width,av_data.height,av_data.frameType);
                
                if( fwrite( av_data.ptr+start,fFrameSize,1, pfd )  <= 0)
                {
                    printf("save file error!!");

                }
    #endif
                if (SerialLock > 0) {
                    GetAVData(cmd[AV_UNLOCK_MP4], SerialLock, &av_data);
                }
                SerialLock = SerialBook;


                if( IsStart )
                {
                    
                    AV_DATA av_data_media;
                    IsStart = 0;

                    GetAVData(AV_OP_GET_MEDIA_INFO, -1, &av_data_media );
                
                    if( av_data_media.flags == 1 )
                    {
                        Checkduration = STREAM_CHECK_DURATION_MS;
                    }else{
                        Checkduration = STREAM_CHECK_DURATION_MS;
                    }

                }
                
                fDurationInMicroseconds = Checkduration;

                SerialBook++;
                //return 1;
            }
            else if (ret == RET_NO_VALID_DATA) {
                
                //return 0;
            }
            else {
            
                StreamFlag |= STREAM_NEW_GOP;
                //return 0;
            }
        }
       
     
    #ifdef FILE_WRITE    
        fclose(pfd);
    #endif
        
    }

    But the frame size suggests  there  are  indeed P frames in it. See below

    width = 720 height = 480  frame_type = 1 framesize = 41717
    width = 720 height = 480  frame_type = 2 framesize = 9231
    width = 720 height = 480  frame_type = 2 framesize = 6833
    width = 720 height = 480  frame_type = 2 framesize = 6667
    width = 720 height = 480  frame_type = 2 framesize = 6600
    width = 720 height = 480  frame_type = 2 framesize = 6802
    width = 720 height = 480  frame_type = 2 framesize = 6580
    width = 720 height = 480  frame_type = 2 framesize = 6550
    width = 720 height = 480  frame_type = 2 framesize = 7818
    width = 720 height = 480  frame_type = 2 framesize = 6704
    width = 720 height = 480  frame_type = 2 framesize = 6588
    width = 720 height = 480  frame_type = 2 framesize = 7575
    width = 720 height = 480  frame_type = 2 framesize = 6532
    width = 720 height = 480  frame_type = 2 framesize = 7511
    width = 720 height = 480  frame_type = 2 framesize = 6712
    width = 720 height = 480  frame_type = 2 framesize = 7465
    width = 720 height = 480  frame_type = 2 framesize = 6601
    width = 720 height = 480  frame_type = 2 framesize = 8170
    width = 720 height = 480  frame_type = 2 framesize = 6661
    width = 720 height = 480  frame_type = 2 framesize = 7506
    width = 720 height = 480  frame_type = 2 framesize = 6528
    width = 720 height = 480  frame_type = 2 framesize = 8029
    width = 720 height = 480  frame_type = 2 framesize = 6430
    width = 720 height = 480  frame_type = 2 framesize = 8290
    width = 720 height = 480  frame_type = 2 framesize = 6546
    width = 720 height = 480  frame_type = 2 framesize = 8416
    width = 720 height = 480  frame_type = 2 framesize = 7580
    width = 720 height = 480  frame_type = 2 framesize = 8062
    width = 720 height = 480  frame_type = 2 framesize = 7848
    width = 720 height = 480  frame_type = 2 framesize = 6545
    width = 720 height = 480  frame_type = 1 framesize = 41855
    width = 720 height = 480  frame_type = 2 framesize = 9017
    width = 720 height = 480  frame_type = 2 framesize = 6683
    width = 720 height = 480  frame_type = 2 framesize = 6722
    width = 720 height = 480  frame_type = 2 framesize = 6667
    width = 720 height = 480  frame_type = 2 framesize = 6724
    width = 720 height = 480  frame_type = 2 framesize = 6736
    width = 720 height = 480  frame_type = 2 framesize = 6533
    width = 720 height = 480  frame_type = 2 framesize = 6568
    width = 720 height = 480  frame_type = 2 framesize = 7497
    width = 720 height = 480  frame_type = 2 framesize = 6506
    width = 720 height = 480  frame_type = 2 framesize = 7604
    width = 720 height = 480  frame_type = 2 framesize = 6580
    width = 720 height = 480  frame_type = 2 framesize = 7583
    width = 720 height = 480  frame_type = 2 framesize = 6507
    width = 720 height = 480  frame_type = 2 framesize = 7369
    width = 720 height = 480  frame_type = 2 framesize = 6325
    width = 720 height = 480  frame_type = 2 framesize = 8067
    width = 720 height = 480  frame_type = 2 framesize = 6653
    width = 720 height = 480  frame_type = 2 framesize = 8045
    width = 720 height = 480  frame_type = 2 framesize = 6766
    width = 720 height = 480  frame_type = 2 framesize = 7644
    width = 720 height = 480  frame_type = 2 framesize = 6484
    width = 720 height = 480  frame_type = 2 framesize = 8276
    width = 720 height = 480  frame_type = 2 framesize = 6485
    width = 720 height = 480  frame_type = 2 framesize = 8143
    width = 720 height = 480  frame_type = 2 framesize = 6532
    width = 720 height = 480  frame_type = 2 framesize = 8300
    width = 720 height = 480  frame_type = 2 framesize = 7677
    width = 720 height = 480  frame_type = 2 framesize = 7724
    width = 720 height = 480  frame_type = 1 framesize = 41334
    width = 720 height = 480  frame_type = 2 framesize = 7718
    width = 720 height = 480  frame_type = 2 framesize = 6912
    width = 720 height = 480  frame_type = 2 framesize = 6525
    width = 720 height = 480  frame_type = 2 framesize = 6736
    width = 720 height = 480  frame_type = 2 framesize = 6726
    queue id:0
    width = 720 height = 480  frame_type = 2 framesize = 6740
    width = 720 height = 480  frame_type = 2 framesize = 6568
    width = 720 height = 480  frame_type = 2 framesize = 6599
    width = 720 height = 480  frame_type = 2 framesize = 6636
    queue id:0
    width = 720 height = 480  frame_type = 2 framesize = 7635

    Anyone pls help.

    Best Regards

    JK

  • Hi JK,

    I verified 'test.mp4' in Elecard stream eye tool and found that all the frames are I frames and are decodable. Pl. see the attached snapshot.

    Your log shows both I and P frames are written to the file 'test.h264'.

    So have you done any conversion from test.h264 to test.mp4??

    Can you share the original test.h264 file?

    regards,

    Anand  

  • Hi Anand

    Thanks.The stream (test.mp4) is in fact a .264 stream only. I could not upload file with .264 ext, so I simply changed the

    extension to .mp4.

    The frame size shows it is indeed I and P frames. I am now able to get frames as I & P frames by making the following modification.

     if( fwrite( av_data.ptr+start,fFrameSize,1, pfd )  <= 0) 

                                 to

     if( fwrite( av_data.ptr,fFrameSize,1, pfd )  <= 0)

    Now I am able to stream using my custom server and play live streams in mplayer. Got few questions.

    1. What is the purpose of AV_LOCK_MP4_VOL ?

    2. Is there any API to download IDR frames , something similar to AV_LOCK_MP4_IFRAME ?

     How do I get an IDR frame, if by any chance the first IDR is missed, when staticParams->IDRFrameInterval  = 0; (in encLink_h264.c) ? Can I force the Encoder to generate an  IDR frame , from a different process?

    When staticParams->IDRFrameInterval  = 1  , all I frames are  IDR .

    I wanted to have SPS and PPS in the beginning of sequence only.

    Pls answer.

    Best Regards

    JK

     

  • Hi JK,

    My asnwers:

    1. The MPEG4 bitstream requires the first frame to have VOL header at the beginning,so when encoder encodes the first frame the VOL header is saved for future use.The cmd 'AV_LOCK_MP4_VOL' and 'AV_UNLOCK_MP4_VOL' are used to get the VOL header data.
    2. GetAVData() is the only way to get the stored encoded bitstream and the cmd 'AV_OP_LOCK_MP4_IFRAME' will give the latest IDR frame stored in bitstream buffer. There is 'Venc_forceIDR()' API defined in ..\ipnc_rdk\ipnc_mcfw\mcfw\src_linux\mcfw_api\ti_venc.c file which forces the next encoded frame to be an IDR frame.

    regards,

    Anand

  • Hi Anand,

    Thanks.

    'AV_OP_LOCK_MP4_IFRAME' gave an I frame instead of IDR frame.

    Pls find the attached frame, which is downloaded from AV server using 'AV_OP_LOCK_MP4_IFRAME' cmd.

    (file ext changed to mp4)

    GetAVData(AV_OP_LOCK_MP4_IFRAME,-1,&av_data);

    Request you to check this.

    Best Regards

    JK