OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/base/video_frame.h" | 5 #include "media/base/video_frame.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 const gfx::Size& natural_size, | 24 const gfx::Size& natural_size, |
25 base::TimeDelta timestamp) { | 25 base::TimeDelta timestamp) { |
26 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); | 26 DCHECK(IsValidConfig(format, coded_size, visible_rect, natural_size)); |
27 scoped_refptr<VideoFrame> frame(new VideoFrame( | 27 scoped_refptr<VideoFrame> frame(new VideoFrame( |
28 format, coded_size, visible_rect, natural_size, timestamp)); | 28 format, coded_size, visible_rect, natural_size, timestamp)); |
29 switch (format) { | 29 switch (format) { |
30 case VideoFrame::RGB32: | 30 case VideoFrame::RGB32: |
31 frame->AllocateRGB(4u); | 31 frame->AllocateRGB(4u); |
32 break; | 32 break; |
33 case VideoFrame::YV12: | 33 case VideoFrame::YV12: |
34 case VideoFrame::YV12A: | |
34 case VideoFrame::YV16: | 35 case VideoFrame::YV16: |
35 frame->AllocateYUV(); | 36 frame->AllocateYUV(); |
36 break; | 37 break; |
37 default: | 38 default: |
38 LOG(FATAL) << "Unsupported frame format: " << format; | 39 LOG(FATAL) << "Unsupported frame format: " << format; |
39 } | 40 } |
40 return frame; | 41 return frame; |
41 } | 42 } |
42 | 43 |
43 // static | 44 // static |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 strides_[VideoFrame::kRGBPlane] = bytes_per_row; | 157 strides_[VideoFrame::kRGBPlane] = bytes_per_row; |
157 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( | 158 data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( |
158 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, | 159 base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, |
159 kFrameAddressAlignment)); | 160 kFrameAddressAlignment)); |
160 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); | 161 no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); |
161 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); | 162 DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); |
162 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); | 163 COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); |
163 } | 164 } |
164 | 165 |
165 void VideoFrame::AllocateYUV() { | 166 void VideoFrame::AllocateYUV() { |
166 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16); | 167 DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || |
168 format_ == VideoFrame::YV12A); | |
167 // Align Y rows at least at 16 byte boundaries. The stride for both | 169 // Align Y rows at least at 16 byte boundaries. The stride for both |
168 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for | 170 // YV12 and YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for |
169 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in | 171 // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in |
170 // the case of YV12 the strides are identical for the same width surface, but | 172 // the case of YV12 the strides are identical for the same width surface, but |
171 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as | 173 // the number of bytes allocated for YV12 is 1/2 the amount for U & V as |
172 // YV16. We also round the height of the surface allocated to be an even | 174 // YV16. We also round the height of the surface allocated to be an even |
173 // number to avoid any potential of faulting by code that attempts to access | 175 // number to avoid any potential of faulting by code that attempts to access |
174 // the Y values of the final row, but assumes that the last row of U & V | 176 // the Y values of the final row, but assumes that the last row of U & V |
175 // applies to a full two rows of Y. | 177 // applies to a full two rows of Y. YV12A is the same as YV12 but with a |
178 // following alpha plane that is aligned and sized in the same manner as the | |
Tom Finegan
2013/02/25 22:56:06
How about:
YV12A is the same as YV12, but with a
vignesh
2013/02/25 23:33:14
Done.
| |
179 // Y plane. | |
180 | |
176 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), | 181 size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane), |
177 kFrameSizeAlignment); | 182 kFrameSizeAlignment); |
178 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), | 183 size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane), |
179 kFrameSizeAlignment); | 184 kFrameSizeAlignment); |
180 // The *2 here is because some formats (e.g. h264) allow interlaced coding, | 185 // The *2 here is because some formats (e.g. h264) allow interlaced coding, |
181 // and then the size needs to be a multiple of two macroblocks (vertically). | 186 // and then the size needs to be a multiple of two macroblocks (vertically). |
182 // See libavcodec/utils.c:avcodec_align_dimensions2(). | 187 // See libavcodec/utils.c:avcodec_align_dimensions2(). |
183 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); | 188 size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2); |
184 size_t uv_height = format_ == VideoFrame::YV12 ? y_height / 2 : y_height; | 189 size_t uv_height = (format_ == VideoFrame::YV12 || |
190 format_ == VideoFrame::YV12A) ? | |
191 y_height / 2 : y_height; | |
185 size_t y_bytes = y_height * y_stride; | 192 size_t y_bytes = y_height * y_stride; |
186 size_t uv_bytes = uv_height * uv_stride; | 193 size_t uv_bytes = uv_height * uv_stride; |
194 size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0; | |
187 | 195 |
188 // The extra line of UV being allocated is because h264 chroma MC | 196 // The extra line of UV being allocated is because h264 chroma MC |
189 // overreads by one line in some cases, see libavcodec/utils.c: | 197 // overreads by one line in some cases, see libavcodec/utils.c: |
190 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: | 198 // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm: |
191 // put_h264_chroma_mc4_ssse3(). | 199 // put_h264_chroma_mc4_ssse3(). |
192 uint8* data = reinterpret_cast<uint8*>( | 200 uint8* data = reinterpret_cast<uint8*>( |
193 base::AlignedAlloc( | 201 base::AlignedAlloc( |
194 y_bytes + (uv_bytes * 2 + uv_stride) + kFrameSizePadding, | 202 y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding, |
195 kFrameAddressAlignment)); | 203 kFrameAddressAlignment)); |
196 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); | 204 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); |
197 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); | 205 COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0); |
198 data_[VideoFrame::kYPlane] = data; | 206 data_[VideoFrame::kYPlane] = data; |
199 data_[VideoFrame::kUPlane] = data + y_bytes; | 207 data_[VideoFrame::kUPlane] = data + y_bytes; |
200 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; | 208 data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes; |
201 strides_[VideoFrame::kYPlane] = y_stride; | 209 strides_[VideoFrame::kYPlane] = y_stride; |
202 strides_[VideoFrame::kUPlane] = uv_stride; | 210 strides_[VideoFrame::kUPlane] = uv_stride; |
203 strides_[VideoFrame::kVPlane] = uv_stride; | 211 strides_[VideoFrame::kVPlane] = uv_stride; |
212 if (format_ == YV12A) { | |
213 data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes); | |
214 strides_[VideoFrame::kAPlane] = y_stride; | |
215 } | |
204 } | 216 } |
205 | 217 |
206 VideoFrame::VideoFrame(VideoFrame::Format format, | 218 VideoFrame::VideoFrame(VideoFrame::Format format, |
207 const gfx::Size& coded_size, | 219 const gfx::Size& coded_size, |
208 const gfx::Rect& visible_rect, | 220 const gfx::Rect& visible_rect, |
209 const gfx::Size& natural_size, | 221 const gfx::Size& natural_size, |
210 base::TimeDelta timestamp) | 222 base::TimeDelta timestamp) |
211 : format_(format), | 223 : format_(format), |
212 coded_size_(coded_size), | 224 coded_size_(coded_size), |
213 visible_rect_(visible_rect), | 225 visible_rect_(visible_rect), |
(...skipping 12 matching lines...) Expand all Loading... | |
226 | 238 |
227 bool VideoFrame::IsValidPlane(size_t plane) const { | 239 bool VideoFrame::IsValidPlane(size_t plane) const { |
228 switch (format_) { | 240 switch (format_) { |
229 case RGB32: | 241 case RGB32: |
230 return plane == kRGBPlane; | 242 return plane == kRGBPlane; |
231 | 243 |
232 case YV12: | 244 case YV12: |
233 case YV16: | 245 case YV16: |
234 return plane == kYPlane || plane == kUPlane || plane == kVPlane; | 246 return plane == kYPlane || plane == kUPlane || plane == kVPlane; |
235 | 247 |
248 case YV12A: | |
249 return plane == kYPlane || plane == kUPlane || plane == kVPlane || | |
250 plane == kAPlane; | |
Tom Finegan
2013/02/25 22:56:06
Fix indent.
vignesh
2013/02/25 23:33:14
Done.
| |
251 | |
236 case NATIVE_TEXTURE: | 252 case NATIVE_TEXTURE: |
237 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!"; | 253 NOTREACHED() << "NATIVE_TEXTUREs don't use plane-related methods!"; |
238 return false; | 254 return false; |
239 | 255 |
240 default: | 256 default: |
241 break; | 257 break; |
242 } | 258 } |
243 | 259 |
244 // Intentionally leave out non-production formats. | 260 // Intentionally leave out non-production formats. |
245 NOTREACHED() << "Unsupported video frame format: " << format_; | 261 NOTREACHED() << "Unsupported video frame format: " << format_; |
246 return false; | 262 return false; |
247 } | 263 } |
248 | 264 |
249 int VideoFrame::stride(size_t plane) const { | 265 int VideoFrame::stride(size_t plane) const { |
250 DCHECK(IsValidPlane(plane)); | 266 DCHECK(IsValidPlane(plane)); |
251 return strides_[plane]; | 267 return strides_[plane]; |
252 } | 268 } |
253 | 269 |
254 int VideoFrame::row_bytes(size_t plane) const { | 270 int VideoFrame::row_bytes(size_t plane) const { |
255 DCHECK(IsValidPlane(plane)); | 271 DCHECK(IsValidPlane(plane)); |
256 int width = coded_size_.width(); | 272 int width = coded_size_.width(); |
257 switch (format_) { | 273 switch (format_) { |
258 // 32bpp. | 274 // 32bpp. |
259 case RGB32: | 275 case RGB32: |
260 return width * 4; | 276 return width * 4; |
261 | 277 |
262 // Planar, 8bpp. | 278 // Planar, 8bpp. |
263 case YV12: | 279 case YV12: |
264 case YV16: | 280 case YV16: |
265 if (plane == kYPlane) | 281 case YV12A: |
282 if (plane == kYPlane || plane == kAPlane) | |
266 return width; | 283 return width; |
267 return RoundUp(width, 2) / 2; | 284 return RoundUp(width, 2) / 2; |
268 | 285 |
269 default: | 286 default: |
270 break; | 287 break; |
271 } | 288 } |
272 | 289 |
273 // Intentionally leave out non-production formats. | 290 // Intentionally leave out non-production formats. |
274 NOTREACHED() << "Unsupported video frame format: " << format_; | 291 NOTREACHED() << "Unsupported video frame format: " << format_; |
275 return 0; | 292 return 0; |
276 } | 293 } |
277 | 294 |
278 int VideoFrame::rows(size_t plane) const { | 295 int VideoFrame::rows(size_t plane) const { |
279 DCHECK(IsValidPlane(plane)); | 296 DCHECK(IsValidPlane(plane)); |
280 int height = coded_size_.height(); | 297 int height = coded_size_.height(); |
281 switch (format_) { | 298 switch (format_) { |
282 case RGB32: | 299 case RGB32: |
283 case YV16: | 300 case YV16: |
284 return height; | 301 return height; |
285 | 302 |
286 case YV12: | 303 case YV12: |
287 if (plane == kYPlane) | 304 case YV12A: |
305 if (plane == kYPlane || plane == kAPlane) | |
288 return height; | 306 return height; |
289 return RoundUp(height, 2) / 2; | 307 return RoundUp(height, 2) / 2; |
290 | 308 |
291 default: | 309 default: |
292 break; | 310 break; |
293 } | 311 } |
294 | 312 |
295 // Intentionally leave out non-production formats. | 313 // Intentionally leave out non-production formats. |
296 NOTREACHED() << "Unsupported video frame format: " << format_; | 314 NOTREACHED() << "Unsupported video frame format: " << format_; |
297 return 0; | 315 return 0; |
(...skipping 24 matching lines...) Expand all Loading... | |
322 break; | 340 break; |
323 for (int row = 0; row < rows(plane); ++row) { | 341 for (int row = 0; row < rows(plane); ++row) { |
324 base::MD5Update(context, base::StringPiece( | 342 base::MD5Update(context, base::StringPiece( |
325 reinterpret_cast<char*>(data(plane) + stride(plane) * row), | 343 reinterpret_cast<char*>(data(plane) + stride(plane) * row), |
326 row_bytes(plane))); | 344 row_bytes(plane))); |
327 } | 345 } |
328 } | 346 } |
329 } | 347 } |
330 | 348 |
331 } // namespace media | 349 } // namespace media |
OLD | NEW |