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#import "RTCNativeI420Buffer+Private.h"
12
13#include "api/video/i420_buffer.h"
14
15#if !defined(NDEBUG) && defined(WEBRTC_IOS)
16#import <UIKit/UIKit.h>
17#include "third_party/libyuv/include/libyuv.h"
18#endif
19
20@implementation RTC_OBJC_TYPE (RTCI420Buffer)
21
22- (instancetype)initWithWidth:(int)width height:(int)height {
23  if (self = [super init]) {
24    _i420Buffer = webrtc::I420Buffer::Create(width, height);
25  }
26
27  return self;
28}
29
30- (instancetype)initWithWidth:(int)width
31                       height:(int)height
32                        dataY:(const uint8_t *)dataY
33                        dataU:(const uint8_t *)dataU
34                        dataV:(const uint8_t *)dataV {
35  if (self = [super init]) {
36    _i420Buffer = webrtc::I420Buffer::Copy(
37        width, height, dataY, width, dataU, (width + 1) / 2, dataV, (width + 1) / 2);
38  }
39  return self;
40}
41
42- (instancetype)initWithWidth:(int)width
43                       height:(int)height
44                      strideY:(int)strideY
45                      strideU:(int)strideU
46                      strideV:(int)strideV {
47  if (self = [super init]) {
48    _i420Buffer = webrtc::I420Buffer::Create(width, height, strideY, strideU, strideV);
49  }
50
51  return self;
52}
53
54- (instancetype)initWithFrameBuffer:(rtc::scoped_refptr<webrtc::I420BufferInterface>)i420Buffer {
55  if (self = [super init]) {
56    _i420Buffer = i420Buffer;
57  }
58
59  return self;
60}
61
62- (int)width {
63  return _i420Buffer->width();
64}
65
66- (int)height {
67  return _i420Buffer->height();
68}
69
70- (int)strideY {
71  return _i420Buffer->StrideY();
72}
73
74- (int)strideU {
75  return _i420Buffer->StrideU();
76}
77
78- (int)strideV {
79  return _i420Buffer->StrideV();
80}
81
82- (int)chromaWidth {
83  return _i420Buffer->ChromaWidth();
84}
85
86- (int)chromaHeight {
87  return _i420Buffer->ChromaHeight();
88}
89
90- (const uint8_t *)dataY {
91  return _i420Buffer->DataY();
92}
93
94- (const uint8_t *)dataU {
95  return _i420Buffer->DataU();
96}
97
98- (const uint8_t *)dataV {
99  return _i420Buffer->DataV();
100}
101
102- (id<RTC_OBJC_TYPE(RTCI420Buffer)>)toI420 {
103  return self;
104}
105
106#pragma mark - Private
107
108- (rtc::scoped_refptr<webrtc::I420BufferInterface>)nativeI420Buffer {
109  return _i420Buffer;
110}
111
112#pragma mark - Debugging
113
114#if !defined(NDEBUG) && defined(WEBRTC_IOS)
115- (id)debugQuickLookObject {
116  UIGraphicsBeginImageContext(CGSizeMake(_i420Buffer->width(), _i420Buffer->height()));
117  CGContextRef c = UIGraphicsGetCurrentContext();
118  uint8_t *ctxData = (uint8_t *)CGBitmapContextGetData(c);
119
120  libyuv::I420ToARGB(_i420Buffer->DataY(),
121                     _i420Buffer->StrideY(),
122                     _i420Buffer->DataU(),
123                     _i420Buffer->StrideU(),
124                     _i420Buffer->DataV(),
125                     _i420Buffer->StrideV(),
126                     ctxData,
127                     CGBitmapContextGetBytesPerRow(c),
128                     CGBitmapContextGetWidth(c),
129                     CGBitmapContextGetHeight(c));
130
131  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
132  UIGraphicsEndImageContext();
133
134  return image;
135}
136#endif
137
138@end
139