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.

Encode 1.0 mpeg - Indexed frames and losted frames

Hi,

I'm encoding videos on DM6446 with "Video 1.0 Encoder Code". The process runs and finishes correctly but I have few problems with the mpeg result when I watch it with a standard player (mplayer, xine, kaffeine,..):

- Frames are not indexed. I Can't jump to far frames, only next frame of the current frame.

- Second, third, fourth and last frame doesn't exist. I can't see them, but I'm sure they have been writted.

 

I don't use any codec function to close video, would it be necessary?

 

This is my simplified code:

 

IVIDENC1_create

IVIDENC1_control (XDM_SETPARAMS)

IVIDENC1_control (XDM_GETBUFINFO)

open file

for(i=1;i<=numFrame;i++)

{

      IVIDENC1_process

      write data frame to file

}

close file

 

 

Thanks,

Santi

  • Santi,

    I am just guessing here based on the information available. Have you taken care of the cache invalidate operations for I/O buffers before and after process call?

    Regards,

    Anirban

  • Hi,

     

    I'm sure that I invalidate cache memory before and after process.

    I'm also sure that:

     

    - Frames 2, 3 and 4 have been written but never can't be played.

    - Video is not seekable.

    - I don't know what is wrong in my code.

     

    This is a snippet of my code:

     

       
        VIDENC1_Handle m_VideoCodec;
        IVIDENC1_Params m_StaticParams;
        VIDENC1_DynamicParams m_DynamicParams;
        IVIDENC1_Status m_Status;

       
        memset(&m_StaticParams,0,sizeof(m_StaticParams));
        m_StaticParams.size = sizeof(m_StaticParams);

        m_StaticParams.encodingPreset         = XDM_HIGH_QUALITY;    
        m_StaticParams.rateControlPreset     = IVIDEO_STORAGE;       
        m_StaticParams.dataEndianness        = XDM_BYTE;               
        m_StaticParams.maxInterFrameInterval= 1;                    
        m_StaticParams.inputContentType     = IVIDEO_PROGRESSIVE;   
        m_StaticParams.reconChromaFormat     = XDM_CHROMA_NA;        
        m_StaticParams.maxWidth                = 720;                   
        m_StaticParams.maxHeight             = 576;                   
        m_StaticParams.maxFrameRate            = 13*1000;               
        m_StaticParams.maxBitRate            = 20*1000*1000;           
        m_StaticParams.inputChromaFormat    = XDM_YUV_422ILE;


        m_VideoCodec = VIDENC1_create(((CDSP*)m_pDSP)->get_Engine() , DSP_MPEG_CODEC, &m_StaticParams);
        if(!m_VideoCodec) return false:

        memset(&m_DynamicParams,0,sizeof(m_DynamicParams));
        m_DynamicParams.size = sizeof(m_DynamicParams);

        m_DynamicParams.inputWidth             = 720;
        m_DynamicParams.inputHeight         = 576;
        m_DynamicParams.refFrameRate         = 13*1000;
        m_DynamicParams.targetFrameRate     = 13*1000;
        m_DynamicParams.targetBitRate         = 20*1000*1000;
        m_DynamicParams.intraFrameInterval    = 1;
        m_DynamicParams.generateHeader         = XDM_ENCODE_AU;
        m_DynamicParams.captureWidth         = 0;
        m_DynamicParams.forceFrame             = IVIDEO_NA_FRAME;
        m_DynamicParams.interFrameInterval    = 1;
        m_DynamicParams.mbDataFlag             = 0;

        memset(&m_Status,0,sizeof(m_Status));
        m_Status.size=sizeof(m_Status);
        if(VIDENC1_control(m_VideoCodec, XDM_SETPARAMS, &m_DynamicParams, &m_Status) != VIDENC1_EOK) return false;

        memset(&m_Status,0,sizeof(m_Status));
        m_Status.size=sizeof(m_Status);
        if(VIDENC1_control(m_VideoCodec, XDM_GETBUFINFO, &m_DynamicParams, &m_Status) != VIDENC1_EOK) return false;

        FILE* pFile = fopen("helloWorld.mpg", "wb");

        m_pYUVbuffer=(XDAS_Int8*)Memory_contigAlloc(2*1024*1024,Memory_DEFAULTALIGNMENT);
        m_pMpegBuffer=(XDAS_Int8*)Memory_contigAlloc(2*1024*1024,Memory_DEFAULTALIGNMENT);
       
        memset(m_pYUVbuffer, 128, 2*1024*1024); //Fill YUV

        for(int imageId=0;imageId<=100;imageId++)
        {
            //VIDENC1_process
            IVIDEO1_BufDescIn m_InBufs;
            XDM_BufDesc outBufs;
            VIDENC1_InArgs inArgs;
            VIDENC1_OutArgs outArgs;
            XDAS_Int32  outBufSizeArray[XDM_MAX_IO_BUFFERS];
            XDAS_Int8*  pOutBuffers[XDM_MAX_IO_BUFFERS];
           
            //InBufs
            memset(&m_InBufs,0,sizeof(m_InBufs));
            m_InBufs.numBufs = 1;
            m_InBufs.frameHeight= m_DynamicParams.inputHeight;
            m_InBufs.frameWidth = m_DynamicParams.inputWidth;
            m_InBufs.framePitch = m_InBufs.frameWidth;
            m_InBufs.bufDesc[0].bufSize = m_InBufs.frameWidth*m_InBufs.frameHeight*2;
            m_InBufs.bufDesc[0].buf = (XDAS_Int8*) pInBuffer;
            if((m_InBufs.bufDesc[0].bufSize < m_Status.bufInfo.minInBufSize[0])||(m_InBufs.numBufs < m_Status.bufInfo.minNumInBufs)) return false;
               
            //OutBufs
            memset(&outBufs,0,sizeof(outBufs));
            memset(pOutBuffers, 0, sizeof(pOutBuffers[0]) * XDM_MAX_IO_BUFFERS);
            memset(outBufSizeArray, 0,    sizeof(outBufSizeArray[0]) * XDM_MAX_IO_BUFFERS);
            outBufs.bufs         = (XDAS_Int8 **) pOutBuffers;
            outBufs.bufSizes     = (XDAS_Int32 *) outBufSizeArray;
            outBufs.numBufs     = 1;
            outBufs.bufs[0]     = (XDAS_Int8*) m_pMpegBuffer;
            outBufs.bufSizes[0] = maxLength;
            if((outBufs.bufSizes[0] < m_Status.bufInfo.minOutBufSize[0])||(outBufs.numBufs < m_Status.bufInfo.minNumOutBufs)) return false;
           
            //InArgs
            memset(&inArgs,0,sizeof(inArgs));
            inArgs.size = sizeof(inArgs);
            inArgs.inputID = imageId;
            inArgs.topFieldFirstFlag = XDAS_FALSE;
           
            //OutArgs
            memset(&outArgs,0,sizeof(outArgs));
            outArgs.size = sizeof(outArgs);
       
            Memory_cacheWb((unsigned char*) m_InBufs.bufDesc[0].buf, m_InBufs.bufDesc[0].bufSize);
            if(VIDENC1_process(m_VideoCodec, &m_InBufs, &outBufs, &inArgs, &outArgs)!= VIDENC1_EOK) return -1;
            Memory_cacheInv((unsigned char*) m_pMpegBuffer, outArgs.bytesGenerated);
            fwrite(m_pMpegBuffer, outArgs.bytesGenerated, 1, pFile);
        }

        fclose(pFile);

     

    Thanks, 

     

    best regards

     

     

  • Hi Santi,

    Please check and let us know if any error is getting retuned by the codec, check extendedError parameter of status.

     

    Also check following outArgs parameter after the process call,

    1. bytesGenerated
    2. inputFrameSkip

    Regards

    sangita

     

  • extendedError is always 0 and inputFrameSkip is always "IVIDEO_FRAME_ENCODED".

    bytesGenerated also seems correct. If I encode 30 black frames (720*567) first frame generates 4493 bytes and others frames generate 4465 (also second, thirth, fourth and last frame, which can't be written by video player).

    Santi

  • Hi Santi,

    I am trying to understand the behavior please correct if wrong,

    1. You are setting frames to encode as 30 with Iframe interval as 1.
    2. This should generate 30 I frames.
    3. If you add printf for bytes generated you can get 30 different bytes generated values.
    4. But output dump in a file shows less number of frames.
    5. Can you check with NMview tool?

    Try Following,

    Ø       Check if fwrite is successful

    Ø       Call fflush after fwrite

    Ø      Do cache invalidation for outputBufDesc.bufSizes[]

     

    Can you share the input and output file, will try to reproduce the scenario in standalone codec level.

    Regards

    sangita

  • Hi Santi,

    I am trying to understand the behavior please correct if wrong,

    1. You are setting frames to encode as 30 with Iframe interval as 1.
    2. This should generate 30 I frames.
    3. If you add printf for bytes generated you can get 30 different bytes generated values.
    4. But output dump in a file shows less number of frames.
    5. Can you check with NMview tool?

    Try Following,

    Ø       Check if fwrite is successful

    Ø       Call fflush after fwrite

    Ø      Do cache invalidation for outputBufDesc.bufSizes[]

     

    Can you share the input and output file, will try to reproduce the scenario in standalone codec level.

    Regards

    sangita

  • Hi again,

     

    I've composed a simplified code to encode. The result is also wrong. As input file I've used "foreman_vga_422.yuv", from mpeg4enc ("codec_engine_2_00/packages/ti/sdo/codecs/mpeg4enc/app/Client/Test/TestVecs/Input").

    As usual, I can't watch second, third, fourth and last frame and I can't jump directly to specific frame.

     

    I share intput yuv video, output mpeg "wrong" video, main.cpp code and memory maps which I used.

     

    Thanks in advance,

    santi

    Files.tar.gz
  • HI Santi,

    I have checked the input and output file shared by you. I have checked the outFile.mpg with NMview tool, it is showing all 16 frames correctly.

    Please use NMview or Elecard viewer to check the output.

    Regards

    Sangita

  • Hi Sangita,

     

    where coud I download NMview? I didn't find it anywhere.

     

    I don't understand why I can't watch videos correctly with an standard player (Windows media player and classic media player on Windows, mplayer, kaffeine on linux).

    Would I add additional head at the begin/end of video.

     

    Thanks!

    Santi

  • Hi Santi,

    NMview isthe video analyzer from Nikon System.

    You can try downloading trial version of Elecard, http://www.softpedia.com/progDownload/Elecard-StreamEye-Download-85528.html

    mplayer is able to play the clip , but this player do not give any control to play frame by frame.

     

    Regards

    sangita

     

     

  • Hi,

    I revised videos and I verify that I can watch ALL frames on Windows (windows media player) but I still losing second, third, fourth and last frame on Linux. I think it's a problem of linux libraries, so I'm going to solve it in future.

    Now, the main problem is that I can't jump back/forward on video. I need to use Real Media Player 11 (my clients work with it) and I can't back/forward on video using it. Am I indexing correctly the video?

    I'm using exactly code that I uploaded yesterday.

     

    Thanks,

    santi

  • Hi Santi,

     

    I have verified the output file shared by you with mpeg4 Analyzer and it is working properly. Codec is working as per expectation.

     I do not have any idea on how Real Media Player works.

    Regards

    sangita

     

     

  • I'm confused. I'd want to watch this videos with Real Media Player. If I watch another mpeg video (mpeg4 sample video downloaded from a web page) i can jump to far frames along the video.


    Which could be the difference?


    Are there any option to index the frames on video?

     

    Regards, Santi

  • The video encoder gives out elementary stream(Mpeg4 elementary stream). What you downlaod from web is with a container format(Mp4, AVI, RM). You can try putting the elementary video in appropriate container format and then check.

    regards

    Yashwant

  • I did it and now I can see videos correctly.

     

    Thanks