5#include "private/qvideotexturehelper_p.h"
9#include <libavutil/pixdesc.h>
10#include <libavutil/hdr_dynamic_metadata.h>
11#include <libavutil/mastering_display_metadata.h>
15 for (
int i = 0;
i < AV_NUM_DATA_POINTERS &&
frame.data[
i]; ++
i) {
28 if (
frame->hw_frames_ctx) {
29 hwFrame = std::move(
frame);
34 swFrame = std::move(
frame);
45 bool needsConversion =
false;
50 SwsContext *
c = sws_getContext(swFrame->width, swFrame->height, AVPixelFormat(swFrame->format),
51 swFrame->width, swFrame->height, newFormat,
52 SWS_BICUBIC,
nullptr,
nullptr,
nullptr);
55 newFrame->width = swFrame->width;
56 newFrame->height = swFrame->height;
57 newFrame->format = newFormat;
58 av_frame_get_buffer(newFrame.get(), 0);
60 sws_scale(
c, swFrame->data, swFrame->linesize, 0, swFrame->height, newFrame->data, newFrame->linesize);
61 if (frame == swFrame.get())
62 frame = newFrame.get();
63 swFrame = std::move(newFrame);
70 textureConverter = converter;
71 textureConverter.
init(hwFrame.get());
77 switch (frame->colorspace) {
79 case AVCOL_SPC_UNSPECIFIED:
80 case AVCOL_SPC_RESERVED:
82 case AVCOL_SPC_SMPTE240M:
84 case AVCOL_SPC_SMPTE2085:
85 case AVCOL_SPC_CHROMA_DERIVED_NCL:
86 case AVCOL_SPC_CHROMA_DERIVED_CL:
93 case AVCOL_SPC_BT470BG:
94 case AVCOL_SPC_SMPTE170M:
96 case AVCOL_SPC_BT2020_NCL:
97 case AVCOL_SPC_BT2020_CL:
104 switch (frame->color_trc) {
105 case AVCOL_TRC_BT709:
107 case AVCOL_TRC_BT1361_ECG:
108 case AVCOL_TRC_BT2020_10:
109 case AVCOL_TRC_BT2020_12:
110 case AVCOL_TRC_SMPTE240M:
112 case AVCOL_TRC_GAMMA22:
113 case AVCOL_TRC_SMPTE428 :
114 case AVCOL_TRC_IEC61966_2_1:
115 case AVCOL_TRC_IEC61966_2_4:
117 case AVCOL_TRC_GAMMA28:
119 case AVCOL_TRC_SMPTE170M:
121 case AVCOL_TRC_LINEAR:
123 case AVCOL_TRC_SMPTE2084:
125 case AVCOL_TRC_ARIB_STD_B67:
135 switch (frame->color_range) {
136 case AVCOL_RANGE_MPEG:
138 case AVCOL_RANGE_JPEG:
148 for (
int i = 0;
i < frame->nb_side_data; ++
i) {
149 AVFrameSideData *sd = frame->side_data[
i];
151 if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
152 auto *
data =
reinterpret_cast<AVMasteringDisplayMetadata *
>(sd->data);
155 maxNits = float(maybeLum.value());
169 Q_ASSERT(hwFrame && hwFrame->hw_frames_ctx);
172 int ret = av_hwframe_transfer_data(swFrame.get(), hwFrame.get(), 0);
174 qWarning() <<
"Error transferring the data to system memory:" <<
ret;
208 static thread_local int lastFormat = 0;
209 if (std::exchange(lastFormat, hwFrame->format) != hwFrame->format)
210 qWarning() <<
" failed to get textures for frame; format:" << hwFrame->format
211 <<
"textureConverter" << (textureConverter.
isNull() ?
"null" :
"not null");
223 return m_pixelFormat;
228 return QSize(frame->width, frame->height);
234 *needsConversion =
false;
236 switch (avPixelFormat) {
239 case AV_PIX_FMT_NONE:
240 Q_ASSERT(!
"Invalid avPixelFormat!");
242 case AV_PIX_FMT_ARGB:
244 case AV_PIX_FMT_0RGB:
246 case AV_PIX_FMT_BGRA:
248 case AV_PIX_FMT_BGR0:
250 case AV_PIX_FMT_ABGR:
252 case AV_PIX_FMT_0BGR:
254 case AV_PIX_FMT_RGBA:
256 case AV_PIX_FMT_RGB0:
259 case AV_PIX_FMT_YUV422P:
261 case AV_PIX_FMT_YUV420P:
263 case AV_PIX_FMT_YUV420P10:
265 case AV_PIX_FMT_UYVY422:
267 case AV_PIX_FMT_YUYV422:
269 case AV_PIX_FMT_NV12:
271 case AV_PIX_FMT_NV21:
273 case AV_PIX_FMT_GRAY8:
275 case AV_PIX_FMT_GRAY16:
278 case AV_PIX_FMT_P010:
280 case AV_PIX_FMT_P016:
282 case AV_PIX_FMT_MEDIACODEC:
287 *needsConversion =
true;
289 const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avPixelFormat);
291 if (descriptor->flags & AV_PIX_FMT_FLAG_RGB)
294 if (descriptor->comp[0].depth > 8)
311 return AV_PIX_FMT_NONE;
314 return AV_PIX_FMT_BGRA;
317 return AV_PIX_FMT_ARGB;
319 return AV_PIX_FMT_0RGB;
322 return AV_PIX_FMT_BGRA;
324 return AV_PIX_FMT_BGR0;
326 return AV_PIX_FMT_ABGR;
328 return AV_PIX_FMT_0BGR;
330 return AV_PIX_FMT_RGBA;
332 return AV_PIX_FMT_RGB0;
335 return AV_PIX_FMT_YUV422P;
337 return AV_PIX_FMT_YUV420P;
339 return AV_PIX_FMT_YUV420P10;
341 return AV_PIX_FMT_UYVY422;
343 return AV_PIX_FMT_YUYV422;
345 return AV_PIX_FMT_NV12;
347 return AV_PIX_FMT_NV21;
349 return AV_PIX_FMT_GRAY8;
351 return AV_PIX_FMT_GRAY16;
354 return AV_PIX_FMT_P010;
356 return AV_PIX_FMT_P016;
359 return AV_PIX_FMT_MEDIACODEC;
The QAbstractVideoBuffer class is an abstraction for video data. \inmodule QtMultimedia.
QVideoFrame::HandleType m_type
QVideoFrameFormat::PixelFormat pixelFormat() const
QVideoFrameFormat::ColorSpace colorSpace() const
void unmap() override
Releases the memory mapped by the map() function.
QFFmpegVideoBuffer(AVFrameUPtr frame)
MapData map(QVideoFrame::MapMode mode) override
Independently maps the planes of a video buffer to memory.
QVideoFrameFormat::ColorTransfer colorTransfer() const
QFFmpeg::AVFrameUPtr AVFrameUPtr
void setTextureConverter(const QFFmpeg::TextureConverter &converter)
virtual std::unique_ptr< QVideoFrameTextures > mapTextures(QRhi *) override
virtual quint64 textureHandle(int plane) const override
Returns a texture handle to the data buffer.
static AVPixelFormat toAVPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
QVideoFrameFormat::ColorRange colorRange() const
static QVideoFrameFormat::PixelFormat toQtPixelFormat(AVPixelFormat avPixelFormat, bool *needsConversion=nullptr)
~QFFmpegVideoBuffer() override
QVideoFrame::MapMode mapMode() const override
static AVPixelFormat format(AVFrame *frame)
TextureSet * getTextures(AVFrame *frame)
void init(AVFrame *frame)
The QVideoFrame class represents a frame of video data.
MapMode
Enumerates how a video buffer's data is mapped to system memory.
AVFrameUPtr makeAVFrame()
std::optional< qint64 > mul(qint64 a, AVRational b)
Combined button and popup list for selecting options.
const TextureDescription * textureDescription(QVideoFrameFormat::PixelFormat format)
static QDBusError::ErrorType get(const char *name)
static bool isFrameFlipped(const AVFrame &frame)
GLuint const GLuint GLuint const GLuint * textures
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
static QAbstractVideoBuffer::MapData mapData(const camera_frame_nv12_t &frame, unsigned char *baseAddress)
unsigned long long quint64