0

I'm using ffms2 (aka FFmpegSource) for decoding video frames and display on UI based on wxWidgets. My player works fine for low resolution video (320*240, 640*480) but for higher resolution (1080) it is very slow. I'm not able to meed the desired frame for high resolution video. After time analysis I found that FFMS_GetFrame() frame function takes much longer time for high resolution frame. Here are the results. 1. 320*240 FFMS_GetFrame takes 4-6ms 2. 640*480 FFMS_GetFrame takes >20ms 3. 1080*720 FFMS_GetFrame takes >40

Which means that I'll never meets 30 fps requirement for 1080p frame with FFMS2. But I'm not sure if this is the case. Please suggest what could be going wrong.

void SetPosition(int64 pos)
{
    uint8_t* data_ptr = NULL;
    /*check if position is valid*/

    if (!m_track || pos < 0  && pos > m_videoProp->NumFrames - 1)
        return; // ERR_POS;

    wxMilliClock_t start_wx_t =  wxGetLocalTimeMillis();
    long long start_t = start_wx_t.GetValue();
    m_frameId = pos;
   if(m_video)
   {
     m_frameProp = FFMS_GetFrame(m_video, m_frameId, &m_errInfo);

     if(!m_frameProp) return;

     if(m_frameProp)
     {
        m_width_ffms2 = m_frameProp->EncodedWidth;
        m_height_ffms2 = m_frameProp->EncodedHeight;
     }

       wxMilliClock_t end_wx_t =  wxGetLocalTimeMillis();
    long long end_t = end_wx_t.GetValue();
    long long diff_t =  end_t - start_t;
    wxLogDebug(wxString(wxT("Frame Grabe Millisec") + ToString(diff_t)));

    //m_frameInfo = FFMS_GetFrameInfo(m_track, FFMS_TYPE_VIDEO);

    /* If you want to change the output colorspace or resize the output frame size, now is the time to do it. 
    IMPORTANT: This step is also required to prevent resolution and colorspace changes midstream. You can 
    always tell a frame's original properties by examining the Encoded properties in FFMS_Frame. */

    /* A -1 terminated list of the acceptable output formats (see pixfmt.h for the list of pixel formats/colorspaces).
    To get the name of a given pixel format, strip the leading PIX_FMT_ and convert to lowercase. For example, 
    PIX_FMT_YUV420P becomes "yuv420p". */
#if 0
    int pixfmt[2];
    pixfmt[0] = FFMS_GetPixFmt("bgr24"); 
    pixfmt[1] = -1;
#endif
    // FFMS_SetOutputFormatV2 returns 0 on success. It Returns non-0 and sets ErrorMsg on failure.
    int failure = FFMS_SetOutputFormatV2(m_video, pixfmt, m_width_ffms2, m_height_ffms2, FFMS_RESIZER_BICUBIC, &m_errInfo);
    if (failure) 
    {
        //FFMS_DestroyVideoSource(m_video);
        //m_video = NULL;
        return; //return ERR_POS;
    }
     data_ptr = m_frameProp->Data[0]; 

  }
   else
   {
        m_width_ffms2 = 320;
        m_height_ffms2 = 240;
   }
   if(data_ptr)
   {
     memcpy(m_buf, data_ptr, 3*m_height_ffms2 * m_width_ffms2);
   }
   else
   {
     memset(m_buf, 0, 3*m_height_ffms2 * m_width_ffms2);    
   }
}
praks411
  • 1,972
  • 16
  • 23

1 Answers1

1

Slower video decoding with larger frames is totally normal. 1080x720 has about ten times as many pixels as 320x240, so having GetFrame take about ten times as long is not surprising (it's not a strictly linear relationship as there's a lot of other factors that play into decoding speed, but pixel count and time to decode are fairly correlated).

Setting the output format for every frame is unnecessary and is going to be making things a lot slower. Unless you specifically want the output format to change you should call it just once after opening the video, and it'll apply to all frames requested after that.

Thomas Goyne
  • 8,010
  • 32
  • 30
  • You are correct i've seen this setting output format add extra 10-20msec of delay. I'll try to set it once at the start and see how it behave. However if you have some more suggestions please share. For now i'll mark this answer as correct. – praks411 Jun 21 '13 at 22:40