53 frame->buf[0] = av_buffer_create(
nullptr, 0, releasePixBufFn, pixbuf, 0);
66 CVPixelBufferRef source)
69 Q_ASSERT(CVPixelBufferGetWidth(source) != 0);
70 Q_ASSERT(CVPixelBufferGetHeight(source) != 0);
71 Q_ASSERT(CVPixelBufferGetPixelFormatType(source) != CvPixelFormatInvalid);
76 NSDictionary *attributes = @{
77 (id)kCVPixelBufferIOSurfacePropertiesKey : @{},
78 (id)kCVPixelBufferMetalCompatibilityKey : @YES,
81 CVPixelBufferRef destination =
nullptr;
82 const CVReturn createResult = CVPixelBufferCreate(
84 CVPixelBufferGetWidth(source),
85 CVPixelBufferGetHeight(source),
86 CVPixelBufferGetPixelFormatType(source),
87 (__bridge CFDictionaryRef)attributes,
89 if (createResult != kCVReturnSuccess || !destination)
90 return q23::unexpected{
91 u"Failed to allocate destination CVPixelBuffer (CVReturn %1)"_s.arg(createResult) };
94 QAVFHelpers::QSharedCVPixelBuffer destinationBuffer {
96 QAVFHelpers::QSharedCVPixelBuffer::RefMode::HasRef };
101 VTPixelTransferSessionRef transferSession =
nullptr;
102 const OSStatus sessionResult = VTPixelTransferSessionCreate(
105 if (sessionResult != noErr || !transferSession)
106 return q23::unexpected{
107 u"Failed to create VTPixelTransferSession (OSStatus %1)"_s.arg(sessionResult) };
108 auto sessionGuard = qScopeGuard([&] {
109 VTPixelTransferSessionInvalidate(transferSession);
110 CFRelease(transferSession);
113 const OSStatus transferResult =
114 VTPixelTransferSessionTransferImage(transferSession, source, destinationBuffer.get());
115 if (transferResult != noErr)
116 return q23::unexpected{
117 u"VTPixelTransferSessionTransferImage failed (OSStatus %1)"_s.arg(transferResult) };
123 CVBufferPropagateAttachments(source, destinationBuffer.get());
125 return destinationBuffer;
129 const QFFmpeg::HWAccel &hwAccel,
130 std::chrono::microseconds presentationTimeStamp,
131 const QAVFHelpers::QSharedCVPixelBuffer &imageBuffer,
132 QVideoFrameFormat format)
134 q23::expected<AVFrameUPtr, QString> avFrameResult = allocHWFrame(
135 hwAccel.hwFramesContextAsBuffer(),
138 return q23::unexpected{ u"Failed to allocate FFmpeg HwFrame"_s };
139 AVFrameUPtr &avFrame = *avFrameResult;
141 avFrame->pts = presentationTimeStamp.count();
143 return QVideoFramePrivate::createFrame(
144 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)