52 frame->buf[0] = av_buffer_create(
nullptr, 0, releasePixBufFn, pixbuf, 0);
65 CVPixelBufferRef source)
68 const QSize sourceSize = QAVFHelpers::CVPixelBufferSize(source);
69 Q_ASSERT(!sourceSize.isEmpty());
70 Q_ASSERT(CVPixelBufferGetPixelFormatType(source) != CvPixelFormatInvalid);
75 NSDictionary *attributes = @{
76 (id)kCVPixelBufferIOSurfacePropertiesKey : @{},
77 (id)kCVPixelBufferMetalCompatibilityKey : @YES,
80 CVPixelBufferRef destination =
nullptr;
81 const CVReturn createResult = CVPixelBufferCreate(
85 CVPixelBufferGetPixelFormatType(source),
86 (__bridge CFDictionaryRef)attributes,
88 if (createResult != kCVReturnSuccess || !destination)
89 return q23::unexpected{
90 u"Failed to allocate destination CVPixelBuffer (CVReturn %1)"_s.arg(createResult) };
93 QAVFHelpers::QSharedCVPixelBuffer destinationBuffer {
95 QAVFHelpers::QSharedCVPixelBuffer::RefMode::HasRef };
100 VTPixelTransferSessionRef transferSession =
nullptr;
101 const OSStatus sessionResult = VTPixelTransferSessionCreate(
104 if (sessionResult != noErr || !transferSession)
105 return q23::unexpected{
106 u"Failed to create VTPixelTransferSession (OSStatus %1)"_s.arg(sessionResult) };
107 auto sessionGuard = qScopeGuard([&] {
108 VTPixelTransferSessionInvalidate(transferSession);
109 CFRelease(transferSession);
112 const OSStatus transferResult =
113 VTPixelTransferSessionTransferImage(transferSession, source, destinationBuffer.get());
114 if (transferResult != noErr)
115 return q23::unexpected{
116 u"VTPixelTransferSessionTransferImage failed (OSStatus %1)"_s.arg(transferResult) };
122 CVBufferPropagateAttachments(source, destinationBuffer.get());
124 return destinationBuffer;
128 const QFFmpeg::HWAccel &hwAccel,
129 std::chrono::microseconds presentationTimeStamp,
130 const QAVFHelpers::QSharedCVPixelBuffer &imageBuffer,
131 QVideoFrameFormat format)
133 q23::expected<AVFrameUPtr, QString> avFrameResult = allocHWFrame(
134 hwAccel.hwFramesContextAsBuffer(),
137 return q23::unexpected{ u"Failed to allocate FFmpeg HwFrame"_s };
138 AVFrameUPtr &avFrame = *avFrameResult;
140 avFrame->pts = presentationTimeStamp.count();
142 return QVideoFramePrivate::createFrame(
143 std::make_unique<QFFmpegVideoBuffer>(std::move(avFrame)),
q23::expected< QVideoFrame, QString > qVideoFrameFromCvPixelBuffer(const QFFmpeg::HWAccel &hwAccel, std::chrono::microseconds presentationTimeStamp, const QAVFHelpers::QSharedCVPixelBuffer &imageBuffer, QVideoFrameFormat format)