Chromium Code Reviews| Index: webkit/media/crypto/ppapi/ffmpeg_cdm_video_frame.cc |
| diff --git a/webkit/media/crypto/ppapi/ffmpeg_cdm_video_frame.cc b/webkit/media/crypto/ppapi/ffmpeg_cdm_video_frame.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c75051253d52453e1084d5ca4b4593dcb316f2fd |
| --- /dev/null |
| +++ b/webkit/media/crypto/ppapi/ffmpeg_cdm_video_frame.cc |
| @@ -0,0 +1,158 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "webkit/media/crypto/ppapi/ffmpeg_cdm_video_frame.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "media/base/limits.h" |
| +#include "webkit/media/crypto/ppapi/ffmpeg_cdm_video_decoder.h" |
| + |
| + |
|
xhwang
2012/10/17 18:43:00
remove extra empty line
Tom Finegan
2012/10/17 19:55:44
Done.
|
| +namespace webkit_media { |
| + |
| +namespace { |
| + |
| +inline size_t RoundUp(size_t value, size_t alignment) { |
|
xhwang
2012/10/17 18:43:00
Can we use "int" ?
Tom Finegan
2012/10/17 19:55:44
Done.
|
| + // Check that |alignment| is a power of 2. |
| + DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); |
| + return ((value + (alignment - 1)) & ~(alignment-1)); |
| +} |
| + |
| +int RowBytes(cdm::VideoFormat format, |
| + cdm::VideoFrame::VideoPlane plane, |
| + int width) { |
| + switch (format) { |
| + case cdm::kYv12: |
| + case cdm::kI420: |
| + if (plane == cdm::VideoFrame::kYPlane) |
| + return width; |
| + return RoundUp(width, 2) / 2; |
| + |
| + default: |
| + NOTREACHED() << "Unsupported video frame format: " << format; |
| + return 0; |
| + } |
| +} |
| + |
| +} // namespace |
|
xhwang
2012/10/17 18:43:00
media code prefer using static to anonymous namesp
Tom Finegan
2012/10/17 19:55:44
Removed anonymous namespace, and made things stati
|
| + |
| +// static |
| +FFmpegCdmVideoFrame* FFmpegCdmVideoFrame::Create(cdm::Allocator* allocator, |
| + cdm::VideoFormat format, |
| + const cdm::Size& size) { |
| + if (!IsValidConfig(format, size)) { |
| + LOG(ERROR) << "Create() invalid config."; |
| + return NULL; |
| + } |
| + |
| + scoped_ptr<FFmpegCdmVideoFrame> frame(new FFmpegCdmVideoFrame(format, size)); |
| + |
| + if (!frame->AllocateYuv(allocator)) |
| + return NULL; |
| + |
| + return frame.release(); |
| +} |
| + |
| +FFmpegCdmVideoFrame::FFmpegCdmVideoFrame(cdm::VideoFormat format, |
| + const cdm::Size& size) |
| + : format_(format), |
| + size_(size), |
| + frame_buffer_(NULL) { |
| + for (int32_t i = 0; i < cdm::VideoFrame::kMaxPlanes; ++i) { |
| + plane_offsets_[i] = 0; |
| + strides_[i] = 0; |
| + } |
| +} |
| + |
| +FFmpegCdmVideoFrame::~FFmpegCdmVideoFrame() { |
| + if (frame_buffer_) |
| + frame_buffer_->Destroy(); |
| +} |
| + |
| +int32_t FFmpegCdmVideoFrame::plane_offset( |
| + cdm::VideoFrame::VideoPlane plane) const { |
| + DCHECK(0 <= plane && plane < cdm::VideoFrame::kMaxPlanes); |
| + return plane_offsets_[plane]; |
| +} |
| + |
| +int32_t FFmpegCdmVideoFrame::stride( |
| + cdm::VideoFrame::VideoPlane plane) const { |
| + DCHECK(0 <= plane && plane < cdm::VideoFrame::kMaxPlanes); |
| + return strides_[plane]; |
| +} |
| + |
| +// static |
| +bool FFmpegCdmVideoFrame::IsValidConfig(cdm::VideoFormat format, |
|
xhwang
2012/10/17 18:43:00
This function is not using any class members. Make
Tom Finegan
2012/10/17 19:55:44
Can't do that-- this method is called from in this
xhwang
2012/10/17 20:23:10
Ok, did't notice it's used in another file. In tha
Tom Finegan
2012/10/17 21:32:22
I made it a static member function of FFmpegCdmVid
|
| + const cdm::Size& data_size) { |
| + return ((format == cdm::kYv12 || format == cdm::kI420) && |
| + data_size.width > 0 && data_size.height > 0 && |
| + data_size.width <= media::limits::kMaxDimension && |
| + data_size.height <= media::limits::kMaxDimension && |
| + data_size.width * data_size.height <= media::limits::kMaxCanvas); |
| +} |
| + |
| +void FFmpegCdmVideoFrame::TransferVideoFrame(cdm::VideoFrame* target) { |
|
ddorwin
2012/10/17 06:10:19
Should we clear this frame to invalid values so it
Tom Finegan
2012/10/17 19:55:44
There's a DCHECK on frame_buffer() in FFmpegCdmVid
|
| + DCHECK(frame_buffer_); |
| + DCHECK(target); |
| + target->set_format(format_); |
| + target->set_frame_buffer(frame_buffer_); |
| + frame_buffer_ = NULL; |
| + |
| + const int kMaxPlanes = cdm::VideoFrame::kMaxPlanes; |
| + for (int i = 0; i < kMaxPlanes; ++i) { |
| + cdm::VideoFrame::VideoPlane plane = |
| + static_cast<cdm::VideoFrame::VideoPlane>(i); |
| + target->set_plane_offset(plane, plane_offsets_[i]); |
| + target->set_stride(plane, strides_[i]); |
| + } |
| +} |
| + |
| +bool FFmpegCdmVideoFrame::AllocateYuv(cdm::Allocator* allocator) { |
| + DCHECK(allocator); |
| + DCHECK(format_ == cdm::kYv12 || format_ == cdm::kI420); |
| + |
| + // Align Y rows at least at 32 byte boundaries for safety on all platforms. |
| + DVLOG(3) << "AllocateYuv() width=" << size_.width << " height=" |
| + << size_.height; |
| + size_t y_stride = RoundUp( |
| + RowBytes(format_, cdm::VideoFrame::kYPlane, size_.width), |
| + kBufferAlignment); |
| + size_t uv_stride = RoundUp( |
| + RowBytes(format_, cdm::VideoFrame::kUPlane, size_.width), |
| + kBufferAlignment); |
|
xhwang
2012/10/17 18:43:00
So for Y, stride is RoundUp(width, kBufferAlignmen
Tom Finegan
2012/10/17 19:55:44
I think it's in case width is an odd number, which
xhwang
2012/10/17 20:23:10
Since kBufferAlignment is even, I don't think it's
Tom Finegan
2012/10/17 21:32:22
sgtm
|
| + |
| + size_t y_height = RoundUp(size_.height, kBufferAlignment); |
|
xhwang
2012/10/17 18:43:00
What exactly is kBufferAlignment (==32 for now)? W
Tom Finegan
2012/10/17 19:55:44
Added comment from media that explains this.
|
| + size_t uv_height = y_height / 2; |
| + size_t y_bytes = y_height * y_stride; |
| + size_t uv_bytes = uv_height * uv_stride; |
| + |
| + frame_buffer_ = allocator->Allocate(y_bytes + (uv_bytes * 2)); |
| + if (!frame_buffer_) { |
| + LOG(ERROR) << "AllocateYuv() cdm::Allocator::Allocate failed."; |
| + return false; |
| + } |
| + |
| + COMPILE_ASSERT(0 == cdm::VideoFrame::kYPlane, y_plane_data_must_be_index_0); |
| + uint8_t* data = frame_buffer_->data(); |
| + DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(data) & (kBufferAlignment - 1)); |
| + |
| + plane_offsets_[cdm::VideoFrame::kYPlane] = 0; |
| + |
| + if (format_ == cdm::kYv12) { |
| + plane_offsets_[cdm::VideoFrame::kVPlane] = y_bytes; |
| + plane_offsets_[cdm::VideoFrame::kUPlane] = y_bytes + uv_bytes; |
| + } else { |
| + plane_offsets_[cdm::VideoFrame::kUPlane] = y_bytes; |
| + plane_offsets_[cdm::VideoFrame::kVPlane] = y_bytes + uv_bytes; |
| + } |
| + |
| + strides_[cdm::VideoFrame::kYPlane] = y_stride; |
| + strides_[cdm::VideoFrame::kUPlane] = uv_stride; |
| + strides_[cdm::VideoFrame::kVPlane] = uv_stride; |
| + |
| + return true; |
| +} |
| + |
| +} // namespace webkit_media |