Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
3.4 kB
3
Indexable
Never
private func handleYUVDataForSoftwareEncoding(_ sampleBuffer: CMSampleBuffer, codecType: BridgeCodecType) {

        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
            return
        }

        // Lock the base address of the pixel buffer
        CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly)

        defer {
            CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
        }

        // Get width and height of the image
        let width = CVPixelBufferGetWidth(pixelBuffer)
        let height = CVPixelBufferGetHeight(pixelBuffer)

        // Check pixel format
        let pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer)
        guard pixelFormat == AsmiraDefaultSettings.videoCameraPixelType else {
            return
        }

        // Get the Y plane data
        guard let yPlaneBaseAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0) else {
            return
        }

        let yStride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0)
        let yDataSize = width * height

        // Get the UV plane data
        guard let uvPlaneBaseAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1) else {
            return
        }

        let uvStride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1)
        let uvHeight = height / 2
        let uvDataSize = (width / 2) * uvHeight

        let yPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: yDataSize)
        let uPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: uvDataSize)
        let vPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: uvDataSize)
        
        for row in 0..<height {
            let yRowStart = yPlaneBaseAddress.advanced(by: row * yStride)
            let yDestRow = yPointer.advanced(by: row * width)
            memcpy(yDestRow, yRowStart, width)
        }

        uvPlaneBaseAddress.withMemoryRebound(to: UInt8.self, capacity: uvStride * uvHeight) { uvSourcePointer in

            let uStride = width / 2
            let uvStrideOffset = uvStride
            let uPointerStride = uStride

            for row in 0..<uvHeight {
                let uvSourceRowBaseIndex = row * uvStrideOffset
                let uDestRowBaseIndex = row * uPointerStride
                let vDestRowBaseIndex = uDestRowBaseIndex

                for col in 0..<uStride {
                    let uvSourceIndex = uvSourceRowBaseIndex + col * 2
                    uPointer[uDestRowBaseIndex + col] = uvSourcePointer[uvSourceIndex]
                    vPointer[vDestRowBaseIndex + col] = uvSourcePointer[uvSourceIndex + 1]
                }
            }
        }
        
        // Get the presentation timestamp (PTS)
        let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        // Get the decode timestamp (DTS)
        let dts = CMSampleBufferGetDecodeTimeStamp(sampleBuffer)

        // Pass the YUV data to the encoder
        asmiraClient.yuvToAV1Encoder(
            codec: codecType,
            width: width,
            height: height,
            pts: pts,
            dts: dts,
            y: yPointer,
            yDataSize: yDataSize,
            u: uPointer,
            uDataSize: uvDataSize,
            v: vPointer,
            vDataSize: uvDataSize
        )

        // Deallocate the pointers
        yPointer.deallocate()
        uPointer.deallocate()
        vPointer.deallocate()
    }
Leave a Comment