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