5#include "private/qvideotexturehelper_p.h"
6#include "private/qmultimediautils_p.h"
11#include <libavutil/pixdesc.h>
12#include <libavutil/hdr_dynamic_metadata.h>
13#include <libavutil/mastering_display_metadata.h>
19 for (
int i = 0;
i < AV_NUM_DATA_POINTERS &&
frame.data[
i]; ++
i) {
33 { pixelAspectRatio.num, pixelAspectRatio.den }))
35 if (
frame->hw_frames_ctx) {
36 m_hwFrame = std::move(
frame);
41 m_swFrame = std::move(
frame);
53 const auto actualAVPixelFormat = AVPixelFormat(m_swFrame->format);
56 if (actualAVPixelFormat != targetAVPixelFormat ||
isFrameFlipped(*m_swFrame)
57 || m_size !=
QSize(m_swFrame->width, m_swFrame->height)) {
60 SwsContext *
c = sws_getContext(m_swFrame->width, m_swFrame->height, actualAVPixelFormat,
61 m_size.
width(), m_size.
height(), targetAVPixelFormat,
62 SWS_BICUBIC,
nullptr,
nullptr,
nullptr);
65 newFrame->width = m_size.
width();
66 newFrame->height = m_size.
height();
67 newFrame->format = targetAVPixelFormat;
68 av_frame_get_buffer(newFrame.get(), 0);
70 sws_scale(
c, m_swFrame->data, m_swFrame->linesize, 0, m_swFrame->height, newFrame->data, newFrame->linesize);
71 if (m_frame == m_swFrame.get())
72 m_frame = newFrame.get();
73 m_swFrame = std::move(newFrame);
80 m_textureConverter = converter;
81 m_textureConverter.
init(m_hwFrame.get());
103 for (
int i = 0;
i < m_frame->nb_side_data; ++
i) {
104 AVFrameSideData *sd = m_frame->side_data[
i];
106 if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
107 auto *
data =
reinterpret_cast<AVMasteringDisplayMetadata *
>(sd->data);
110 maxNits = float(maybeLum.value());
119 Q_ASSERT(m_hwFrame && m_hwFrame->hw_frames_ctx);
122 int ret = av_hwframe_transfer_data(m_swFrame.get(), m_hwFrame.get(), 0);
124 qWarning() <<
"Error transferring the data to system memory:" <<
ret;
134 mapData.planeCount = desc->nplanes;
135 for (
int i = 0;
i <
mapData.planeCount; ++
i) {
139 mapData.bytesPerLine[
i] = m_swFrame->linesize[
i];
140 mapData.dataSize[
i] =
mapData.bytesPerLine[
i]*desc->heightForPlane(m_swFrame->height,
i);
148 <<
"Mapping of FFmpeg video buffer with write mode when "
149 "textures have been created. Visual artifacts might "
150 "happen if the frame is still in the rendering pipeline";
171 if (m_textureConverter.
isNull()) {
172 m_textures =
nullptr;
176 m_textures.reset(m_textureConverter.
getTextures(m_hwFrame.get()));
178 static thread_local int lastFormat = 0;
179 if (std::exchange(lastFormat, m_hwFrame->format) != m_hwFrame->format)
180 qWarning() <<
" failed to get textures for frame; format:" << m_hwFrame->format;
187 return m_textures ? m_textures->textureHandle(
rhi, plane) : 0;
192 return m_pixelFormat;
203 *needsConversion =
false;
205 switch (avPixelFormat) {
208 case AV_PIX_FMT_NONE:
209 Q_ASSERT(!
"Invalid avPixelFormat!");
211 case AV_PIX_FMT_ARGB:
213 case AV_PIX_FMT_0RGB:
215 case AV_PIX_FMT_BGRA:
217 case AV_PIX_FMT_BGR0:
219 case AV_PIX_FMT_ABGR:
221 case AV_PIX_FMT_0BGR:
223 case AV_PIX_FMT_RGBA:
225 case AV_PIX_FMT_RGB0:
228 case AV_PIX_FMT_YUV422P:
230 case AV_PIX_FMT_YUV420P:
232 case AV_PIX_FMT_YUV420P10:
234 case AV_PIX_FMT_UYVY422:
236 case AV_PIX_FMT_YUYV422:
238 case AV_PIX_FMT_NV12:
240 case AV_PIX_FMT_NV21:
242 case AV_PIX_FMT_GRAY8:
244 case AV_PIX_FMT_GRAY16:
247 case AV_PIX_FMT_P010:
249 case AV_PIX_FMT_P016:
251 case AV_PIX_FMT_MEDIACODEC:
256 *needsConversion =
true;
258 const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avPixelFormat);
260 if (descriptor->flags & AV_PIX_FMT_FLAG_RGB)
263 if (descriptor->comp[0].depth > 8)
280 return AV_PIX_FMT_NONE;
283 return AV_PIX_FMT_BGRA;
285 return AV_PIX_FMT_ARGB;
288 return AV_PIX_FMT_0RGB;
290 return AV_PIX_FMT_BGRA;
293 return AV_PIX_FMT_BGR0;
295 return AV_PIX_FMT_ABGR;
297 return AV_PIX_FMT_0BGR;
299 return AV_PIX_FMT_RGBA;
303 return AV_PIX_FMT_RGB0;
306 return AV_PIX_FMT_YUV422P;
308 return AV_PIX_FMT_YUV420P;
310 return AV_PIX_FMT_YUV420P10;
312 return AV_PIX_FMT_UYVY422;
314 return AV_PIX_FMT_YUYV422;
316 return AV_PIX_FMT_NV12;
318 return AV_PIX_FMT_NV21;
320 return AV_PIX_FMT_GRAY8;
322 return AV_PIX_FMT_GRAY16;
325 return AV_PIX_FMT_P010;
327 return AV_PIX_FMT_P016;
330 return AV_PIX_FMT_MEDIACODEC;
QVideoFrameFormat::PixelFormat pixelFormat() const
QVideoFrameFormat::ColorSpace colorSpace() const
void unmap() override
Releases the memory mapped by the map() function.
QVideoFrameFormat::ColorTransfer colorTransfer() const
QFFmpeg::AVFrameUPtr AVFrameUPtr
void setTextureConverter(const QFFmpeg::TextureConverter &converter)
virtual std::unique_ptr< QVideoFrameTextures > mapTextures(QRhi *) override
static AVPixelFormat toAVPixelFormat(QVideoFrameFormat::PixelFormat pixelFormat)
QVideoFrameFormat::ColorRange colorRange() const
MapData map(QtVideo::MapMode mode) override
Maps the planes of a video buffer to memory.
static QVideoFrameFormat::PixelFormat toQtPixelFormat(AVPixelFormat avPixelFormat, bool *needsConversion=nullptr)
QFFmpegVideoBuffer(AVFrameUPtr frame, AVRational pixelAspectRatio={ 1, 1 })
~QFFmpegVideoBuffer() override
virtual quint64 textureHandle(QRhi *rhi, int plane) const override
static AVPixelFormat format(AVFrame *frame)
TextureSet * getTextures(AVFrame *frame)
void init(AVFrame *frame)
QVideoFrame::HandleType m_type
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
The QVideoFrame class represents a frame of video data.
AVFrameUPtr makeAVFrame()
QVideoFrameFormat::ColorSpace fromAvColorSpace(AVColorSpace colorSpace)
QVideoFrameFormat::ColorTransfer fromAvColorTransfer(AVColorTransferCharacteristic colorTrc)
QVideoFrameFormat::ColorRange fromAvColorRange(AVColorRange colorRange)
std::optional< qint64 > mul(qint64 a, AVRational b)
Combined button and popup list for selecting options.
const TextureDescription * textureDescription(QVideoFrameFormat::PixelFormat format)
MapMode
Enumerates how a video buffer's data is mapped to system memory.
static QDBusError::ErrorType get(const char *name)
static QT_BEGIN_NAMESPACE bool isFrameFlipped(const AVFrame &frame)
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
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
The QAbstractVideoBuffer::MapData structure describes the mapped plane layout.