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