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.
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/timestamp_constants.h"
15 #include "media/base/video_decoder_config.h"
16 #include "media/formats/mp2t/es_adapter_video.h"
17 #include "testing/gtest/include/gtest/gtest.h"
24 VideoDecoderConfig
CreateFakeVideoConfig() {
25 gfx::Size
coded_size(320, 240);
26 gfx::Rect
visible_rect(0, 0, 320, 240);
27 gfx::Size
natural_size(320, 240);
28 return VideoDecoderConfig(kCodecH264
, H264PROFILE_MAIN
, PIXEL_FORMAT_I420
,
29 COLOR_SPACE_UNSPECIFIED
, coded_size
, visible_rect
,
30 natural_size
, NULL
, 0, false);
33 StreamParserBuffer::BufferQueue
34 GenerateFakeBuffers(const int* frame_pts_ms
,
35 const bool* is_key_frame
,
37 uint8 dummy_buffer
[] = {0, 0, 0, 0};
39 StreamParserBuffer::BufferQueue
buffers(frame_count
);
40 for (size_t k
= 0; k
< frame_count
; k
++) {
41 buffers
[k
] = StreamParserBuffer::CopyFrom(
42 dummy_buffer
, arraysize(dummy_buffer
),
43 is_key_frame
[k
], DemuxerStream::VIDEO
, 0);
44 if (frame_pts_ms
[k
] < 0) {
45 buffers
[k
]->set_timestamp(kNoTimestamp());
47 buffers
[k
]->set_timestamp(
48 base::TimeDelta::FromMilliseconds(frame_pts_ms
[k
]));
56 class EsAdapterVideoTest
: public testing::Test
{
61 // Feed the ES adapter with the buffers from |buffer_queue|.
62 // Return the durations computed by the ES adapter as well as
63 // whether each frame emitted by the adapter is a key frame.
64 std::string
RunAdapterTest(const StreamParser::BufferQueue
& buffer_queue
);
67 void OnNewConfig(const VideoDecoderConfig
& video_config
);
68 void OnNewBuffer(scoped_refptr
<StreamParserBuffer
> buffer
);
70 EsAdapterVideo es_adapter_
;
72 std::stringstream buffer_descriptors_
;
74 DISALLOW_COPY_AND_ASSIGN(EsAdapterVideoTest
);
77 EsAdapterVideoTest::EsAdapterVideoTest()
78 : es_adapter_(base::Bind(&EsAdapterVideoTest::OnNewConfig
,
79 base::Unretained(this)),
80 base::Bind(&EsAdapterVideoTest::OnNewBuffer
,
81 base::Unretained(this))) {
84 void EsAdapterVideoTest::OnNewConfig(const VideoDecoderConfig
& video_config
) {
87 void EsAdapterVideoTest::OnNewBuffer(
88 scoped_refptr
<StreamParserBuffer
> buffer
) {
89 buffer_descriptors_
<< "(" << buffer
->duration().InMilliseconds() << ","
90 << (buffer
->is_key_frame() ? "Y" : "N") << ") ";
93 std::string
EsAdapterVideoTest::RunAdapterTest(
94 const StreamParserBuffer::BufferQueue
& buffer_queue
) {
95 buffer_descriptors_
.clear();
97 es_adapter_
.OnConfigChanged(CreateFakeVideoConfig());
98 for (StreamParserBuffer::BufferQueue::const_iterator it
=
99 buffer_queue
.begin(); it
!= buffer_queue
.end(); ++it
) {
100 es_adapter_
.OnNewBuffer(*it
);
104 std::string s
= buffer_descriptors_
.str();
105 base::TrimWhitespaceASCII(s
, base::TRIM_ALL
, &s
);
109 TEST_F(EsAdapterVideoTest
, FrameDurationSimpleGop
) {
110 // PTS for a GOP without B frames - strictly increasing.
111 int pts_ms
[] = {30, 31, 33, 36, 40, 45, 51, 58};
112 bool is_key_frame
[] = {
113 true, false, false, false,
114 false, false, false, false };
115 StreamParserBuffer::BufferQueue buffer_queue
=
116 GenerateFakeBuffers(pts_ms
, is_key_frame
, arraysize(pts_ms
));
118 EXPECT_EQ("(1,Y) (2,N) (3,N) (4,N) (5,N) (6,N) (7,N) (7,N)",
119 RunAdapterTest(buffer_queue
));
122 TEST_F(EsAdapterVideoTest
, FrameDurationComplexGop
) {
123 // PTS for a GOP with B frames.
124 int pts_ms
[] = {30, 120, 60, 90, 210, 150, 180, 300, 240, 270};
125 bool is_key_frame
[] = {
126 true, false, false, false, false,
127 false, false, false, false, false };
128 StreamParserBuffer::BufferQueue buffer_queue
=
129 GenerateFakeBuffers(pts_ms
, is_key_frame
, arraysize(pts_ms
));
131 EXPECT_EQ("(30,Y) (30,N) (30,N) (30,N) (30,N) "
132 "(30,N) (30,N) (30,N) (30,N) (30,N)",
133 RunAdapterTest(buffer_queue
));
136 TEST_F(EsAdapterVideoTest
, LeadingNonKeyFrames
) {
137 int pts_ms
[] = {30, 40, 50, 120, 150, 180};
138 bool is_key_frame
[] = {false, false, false, true, false, false};
139 StreamParserBuffer::BufferQueue buffer_queue
=
140 GenerateFakeBuffers(pts_ms
, is_key_frame
, arraysize(pts_ms
));
142 EXPECT_EQ("(30,Y) (30,Y) (30,Y) (30,Y) (30,N) (30,N)",
143 RunAdapterTest(buffer_queue
));
146 TEST_F(EsAdapterVideoTest
, LeadingKeyFrameWithNoTimestamp
) {
147 int pts_ms
[] = {-1, 40, 50, 120, 150, 180};
148 bool is_key_frame
[] = {true, false, false, true, false, false};
149 StreamParserBuffer::BufferQueue buffer_queue
=
150 GenerateFakeBuffers(pts_ms
, is_key_frame
, arraysize(pts_ms
));
152 EXPECT_EQ("(40,Y) (40,Y) (30,Y) (30,N) (30,N)",
153 RunAdapterTest(buffer_queue
));
156 TEST_F(EsAdapterVideoTest
, LeadingFramesWithNoTimestamp
) {
157 int pts_ms
[] = {-1, -1, 50, 120, 150, 180};
158 bool is_key_frame
[] = {false, false, false, true, false, false};
159 StreamParserBuffer::BufferQueue buffer_queue
=
160 GenerateFakeBuffers(pts_ms
, is_key_frame
, arraysize(pts_ms
));
162 EXPECT_EQ("(70,Y) (30,Y) (30,N) (30,N)",
163 RunAdapterTest(buffer_queue
));