Skip to content

How to render frames from h264_mediacodec directly, without conversion, accelerated? #322

@geminixdev

Description

@geminixdev

In #273 you explain the process between decoding and rendering clearly:

Let me explain how "everything" works:

ffmpeg decodes a source using hardware acceleration and puts data to D3D11 or Metal or VDPAU or VAAPI or whatever textures.
Pointer to texture is returned in av_frame->data[x]
To get access to the data for the frame in this case you should use av_hwframe_transfer_data: https://github.com/valbok/QtAVPlayer/blob/master/src/QtAVPlayer/qavvideobuffer_gpu.cpp#L22 - it is done when you call QAVVideoFrame::map() --- it downloads data from gpu to cpu!
What should you do when you would like to render it without mapping in RHI?

F.e. using Metal textures: we convert QAVVideoFrame to QVideoFrame and set QVideoFrame::RhiTextureHandle - > defines that the frame contains raw texture handle.
RHI knows that current platform is macOS and handleType() points to RhiTextureHandle so no need to try to reuse this texture handle instead of calling QVideoFrame::map().

For Windows, D3D11 render is used by default. So if you use QVideoFrame::RhiTextureHandle , Qt is expecting to have pointer to ID3D11Texture2D.
2.1 So if ffmpeg creates this texture for us, we can try to return it - > it does not work since pixel format is NV12 which expects to have 2 textures - color and data.
2.2 Creating 2 instances of ID3D11Texture2D textures and copying data to it from original -> did not work for me yet -> Qt should reuse these textures and avoid mapping but crashes. Need to dive deeper, maybe doing something wrong.

How about Android with h264_mediacodec?

The frames delivered by avcodec_receive_frame seem to be NV12 and seem not to get converted or mapped, when sending them to the videosink they are still NV12 (at least I don't see where mapping or conversion would happen).

In armeabi-v7a devices the h264_mediacodec decoding is too slow, already not smooth anymore with HD.
Top shows 100% CPU load, for mediacodec??? (On arm64-v8a only around 20% for mediacodec.)

So for arm64-v8a devices the decoding and the process after avcodec_receive_frame seems to be very fast, all is playing smoothly, even on older devices.

However on armeabi-v7a devices, usually Android boxes, despite having fast CPUs, the transfer of data in and out of mediacodec plus the decoding is ridiculously slow, and the CPU usage (SD 40%, HD 100%) far too high for hardware decoding.

What could be wrong there, or different there?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions