| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/memory/aligned_memory.h" | 10 #include "base/memory/aligned_memory.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "gpu/command_buffer/common/mailbox_holder.h" | 13 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 14 #include "media/base/yuv_convert.h" | 14 #include "media/base/yuv_convert.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 namespace media { | 17 namespace media { |
| 18 | 18 |
| 19 using base::MD5DigestToBase16; | 19 using base::MD5DigestToBase16; |
| 20 | 20 |
| 21 // Helper function that initializes a YV12 frame with white and black scan | 21 // Helper function that initializes a YV12 frame with white and black scan |
| 22 // lines based on the |white_to_black| parameter. If 0, then the entire | 22 // lines based on the |white_to_black| parameter. If 0, then the entire |
| 23 // frame will be black, if 1 then the entire frame will be white. | 23 // frame will be black, if 1 then the entire frame will be white. |
| 24 void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { | 24 void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { |
| 25 EXPECT_EQ(PIXEL_FORMAT_YV12, frame->format()); | 25 EXPECT_EQ(PIXEL_FORMAT_YV12, frame->format()); |
| 26 const int first_black_row = | 26 const int first_black_row = |
| 27 static_cast<int>(frame->coded_size().height() * white_to_black); | 27 static_cast<int>(frame->coded_size().height() * white_to_black); |
| 28 uint8* y_plane = frame->data(VideoFrame::kYPlane); | 28 uint8_t* y_plane = frame->data(VideoFrame::kYPlane); |
| 29 for (int row = 0; row < frame->coded_size().height(); ++row) { | 29 for (int row = 0; row < frame->coded_size().height(); ++row) { |
| 30 int color = (row < first_black_row) ? 0xFF : 0x00; | 30 int color = (row < first_black_row) ? 0xFF : 0x00; |
| 31 memset(y_plane, color, frame->stride(VideoFrame::kYPlane)); | 31 memset(y_plane, color, frame->stride(VideoFrame::kYPlane)); |
| 32 y_plane += frame->stride(VideoFrame::kYPlane); | 32 y_plane += frame->stride(VideoFrame::kYPlane); |
| 33 } | 33 } |
| 34 uint8* u_plane = frame->data(VideoFrame::kUPlane); | 34 uint8_t* u_plane = frame->data(VideoFrame::kUPlane); |
| 35 uint8* v_plane = frame->data(VideoFrame::kVPlane); | 35 uint8_t* v_plane = frame->data(VideoFrame::kVPlane); |
| 36 for (int row = 0; row < frame->coded_size().height(); row += 2) { | 36 for (int row = 0; row < frame->coded_size().height(); row += 2) { |
| 37 memset(u_plane, 0x80, frame->stride(VideoFrame::kUPlane)); | 37 memset(u_plane, 0x80, frame->stride(VideoFrame::kUPlane)); |
| 38 memset(v_plane, 0x80, frame->stride(VideoFrame::kVPlane)); | 38 memset(v_plane, 0x80, frame->stride(VideoFrame::kVPlane)); |
| 39 u_plane += frame->stride(VideoFrame::kUPlane); | 39 u_plane += frame->stride(VideoFrame::kUPlane); |
| 40 v_plane += frame->stride(VideoFrame::kVPlane); | 40 v_plane += frame->stride(VideoFrame::kVPlane); |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Given a |yv12_frame| this method converts the YV12 frame to RGBA and | 44 // Given a |yv12_frame| this method converts the YV12 frame to RGBA and |
| 45 // makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. | 45 // makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. |
| 46 void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { | 46 void ExpectFrameColor(media::VideoFrame* yv12_frame, |
| 47 uint32_t expect_rgb_color) { |
| 47 ASSERT_EQ(PIXEL_FORMAT_YV12, yv12_frame->format()); | 48 ASSERT_EQ(PIXEL_FORMAT_YV12, yv12_frame->format()); |
| 48 ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), | 49 ASSERT_EQ(yv12_frame->stride(VideoFrame::kUPlane), |
| 49 yv12_frame->stride(VideoFrame::kVPlane)); | 50 yv12_frame->stride(VideoFrame::kVPlane)); |
| 50 ASSERT_EQ( | 51 ASSERT_EQ( |
| 51 yv12_frame->coded_size().width() & (VideoFrame::kFrameSizeAlignment - 1), | 52 yv12_frame->coded_size().width() & (VideoFrame::kFrameSizeAlignment - 1), |
| 52 0); | 53 0); |
| 53 ASSERT_EQ( | 54 ASSERT_EQ( |
| 54 yv12_frame->coded_size().height() & (VideoFrame::kFrameSizeAlignment - 1), | 55 yv12_frame->coded_size().height() & (VideoFrame::kFrameSizeAlignment - 1), |
| 55 0); | 56 0); |
| 56 | 57 |
| 57 size_t bytes_per_row = yv12_frame->coded_size().width() * 4u; | 58 size_t bytes_per_row = yv12_frame->coded_size().width() * 4u; |
| 58 uint8* rgb_data = reinterpret_cast<uint8*>( | 59 uint8_t* rgb_data = reinterpret_cast<uint8_t*>( |
| 59 base::AlignedAlloc(bytes_per_row * yv12_frame->coded_size().height() + | 60 base::AlignedAlloc(bytes_per_row * yv12_frame->coded_size().height() + |
| 60 VideoFrame::kFrameSizePadding, | 61 VideoFrame::kFrameSizePadding, |
| 61 VideoFrame::kFrameAddressAlignment)); | 62 VideoFrame::kFrameAddressAlignment)); |
| 62 | 63 |
| 63 media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), | 64 media::ConvertYUVToRGB32(yv12_frame->data(VideoFrame::kYPlane), |
| 64 yv12_frame->data(VideoFrame::kUPlane), | 65 yv12_frame->data(VideoFrame::kUPlane), |
| 65 yv12_frame->data(VideoFrame::kVPlane), | 66 yv12_frame->data(VideoFrame::kVPlane), |
| 66 rgb_data, | 67 rgb_data, |
| 67 yv12_frame->coded_size().width(), | 68 yv12_frame->coded_size().width(), |
| 68 yv12_frame->coded_size().height(), | 69 yv12_frame->coded_size().height(), |
| 69 yv12_frame->stride(VideoFrame::kYPlane), | 70 yv12_frame->stride(VideoFrame::kYPlane), |
| 70 yv12_frame->stride(VideoFrame::kUPlane), | 71 yv12_frame->stride(VideoFrame::kUPlane), |
| 71 bytes_per_row, | 72 bytes_per_row, |
| 72 media::YV12); | 73 media::YV12); |
| 73 | 74 |
| 74 for (int row = 0; row < yv12_frame->coded_size().height(); ++row) { | 75 for (int row = 0; row < yv12_frame->coded_size().height(); ++row) { |
| 75 uint32* rgb_row_data = reinterpret_cast<uint32*>( | 76 uint32_t* rgb_row_data = |
| 76 rgb_data + (bytes_per_row * row)); | 77 reinterpret_cast<uint32_t*>(rgb_data + (bytes_per_row * row)); |
| 77 for (int col = 0; col < yv12_frame->coded_size().width(); ++col) { | 78 for (int col = 0; col < yv12_frame->coded_size().width(); ++col) { |
| 78 SCOPED_TRACE(base::StringPrintf("Checking (%d, %d)", row, col)); | 79 SCOPED_TRACE(base::StringPrintf("Checking (%d, %d)", row, col)); |
| 79 EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); | 80 EXPECT_EQ(expect_rgb_color, rgb_row_data[col]); |
| 80 } | 81 } |
| 81 } | 82 } |
| 82 | 83 |
| 83 base::AlignedFree(rgb_data); | 84 base::AlignedFree(rgb_data); |
| 84 } | 85 } |
| 85 | 86 |
| 86 // Fill each plane to its reported extents and verify accessors report non | 87 // Fill each plane to its reported extents and verify accessors report non |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 // Verify that frame is initialized with zeros. | 174 // Verify that frame is initialized with zeros. |
| 174 // TODO(emircan): Check all the contents when we know the exact size of the | 175 // TODO(emircan): Check all the contents when we know the exact size of the |
| 175 // allocated buffer. | 176 // allocated buffer. |
| 176 for (size_t i = 0; i < VideoFrame::NumPlanes(frame->format()); ++i) | 177 for (size_t i = 0; i < VideoFrame::NumPlanes(frame->format()); ++i) |
| 177 EXPECT_EQ(0, frame->data(i)[0]); | 178 EXPECT_EQ(0, frame->data(i)[0]); |
| 178 } | 179 } |
| 179 | 180 |
| 180 TEST(VideoFrame, CreateBlackFrame) { | 181 TEST(VideoFrame, CreateBlackFrame) { |
| 181 const int kWidth = 2; | 182 const int kWidth = 2; |
| 182 const int kHeight = 2; | 183 const int kHeight = 2; |
| 183 const uint8 kExpectedYRow[] = { 0, 0 }; | 184 const uint8_t kExpectedYRow[] = {0, 0}; |
| 184 const uint8 kExpectedUVRow[] = { 128 }; | 185 const uint8_t kExpectedUVRow[] = {128}; |
| 185 | 186 |
| 186 scoped_refptr<media::VideoFrame> frame = | 187 scoped_refptr<media::VideoFrame> frame = |
| 187 VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight)); | 188 VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight)); |
| 188 ASSERT_TRUE(frame.get()); | 189 ASSERT_TRUE(frame.get()); |
| 189 EXPECT_TRUE(frame->IsMappable()); | 190 EXPECT_TRUE(frame->IsMappable()); |
| 190 | 191 |
| 191 // Test basic properties. | 192 // Test basic properties. |
| 192 EXPECT_EQ(0, frame->timestamp().InMicroseconds()); | 193 EXPECT_EQ(0, frame->timestamp().InMicroseconds()); |
| 193 EXPECT_FALSE( | 194 EXPECT_FALSE( |
| 194 frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); | 195 frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); |
| 195 | 196 |
| 196 // Test |frame| properties. | 197 // Test |frame| properties. |
| 197 EXPECT_EQ(PIXEL_FORMAT_YV12, frame->format()); | 198 EXPECT_EQ(PIXEL_FORMAT_YV12, frame->format()); |
| 198 EXPECT_EQ(kWidth, frame->coded_size().width()); | 199 EXPECT_EQ(kWidth, frame->coded_size().width()); |
| 199 EXPECT_EQ(kHeight, frame->coded_size().height()); | 200 EXPECT_EQ(kHeight, frame->coded_size().height()); |
| 200 | 201 |
| 201 // Test frames themselves. | 202 // Test frames themselves. |
| 202 uint8* y_plane = frame->data(VideoFrame::kYPlane); | 203 uint8_t* y_plane = frame->data(VideoFrame::kYPlane); |
| 203 for (int y = 0; y < frame->coded_size().height(); ++y) { | 204 for (int y = 0; y < frame->coded_size().height(); ++y) { |
| 204 EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, arraysize(kExpectedYRow))); | 205 EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, arraysize(kExpectedYRow))); |
| 205 y_plane += frame->stride(VideoFrame::kYPlane); | 206 y_plane += frame->stride(VideoFrame::kYPlane); |
| 206 } | 207 } |
| 207 | 208 |
| 208 uint8* u_plane = frame->data(VideoFrame::kUPlane); | 209 uint8_t* u_plane = frame->data(VideoFrame::kUPlane); |
| 209 uint8* v_plane = frame->data(VideoFrame::kVPlane); | 210 uint8_t* v_plane = frame->data(VideoFrame::kVPlane); |
| 210 for (int y = 0; y < frame->coded_size().height() / 2; ++y) { | 211 for (int y = 0; y < frame->coded_size().height() / 2; ++y) { |
| 211 EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, arraysize(kExpectedUVRow))); | 212 EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, arraysize(kExpectedUVRow))); |
| 212 EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, arraysize(kExpectedUVRow))); | 213 EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, arraysize(kExpectedUVRow))); |
| 213 u_plane += frame->stride(VideoFrame::kUPlane); | 214 u_plane += frame->stride(VideoFrame::kUPlane); |
| 214 v_plane += frame->stride(VideoFrame::kVPlane); | 215 v_plane += frame->stride(VideoFrame::kVPlane); |
| 215 } | 216 } |
| 216 } | 217 } |
| 217 | 218 |
| 218 static void FrameNoLongerNeededCallback( | 219 static void FrameNoLongerNeededCallback( |
| 219 const scoped_refptr<media::VideoFrame>& frame, | 220 const scoped_refptr<media::VideoFrame>& frame, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 const gpu::CommandBufferNamespace kNamespace = | 318 const gpu::CommandBufferNamespace kNamespace = |
| 318 gpu::CommandBufferNamespace::GPU_IO; | 319 gpu::CommandBufferNamespace::GPU_IO; |
| 319 const uint64_t kCommandBufferId = 0x123; | 320 const uint64_t kCommandBufferId = 0x123; |
| 320 gpu::Mailbox mailbox[kPlanesNum]; | 321 gpu::Mailbox mailbox[kPlanesNum]; |
| 321 for (int i = 0; i < kPlanesNum; ++i) { | 322 for (int i = 0; i < kPlanesNum; ++i) { |
| 322 mailbox[i].name[0] = 50 + 1; | 323 mailbox[i].name[0] = 50 + 1; |
| 323 } | 324 } |
| 324 | 325 |
| 325 gpu::SyncToken sync_token(kNamespace, 0, kCommandBufferId, 7); | 326 gpu::SyncToken sync_token(kNamespace, 0, kCommandBufferId, 7); |
| 326 sync_token.SetVerifyFlush(); | 327 sync_token.SetVerifyFlush(); |
| 327 uint32 target = 9; | 328 uint32_t target = 9; |
| 328 gpu::SyncToken release_sync_token(kNamespace, 0, kCommandBufferId, 111); | 329 gpu::SyncToken release_sync_token(kNamespace, 0, kCommandBufferId, 111); |
| 329 release_sync_token.SetVerifyFlush(); | 330 release_sync_token.SetVerifyFlush(); |
| 330 | 331 |
| 331 gpu::SyncToken called_sync_token; | 332 gpu::SyncToken called_sync_token; |
| 332 { | 333 { |
| 333 scoped_refptr<VideoFrame> frame = VideoFrame::WrapYUV420NativeTextures( | 334 scoped_refptr<VideoFrame> frame = VideoFrame::WrapYUV420NativeTextures( |
| 334 gpu::MailboxHolder(mailbox[VideoFrame::kYPlane], sync_token, target), | 335 gpu::MailboxHolder(mailbox[VideoFrame::kYPlane], sync_token, target), |
| 335 gpu::MailboxHolder(mailbox[VideoFrame::kUPlane], sync_token, target), | 336 gpu::MailboxHolder(mailbox[VideoFrame::kUPlane], sync_token, target), |
| 336 gpu::MailboxHolder(mailbox[VideoFrame::kVPlane], sync_token, target), | 337 gpu::MailboxHolder(mailbox[VideoFrame::kVPlane], sync_token, target), |
| 337 base::Bind(&TextureCallback, &called_sync_token), | 338 base::Bind(&TextureCallback, &called_sync_token), |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 | 484 |
| 484 for (int i = 0; i < VideoFrameMetadata::NUM_KEYS; ++i) { | 485 for (int i = 0; i < VideoFrameMetadata::NUM_KEYS; ++i) { |
| 485 const VideoFrameMetadata::Key key = static_cast<VideoFrameMetadata::Key>(i); | 486 const VideoFrameMetadata::Key key = static_cast<VideoFrameMetadata::Key>(i); |
| 486 int value = -1; | 487 int value = -1; |
| 487 EXPECT_TRUE(result.GetInteger(key, &value)); | 488 EXPECT_TRUE(result.GetInteger(key, &value)); |
| 488 EXPECT_EQ(i, value); | 489 EXPECT_EQ(i, value); |
| 489 } | 490 } |
| 490 } | 491 } |
| 491 | 492 |
| 492 } // namespace media | 493 } // namespace media |
| OLD | NEW |