66- (
void)captureOutput:(AVCaptureOutput *)captureOutput
67 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
68 fromConnection:(AVCaptureConnection *)connection
70 Q_UNUSED(captureOutput);
75 CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
76 if (!imageBuffer || CFGetTypeID(imageBuffer) != CVPixelBufferGetTypeID()) {
77 qWarning() <<
"Cannot get image buffer from sample buffer";
81 auto pixelBuffer = QAVFHelpers::QSharedCVPixelBuffer(
83 QAVFHelpers::QSharedCVPixelBuffer::RefMode::NeedsRef);
88 q23::expected<QAVFHelpers::QSharedCVPixelBuffer, QString> copyResult =
89 QFFmpeg::deepCopyCvPixelBuffer(pixelBuffer.get());
91 qCWarning(qLcAvfSampleBufferDelegate)
92 <<
"Failed to copy incoming pixel buffer:" << copyResult.error();
95 pixelBuffer = std::move(*copyResult);
97 QSize incomingFrameSize = QAVFHelpers::CVPixelBufferSize(pixelBuffer.get());
98 Q_ASSERT(!incomingFrameSize.isEmpty());
99 CvPixelFormat incomingCvPixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer.get());
102 m_accel->updateFramesContext(
103 av_map_videotoolbox_format_to_pixfmt(incomingCvPixelFormat),
106 std::chrono::microseconds frameTime =
107 QAVFHelpers::CMTimeToMicroseconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer));
109 baseTime = frameTime;
110 startTime = frameTime;
113 QVideoFrameFormat format = QAVFHelpers::videoFormatForImageBuffer(pixelBuffer.get());
114 if (!format.isValid()) {
115 qWarning() <<
"Cannot get get video format for image buffer"
116 << QAVFHelpers::CVPixelBufferSize(pixelBuffer.get());
120 std::optional<QFFmpeg::QAVFSampleBufferDelegateTransform> transform;
121 if (transformationProvider) {
122 transform = transformationProvider(connection);
123 const VideoTransformation &surfaceTransform = transform.value().surfaceTransform;
124 format.setRotation(surfaceTransform.rotation);
125 format.setMirrored(surfaceTransform.mirroredHorizontallyAfterRotation);
128 format.setStreamFrameRate(frameRate);
131 q23::expected<QVideoFrame, QString> frameResult = QFFmpeg::qVideoFrameFromCvPixelBuffer(
133 startTime - *baseTime,
137 qCWarning(qLcAvfSampleBufferDelegate) << frameResult.error();
139 frame = *frameResult;
141 if (!frame.isValid())
142 frame = QVideoFramePrivate::createFrame(
143 std::make_unique<QFFmpeg::CVImageVideoBuffer>(std::move(pixelBuffer)),
146 if (transform.has_value()) {
147 const VideoTransformation &presentationTransform = transform.value().presentationTransform;
148 frame.setRotation(presentationTransform.rotation);
149 frame.setMirrored(presentationTransform.mirroredHorizontallyAfterRotation);
152 frame.setStartTime((startTime - *baseTime).count());
153 frame.setEndTime((frameTime - *baseTime).count());
154 startTime = frameTime;