| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 #include "media/base/media_util.h" | 17 #include "media/base/media_util.h" |
| 18 #include "media/base/stream_parser_buffer.h" | 18 #include "media/base/stream_parser_buffer.h" |
| 19 #include "media/base/timestamp_constants.h" | 19 #include "media/base/timestamp_constants.h" |
| 20 #include "media/base/video_decoder_config.h" | 20 #include "media/base/video_decoder_config.h" |
| 21 #include "media/formats/mp2t/es_adapter_video.h" | 21 #include "media/formats/mp2t/es_adapter_video.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 23 | 23 |
| 24 namespace media { | 24 namespace media { |
| 25 namespace mp2t { | 25 namespace mp2t { |
| 26 | 26 |
| 27 typedef StreamParser::BufferQueue BufferQueue; |
| 28 |
| 27 namespace { | 29 namespace { |
| 28 | 30 |
| 29 VideoDecoderConfig CreateFakeVideoConfig() { | 31 VideoDecoderConfig CreateFakeVideoConfig() { |
| 30 gfx::Size coded_size(320, 240); | 32 gfx::Size coded_size(320, 240); |
| 31 gfx::Rect visible_rect(0, 0, 320, 240); | 33 gfx::Rect visible_rect(0, 0, 320, 240); |
| 32 gfx::Size natural_size(320, 240); | 34 gfx::Size natural_size(320, 240); |
| 33 return VideoDecoderConfig(kCodecH264, H264PROFILE_MAIN, PIXEL_FORMAT_I420, | 35 return VideoDecoderConfig(kCodecH264, H264PROFILE_MAIN, PIXEL_FORMAT_I420, |
| 34 COLOR_SPACE_UNSPECIFIED, coded_size, visible_rect, | 36 COLOR_SPACE_UNSPECIFIED, coded_size, visible_rect, |
| 35 natural_size, EmptyExtraData(), Unencrypted()); | 37 natural_size, EmptyExtraData(), Unencrypted()); |
| 36 } | 38 } |
| 37 | 39 |
| 38 StreamParserBuffer::BufferQueue | 40 BufferQueue GenerateFakeBuffers(const int* frame_pts_ms, |
| 39 GenerateFakeBuffers(const int* frame_pts_ms, | 41 const bool* is_key_frame, |
| 40 const bool* is_key_frame, | 42 size_t frame_count) { |
| 41 size_t frame_count) { | |
| 42 uint8_t dummy_buffer[] = {0, 0, 0, 0}; | 43 uint8_t dummy_buffer[] = {0, 0, 0, 0}; |
| 43 | 44 |
| 44 StreamParserBuffer::BufferQueue buffers(frame_count); | 45 BufferQueue buffers(frame_count); |
| 45 for (size_t k = 0; k < frame_count; k++) { | 46 for (size_t k = 0; k < frame_count; k++) { |
| 46 buffers[k] = StreamParserBuffer::CopyFrom( | 47 buffers[k] = StreamParserBuffer::CopyFrom( |
| 47 dummy_buffer, arraysize(dummy_buffer), | 48 dummy_buffer, arraysize(dummy_buffer), |
| 48 is_key_frame[k], DemuxerStream::VIDEO, 0); | 49 is_key_frame[k], DemuxerStream::VIDEO, 0); |
| 49 if (frame_pts_ms[k] < 0) { | 50 if (frame_pts_ms[k] < 0) { |
| 50 buffers[k]->set_timestamp(kNoTimestamp); | 51 buffers[k]->set_timestamp(kNoTimestamp); |
| 51 } else { | 52 } else { |
| 52 buffers[k]->set_timestamp( | 53 buffers[k]->set_timestamp( |
| 53 base::TimeDelta::FromMilliseconds(frame_pts_ms[k])); | 54 base::TimeDelta::FromMilliseconds(frame_pts_ms[k])); |
| 54 } | 55 } |
| 55 } | 56 } |
| 56 return buffers; | 57 return buffers; |
| 57 } | 58 } |
| 58 | 59 |
| 59 } | 60 } |
| 60 | 61 |
| 61 class EsAdapterVideoTest : public testing::Test { | 62 class EsAdapterVideoTest : public testing::Test { |
| 62 public: | 63 public: |
| 63 EsAdapterVideoTest(); | 64 EsAdapterVideoTest(); |
| 64 | 65 |
| 65 protected: | 66 protected: |
| 66 // Feed the ES adapter with the buffers from |buffer_queue|. | 67 // Feed the ES adapter with the buffers from |buffer_queue|. |
| 67 // Return the durations computed by the ES adapter as well as | 68 // Return the durations computed by the ES adapter as well as |
| 68 // whether each frame emitted by the adapter is a key frame. | 69 // whether each frame emitted by the adapter is a key frame. |
| 69 std::string RunAdapterTest(const StreamParser::BufferQueue& buffer_queue); | 70 std::string RunAdapterTest(const BufferQueue& buffer_queue); |
| 70 | 71 |
| 71 private: | 72 private: |
| 72 void OnNewConfig(const VideoDecoderConfig& video_config); | 73 void OnNewConfig(const VideoDecoderConfig& video_config); |
| 73 void OnNewBuffer(scoped_refptr<StreamParserBuffer> buffer); | 74 void OnNewBuffer(scoped_refptr<StreamParserBuffer> buffer); |
| 74 | 75 |
| 75 EsAdapterVideo es_adapter_; | 76 EsAdapterVideo es_adapter_; |
| 76 | 77 |
| 77 std::stringstream buffer_descriptors_; | 78 std::stringstream buffer_descriptors_; |
| 78 | 79 |
| 79 DISALLOW_COPY_AND_ASSIGN(EsAdapterVideoTest); | 80 DISALLOW_COPY_AND_ASSIGN(EsAdapterVideoTest); |
| 80 }; | 81 }; |
| 81 | 82 |
| 82 EsAdapterVideoTest::EsAdapterVideoTest() | 83 EsAdapterVideoTest::EsAdapterVideoTest() |
| 83 : es_adapter_(base::Bind(&EsAdapterVideoTest::OnNewConfig, | 84 : es_adapter_(base::Bind(&EsAdapterVideoTest::OnNewConfig, |
| 84 base::Unretained(this)), | 85 base::Unretained(this)), |
| 85 base::Bind(&EsAdapterVideoTest::OnNewBuffer, | 86 base::Bind(&EsAdapterVideoTest::OnNewBuffer, |
| 86 base::Unretained(this))) { | 87 base::Unretained(this))) { |
| 87 } | 88 } |
| 88 | 89 |
| 89 void EsAdapterVideoTest::OnNewConfig(const VideoDecoderConfig& video_config) { | 90 void EsAdapterVideoTest::OnNewConfig(const VideoDecoderConfig& video_config) { |
| 90 } | 91 } |
| 91 | 92 |
| 92 void EsAdapterVideoTest::OnNewBuffer( | 93 void EsAdapterVideoTest::OnNewBuffer( |
| 93 scoped_refptr<StreamParserBuffer> buffer) { | 94 scoped_refptr<StreamParserBuffer> buffer) { |
| 94 buffer_descriptors_ << "(" << buffer->duration().InMilliseconds() << "," | 95 buffer_descriptors_ << "(" << buffer->duration().InMilliseconds() << "," |
| 95 << (buffer->is_key_frame() ? "Y" : "N") << ") "; | 96 << (buffer->is_key_frame() ? "Y" : "N") << ") "; |
| 96 } | 97 } |
| 97 | 98 |
| 98 std::string EsAdapterVideoTest::RunAdapterTest( | 99 std::string EsAdapterVideoTest::RunAdapterTest( |
| 99 const StreamParserBuffer::BufferQueue& buffer_queue) { | 100 const BufferQueue& buffer_queue) { |
| 100 buffer_descriptors_.clear(); | 101 buffer_descriptors_.clear(); |
| 101 | 102 |
| 102 es_adapter_.OnConfigChanged(CreateFakeVideoConfig()); | 103 es_adapter_.OnConfigChanged(CreateFakeVideoConfig()); |
| 103 for (StreamParserBuffer::BufferQueue::const_iterator it = | 104 for (BufferQueue::const_iterator it = buffer_queue.begin(); |
| 104 buffer_queue.begin(); it != buffer_queue.end(); ++it) { | 105 it != buffer_queue.end(); ++it) { |
| 105 es_adapter_.OnNewBuffer(*it); | 106 es_adapter_.OnNewBuffer(*it); |
| 106 } | 107 } |
| 107 es_adapter_.Flush(); | 108 es_adapter_.Flush(); |
| 108 | 109 |
| 109 std::string s = buffer_descriptors_.str(); | 110 std::string s = buffer_descriptors_.str(); |
| 110 base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s); | 111 base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s); |
| 111 return s; | 112 return s; |
| 112 } | 113 } |
| 113 | 114 |
| 114 TEST_F(EsAdapterVideoTest, FrameDurationSimpleGop) { | 115 TEST_F(EsAdapterVideoTest, FrameDurationSimpleGop) { |
| 115 // PTS for a GOP without B frames - strictly increasing. | 116 // PTS for a GOP without B frames - strictly increasing. |
| 116 int pts_ms[] = {30, 31, 33, 36, 40, 45, 51, 58}; | 117 int pts_ms[] = {30, 31, 33, 36, 40, 45, 51, 58}; |
| 117 bool is_key_frame[] = { | 118 bool is_key_frame[] = { |
| 118 true, false, false, false, | 119 true, false, false, false, |
| 119 false, false, false, false }; | 120 false, false, false, false }; |
| 120 StreamParserBuffer::BufferQueue buffer_queue = | 121 BufferQueue buffer_queue = |
| 121 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); | 122 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); |
| 122 | 123 |
| 123 EXPECT_EQ("(1,Y) (2,N) (3,N) (4,N) (5,N) (6,N) (7,N) (7,N)", | 124 EXPECT_EQ("(1,Y) (2,N) (3,N) (4,N) (5,N) (6,N) (7,N) (7,N)", |
| 124 RunAdapterTest(buffer_queue)); | 125 RunAdapterTest(buffer_queue)); |
| 125 } | 126 } |
| 126 | 127 |
| 127 TEST_F(EsAdapterVideoTest, FrameDurationComplexGop) { | 128 TEST_F(EsAdapterVideoTest, FrameDurationComplexGop) { |
| 128 // PTS for a GOP with B frames. | 129 // PTS for a GOP with B frames. |
| 129 int pts_ms[] = {30, 120, 60, 90, 210, 150, 180, 300, 240, 270}; | 130 int pts_ms[] = {30, 120, 60, 90, 210, 150, 180, 300, 240, 270}; |
| 130 bool is_key_frame[] = { | 131 bool is_key_frame[] = { |
| 131 true, false, false, false, false, | 132 true, false, false, false, false, |
| 132 false, false, false, false, false }; | 133 false, false, false, false, false }; |
| 133 StreamParserBuffer::BufferQueue buffer_queue = | 134 BufferQueue buffer_queue = |
| 134 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); | 135 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); |
| 135 | 136 |
| 136 EXPECT_EQ("(30,Y) (30,N) (30,N) (30,N) (30,N) " | 137 EXPECT_EQ("(30,Y) (30,N) (30,N) (30,N) (30,N) " |
| 137 "(30,N) (30,N) (30,N) (30,N) (30,N)", | 138 "(30,N) (30,N) (30,N) (30,N) (30,N)", |
| 138 RunAdapterTest(buffer_queue)); | 139 RunAdapterTest(buffer_queue)); |
| 139 } | 140 } |
| 140 | 141 |
| 141 TEST_F(EsAdapterVideoTest, LeadingNonKeyFrames) { | 142 TEST_F(EsAdapterVideoTest, LeadingNonKeyFrames) { |
| 142 int pts_ms[] = {30, 40, 50, 120, 150, 180}; | 143 int pts_ms[] = {30, 40, 50, 120, 150, 180}; |
| 143 bool is_key_frame[] = {false, false, false, true, false, false}; | 144 bool is_key_frame[] = {false, false, false, true, false, false}; |
| 144 StreamParserBuffer::BufferQueue buffer_queue = | 145 BufferQueue buffer_queue = |
| 145 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); | 146 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); |
| 146 | 147 |
| 147 EXPECT_EQ("(30,Y) (30,Y) (30,Y) (30,Y) (30,N) (30,N)", | 148 EXPECT_EQ("(30,Y) (30,Y) (30,Y) (30,Y) (30,N) (30,N)", |
| 148 RunAdapterTest(buffer_queue)); | 149 RunAdapterTest(buffer_queue)); |
| 149 } | 150 } |
| 150 | 151 |
| 151 TEST_F(EsAdapterVideoTest, LeadingKeyFrameWithNoTimestamp) { | 152 TEST_F(EsAdapterVideoTest, LeadingKeyFrameWithNoTimestamp) { |
| 152 int pts_ms[] = {-1, 40, 50, 120, 150, 180}; | 153 int pts_ms[] = {-1, 40, 50, 120, 150, 180}; |
| 153 bool is_key_frame[] = {true, false, false, true, false, false}; | 154 bool is_key_frame[] = {true, false, false, true, false, false}; |
| 154 StreamParserBuffer::BufferQueue buffer_queue = | 155 BufferQueue buffer_queue = |
| 155 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); | 156 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); |
| 156 | 157 |
| 157 EXPECT_EQ("(40,Y) (40,Y) (30,Y) (30,N) (30,N)", | 158 EXPECT_EQ("(40,Y) (40,Y) (30,Y) (30,N) (30,N)", |
| 158 RunAdapterTest(buffer_queue)); | 159 RunAdapterTest(buffer_queue)); |
| 159 } | 160 } |
| 160 | 161 |
| 161 TEST_F(EsAdapterVideoTest, LeadingFramesWithNoTimestamp) { | 162 TEST_F(EsAdapterVideoTest, LeadingFramesWithNoTimestamp) { |
| 162 int pts_ms[] = {-1, -1, 50, 120, 150, 180}; | 163 int pts_ms[] = {-1, -1, 50, 120, 150, 180}; |
| 163 bool is_key_frame[] = {false, false, false, true, false, false}; | 164 bool is_key_frame[] = {false, false, false, true, false, false}; |
| 164 StreamParserBuffer::BufferQueue buffer_queue = | 165 BufferQueue buffer_queue = |
| 165 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); | 166 GenerateFakeBuffers(pts_ms, is_key_frame, arraysize(pts_ms)); |
| 166 | 167 |
| 167 EXPECT_EQ("(70,Y) (30,Y) (30,N) (30,N)", | 168 EXPECT_EQ("(70,Y) (30,Y) (30,N) (30,N)", |
| 168 RunAdapterTest(buffer_queue)); | 169 RunAdapterTest(buffer_queue)); |
| 169 } | 170 } |
| 170 | 171 |
| 171 } // namespace mp2t | 172 } // namespace mp2t |
| 172 } // namespace media | 173 } // namespace media |
| OLD | NEW |