blob: dcce32d8331649ab0ec965b66392ae9e9ca249aa [file] [log] [blame]
Jon Hjelle78234952016-01-11 09:47:07 -08001/*
2 * Copyright 2015 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
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCVideoFrame+Private.h"
Jon Hjelle78234952016-01-11 09:47:07 -080012
kwibergbfefb032016-05-01 14:53:46 -070013#include <memory>
Jon Hjelle78234952016-01-11 09:47:07 -080014
nisse7e4e00d2016-06-21 12:53:48 -070015#include "webrtc/media/engine/webrtcvideoframe.h"
16
Jon Hjelle78234952016-01-11 09:47:07 -080017@implementation RTCVideoFrame {
kwibergbfefb032016-05-01 14:53:46 -070018 std::unique_ptr<cricket::VideoFrame> _videoFrame;
tkchin7d06a8c2016-04-04 14:10:43 -070019 rtc::scoped_refptr<webrtc::VideoFrameBuffer> _i420Buffer;
Jon Hjelle78234952016-01-11 09:47:07 -080020}
21
22- (size_t)width {
nisse71a0c2f2016-04-04 00:57:29 -070023 return _videoFrame->width();
Jon Hjelle78234952016-01-11 09:47:07 -080024}
25
26- (size_t)height {
nisse71a0c2f2016-04-04 00:57:29 -070027 return _videoFrame->height();
Jon Hjelle78234952016-01-11 09:47:07 -080028}
29
nisse71a0c2f2016-04-04 00:57:29 -070030// TODO(nisse): chromaWidth and chromaHeight are used only in
31// RTCOpenGLVideoRenderer.mm. Update, and then delete these
32// properties.
Jon Hjelle78234952016-01-11 09:47:07 -080033- (size_t)chromaWidth {
nisse71a0c2f2016-04-04 00:57:29 -070034 return (self.width + 1) / 2;
Jon Hjelle78234952016-01-11 09:47:07 -080035}
36
37- (size_t)chromaHeight {
nisse71a0c2f2016-04-04 00:57:29 -070038 return (self.height + 1) / 2;
Jon Hjelle78234952016-01-11 09:47:07 -080039}
40
41- (const uint8_t *)yPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070042 if (!self.i420Buffer) {
43 return nullptr;
44 }
nisseca6d5d12016-06-17 05:03:04 -070045 return self.i420Buffer->DataY();
Jon Hjelle78234952016-01-11 09:47:07 -080046}
47
48- (const uint8_t *)uPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070049 if (!self.i420Buffer) {
50 return nullptr;
51 }
nisseca6d5d12016-06-17 05:03:04 -070052 return self.i420Buffer->DataU();
Jon Hjelle78234952016-01-11 09:47:07 -080053}
54
55- (const uint8_t *)vPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070056 if (!self.i420Buffer) {
57 return nullptr;
58 }
nisseca6d5d12016-06-17 05:03:04 -070059 return self.i420Buffer->DataV();
Jon Hjelle78234952016-01-11 09:47:07 -080060}
61
62- (int32_t)yPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070063 if (!self.i420Buffer) {
64 return 0;
65 }
nisseca6d5d12016-06-17 05:03:04 -070066 return self.i420Buffer->StrideY();
Jon Hjelle78234952016-01-11 09:47:07 -080067}
68
69- (int32_t)uPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070070 if (!self.i420Buffer) {
71 return 0;
72 }
nisseca6d5d12016-06-17 05:03:04 -070073 return self.i420Buffer->StrideU();
Jon Hjelle78234952016-01-11 09:47:07 -080074}
75
76- (int32_t)vPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070077 if (!self.i420Buffer) {
78 return 0;
79 }
nisseca6d5d12016-06-17 05:03:04 -070080 return self.i420Buffer->StrideV();
tkchin7d06a8c2016-04-04 14:10:43 -070081}
82
83- (int64_t)timeStamp {
84 return _videoFrame->GetTimeStamp();
85}
86
87- (CVPixelBufferRef)nativeHandle {
nisse04ebea32016-05-20 01:48:45 -070088 return static_cast<CVPixelBufferRef>(
89 _videoFrame->video_frame_buffer()->native_handle());
tkchin7d06a8c2016-04-04 14:10:43 -070090}
91
92- (void)convertBufferIfNeeded {
93 if (!_i420Buffer) {
nisse04ebea32016-05-20 01:48:45 -070094 if (_videoFrame->video_frame_buffer()->native_handle()) {
tkchin7d06a8c2016-04-04 14:10:43 -070095 // Convert to I420.
nissef3868762016-04-13 03:29:16 -070096 _i420Buffer = _videoFrame->video_frame_buffer()->NativeToI420Buffer();
tkchin7d06a8c2016-04-04 14:10:43 -070097 } else {
98 // Should already be I420.
nissef3868762016-04-13 03:29:16 -070099 _i420Buffer = _videoFrame->video_frame_buffer();
tkchin7d06a8c2016-04-04 14:10:43 -0700100 }
101 }
Jon Hjelle78234952016-01-11 09:47:07 -0800102}
103
104#pragma mark - Private
105
106- (instancetype)initWithNativeFrame:(const cricket::VideoFrame *)nativeFrame {
107 if (self = [super init]) {
108 // Keep a shallow copy of the video frame. The underlying frame buffer is
109 // not copied.
nisse7e4e00d2016-06-21 12:53:48 -0700110 _videoFrame.reset(new cricket::WebRtcVideoFrame(
111 nativeFrame->video_frame_buffer(),
112 nativeFrame->rotation(),
113 nativeFrame->timestamp_us()));
Jon Hjelle78234952016-01-11 09:47:07 -0800114 }
115 return self;
116}
117
tkchin7d06a8c2016-04-04 14:10:43 -0700118- (rtc::scoped_refptr<webrtc::VideoFrameBuffer>)i420Buffer {
119 [self convertBufferIfNeeded];
120 return _i420Buffer;
121}
122
Jon Hjelle78234952016-01-11 09:47:07 -0800123@end