/* * Copyright 2017 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "sdk/objc/native/src/objc_frame_buffer.h" #include "api/make_ref_counted.h" #import "base/RTCVideoFrameBuffer.h" #import "sdk/objc/api/video_frame_buffer/RTCNativeI420Buffer+Private.h" namespace webrtc { namespace { /** ObjCFrameBuffer that conforms to I420BufferInterface by wrapping RTC_OBJC_TYPE(RTCI420Buffer) */ class ObjCI420FrameBuffer : public I420BufferInterface { public: explicit ObjCI420FrameBuffer(id frame_buffer) : frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {} ~ObjCI420FrameBuffer() override {} int width() const override { return width_; } int height() const override { return height_; } const uint8_t* DataY() const override { return frame_buffer_.dataY; } const uint8_t* DataU() const override { return frame_buffer_.dataU; } const uint8_t* DataV() const override { return frame_buffer_.dataV; } int StrideY() const override { return frame_buffer_.strideY; } int StrideU() const override { return frame_buffer_.strideU; } int StrideV() const override { return frame_buffer_.strideV; } private: id frame_buffer_; int width_; int height_; }; } // namespace ObjCFrameBuffer::ObjCFrameBuffer(id frame_buffer) : frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {} ObjCFrameBuffer::~ObjCFrameBuffer() {} VideoFrameBuffer::Type ObjCFrameBuffer::type() const { return Type::kNative; } int ObjCFrameBuffer::width() const { return width_; } int ObjCFrameBuffer::height() const { return height_; } rtc::scoped_refptr ObjCFrameBuffer::ToI420() { return rtc::make_ref_counted([frame_buffer_ toI420]); } rtc::scoped_refptr ObjCFrameBuffer::CropAndScale(int offset_x, int offset_y, int crop_width, int crop_height, int scaled_width, int scaled_height) { if ([frame_buffer_ respondsToSelector:@selector (cropAndScaleWith:offsetY:cropWidth:cropHeight:scaleWidth:scaleHeight:)]) { return rtc::make_ref_counted([frame_buffer_ cropAndScaleWith:offset_x offsetY:offset_y cropWidth:crop_width cropHeight:crop_height scaleWidth:scaled_width scaleHeight:scaled_height]); } // Use the default implementation. return VideoFrameBuffer::CropAndScale( offset_x, offset_y, crop_width, crop_height, scaled_width, scaled_height); } id ObjCFrameBuffer::wrapped_frame_buffer() const { return frame_buffer_; } id ToObjCVideoFrameBuffer( const rtc::scoped_refptr& buffer) { if (buffer->type() == VideoFrameBuffer::Type::kNative) { return static_cast(buffer.get())->wrapped_frame_buffer(); } else { return [[RTC_OBJC_TYPE(RTCI420Buffer) alloc] initWithFrameBuffer:buffer->ToI420()]; } } } // namespace webrtc