OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "media/base/android/test_data_factory.h" | |
6 | |
7 #include <iterator> | |
8 | |
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" | |
13 | |
14 namespace media { | |
15 | |
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; | |
23 | |
24 switch (audio_codec) { | |
25 case kCodecVorbis: { | |
26 configs.audio_sampling_rate = 44100; | |
27 scoped_refptr<DecoderBuffer> buffer = | |
28 ReadTestDataFile("vorbis-extradata"); | |
29 configs.audio_extra_data = std::vector<uint8_t>( | |
30 buffer->data(), buffer->data() + buffer->data_size()); | |
31 } break; | |
32 | |
33 case kCodecAAC: { | |
34 configs.audio_sampling_rate = 44100; | |
35 configs.audio_extra_data = {0x12, 0x10}; | |
36 } break; | |
37 | |
38 default: | |
39 // Other codecs are not supported by this helper. | |
40 NOTREACHED(); | |
41 break; | |
42 } | |
43 | |
44 return configs; | |
45 } | |
46 | |
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; | |
56 | |
57 return configs; | |
58 } | |
59 | |
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), | |
65 total_chunks_(0), | |
66 starvation_mode_(false), | |
67 eos_reached_(false) { | |
68 LoadPackets(file_name_template); | |
69 } | |
70 | |
71 TestDataFactory::~TestDataFactory() {} | |
72 | |
73 bool TestDataFactory::CreateChunk(DemuxerData* chunk, base::TimeDelta* delay) { | |
74 DCHECK(chunk); | |
75 DCHECK(delay); | |
76 | |
77 if (eos_reached_) | |
78 return false; | |
79 | |
80 *delay = base::TimeDelta(); | |
81 | |
82 if (!total_chunks_ && | |
83 HasReconfigForInterval(base::TimeDelta::FromMilliseconds(-1), | |
84 base::TimeDelta())) { | |
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); | |
88 ++total_chunks_; | |
89 return true; | |
90 } | |
91 | |
92 for (int i = 0; i < 4; ++i) { | |
93 chunk->access_units.push_back(AccessUnit()); | |
94 AccessUnit& unit = chunk->access_units.back(); | |
95 | |
96 unit.status = DemuxerStream::kOk; | |
97 unit.timestamp = regular_pts_; | |
98 unit.data = packet_[i]; | |
99 | |
100 regular_pts_ += frame_period_; | |
101 } | |
102 | |
103 if (chunk->access_units.back().timestamp > duration_) { | |
104 eos_reached_ = true; | |
105 | |
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; | |
110 unit.data.clear(); | |
111 } | |
112 } | |
113 | |
114 // Allow for modification by subclasses. | |
115 ModifyChunk(chunk); | |
116 | |
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; | |
121 } | |
122 | |
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_; | |
126 | |
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); | |
133 } | |
134 chunk_begin_pts_ = new_chunk_begin_pts; | |
135 | |
136 ++total_chunks_; | |
137 return true; | |
138 } | |
139 | |
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; | |
145 } | |
146 | |
147 void TestDataFactory::RequestInitialConfigs() { | |
148 reconfigs_.insert(base::TimeDelta::FromMilliseconds(-1)); | |
149 } | |
150 | |
151 void TestDataFactory::RequestConfigChange(base::TimeDelta config_position) { | |
152 reconfigs_.insert(config_position); | |
153 } | |
154 | |
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_t>(buffer->data(), | |
160 buffer->data() + buffer->data_size()); | |
161 } | |
162 } | |
163 | |
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); | |
168 | |
169 // |last| points to an element greater or equal to |right|. | |
170 PTSSet::const_iterator last = reconfigs_.lower_bound(right); | |
171 | |
172 return std::distance(first, last); | |
173 } | |
174 | |
175 void TestDataFactory::AddConfiguration(DemuxerData* chunk) { | |
176 DCHECK(chunk); | |
177 chunk->access_units.push_back(AccessUnit()); | |
178 AccessUnit& unit = chunk->access_units.back(); | |
179 unit.status = DemuxerStream::kConfigChanged; | |
180 | |
181 DCHECK(chunk->demuxer_configs.empty()); | |
182 chunk->demuxer_configs.push_back(GetConfigs()); | |
183 } | |
184 | |
185 } // namespace media | |
OLD | NEW |