54- (
void)captureOutput:(AVCaptureOutput *)captureOutput
55 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
56 fromConnection:(AVCaptureConnection *)connection
58 Q_UNUSED(captureOutput);
63 CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
64 if (!imageBuffer || CFGetTypeID(imageBuffer) != CVPixelBufferGetTypeID()) {
65 qWarning() <<
"Cannot get image buffer from sample buffer";
69 auto pixelBuffer = QAVFHelpers::QSharedCVPixelBuffer(
71 QAVFHelpers::QSharedCVPixelBuffer::RefMode::NeedsRef);
73 std::chrono::microseconds frameTime =
74 QAVFHelpers::CMTimeToMicroseconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer));
77 startTime = frameTime;
80 QVideoFrameFormat format = QAVFHelpers::videoFormatForImageBuffer(pixelBuffer.get());
81 if (!format.isValid()) {
82 qWarning() <<
"Cannot get get video format for image buffer"
83 << CVPixelBufferGetWidth(pixelBuffer.get()) <<
'x'
84 << CVPixelBufferGetHeight(pixelBuffer.get());
88 std::optional<QFFmpeg::QAVFSampleBufferDelegateTransform> transform;
89 if (transformationProvider) {
90 transform = transformationProvider(connection);
91 const VideoTransformation &surfaceTransform = transform.value().surfaceTransform;
92 format.setRotation(surfaceTransform.rotation);
93 format.setMirrored(surfaceTransform.mirroredHorizontallyAfterRotation);
96 format.setStreamFrameRate(frameRate);
98 Q_ASSERT(self->m_accel);
99 QVideoFrame frame = QFFmpeg::qVideoFrameFromCvPixelBuffer(
101 startTime - *baseTime,
104 if (!frame.isValid())
105 frame = QVideoFramePrivate::createFrame(
106 std::make_unique<QFFmpeg::CVImageVideoBuffer>(std::move(pixelBuffer)),
109 if (transform.has_value()) {
110 const VideoTransformation &presentationTransform = transform.value().presentationTransform;
111 frame.setRotation(presentationTransform.rotation);
112 frame.setMirrored(presentationTransform.mirroredHorizontallyAfterRotation);
115 frame.setStartTime((startTime - *baseTime).count());
116 frame.setEndTime((frameTime - *baseTime).count());
117 startTime = frameTime;