Hello,
I just realized that my MSDK code is running slower than it should. My code is basically a transcoder with some object detection between the H.264 decoder and H.264 encoder. The decoder resolution is 1920x1080; the encoder 640x480.
Right now, it looks like the decoder is slowing things down. So I added some code to measure the performance, like this:
mfxStatus SurvlChannel::DecodeOneFrame(ExtendedSurface *pExtSurface) { MSDK_CHECK_POINTER(pExtSurface, MFX_ERR_NULL_PTR); timespec t0, t1; //requires GLIBC_2.17+ long tdiff; mfxStatus sts = MFX_ERR_MORE_SURFACE; mfxFrameSurface1 *pmfxSurface = NULL; mfxBitstream *pInBitstream = &m_mfxDecBS; pExtSurface->pSurface = NULL; mfxU32 i = 0; msdk_printf(MSDK_STRING("Channel %u frame %d DecodeOneFrame() entering loop ... \n"), m_nChanID, m_nProcessedFramesNum); while (MFX_ERR_MORE_DATA == sts || MFX_ERR_MORE_SURFACE == sts || MFX_ERR_NONE < sts) { if (MFX_WRN_DEVICE_BUSY == sts) { MSDK_SLEEP(TIME_TO_SLEEP); // just wait and then repeat the same call to DecodeFrameAsync } else if (MFX_ERR_MORE_DATA == sts) { clock_gettime(CLOCK_MONOTONIC, &t0); sts = m_pFileReader->ReadNextFrame(pInBitstream); // read more data to input bit stream MSDK_BREAK_ON_ERROR(sts); clock_gettime(CLOCK_MONOTONIC, &t1); tdiff = timespec_diff_ns(t0, t1); msdk_printf(MSDK_STRING("Channel %u frame %d decoder ReadNextFrame() %ld (ns)\n"), m_nChanID, m_nProcessedFramesNum, tdiff); } else if (MFX_ERR_MORE_SURFACE == sts) { // find new working surface clock_gettime(CLOCK_MONOTONIC, &t0); pmfxSurface = GetFreeSurfaceDec(); while (NULL == pmfxSurface) { pmfxSurface = GetFreeSurfaceDec(); } MSDK_CHECK_POINTER(pmfxSurface, MFX_ERR_MEMORY_ALLOC); // return an error if a free surface wasn't found clock_gettime(CLOCK_MONOTONIC, &t1); tdiff = timespec_diff_ns(t0, t1); msdk_printf(MSDK_STRING("Channel %u frame %d decoder GetFreeSurfaceDec() %ld (ns)\n"), m_nChanID, m_nProcessedFramesNum, tdiff); } clock_gettime(CLOCK_MONOTONIC, &t0); sts = m_pmfxDEC->DecodeFrameAsync(pInBitstream, pmfxSurface, &pExtSurface->pSurface, &pExtSurface->Syncp); clock_gettime(CLOCK_MONOTONIC, &t1); tdiff = timespec_diff_ns(t0, t1); msdk_printf(MSDK_STRING("Channel %u frame %d decoder DecodeFrameAsync() %ld (ns)\n"), m_nChanID, m_nProcessedFramesNum, tdiff); // ignore warnings if output is available, if (MFX_ERR_NONE < sts && pExtSurface->Syncp) { sts = MFX_ERR_NONE; } } //while processing return sts; }
And the output looks like this:
Channel 0 frame 51 DecodeOneFrame() entering loop ... Channel 0 frame 51 decoder GetFreeSurfaceDec() 701 (ns) Channel 0 frame 51 decoder DecodeFrameAsync() 45474 (ns) Channel 0 frame 51 decoder ReadNextFrame() 42505 (ns) Channel 0 frame 51 decoder DecodeFrameAsync() 255923 (ns) Channel 0 frame 51 decoder ReadNextFrame() 31038 (ns) Channel 0 frame 51 decoder DecodeFrameAsync() 144357 (ns) Channel 0 frame 51 decoder ReadNextFrame() 14646 (ns) Channel 0 frame 51 decoder DecodeFrameAsync() 129694 (ns)
We can see that it takes several iterations of reading and decoding to really finish a frame. I have set the input bit-stream's MaxLength to 1024*1920*1080, but that does not solve the problem.
Why is that? Is there something else I can do to make each frame finish in one iteration?
Thanks,
Robby