Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
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
4
#
include
<
QtFFmpegMediaPluginImpl
/
private
/
qffmpeghwaccel_mediacodec_p
.
h
>
5
6
#
include
<
QtGui
/
rhi
/
qrhi
.
h
>
7
8
// TODO: This class is reused from the native Android media backend and breaks ODR.
9
#
include
"../android/wrappers/jni/androidsurfacetexture_p.h"
10
11
extern
"C"
{
12
#
include
<
libavcodec
/
mediacodec
.
h
>
13
#
include
<
libavutil
/
hwcontext_mediacodec
.
h
>
14
}
15
16
#
if
!
defined
(
Q_OS_ANDROID
)
17
#
error
"Configuration error"
18
#
endif
19
20
QT_BEGIN_NAMESPACE
21
22
namespace
QFFmpeg
{
23
24
namespace
{
25
26
class
MediaCodecTextureHandles :
public
QVideoFrameTexturesHandles
27
{
28
public
:
29
MediaCodecTextureHandles(TextureConverterBackendPtr &&converterBackend, quint64 textureHandle)
30
: m_parentConverterBackend(std::move(converterBackend)), m_handle(textureHandle)
31
{
32
}
33
34
quint64 textureHandle(QRhi &,
int
plane)
override
{
return
(plane == 0) ? m_handle : 0; }
35
36
private
:
37
TextureConverterBackendPtr m_parentConverterBackend;
// ensures the backend is kept
38
quint64 m_handle;
39
};
40
41
void
deleteSurface(AVHWDeviceContext *ctx)
42
{
43
AndroidSurfaceTexture
* s =
reinterpret_cast
<
AndroidSurfaceTexture
*>(ctx->user_opaque);
44
delete
s;
45
}
46
47
AndroidSurfaceTexture
* getTextureSurface(AVFrame *frame)
48
{
49
if
(!frame || !frame->hw_frames_ctx)
50
return
nullptr
;
51
52
auto
*frameContext =
reinterpret_cast
<AVHWFramesContext *>(frame->hw_frames_ctx->data);
53
54
if
(!frameContext || !frameContext->device_ctx)
55
return
nullptr
;
56
57
AVHWDeviceContext *deviceContext = frameContext->device_ctx;
58
59
return
reinterpret_cast
<
AndroidSurfaceTexture
*>(deviceContext->user_opaque);
60
}
61
}
// namespace
62
63
void
MediaCodecTextureConverter
::
setupDecoderSurface
(
AVCodecContext
*
avCodecContext
)
64
{
65
std
::
unique_ptr
<
AndroidSurfaceTexture
>
androidSurfaceTexture
(
new
AndroidSurfaceTexture
(0));
66
AVMediaCodecContext
*
mediacodecContext
=
av_mediacodec_alloc_context
();
67
av_mediacodec_default_init
(
avCodecContext
,
mediacodecContext
,
androidSurfaceTexture
->
surface
());
68
69
if
(!
avCodecContext
->
hw_device_ctx
|| !
avCodecContext
->
hw_device_ctx
->
data
)
70
return
;
71
72
AVHWDeviceContext
*
deviceContext
=
73
reinterpret_cast
<
AVHWDeviceContext
*>(
avCodecContext
->
hw_device_ctx
->
data
);
74
75
if
(!
deviceContext
->
hwctx
)
76
return
;
77
78
AVMediaCodecDeviceContext
*
mediaDeviceContext
=
79
reinterpret_cast
<
AVMediaCodecDeviceContext
*>(
deviceContext
->
hwctx
);
80
81
if
(!
mediaDeviceContext
)
82
return
;
83
84
mediaDeviceContext
->
surface
=
androidSurfaceTexture
->
surface
();
85
86
Q_ASSERT
(
deviceContext
->
user_opaque
==
nullptr
);
87
deviceContext
->
user_opaque
=
androidSurfaceTexture
.
release
();
88
deviceContext
->
free
=
deleteSurface
;
89
}
90
91
QVideoFrameTexturesUPtr
92
MediaCodecTextureConverter
::
createTextures
(
AVFrame
*
/*frame*/
)
93
{
94
// Most likely, this method should be used instead of createTextureHandles, QRhiTexture is
95
// already created, and we don't need to convert it to handle and back. This work should be done
96
// in the scope of QTBUG-132174
97
return
nullptr
;
98
}
99
100
QVideoFrameTexturesHandlesUPtr
101
MediaCodecTextureConverter
::
createTextureHandles
(
AVFrame
*
frame
)
102
{
103
// TODO: reuse oldHandles: the underlying QRhiTexture must be taken from it instead of
104
// keeping it in AndroidTextureConverter. See QTBUG-132174
105
AndroidSurfaceTexture
*
androidSurfaceTexture
=
getTextureSurface
(
frame
);
106
107
if
(!
androidSurfaceTexture
|| !
androidSurfaceTexture
->
isValid
())
108
return
{};
109
110
if
(!
externalTexture
||
m_currentSurfaceIndex
!=
androidSurfaceTexture
->
index
()) {
111
m_currentSurfaceIndex
=
androidSurfaceTexture
->
index
();
112
androidSurfaceTexture
->
detachFromGLContext
();
113
externalTexture
=
std
::
unique_ptr
<
QRhiTexture
>(
rhi
->
newTexture
(
114
QRhiTexture
::
Format
::
RGBA8
,
frameSize
(
frame
), 1,
QRhiTexture
::
ExternalOES
));
115
116
if
(!
externalTexture
->
create
()) {
117
qWarning
() <<
"Failed to create the external texture!"
;
118
return
{};
119
}
120
121
quint64
textureHandle
=
externalTexture
->
nativeTexture
().
object
;
122
androidSurfaceTexture
->
attachToGLContext
(
textureHandle
);
123
}
124
125
// release a MediaCodec buffer and render it to the surface
126
AVMediaCodecBuffer
*
buffer
= (
AVMediaCodecBuffer
*)
frame
->
data
[3];
127
128
if
(!
buffer
) {
129
qWarning
() <<
"Received a frame without AVMediaCodecBuffer."
;
130
}
else
if
(
av_mediacodec_release_buffer
(
buffer
, 1) < 0) {
131
qWarning
() <<
"Failed to render buffer to surface."
;
132
return
{};
133
}
134
135
androidSurfaceTexture
->
updateTexImage
();
136
137
return
std
::
make_unique
<
MediaCodecTextureHandles
>(
shared_from_this
(),
138
externalTexture
->
nativeTexture
().
object
);
139
}
140
}
141
142
QT_END_NAMESPACE
AndroidSurfaceTexture
Definition
androidsurfacetexture_p.h:26
QFFmpeg
Definition
qandroidcacertificates.cpp:26
qtmultimedia
src
plugins
multimedia
ffmpeg
android
qffmpeghwaccel_mediacodec.cpp
Generated on
for Qt by
1.18.0