Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qffmpeghwaccel_mediacodec.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
7#include <rhi/qrhi.h>
8
9extern "C" {
10#include <libavcodec/mediacodec.h>
11#include <libavutil/hwcontext_mediacodec.h>
12}
13
14#if !defined(Q_OS_ANDROID)
15# error "Configuration error"
16#endif
17
18namespace QFFmpeg {
19
20Q_GLOBAL_STATIC(AndroidSurfaceTexture, androidSurfaceTexture, 0);
21
23{
24public:
26
27 qint64 textureHandle(int plane) override { return (plane == 0) ? handle : 0; }
28
29private:
31};
32
33void MediaCodecTextureConverter::setupDecoderSurface(AVCodecContext *avCodecContext)
34{
35 AVMediaCodecContext *mediacodecContext = av_mediacodec_alloc_context();
36 av_mediacodec_default_init(avCodecContext, mediacodecContext, androidSurfaceTexture->surface());
37
38 if (!avCodecContext->hw_device_ctx || !avCodecContext->hw_device_ctx->data)
39 return;
40
41 AVHWDeviceContext *deviceContext =
42 reinterpret_cast<AVHWDeviceContext *>(avCodecContext->hw_device_ctx->data);
43
44 if (!deviceContext->hwctx)
45 return;
46
47 AVMediaCodecDeviceContext *mediaDeviceContext =
48 reinterpret_cast<AVMediaCodecDeviceContext *>(deviceContext->hwctx);
49
50 if (!mediaDeviceContext)
51 return;
52
53 mediaDeviceContext->surface = androidSurfaceTexture->surface();
54}
55
57{
58 if (!androidSurfaceTexture->isValid())
59 return {};
60
61 if (!externalTexture) {
62 androidSurfaceTexture->detachFromGLContext();
63 externalTexture = std::unique_ptr<QRhiTexture>(
64 rhi->newTexture(QRhiTexture::Format::RGBA8, { frame->width, frame->height }, 1,
66
67 if (!externalTexture->create()) {
68 qWarning() << "Failed to create the external texture!";
69 return {};
70 }
71
72 quint64 textureHandle = externalTexture->nativeTexture().object;
73 androidSurfaceTexture->attachToGLContext(textureHandle);
74 }
75
76 // release a MediaCodec buffer and render it to the surface
77 AVMediaCodecBuffer *buffer = (AVMediaCodecBuffer *)frame->data[3];
78
79 if (!buffer) {
80 qWarning() << "Received a frame without AVMediaCodecBuffer.";
81 } else if (av_mediacodec_release_buffer(buffer, 1) < 0) {
82 qWarning() << "Failed to render buffer to surface.";
83 return {};
84 }
85
86 androidSurfaceTexture->updateTexImage();
87
88 return new MediaCodecTextureSet(externalTexture->nativeTexture().object);
89}
90}
static void setupDecoderSurface(AVCodecContext *s)
TextureSet * getTextures(AVFrame *frame) override
qint64 textureHandle(int plane) override
@ ExternalOES
Definition qrhi.h:894
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition qrhi.cpp:10133
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
GLuint64 GLenum void * handle
GLenum GLuint buffer
unsigned long long quint64
Definition qtypes.h:56
long long qint64
Definition qtypes.h:55
QFrame frame
[0]