diff options
-rw-r--r-- | cc/resources/video_resource_updater.cc | 2 | ||||
-rw-r--r-- | media/base/video_frame.cc | 31 | ||||
-rw-r--r-- | media/base/video_frame.h | 5 | ||||
-rw-r--r-- | media/base/video_frame_unittest.cc | 44 | ||||
-rw-r--r-- | media/filters/video_renderer_base_unittest.cc | 2 |
5 files changed, 60 insertions, 24 deletions
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 2386984..ebd23b1 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc @@ -77,6 +77,7 @@ bool VideoResourceUpdater::VerifyFrame( // Unacceptable inputs. ¯\(°_o)/¯ case media::VideoFrame::UNKNOWN: + case media::VideoFrame::RGB32: case media::VideoFrame::EMPTY: case media::VideoFrame::I420: break; @@ -104,6 +105,7 @@ static gfx::Size SoftwarePlaneDimension( return gfx::ToFlooredSize(gfx::ScaleSize(coded_size, 0.5f, 1.f)); case media::VideoFrame::UNKNOWN: + case media::VideoFrame::RGB32: case media::VideoFrame::EMPTY: case media::VideoFrame::I420: case media::VideoFrame::NATIVE_TEXTURE: diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index f706cde..9c07251 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc @@ -28,6 +28,9 @@ scoped_refptr<VideoFrame> VideoFrame::CreateFrame( scoped_refptr<VideoFrame> frame(new VideoFrame( format, coded_size, visible_rect, natural_size, timestamp)); switch (format) { + case VideoFrame::RGB32: + frame->AllocateRGB(4u); + break; case VideoFrame::YV12: case VideoFrame::YV12A: case VideoFrame::YV16: @@ -45,6 +48,8 @@ std::string VideoFrame::FormatToString(VideoFrame::Format format) { switch (format) { case VideoFrame::UNKNOWN: return "UNKNOWN"; + case VideoFrame::RGB32: + return "RGB32"; case VideoFrame::YV12: return "YV12"; case VideoFrame::YV16: @@ -226,6 +231,8 @@ size_t VideoFrame::NumPlanes(Format format) { case VideoFrame::HOLE: #endif return 0; + case VideoFrame::RGB32: + return 1; case VideoFrame::YV12: case VideoFrame::YV16: case VideoFrame::I420: @@ -249,6 +256,8 @@ static inline size_t RoundUp(size_t value, size_t alignment) { // static size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { switch (format) { + case VideoFrame::RGB32: + return coded_size.GetArea() * 4; case VideoFrame::YV12: case VideoFrame::I420: { const size_t rounded_size = @@ -277,12 +286,27 @@ size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { return 0; } -// Release data allocated by AllocateYUV(). +// Release data allocated by AllocateRGB() or AllocateYUV(). static void ReleaseData(uint8* data) { DCHECK(data); base::AlignedFree(data); } +void VideoFrame::AllocateRGB(size_t bytes_per_pixel) { + // Round up to align at least at a 16-byte boundary for each row. + // This is sufficient for MMX and SSE2 reads (movq/movdqa). + size_t bytes_per_row = RoundUp(coded_size_.width(), + kFrameSizeAlignment) * bytes_per_pixel; + size_t aligned_height = RoundUp(coded_size_.height(), kFrameSizeAlignment); + strides_[VideoFrame::kRGBPlane] = bytes_per_row; + data_[VideoFrame::kRGBPlane] = reinterpret_cast<uint8*>( + base::AlignedAlloc(bytes_per_row * aligned_height + kFrameSizePadding, + kFrameAddressAlignment)); + no_longer_needed_cb_ = base::Bind(&ReleaseData, data_[VideoFrame::kRGBPlane]); + DCHECK(!(reinterpret_cast<intptr_t>(data_[VideoFrame::kRGBPlane]) & 7)); + COMPILE_ASSERT(0 == VideoFrame::kRGBPlane, RGB_data_must_be_index_0); +} + void VideoFrame::AllocateYUV() { DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 || format_ == VideoFrame::YV12A || format_ == VideoFrame::I420); @@ -370,6 +394,10 @@ int VideoFrame::row_bytes(size_t plane) const { DCHECK(IsValidPlane(plane)); int width = coded_size_.width(); switch (format_) { + // 32bpp. + case RGB32: + return width * 4; + // Planar, 8bpp. case YV12A: if (plane == kAPlane) @@ -395,6 +423,7 @@ int VideoFrame::rows(size_t plane) const { DCHECK(IsValidPlane(plane)); int height = coded_size_.height(); switch (format_) { + case RGB32: case YV16: return height; diff --git a/media/base/video_frame.h b/media/base/video_frame.h index df0ed23..fa8aa96 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h @@ -28,6 +28,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { enum { kMaxPlanes = 4, + kRGBPlane = 0, + kYPlane = 0, kUPlane = 1, kVPlane = 2, @@ -39,6 +41,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // http://www.fourcc.org/yuv.php enum Format { UNKNOWN = 0, // Unknown format value. + RGB32 = 4, // 32bpp RGB packed with extra byte 8:8:8 YV12 = 6, // 12bpp YVU planar 1x1 Y, 2x2 VU samples YV16 = 7, // 16bpp YVU planar 1x1 Y, 2x1 VU samples EMPTY = 9, // An empty frame. @@ -248,6 +251,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { base::TimeDelta timestamp); virtual ~VideoFrame(); + // Used internally by CreateFrame(). + void AllocateRGB(size_t bytes_per_pixel); void AllocateYUV(); // Used to DCHECK() plane parameters. diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc index 710c69f..b88d20c 100644 --- a/media/base/video_frame_unittest.cc +++ b/media/base/video_frame_unittest.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/format_macros.h" -#include "base/memory/aligned_memory.h" #include "base/memory/scoped_ptr.h" #include "base/strings/stringprintf.h" #include "media/base/buffers.h" @@ -47,41 +46,40 @@ void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { ASSERT_EQ(VideoFrame::YV12, yv12_frame->format()); ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), yv12_frame->stride(VideoFrame::kVPlane)); - ASSERT_EQ( - yv12_frame->coded_size().width() & (VideoFrame::kFrameSizeAlignment - 1), - 0); - ASSERT_EQ( - yv12_frame->coded_size().height() & (VideoFrame::kFrameSizeAlignment - 1), - 0); - - size_t bytes_per_row = yv12_frame->coded_size().width() * 4u; - uint8* rgb_data = reinterpret_cast<uint8*>( - base::AlignedAlloc(bytes_per_row * yv12_frame->coded_size().height() + - VideoFrame::kFrameSizePadding, - VideoFrame::kFrameAddressAlignment)); + + scoped_refptr<media::VideoFrame> rgb_frame; + rgb_frame = media::VideoFrame::CreateFrame(VideoFrame::RGB32, + yv12_frame->coded_size(), + yv12_frame->visible_rect(), + yv12_frame->natural_size(), + yv12_frame->GetTimestamp()); + + ASSERT_EQ(yv12_frame->coded_size().width(), + rgb_frame->coded_size().width()); + ASSERT_EQ(yv12_frame->coded_size().height(), + rgb_frame->coded_size().height()); media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), yv12_frame->data(VideoFrame::kUPlane), yv12_frame->data(VideoFrame::kVPlane), - rgb_data, - yv12_frame->coded_size().width(), - yv12_frame->coded_size().height(), + rgb_frame->data(VideoFrame::kRGBPlane), + rgb_frame->coded_size().width(), + rgb_frame->coded_size().height(), yv12_frame->stride(VideoFrame::kYPlane), yv12_frame->stride(VideoFrame::kUPlane), - bytes_per_row, + rgb_frame->stride(VideoFrame::kRGBPlane), media::YV12); - for (int row = 0; row < yv12_frame->coded_size().height(); ++row) { + for (int row = 0; row < rgb_frame->coded_size().height(); ++row) { uint32* rgb_row_data = reinterpret_cast<uint32*>( - rgb_data + (bytes_per_row * row)); - for (int col = 0; col < yv12_frame->coded_size().width(); ++col) { + rgb_frame->data(VideoFrame::kRGBPlane) + + (rgb_frame->stride(VideoFrame::kRGBPlane) * row)); + for (int col = 0; col < rgb_frame->coded_size().width(); ++col) { SCOPED_TRACE( base::StringPrintf("Checking (%d, %d)", row, col)); EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); } } - - base::AlignedFree(rgb_data); } // Fill each plane to its reported extents and verify accessors report non @@ -206,6 +204,8 @@ TEST(VideoFrame, CheckFrameExtents) { // and the expected hash of all planes if filled with kFillByte (defined in // ExpectFrameExtents). ExpectFrameExtents( + VideoFrame::RGB32, 1, 4, "de6d3d567e282f6a38d478f04fc81fb0"); + ExpectFrameExtents( VideoFrame::YV12, 3, 1, "71113bdfd4c0de6cf62f48fb74f7a0b1"); ExpectFrameExtents( VideoFrame::YV16, 3, 1, "9bb99ac3ff350644ebff4d28dc01b461"); diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc index db87b61..84d356d 100644 --- a/media/filters/video_renderer_base_unittest.cc +++ b/media/filters/video_renderer_base_unittest.cc @@ -186,7 +186,7 @@ class VideoRendererBaseTest : public ::testing::Test { gfx::Size natural_size = TestVideoConfig::NormalCodedSize(); scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( - VideoFrame::YV12, natural_size, gfx::Rect(natural_size), natural_size, + VideoFrame::RGB32, natural_size, gfx::Rect(natural_size), natural_size, next_frame_timestamp_); decode_results_.push_back(std::make_pair( VideoDecoder::kOk, frame)); |