Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qffmpegdarwinhwframehelpers.mm
Go to the documentation of this file.
1// Copyright (C) 2026 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/qffmpegdarwinhwframehelpers_p.h>
5
6#include <QtMultimedia/private/qvideoframe_p.h>
7
8#define AVMediaType XAVMediaType
9#include <QtFFmpegMediaPluginImpl/private/qffmpegvideobuffer_p.h>
10#include <QtFFmpegMediaPluginImpl/private/qffmpeghwaccel_p.h>
11#undef AVMediaType
12
13QT_BEGIN_NAMESPACE
14
15namespace QFFmpeg {
16
17namespace {
18
19// Make sure this is compatible with the layout used in ffmpeg's hwcontext_videotoolbox
20[[nodiscard]] AVFrameUPtr allocHWFrame(
21 AVBufferRef *hwContext,
22 QAVFHelpers::QSharedCVPixelBuffer sharedPixBuf)
23{
24 Q_ASSERT(sharedPixBuf);
25
26 AVHWFramesContext *ctx = (AVHWFramesContext *)hwContext->data;
27 auto frame = QFFmpeg::makeAVFrame();
28 frame->hw_frames_ctx = av_buffer_ref(hwContext);
29 frame->extended_data = frame->data;
30
31 CVPixelBufferRef pixbuf = sharedPixBuf.release();
32 auto releasePixBufFn = [](void* opaquePtr, uint8_t *) {
33 CVPixelBufferRelease(static_cast<CVPixelBufferRef>(opaquePtr));
34 };
35 frame->buf[0] = av_buffer_create(nullptr, 0, releasePixBufFn, pixbuf, 0);
36
37 // It is convention to use 4th data plane for hardware frames.
38 frame->data[3] = (uint8_t *)pixbuf;
39 frame->width = ctx->width;
40 frame->height = ctx->height;
41 frame->format = AV_PIX_FMT_VIDEOTOOLBOX;
42 if (frame->width != (int)CVPixelBufferGetWidth(pixbuf)
43 || frame->height != (int)CVPixelBufferGetHeight(pixbuf)) {
44
45 // This can happen while changing camera format
46 return nullptr;
47 }
48 return frame;
49}
50
51} // Anonymous namespace end
52
54 const QFFmpeg::HWAccel &hwAccel,
55 qint64 presentationTimeStamp,
56 const QAVFHelpers::QSharedCVPixelBuffer &imageBuffer,
57 QVideoFrameFormat format)
58{
59 AVFrameUPtr avFrame = allocHWFrame(
60 hwAccel.hwFramesContextAsBuffer(),
61 imageBuffer);
62 if (!avFrame)
63 return {};
64
65#ifdef USE_SW_FRAMES
66 {
67 auto swFrame = QFFmpeg::makeAVFrame();
68 /* retrieve data from GPU to CPU */
69 const int ret = av_hwframe_transfer_data(swFrame.get(), avFrame.get(), 0);
70 if (ret < 0) {
71 qWarning() << "Error transferring the data to system memory:" << ret;
72 } else {
73 avFrame = std::move(swFrame);
74 }
75 }
76#endif
77
78 avFrame->pts = presentationTimeStamp;
79
80 return QVideoFramePrivate::createFrame(
81 std::make_unique<QFFmpegVideoBuffer>(std::move(avFrame)),
82 format);
83}
84
85} // namespace QFFmpeg
86
87QT_END_NAMESPACE
QVideoFrame qVideoFrameFromCvPixelBuffer(const QFFmpeg::HWAccel &hwAccel, qint64 presentationTimeStamp, const QAVFHelpers::QSharedCVPixelBuffer &imageBuffer, QVideoFrameFormat format)
std::conditional_t< QT_FFMPEG_AVIO_WRITE_CONST, const uint8_t *, uint8_t * > AvioWriteBufferType