RTCVideoFrameBuffer to CVPixelBuffer in iOS. nativeHandle function was closed! Any other options?

2,621 views
Skip to first unread message

Giraff Wonbat

unread,
Feb 9, 2019, 11:43:35 AM2/9/19
to discuss-webrtc
Hi guys,

I would like to modify captured frames/buffers under RTCCameraVideoCapturer. I found the git below is simple and effective using RTCVideoCapturerDelegate and capturer(_ capturer: RTCVideoCapturer, didCapture frame: RTCVideoFrame).


However, I cannot get CVPixelBuffer from RTCVideoFrame. I found Chromium says nativeHandle function to get pixelBuffer is no more available (pls see below link). Also, frame.buffer gives me RTCVideoFrameBuffer but it does not contain pixel buffer. Looking at my framework>headers>RTCVideoFrameBuffer.h, pixelBuffer property was also gone!


So my questions are:
1) Any efficient ways to convert back and forth btw RTCVideoFrame and CVPixelBuffer. Or I shouldn't?
2) Any other good scheme to modify captured buffer under RTCCameraVideoCapturer?

Thank you very much for any helps.
Regards, GW


Nagamuni reddy

unread,
Feb 11, 2019, 2:48:13 AM2/11/19
to discuss-webrtc
Hey Giraff Wonbat,

1. You can convert  RTCVideoFrame into CVPixelBuffer using the following code: 

  RTCCVPixelBuffer* remotePixelBuffer = (RTCCVPixelBuffer *)frame.buffer;

  CVPixelBufferRef pixelBuffer = remotePixelBuffer.pixelBuffer;


    frame is of type : RTCVideoFrame.

2. To convert CVPixelBuffer back to RTCVideoFrame : 

- (instancetype)initWithBuffer:(id<RTCVideoFrameBuffer>)buffer

                      rotation:(RTCVideoRotation)rotation

                   timeStampNs:(int64_t)timeStampNs


use that instance method to convert CVPixelBuffer back to RTCVideoFrame.


Hope this information is helpful.

Sanjay Kumawat

unread,
Mar 11, 2021, 9:48:33 AM3/11/21
to discuss-webrtc
How to manage RTCI420Buffers?

sanjay kumawat

unread,
Mar 12, 2021, 4:16:24 PM3/12/21
to discuss-webrtc
RTCCVPixelBuffer* remotePixelBuffer = (RTCCVPixelBuffer *)frame.buffer;

Every frame is not a RTCCVPixelBuffer, how do you manage if the frame is of type RTCI420Buffer?

Juan Giorello

unread,
Jun 12, 2021, 5:36:10 AM6/12/21
to discuss-webrtc
Hey Sanjay, did you manage to find a solution?

Sanjay Kumawat

unread,
Jun 14, 2021, 2:40:30 AM6/14/21
to discuss-webrtc
not yet. Do you have any solutions?

Juan Giorello

unread,
Jun 14, 2021, 8:24:31 AM6/14/21
to discuss-webrtc
I did find a workaround, which might not be the most performant one:

Using  the method (UIImage *)convert:(RTCVideoFrame *)frame from: https://gist.github.com/shalyf/69880f70ca9470a1e91440196cb7d127

And then:

    func buffer(from image: CIImage) -> CVPixelBuffer? {

        let attrs = [kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary

        var pixelBuffer : CVPixelBuffer?

        let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.extent.width), Int(image.extent.height), kCVPixelFormatType_32BGRA, attrs, &pixelBuffer)


        guard (status == kCVReturnSuccess) else {

            return nil

        }

        return pixelBuffer   

    }


If you are going to use it in the Metal framework, then, make sure to put kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue in the attrs dictionary.

One thing to notice is that in the emulator I received RTCI420Buffers but in the real device I got RTCCVPixelBuffer. Unfortunately, somehow the RTCCVPixelBuffer is not compatible with the Metal view I'm using along with some video effects I'm currently using.


Hope it's helpfull! 

Reply all
Reply to author
Forward
0 new messages