| /* | |
| * 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<RTC_OBJC_TYPE(RTCI420Buffer)> 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<RTC_OBJC_TYPE(RTCI420Buffer)> frame_buffer_; | |
| int width_; | |
| int height_; | |
| }; | |
| } // namespace | |
| ObjCFrameBuffer::ObjCFrameBuffer( | |
| id<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> 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_; | |
| } | |
| webrtc::scoped_refptr<I420BufferInterface> ObjCFrameBuffer::ToI420() { | |
| return webrtc::make_ref_counted<ObjCI420FrameBuffer>([frame_buffer_ toI420]); | |
| } | |
| webrtc::scoped_refptr<VideoFrameBuffer> 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 webrtc::make_ref_counted<ObjCFrameBuffer>([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<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> ObjCFrameBuffer::wrapped_frame_buffer() | |
| const { | |
| return frame_buffer_; | |
| } | |
| id<RTC_OBJC_TYPE(RTCVideoFrameBuffer)> ToObjCVideoFrameBuffer( | |
| const webrtc::scoped_refptr<VideoFrameBuffer>& buffer) { | |
| if (buffer->type() == VideoFrameBuffer::Type::kNative) { | |
| return static_cast<ObjCFrameBuffer*>(buffer.get())->wrapped_frame_buffer(); | |
| } else { | |
| return [[RTC_OBJC_TYPE(RTCI420Buffer) alloc] | |
| initWithFrameBuffer:buffer->ToI420()]; | |
| } | |
| } | |
| } // namespace webrtc |