1/* 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "sdk/objc/native/src/objc_frame_buffer.h" 12 13#include "api/make_ref_counted.h" 14#import "base/RTCVideoFrameBuffer.h" 15#import "sdk/objc/api/video_frame_buffer/RTCNativeI420Buffer+Private.h" 16 17namespace webrtc { 18 19namespace { 20 21/** ObjCFrameBuffer that conforms to I420BufferInterface by wrapping RTC_OBJC_TYPE(RTCI420Buffer) */ 22class ObjCI420FrameBuffer : public I420BufferInterface { 23 public: 24 explicit ObjCI420FrameBuffer(id<RTC_OBJC_TYPE(RTCI420Buffer)> frame_buffer) 25 : frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {} 26 ~ObjCI420FrameBuffer() override {} 27 28 int width() const override { return width_; } 29 30 int height() const override { return height_; } 31 32 const uint8_t* DataY() const override { return frame_buffer_.dataY; } 33 34 const uint8_t* DataU() const override { return frame_buffer_.dataU; } 35 36 const uint8_t* DataV() const override { return frame_buffer_.dataV; } 37 38 int StrideY() const override { return frame_buffer_.strideY; } 39 40 int StrideU() const override { return frame_buffer_.strideU; } 41 42 int StrideV() const override { return frame_buffer_.strideV; } 43 44 private: 45 id<RTC_OBJC_TYPE(RTCI420Buffer)> frame_buffer_; 46 int width_; 47 int height_; 48}; 49 50} // namespace 51 52ObjCFrameBuffer::ObjCFrameBuffer(id<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> frame_buffer) 53 : frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {} 54 55ObjCFrameBuffer::~ObjCFrameBuffer() {} 56 57VideoFrameBuffer::Type ObjCFrameBuffer::type() const { 58 return Type::kNative; 59} 60 61int ObjCFrameBuffer::width() const { 62 return width_; 63} 64 65int ObjCFrameBuffer::height() const { 66 return height_; 67} 68 69rtc::scoped_refptr<I420BufferInterface> ObjCFrameBuffer::ToI420() { 70 return rtc::make_ref_counted<ObjCI420FrameBuffer>([frame_buffer_ toI420]); 71} 72 73rtc::scoped_refptr<VideoFrameBuffer> ObjCFrameBuffer::CropAndScale(int offset_x, 74 int offset_y, 75 int crop_width, 76 int crop_height, 77 int scaled_width, 78 int scaled_height) { 79 if ([frame_buffer_ respondsToSelector:@selector 80 (cropAndScaleWith:offsetY:cropWidth:cropHeight:scaleWidth:scaleHeight:)]) { 81 return rtc::make_ref_counted<ObjCFrameBuffer>([frame_buffer_ cropAndScaleWith:offset_x 82 offsetY:offset_y 83 cropWidth:crop_width 84 cropHeight:crop_height 85 scaleWidth:scaled_width 86 scaleHeight:scaled_height]); 87 } 88 89 // Use the default implementation. 90 return VideoFrameBuffer::CropAndScale( 91 offset_x, offset_y, crop_width, crop_height, scaled_width, scaled_height); 92} 93 94id<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> ObjCFrameBuffer::wrapped_frame_buffer() const { 95 return frame_buffer_; 96} 97 98id<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> ToObjCVideoFrameBuffer( 99 const rtc::scoped_refptr<VideoFrameBuffer>& buffer) { 100 if (buffer->type() == VideoFrameBuffer::Type::kNative) { 101 return static_cast<ObjCFrameBuffer*>(buffer.get())->wrapped_frame_buffer(); 102 } else { 103 return [[RTC_OBJC_TYPE(RTCI420Buffer) alloc] initWithFrameBuffer:buffer->ToI420()]; 104 } 105} 106 107} // namespace webrtc 108