Quantcast
Channel: Intel® Software - Media
Viewing all articles
Browse latest Browse all 2185

DecodeFrameAsync seemingly starved of data by ReadNextFrame()

$
0
0

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


Viewing all articles
Browse latest Browse all 2185

Trending Articles