diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-23 22:34:24 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-23 22:34:24 +0000 |
commit | 34f993563386ad569f3674d157153e697e847e0a (patch) | |
tree | bb12aa46242ad8534f51387cca789375ba92f10f /media/base/video_frame_unittest.cc | |
parent | 5ff5ee97910c9fb6909f4a3029427edd21366d9b (diff) | |
download | chromium_src-34f993563386ad569f3674d157153e697e847e0a.zip chromium_src-34f993563386ad569f3674d157153e697e847e0a.tar.gz chromium_src-34f993563386ad569f3674d157153e697e847e0a.tar.bz2 |
Merged VideoSurface, VideoFrame and VideoFrameImpl in VideoFrame.
Patch by sergeyu@chromium.org
BUG=28100
TEST=Ran media_unittests
Review URL: http://codereview.chromium.org/1226001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/video_frame_unittest.cc')
-rw-r--r-- | media/base/video_frame_unittest.cc | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc new file mode 100644 index 0000000..27e15dc --- /dev/null +++ b/media/base/video_frame_unittest.cc @@ -0,0 +1,176 @@ +// Copyright (c) 2010 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 "media/base/video_frame.h" + +#include "base/format_macros.h" +#include "base/string_util.h" +#include "media/base/buffers.h" +#include "media/base/mock_filters.h" +#include "media/base/yuv_convert.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +// Helper function that initializes a YV12 frame with white and black scan +// lines based on the |white_to_black| parameter. If 0, then the entire +// frame will be black, if 1 then the entire frame will be white. +void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { + EXPECT_EQ(VideoFrame::YV12, frame->format()); + size_t first_black_row = static_cast<size_t>(frame->height() * + white_to_black); + uint8* y_plane = frame->data(VideoFrame::kYPlane); + for (size_t row = 0; row < frame->height(); ++row) { + int color = (row < first_black_row) ? 0xFF : 0x00; + memset(y_plane, color, frame->width()); + y_plane += frame->stride(VideoFrame::kYPlane); + } + uint8* u_plane = frame->data(VideoFrame::kUPlane); + uint8* v_plane = frame->data(VideoFrame::kVPlane); + for (size_t row = 0; row < frame->height(); row += 2) { + memset(u_plane, 0x80, frame->width() / 2); + memset(v_plane, 0x80, frame->width() / 2); + u_plane += frame->stride(VideoFrame::kUPlane); + v_plane += frame->stride(VideoFrame::kVPlane); + } +} + +// Given a |yv12_frame| this method converts the YV12 frame to RGBA and +// makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. +void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { + // On linux and mac builds if you directly compare using EXPECT_EQ and use + // the VideoFrame::kNumxxxPlanes constants, it generates an error when + // linking. These are declared so that we can compare against locals. + const size_t expect_yuv_planes = VideoFrame::kNumYUVPlanes; + const size_t expect_rgb_planes = VideoFrame::kNumRGBPlanes; + + ASSERT_EQ(VideoFrame::YV12, yv12_frame->format()); + ASSERT_EQ(expect_yuv_planes, yv12_frame->planes()); + ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), + yv12_frame->stride(VideoFrame::kVPlane)); + + scoped_refptr<media::VideoFrame> rgb_frame; + media::VideoFrame::CreateFrame(VideoFrame::RGBA, + yv12_frame->width(), + yv12_frame->height(), + yv12_frame->GetTimestamp(), + yv12_frame->GetDuration(), + &rgb_frame); + + ASSERT_EQ(yv12_frame->width(), rgb_frame->width()); + ASSERT_EQ(yv12_frame->height(), rgb_frame->height()); + ASSERT_EQ(expect_rgb_planes, rgb_frame->planes()); + + media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), + yv12_frame->data(VideoFrame::kUPlane), + yv12_frame->data(VideoFrame::kVPlane), + rgb_frame->data(VideoFrame::kRGBPlane), + rgb_frame->width(), + rgb_frame->height(), + yv12_frame->stride(VideoFrame::kYPlane), + yv12_frame->stride(VideoFrame::kUPlane), + rgb_frame->stride(VideoFrame::kRGBPlane), + media::YV12); + + for (size_t row = 0; row < rgb_frame->height(); ++row) { + uint32* rgb_row_data = reinterpret_cast<uint32*>( + rgb_frame->data(VideoFrame::kRGBPlane) + + (rgb_frame->stride(VideoFrame::kRGBPlane) * row)); + for (size_t col = 0; col < rgb_frame->width(); ++col) { + SCOPED_TRACE(StringPrintf("Checking (%" PRIuS ", %" PRIuS ")", + row, col)); + EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); + } + } +} + +TEST(VideoFrame, CreateFrame) { + const size_t kWidth = 64; + const size_t kHeight = 48; + const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337); + const base::TimeDelta kDurationA = base::TimeDelta::FromMicroseconds(1667); + const base::TimeDelta kTimestampB = base::TimeDelta::FromMicroseconds(1234); + const base::TimeDelta kDurationB = base::TimeDelta::FromMicroseconds(5678); + + // Create a YV12 Video Frame. + scoped_refptr<media::VideoFrame> frame; + VideoFrame::CreateFrame(media::VideoFrame::YV12, kWidth, kHeight, + kTimestampA, kDurationA, &frame); + ASSERT_TRUE(frame); + + // Test StreamSample implementation. + EXPECT_EQ(kTimestampA.InMicroseconds(), + frame->GetTimestamp().InMicroseconds()); + EXPECT_EQ(kDurationA.InMicroseconds(), + frame->GetDuration().InMicroseconds()); + EXPECT_FALSE(frame->IsEndOfStream()); + EXPECT_FALSE(frame->IsDiscontinuous()); + frame->SetTimestamp(kTimestampB); + frame->SetDuration(kDurationB); + EXPECT_EQ(kTimestampB.InMicroseconds(), + frame->GetTimestamp().InMicroseconds()); + EXPECT_EQ(kDurationB.InMicroseconds(), + frame->GetDuration().InMicroseconds()); + EXPECT_FALSE(frame->IsEndOfStream()); + frame->SetDiscontinuous(true); + EXPECT_TRUE(frame->IsDiscontinuous()); + frame->SetDiscontinuous(false); + EXPECT_FALSE(frame->IsDiscontinuous()); + + // Test VideoFrame implementation. + { + SCOPED_TRACE(""); + InitializeYV12Frame(frame, 0.0f); + ExpectFrameColor(frame, 0xFF000000); + } + { + SCOPED_TRACE(""); + InitializeYV12Frame(frame, 1.0f); + ExpectFrameColor(frame, 0xFFFFFFFF); + } + + // Test an empty frame. + VideoFrame::CreateEmptyFrame(&frame); + EXPECT_TRUE(frame->IsEndOfStream()); +} + +TEST(VideoFrame, CreateBlackFrame) { + const size_t kWidth = 2; + const size_t kHeight = 2; + const uint8 kExpectedYRow[] = { 0, 0 }; + const uint8 kExpectedUVRow[] = { 128 }; + + scoped_refptr<media::VideoFrame> frame; + VideoFrame::CreateBlackFrame(kWidth, kHeight, &frame); + ASSERT_TRUE(frame); + + // Test basic properties. + EXPECT_EQ(0, frame->GetTimestamp().InMicroseconds()); + EXPECT_EQ(0, frame->GetDuration().InMicroseconds()); + EXPECT_FALSE(frame->IsEndOfStream()); + + // Test |frame| properties. + EXPECT_EQ(VideoFrame::YV12, frame->format()); + EXPECT_EQ(kWidth, frame->width()); + EXPECT_EQ(kHeight, frame->height()); + EXPECT_EQ(3u, frame->planes()); + + // Test frames themselves. + uint8* y_plane = frame->data(VideoFrame::kYPlane); + for (size_t y = 0; y < frame->height(); ++y) { + EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, arraysize(kExpectedYRow))); + y_plane += frame->stride(VideoFrame::kYPlane); + } + + uint8* u_plane = frame->data(VideoFrame::kUPlane); + uint8* v_plane = frame->data(VideoFrame::kVPlane); + for (size_t y = 0; y < frame->height() / 2; ++y) { + EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, arraysize(kExpectedUVRow))); + EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, arraysize(kExpectedUVRow))); + u_plane += frame->stride(VideoFrame::kUPlane); + v_plane += frame->stride(VideoFrame::kVPlane); + } +} + +} // namespace media |