| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mojo/common/media_type_converters.h" | 5 #include "media/mojo/common/media_type_converters.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 | 10 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "media/base/audio_buffer.h" | 13 #include "media/base/audio_buffer.h" |
| 14 #include "media/base/audio_decoder_config.h" | 14 #include "media/base/audio_decoder_config.h" |
| 15 #include "media/base/cdm_config.h" | 15 #include "media/base/cdm_config.h" |
| 16 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/encryption_scheme.h" | 17 #include "media/base/encryption_scheme.h" |
| 18 #include "media/base/media_util.h" | 18 #include "media/base/media_util.h" |
| 19 #include "media/base/sample_format.h" | 19 #include "media/base/sample_format.h" |
| 20 #include "media/base/test_helpers.h" | 20 #include "media/base/test_helpers.h" |
| 21 #include "media/base/video_frame.h" | |
| 22 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" | |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 22 |
| 25 namespace media { | 23 namespace media { |
| 26 | 24 |
| 27 namespace { | 25 namespace { |
| 28 | 26 |
| 29 static const gfx::Size kCodedSize(320, 240); | 27 static const gfx::Size kCodedSize(320, 240); |
| 30 static const gfx::Rect kVisibleRect(320, 240); | 28 static const gfx::Rect kVisibleRect(320, 240); |
| 31 static const gfx::Size kNaturalSize(320, 240); | 29 static const gfx::Size kNaturalSize(320, 240); |
| 32 | 30 |
| 33 void CompareBytes(uint8_t* original_data, uint8_t* result_data, size_t length) { | 31 void CompareBytes(uint8_t* original_data, uint8_t* result_data, size_t length) { |
| 34 EXPECT_GT(length, 0u); | 32 EXPECT_GT(length, 0u); |
| 35 EXPECT_EQ(memcmp(original_data, result_data, length), 0); | 33 EXPECT_EQ(memcmp(original_data, result_data, length), 0); |
| 36 } | 34 } |
| 37 | 35 |
| 38 // Compare the actual video frame bytes (|rows| rows of |row|bytes| data), | |
| 39 // skipping any padding that may be in either frame. | |
| 40 void CompareRowBytes(uint8_t* original_data, | |
| 41 uint8_t* result_data, | |
| 42 size_t rows, | |
| 43 size_t row_bytes, | |
| 44 size_t original_stride, | |
| 45 size_t result_stride) { | |
| 46 DCHECK_GE(original_stride, row_bytes); | |
| 47 DCHECK_GE(result_stride, row_bytes); | |
| 48 | |
| 49 for (size_t i = 0; i < rows; ++i) { | |
| 50 CompareBytes(original_data, result_data, row_bytes); | |
| 51 original_data += original_stride; | |
| 52 result_data += result_stride; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 void CompareAudioBuffers(SampleFormat sample_format, | 36 void CompareAudioBuffers(SampleFormat sample_format, |
| 57 const scoped_refptr<AudioBuffer>& original, | 37 const scoped_refptr<AudioBuffer>& original, |
| 58 const scoped_refptr<AudioBuffer>& result) { | 38 const scoped_refptr<AudioBuffer>& result) { |
| 59 EXPECT_EQ(original->frame_count(), result->frame_count()); | 39 EXPECT_EQ(original->frame_count(), result->frame_count()); |
| 60 EXPECT_EQ(original->timestamp(), result->timestamp()); | 40 EXPECT_EQ(original->timestamp(), result->timestamp()); |
| 61 EXPECT_EQ(original->duration(), result->duration()); | 41 EXPECT_EQ(original->duration(), result->duration()); |
| 62 EXPECT_EQ(original->sample_rate(), result->sample_rate()); | 42 EXPECT_EQ(original->sample_rate(), result->sample_rate()); |
| 63 EXPECT_EQ(original->channel_count(), result->channel_count()); | 43 EXPECT_EQ(original->channel_count(), result->channel_count()); |
| 64 EXPECT_EQ(original->channel_layout(), result->channel_layout()); | 44 EXPECT_EQ(original->channel_layout(), result->channel_layout()); |
| 65 EXPECT_EQ(original->end_of_stream(), result->end_of_stream()); | 45 EXPECT_EQ(original->end_of_stream(), result->end_of_stream()); |
| 66 | 46 |
| 67 // Compare bytes in buffer. | 47 // Compare bytes in buffer. |
| 68 int bytes_per_channel = | 48 int bytes_per_channel = |
| 69 original->frame_count() * SampleFormatToBytesPerChannel(sample_format); | 49 original->frame_count() * SampleFormatToBytesPerChannel(sample_format); |
| 70 if (IsPlanar(sample_format)) { | 50 if (IsPlanar(sample_format)) { |
| 71 for (int i = 0; i < original->channel_count(); ++i) { | 51 for (int i = 0; i < original->channel_count(); ++i) { |
| 72 CompareBytes(original->channel_data()[i], result->channel_data()[i], | 52 CompareBytes(original->channel_data()[i], result->channel_data()[i], |
| 73 bytes_per_channel); | 53 bytes_per_channel); |
| 74 } | 54 } |
| 75 return; | 55 return; |
| 76 } | 56 } |
| 77 | 57 |
| 78 DCHECK(IsInterleaved(sample_format)) << sample_format; | 58 DCHECK(IsInterleaved(sample_format)) << sample_format; |
| 79 CompareBytes(original->channel_data()[0], result->channel_data()[0], | 59 CompareBytes(original->channel_data()[0], result->channel_data()[0], |
| 80 bytes_per_channel * original->channel_count()); | 60 bytes_per_channel * original->channel_count()); |
| 81 } | 61 } |
| 82 | 62 |
| 83 void CompareVideoPlane(size_t plane, | |
| 84 const scoped_refptr<VideoFrame>& original, | |
| 85 const scoped_refptr<VideoFrame>& result) { | |
| 86 EXPECT_EQ(original->stride(plane), result->stride(plane)); | |
| 87 EXPECT_EQ(original->row_bytes(plane), result->row_bytes(plane)); | |
| 88 EXPECT_EQ(original->rows(plane), result->rows(plane)); | |
| 89 CompareRowBytes(original->data(plane), result->data(plane), | |
| 90 original->rows(plane), original->row_bytes(plane), | |
| 91 original->stride(plane), result->stride(plane)); | |
| 92 } | |
| 93 | |
| 94 void CompareVideoFrames(const scoped_refptr<VideoFrame>& original, | |
| 95 const scoped_refptr<VideoFrame>& result) { | |
| 96 if (original->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) { | |
| 97 EXPECT_TRUE(result->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); | |
| 98 return; | |
| 99 } | |
| 100 | |
| 101 EXPECT_EQ(original->format(), result->format()); | |
| 102 EXPECT_EQ(original->coded_size().height(), result->coded_size().height()); | |
| 103 EXPECT_EQ(original->coded_size().width(), result->coded_size().width()); | |
| 104 EXPECT_EQ(original->visible_rect().height(), result->visible_rect().height()); | |
| 105 EXPECT_EQ(original->visible_rect().width(), result->visible_rect().width()); | |
| 106 EXPECT_EQ(original->natural_size().height(), result->natural_size().height()); | |
| 107 EXPECT_EQ(original->natural_size().width(), result->natural_size().width()); | |
| 108 | |
| 109 CompareVideoPlane(VideoFrame::kYPlane, original, result); | |
| 110 CompareVideoPlane(VideoFrame::kUPlane, original, result); | |
| 111 CompareVideoPlane(VideoFrame::kVPlane, original, result); | |
| 112 } | |
| 113 | |
| 114 // Returns a color VideoFrame that stores the data in a | |
| 115 // mojo::SharedBufferHandle. | |
| 116 scoped_refptr<VideoFrame> CreateMojoSharedBufferColorFrame() { | |
| 117 // Create a color VideoFrame to use as reference (data will need to be copied | |
| 118 // to a mojo::SharedBufferHandle). | |
| 119 const int kWidth = 16; | |
| 120 const int kHeight = 9; | |
| 121 const base::TimeDelta kTimestamp = base::TimeDelta::FromSeconds(26); | |
| 122 scoped_refptr<VideoFrame> color_frame(VideoFrame::CreateColorFrame( | |
| 123 gfx::Size(kWidth, kHeight), 255, 128, 24, kTimestamp)); | |
| 124 | |
| 125 // Allocate a mojo::SharedBufferHandle big enough to contain | |
| 126 // |color_frame|'s data. | |
| 127 const size_t allocation_size = VideoFrame::AllocationSize( | |
| 128 color_frame->format(), color_frame->coded_size()); | |
| 129 mojo::ScopedSharedBufferHandle handle = | |
| 130 mojo::SharedBufferHandle::Create(allocation_size); | |
| 131 EXPECT_TRUE(handle.is_valid()); | |
| 132 | |
| 133 // Create a MojoSharedBufferVideoFrame whose dimensions match |color_frame|. | |
| 134 const size_t y_plane_size = color_frame->rows(VideoFrame::kYPlane) * | |
| 135 color_frame->stride(VideoFrame::kYPlane); | |
| 136 const size_t u_plane_size = color_frame->rows(VideoFrame::kUPlane) * | |
| 137 color_frame->stride(VideoFrame::kUPlane); | |
| 138 const size_t v_plane_size = color_frame->rows(VideoFrame::kVPlane) * | |
| 139 color_frame->stride(VideoFrame::kVPlane); | |
| 140 scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::Create( | |
| 141 color_frame->format(), color_frame->coded_size(), | |
| 142 color_frame->visible_rect(), color_frame->natural_size(), | |
| 143 std::move(handle), allocation_size, 0, y_plane_size, | |
| 144 y_plane_size + u_plane_size, color_frame->stride(VideoFrame::kYPlane), | |
| 145 color_frame->stride(VideoFrame::kUPlane), | |
| 146 color_frame->stride(VideoFrame::kVPlane), color_frame->timestamp())); | |
| 147 EXPECT_EQ(color_frame->coded_size(), frame->coded_size()); | |
| 148 EXPECT_EQ(color_frame->visible_rect(), frame->visible_rect()); | |
| 149 EXPECT_EQ(color_frame->natural_size(), frame->natural_size()); | |
| 150 EXPECT_EQ(color_frame->rows(VideoFrame::kYPlane), | |
| 151 frame->rows(VideoFrame::kYPlane)); | |
| 152 EXPECT_EQ(color_frame->rows(VideoFrame::kUPlane), | |
| 153 frame->rows(VideoFrame::kUPlane)); | |
| 154 EXPECT_EQ(color_frame->rows(VideoFrame::kVPlane), | |
| 155 frame->rows(VideoFrame::kVPlane)); | |
| 156 EXPECT_EQ(color_frame->stride(VideoFrame::kYPlane), | |
| 157 frame->stride(VideoFrame::kYPlane)); | |
| 158 EXPECT_EQ(color_frame->stride(VideoFrame::kUPlane), | |
| 159 frame->stride(VideoFrame::kUPlane)); | |
| 160 EXPECT_EQ(color_frame->stride(VideoFrame::kVPlane), | |
| 161 frame->stride(VideoFrame::kVPlane)); | |
| 162 | |
| 163 // Copy all the data from |color_frame| into |frame|. | |
| 164 memcpy(frame->data(VideoFrame::kYPlane), | |
| 165 color_frame->data(VideoFrame::kYPlane), y_plane_size); | |
| 166 memcpy(frame->data(VideoFrame::kUPlane), | |
| 167 color_frame->data(VideoFrame::kUPlane), u_plane_size); | |
| 168 memcpy(frame->data(VideoFrame::kVPlane), | |
| 169 color_frame->data(VideoFrame::kVPlane), v_plane_size); | |
| 170 return frame; | |
| 171 } | |
| 172 | |
| 173 } // namespace | 63 } // namespace |
| 174 | 64 |
| 175 TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) { | 65 TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) { |
| 176 const uint8_t kData[] = "hello, world"; | 66 const uint8_t kData[] = "hello, world"; |
| 177 const uint8_t kSideData[] = "sideshow bob"; | 67 const uint8_t kSideData[] = "sideshow bob"; |
| 178 const size_t kDataSize = arraysize(kData); | 68 const size_t kDataSize = arraysize(kData); |
| 179 const size_t kSideDataSize = arraysize(kSideData); | 69 const size_t kSideDataSize = arraysize(kSideData); |
| 180 | 70 |
| 181 // Original. | 71 // Original. |
| 182 scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom( | 72 scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CopyFrom( |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 0.0f, 1.0f, | 327 ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 0.0f, 1.0f, |
| 438 kSampleRate / 10, start_time); | 328 kSampleRate / 10, start_time); |
| 439 // Convert to and back. | 329 // Convert to and back. |
| 440 mojom::AudioBufferPtr ptr(mojom::AudioBuffer::From(buffer)); | 330 mojom::AudioBufferPtr ptr(mojom::AudioBuffer::From(buffer)); |
| 441 scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>()); | 331 scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>()); |
| 442 | 332 |
| 443 // Compare. | 333 // Compare. |
| 444 CompareAudioBuffers(kSampleFormatPlanarF32, buffer, result); | 334 CompareAudioBuffers(kSampleFormatPlanarF32, buffer, result); |
| 445 } | 335 } |
| 446 | 336 |
| 447 TEST(MediaTypeConvertersTest, ConvertVideoFrame_EOS) { | |
| 448 // Original. | |
| 449 scoped_refptr<VideoFrame> buffer(VideoFrame::CreateEOSFrame()); | |
| 450 | |
| 451 // Convert to and back. | |
| 452 mojom::VideoFramePtr ptr(mojom::VideoFrame::From(buffer)); | |
| 453 scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>()); | |
| 454 | |
| 455 // Compare. | |
| 456 CompareVideoFrames(buffer, result); | |
| 457 } | |
| 458 | |
| 459 TEST(MediaTypeConvertersTest, ConvertVideoFrame_EmptyFrame) { | |
| 460 // Original. | |
| 461 scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::CreateDefaultI420( | |
| 462 gfx::Size(100, 100), base::TimeDelta::FromSeconds(100))); | |
| 463 | |
| 464 // Convert to and back. | |
| 465 mojom::VideoFramePtr ptr(mojom::VideoFrame::From(frame)); | |
| 466 scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>()); | |
| 467 EXPECT_NE(result.get(), nullptr); | |
| 468 | |
| 469 // Compare. | |
| 470 CompareVideoFrames(frame, result); | |
| 471 } | |
| 472 | |
| 473 TEST(MediaTypeConvertersTest, ConvertVideoFrame_ColorFrame) { | |
| 474 scoped_refptr<VideoFrame> frame(CreateMojoSharedBufferColorFrame()); | |
| 475 | |
| 476 // Convert to and back. | |
| 477 mojom::VideoFramePtr ptr(mojom::VideoFrame::From(frame)); | |
| 478 scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>()); | |
| 479 EXPECT_NE(result.get(), nullptr); | |
| 480 | |
| 481 // Compare. | |
| 482 CompareVideoFrames(frame, result); | |
| 483 } | |
| 484 | |
| 485 TEST(MediaTypeConvertersTest, ConvertEncryptionSchemeAesCbcWithPattern) { | 337 TEST(MediaTypeConvertersTest, ConvertEncryptionSchemeAesCbcWithPattern) { |
| 486 // Original. | 338 // Original. |
| 487 EncryptionScheme scheme(EncryptionScheme::CIPHER_MODE_AES_CBC, | 339 EncryptionScheme scheme(EncryptionScheme::CIPHER_MODE_AES_CBC, |
| 488 EncryptionScheme::Pattern(1, 9)); | 340 EncryptionScheme::Pattern(1, 9)); |
| 489 | 341 |
| 490 // Convert to and back. | 342 // Convert to and back. |
| 491 mojom::EncryptionSchemePtr ptr(mojom::EncryptionScheme::From(scheme)); | 343 mojom::EncryptionSchemePtr ptr(mojom::EncryptionScheme::From(scheme)); |
| 492 EncryptionScheme result(ptr.To<EncryptionScheme>()); | 344 EncryptionScheme result(ptr.To<EncryptionScheme>()); |
| 493 | 345 |
| 494 EXPECT_TRUE(result.Matches(scheme)); | 346 EXPECT_TRUE(result.Matches(scheme)); |
| 495 | 347 |
| 496 // Verify a couple of negative cases. | 348 // Verify a couple of negative cases. |
| 497 EXPECT_FALSE(result.Matches(Unencrypted())); | 349 EXPECT_FALSE(result.Matches(Unencrypted())); |
| 498 EXPECT_FALSE(result.Matches(AesCtrEncryptionScheme())); | 350 EXPECT_FALSE(result.Matches(AesCtrEncryptionScheme())); |
| 499 } | 351 } |
| 500 | 352 |
| 501 } // namespace media | 353 } // namespace media |
| OLD | NEW |