OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2011 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 #include "webrtc/media/engine/webrtcvideoframe.h" | |
12 | |
13 #include "libyuv/convert.h" | |
14 #include "webrtc/base/logging.h" | |
15 #include "webrtc/media/base/videocapturer.h" | |
16 #include "webrtc/media/base/videocommon.h" | |
17 #include "webrtc/video_frame.h" | |
18 | |
19 using webrtc::kYPlane; | |
20 using webrtc::kUPlane; | |
21 using webrtc::kVPlane; | |
22 | |
23 namespace cricket { | |
24 | |
25 WebRtcVideoFrame::WebRtcVideoFrame() | |
26 : timestamp_us_(0), rotation_(webrtc::kVideoRotation_0) {} | |
27 | |
28 WebRtcVideoFrame::WebRtcVideoFrame( | |
29 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | |
30 webrtc::VideoRotation rotation, | |
31 int64_t timestamp_us, | |
32 uint32_t transport_frame_id) | |
33 : video_frame_buffer_(buffer), | |
34 timestamp_us_(timestamp_us), | |
35 transport_frame_id_(transport_frame_id), | |
36 rotation_(rotation) {} | |
37 | |
38 WebRtcVideoFrame::WebRtcVideoFrame( | |
39 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | |
40 webrtc::VideoRotation rotation, | |
41 int64_t timestamp_us) | |
42 : WebRtcVideoFrame(buffer, rotation, timestamp_us, 0) {}; | |
43 | |
44 WebRtcVideoFrame::WebRtcVideoFrame( | |
45 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, | |
46 int64_t time_stamp_ns, | |
47 webrtc::VideoRotation rotation) | |
48 : WebRtcVideoFrame(buffer, | |
49 rotation, | |
50 time_stamp_ns / rtc::kNumNanosecsPerMicrosec, | |
51 0) {} | |
52 | |
53 WebRtcVideoFrame::~WebRtcVideoFrame() {} | |
54 | |
55 bool WebRtcVideoFrame::Init(uint32_t format, | |
56 int w, | |
57 int h, | |
58 int dw, | |
59 int dh, | |
60 uint8_t* sample, | |
61 size_t sample_size, | |
62 int64_t time_stamp_ns, | |
63 webrtc::VideoRotation rotation) { | |
64 return Reset(format, w, h, dw, dh, sample, sample_size, | |
65 time_stamp_ns / rtc::kNumNanosecsPerMicrosec, rotation, | |
66 true /*apply_rotation*/); | |
67 } | |
68 | |
69 bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh, | |
70 bool apply_rotation) { | |
71 return Reset(frame->fourcc, frame->width, frame->height, dw, dh, | |
72 static_cast<uint8_t*>(frame->data), frame->data_size, | |
73 frame->time_stamp / rtc::kNumNanosecsPerMicrosec, | |
74 frame->rotation, apply_rotation); | |
75 } | |
76 | |
77 int WebRtcVideoFrame::width() const { | |
78 return video_frame_buffer_ ? video_frame_buffer_->width() : 0; | |
79 } | |
80 | |
81 int WebRtcVideoFrame::height() const { | |
82 return video_frame_buffer_ ? video_frame_buffer_->height() : 0; | |
83 } | |
84 | |
85 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& | |
86 WebRtcVideoFrame::video_frame_buffer() const { | |
87 return video_frame_buffer_; | |
88 } | |
89 | |
90 uint32_t WebRtcVideoFrame::transport_frame_id() const { | |
91 return transport_frame_id_; | |
92 } | |
93 | |
94 int64_t WebRtcVideoFrame::timestamp_us() const { | |
95 return timestamp_us_; | |
96 } | |
97 | |
98 void WebRtcVideoFrame::set_timestamp_us(int64_t time_us) { | |
99 timestamp_us_ = time_us; | |
100 } | |
101 | |
102 webrtc::VideoRotation WebRtcVideoFrame::rotation() const { | |
103 return rotation_; | |
104 } | |
105 | |
106 bool WebRtcVideoFrame::Reset(uint32_t format, | |
107 int w, | |
108 int h, | |
109 int dw, | |
110 int dh, | |
111 uint8_t* sample, | |
112 size_t sample_size, | |
113 int64_t timestamp_us, | |
114 webrtc::VideoRotation rotation, | |
115 bool apply_rotation) { | |
116 if (!Validate(format, w, h, sample, sample_size)) { | |
117 return false; | |
118 } | |
119 // Translate aliases to standard enums (e.g., IYUV -> I420). | |
120 format = CanonicalFourCC(format); | |
121 | |
122 // Set up a new buffer. | |
123 // TODO(fbarchard): Support lazy allocation. | |
124 int new_width = dw; | |
125 int new_height = dh; | |
126 // If rotated swap width, height. | |
127 if (apply_rotation && (rotation == 90 || rotation == 270)) { | |
128 new_width = dh; | |
129 new_height = dw; | |
130 } | |
131 | |
132 InitToEmptyBuffer(new_width, new_height); | |
133 rotation_ = apply_rotation ? webrtc::kVideoRotation_0 : rotation; | |
134 | |
135 int horiz_crop = ((w - dw) / 2) & ~1; | |
136 // ARGB on Windows has negative height. | |
137 // The sample's layout in memory is normal, so just correct crop. | |
138 int vert_crop = ((abs(h) - dh) / 2) & ~1; | |
139 // Conversion functions expect negative height to flip the image. | |
140 int idh = (h < 0) ? -dh : dh; | |
141 int r = libyuv::ConvertToI420( | |
142 sample, sample_size, | |
143 video_frame_buffer_->MutableDataY(), | |
144 video_frame_buffer_->StrideY(), | |
145 video_frame_buffer_->MutableDataU(), | |
146 video_frame_buffer_->StrideU(), | |
147 video_frame_buffer_->MutableDataV(), | |
148 video_frame_buffer_->StrideV(), | |
149 horiz_crop, vert_crop, | |
150 w, h, | |
151 dw, idh, | |
152 static_cast<libyuv::RotationMode>( | |
153 apply_rotation ? rotation : webrtc::kVideoRotation_0), | |
154 format); | |
155 if (r) { | |
156 LOG(LS_ERROR) << "Error parsing format: " << GetFourccName(format) | |
157 << " return code : " << r; | |
158 return false; | |
159 } | |
160 timestamp_us_ = timestamp_us; | |
161 return true; | |
162 } | |
163 | |
164 void WebRtcVideoFrame::InitToEmptyBuffer(int w, int h) { | |
165 video_frame_buffer_ = new rtc::RefCountedObject<webrtc::I420Buffer>(w, h); | |
166 rotation_ = webrtc::kVideoRotation_0; | |
167 } | |
168 | |
169 } // namespace cricket | |
OLD | NEW |