blob: 5b2d2586b156fd5cc68840ca5a28619c76ec7690 [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
Jon Hjelle78234952016-01-11 09:47:07 -080015@implementation RTCVideoFrame {
kwibergbfefb032016-05-01 14:53:46 -070016 std::unique_ptr<cricket::VideoFrame> _videoFrame;
tkchin7d06a8c2016-04-04 14:10:43 -070017 rtc::scoped_refptr<webrtc::VideoFrameBuffer> _i420Buffer;
Jon Hjelle78234952016-01-11 09:47:07 -080018}
19
20- (size_t)width {
nisse71a0c2f2016-04-04 00:57:29 -070021 return _videoFrame->width();
Jon Hjelle78234952016-01-11 09:47:07 -080022}
23
24- (size_t)height {
nisse71a0c2f2016-04-04 00:57:29 -070025 return _videoFrame->height();
Jon Hjelle78234952016-01-11 09:47:07 -080026}
27
nisse71a0c2f2016-04-04 00:57:29 -070028// TODO(nisse): chromaWidth and chromaHeight are used only in
29// RTCOpenGLVideoRenderer.mm. Update, and then delete these
30// properties.
Jon Hjelle78234952016-01-11 09:47:07 -080031- (size_t)chromaWidth {
nisse71a0c2f2016-04-04 00:57:29 -070032 return (self.width + 1) / 2;
Jon Hjelle78234952016-01-11 09:47:07 -080033}
34
35- (size_t)chromaHeight {
nisse71a0c2f2016-04-04 00:57:29 -070036 return (self.height + 1) / 2;
Jon Hjelle78234952016-01-11 09:47:07 -080037}
38
39- (const uint8_t *)yPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070040 if (!self.i420Buffer) {
41 return nullptr;
42 }
nisseca6d5d12016-06-17 05:03:04 -070043 return self.i420Buffer->DataY();
Jon Hjelle78234952016-01-11 09:47:07 -080044}
45
46- (const uint8_t *)uPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070047 if (!self.i420Buffer) {
48 return nullptr;
49 }
nisseca6d5d12016-06-17 05:03:04 -070050 return self.i420Buffer->DataU();
Jon Hjelle78234952016-01-11 09:47:07 -080051}
52
53- (const uint8_t *)vPlane {
tkchin7d06a8c2016-04-04 14:10:43 -070054 if (!self.i420Buffer) {
55 return nullptr;
56 }
nisseca6d5d12016-06-17 05:03:04 -070057 return self.i420Buffer->DataV();
Jon Hjelle78234952016-01-11 09:47:07 -080058}
59
60- (int32_t)yPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070061 if (!self.i420Buffer) {
62 return 0;
63 }
nisseca6d5d12016-06-17 05:03:04 -070064 return self.i420Buffer->StrideY();
Jon Hjelle78234952016-01-11 09:47:07 -080065}
66
67- (int32_t)uPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070068 if (!self.i420Buffer) {
69 return 0;
70 }
nisseca6d5d12016-06-17 05:03:04 -070071 return self.i420Buffer->StrideU();
Jon Hjelle78234952016-01-11 09:47:07 -080072}
73
74- (int32_t)vPitch {
tkchin7d06a8c2016-04-04 14:10:43 -070075 if (!self.i420Buffer) {
76 return 0;
77 }
nisseca6d5d12016-06-17 05:03:04 -070078 return self.i420Buffer->StrideV();
tkchin7d06a8c2016-04-04 14:10:43 -070079}
80
81- (int64_t)timeStamp {
82 return _videoFrame->GetTimeStamp();
83}
84
85- (CVPixelBufferRef)nativeHandle {
nisse04ebea32016-05-20 01:48:45 -070086 return static_cast<CVPixelBufferRef>(
87 _videoFrame->video_frame_buffer()->native_handle());
tkchin7d06a8c2016-04-04 14:10:43 -070088}
89
90- (void)convertBufferIfNeeded {
91 if (!_i420Buffer) {
nisse04ebea32016-05-20 01:48:45 -070092 if (_videoFrame->video_frame_buffer()->native_handle()) {
tkchin7d06a8c2016-04-04 14:10:43 -070093 // Convert to I420.
nissef3868762016-04-13 03:29:16 -070094 _i420Buffer = _videoFrame->video_frame_buffer()->NativeToI420Buffer();
tkchin7d06a8c2016-04-04 14:10:43 -070095 } else {
96 // Should already be I420.
nissef3868762016-04-13 03:29:16 -070097 _i420Buffer = _videoFrame->video_frame_buffer();
tkchin7d06a8c2016-04-04 14:10:43 -070098 }
99 }
Jon Hjelle78234952016-01-11 09:47:07 -0800100}
101
102#pragma mark - Private
103
104- (instancetype)initWithNativeFrame:(const cricket::VideoFrame *)nativeFrame {
105 if (self = [super init]) {
106 // Keep a shallow copy of the video frame. The underlying frame buffer is
107 // not copied.
nisse3a2a6402016-06-21 04:17:28 -0700108 _videoFrame.reset(nativeFrame->Copy());
Jon Hjelle78234952016-01-11 09:47:07 -0800109 }
110 return self;
111}
112
tkchin7d06a8c2016-04-04 14:10:43 -0700113- (rtc::scoped_refptr<webrtc::VideoFrameBuffer>)i420Buffer {
114 [self convertBufferIfNeeded];
115 return _i420Buffer;
116}
117
Jon Hjelle78234952016-01-11 09:47:07 -0800118@end