1 // Copyright 2015 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.
5 #include "media/base/android/test_data_factory.h"
9 #include "base/strings/stringprintf.h"
10 #include "media/base/android/demuxer_stream_player_params.h"
11 #include "media/base/decoder_buffer.h"
12 #include "media/base/test_data_util.h"
16 DemuxerConfigs
TestDataFactory::CreateAudioConfigs(AudioCodec audio_codec
,
17 base::TimeDelta duration
) {
18 DemuxerConfigs configs
;
19 configs
.audio_codec
= audio_codec
;
20 configs
.audio_channels
= 2;
21 configs
.is_audio_encrypted
= false;
22 configs
.duration
= duration
;
24 switch (audio_codec
) {
26 configs
.audio_sampling_rate
= 44100;
27 scoped_refptr
<DecoderBuffer
> buffer
=
28 ReadTestDataFile("vorbis-extradata");
29 configs
.audio_extra_data
= std::vector
<uint8
>(
30 buffer
->data(), buffer
->data() + buffer
->data_size());
34 configs
.audio_sampling_rate
= 44100;
35 configs
.audio_extra_data
= {0x12, 0x10};
39 // Other codecs are not supported by this helper.
47 DemuxerConfigs
TestDataFactory::CreateVideoConfigs(
48 VideoCodec video_codec
,
49 base::TimeDelta duration
,
50 const gfx::Size
& video_size
) {
51 DemuxerConfigs configs
;
52 configs
.video_codec
= video_codec
;
53 configs
.video_size
= video_size
;
54 configs
.is_video_encrypted
= false;
55 configs
.duration
= duration
;
60 TestDataFactory::TestDataFactory(const char* file_name_template
,
61 base::TimeDelta duration
,
62 base::TimeDelta frame_period
)
63 : duration_(duration
),
64 frame_period_(frame_period
),
66 starvation_mode_(false),
68 LoadPackets(file_name_template
);
71 TestDataFactory::~TestDataFactory() {}
73 bool TestDataFactory::CreateChunk(DemuxerData
* chunk
, base::TimeDelta
* delay
) {
80 *delay
= base::TimeDelta();
83 HasReconfigForInterval(base::TimeDelta::FromMilliseconds(-1),
85 // Since the configs AU has to come last in the chunk the initial configs
86 // preceeding any other data has to be the only unit in the chunk.
87 AddConfiguration(chunk
);
92 for (int i
= 0; i
< 4; ++i
) {
93 chunk
->access_units
.push_back(AccessUnit());
94 AccessUnit
& unit
= chunk
->access_units
.back();
96 unit
.status
= DemuxerStream::kOk
;
97 unit
.timestamp
= regular_pts_
;
98 unit
.data
= packet_
[i
];
100 regular_pts_
+= frame_period_
;
103 if (chunk
->access_units
.back().timestamp
> duration_
) {
106 // Replace last access unit with stand-alone EOS if we exceeded duration.
107 if (!starvation_mode_
) {
108 AccessUnit
& unit
= chunk
->access_units
.back();
109 unit
.is_end_of_stream
= true;
114 // Allow for modification by subclasses.
117 // Maintain last PTS.
118 for (const AccessUnit
& unit
: chunk
->access_units
) {
119 if (last_pts_
< unit
.timestamp
&& !unit
.data
.empty())
120 last_pts_
= unit
.timestamp
;
123 // Replace last access unit with |kConfigChanged| if we have a config
124 // request for the chunk's interval.
125 base::TimeDelta new_chunk_begin_pts
= regular_pts_
;
127 // The interval is [first, last)
128 if (HasReconfigForInterval(chunk_begin_pts_
, new_chunk_begin_pts
)) {
129 eos_reached_
= false;
130 regular_pts_
-= frame_period_
;
131 chunk
->access_units
.pop_back();
132 AddConfiguration(chunk
);
134 chunk_begin_pts_
= new_chunk_begin_pts
;
140 void TestDataFactory::SeekTo(const base::TimeDelta
& seek_time
) {
141 regular_pts_
= seek_time
;
142 chunk_begin_pts_
= seek_time
;
143 last_pts_
= base::TimeDelta();
144 eos_reached_
= false;
147 void TestDataFactory::RequestInitialConfigs() {
148 reconfigs_
.insert(base::TimeDelta::FromMilliseconds(-1));
151 void TestDataFactory::RequestConfigChange(base::TimeDelta config_position
) {
152 reconfigs_
.insert(config_position
);
155 void TestDataFactory::LoadPackets(const char* file_name_template
) {
156 for (int i
= 0; i
< 4; ++i
) {
157 scoped_refptr
<DecoderBuffer
> buffer
=
158 ReadTestDataFile(base::StringPrintf(file_name_template
, i
));
159 packet_
[i
] = std::vector
<uint8
>(buffer
->data(),
160 buffer
->data() + buffer
->data_size());
164 bool TestDataFactory::HasReconfigForInterval(base::TimeDelta left
,
165 base::TimeDelta right
) const {
166 // |first| points to an element greater or equal to |left|.
167 PTSSet::const_iterator first
= reconfigs_
.lower_bound(left
);
169 // |last| points to an element greater or equal to |right|.
170 PTSSet::const_iterator last
= reconfigs_
.lower_bound(right
);
172 return std::distance(first
, last
);
175 void TestDataFactory::AddConfiguration(DemuxerData
* chunk
) {
177 chunk
->access_units
.push_back(AccessUnit());
178 AccessUnit
& unit
= chunk
->access_units
.back();
179 unit
.status
= DemuxerStream::kConfigChanged
;
181 DCHECK(chunk
->demuxer_configs
.empty());
182 chunk
->demuxer_configs
.push_back(GetConfigs());