Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: media/base/android/access_unit_queue.cc

Issue 1287423004: MediaCodecPlayer implementation (stage 5 - reconfiguration) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-cleanuptest
Patch Set: Notified another stream after the drain completed; emulated reconfig Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/android/access_unit_queue.h" 5 #include "media/base/android/access_unit_queue.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "media/base/demuxer_stream.h" 9 #include "media/base/demuxer_stream.h"
10 10
11 namespace media { 11 namespace media {
12 12
13 namespace { 13 namespace {
14 // Amount of history chunks we keep by default. The zero size means we do not 14 // Amount of history chunks we keep by default. The zero size means we do not
15 // keep chunks before the current one and the history is limited by the size 15 // keep chunks before the current one and the history is limited by the size
16 // of one chunk. 16 // of one chunk.
17 const int kDefaultHistoryChunksAmount = 0; 17 const int kDefaultHistoryChunksAmount = 0;
18 } 18 }
19 19
20 AccessUnitQueue::AccessUnitQueue() 20 AccessUnitQueue::AccessUnitQueue()
21 : index_in_chunk_(0), 21 : index_in_chunk_(0),
22 history_chunks_amount_(kDefaultHistoryChunksAmount), 22 history_chunks_amount_(kDefaultHistoryChunksAmount),
23 has_eos_(false) { 23 has_eos_(false),
24 emulate_config_changes_(false) {
24 current_chunk_ = chunks_.end(); 25 current_chunk_ = chunks_.end();
25 } 26 }
26 27
27 AccessUnitQueue::~AccessUnitQueue() { 28 AccessUnitQueue::~AccessUnitQueue() {
28 STLDeleteContainerPointers(chunks_.begin(), chunks_.end()); 29 STLDeleteContainerPointers(chunks_.begin(), chunks_.end());
29 } 30 }
30 31
31 void AccessUnitQueue::PushBack(const DemuxerData& data) { 32 void AccessUnitQueue::PushBack(const DemuxerData& data) {
32 // Media thread 33 // Media thread
33 DCHECK(!data.access_units.empty()); 34 DCHECK(!data.access_units.empty());
(...skipping 16 matching lines...) Expand all
50 DCHECK(data.demuxer_configs.size() == 1); 51 DCHECK(data.demuxer_configs.size() == 1);
51 } 52 }
52 53
53 if (unit.status == DemuxerStream::kAborted) { 54 if (unit.status == DemuxerStream::kAborted) {
54 DVLOG(1) << "AccessUnitQueue::" << __FUNCTION__ << " kAborted"; 55 DVLOG(1) << "AccessUnitQueue::" << __FUNCTION__ << " kAborted";
55 } 56 }
56 } 57 }
57 #endif 58 #endif
58 59
59 // Create the next chunk and copy data to it. 60 // Create the next chunk and copy data to it.
60 DemuxerData* chunk = new DemuxerData(data); 61 // It might be split if we emulate config changes
62 std::vector<DemuxerData*> cloned_data = CloneData(data);
63 DCHECK(!cloned_data.empty());
61 64
62 // EOS flag can only be in the last access unit. 65 // EOS flag can only be in the last access unit.
63 bool has_eos = chunk->access_units.back().is_end_of_stream; 66 bool has_eos = cloned_data.back()->access_units.back().is_end_of_stream;
64 67
65 // Append this chunk to the queue. 68 // Append this chunk to the queue.
66 base::AutoLock lock(lock_); 69 base::AutoLock lock(lock_);
67 70
68 // Ignore the input after we have received EOS. 71 // Ignore the input after we have received EOS.
69 if (has_eos_) { 72 if (has_eos_) {
70 delete chunk; 73 for (DemuxerData* chunk : cloned_data)
74 delete chunk;
75
71 return; 76 return;
72 } 77 }
73 78
74 bool was_empty = (current_chunk_ == chunks_.end()); 79 for (DemuxerData* chunk : cloned_data) {
80 bool was_empty = (current_chunk_ == chunks_.end());
75 81
76 // The container |chunks_| will own the chunk. 82 // The container |chunks_| will own the chunk.
77 chunks_.push_back(chunk); 83 chunks_.push_back(chunk);
78 84
79 // Position the current chunk. 85 // Position the current chunk.
80 if (was_empty) { 86 if (was_empty) {
81 current_chunk_ = --chunks_.end(); 87 current_chunk_ = --chunks_.end();
82 index_in_chunk_ = 0; 88 index_in_chunk_ = 0;
89 }
83 } 90 }
84 91
85 // We expect that the chunk containing EOS is the last chunk. 92 // We expect that the chunk containing EOS is the last chunk.
86 DCHECK(!has_eos_); 93 DCHECK(!has_eos_);
87 has_eos_ = has_eos; 94 has_eos_ = has_eos;
88 } 95 }
89 96
90 void AccessUnitQueue::Advance() { 97 void AccessUnitQueue::Advance() {
91 // Decoder thread 98 // Decoder thread
92 base::AutoLock lock(lock_); 99 base::AutoLock lock(lock_);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 info.front_unit = &(*current_chunk_)->access_units[index_in_chunk_]; 182 info.front_unit = &(*current_chunk_)->access_units[index_in_chunk_];
176 183
177 if (info.front_unit->status == DemuxerStream::kConfigChanged) { 184 if (info.front_unit->status == DemuxerStream::kConfigChanged) {
178 DCHECK((*current_chunk_)->demuxer_configs.size() == 1); 185 DCHECK((*current_chunk_)->demuxer_configs.size() == 1);
179 info.configs = &(*current_chunk_)->demuxer_configs[0]; 186 info.configs = &(*current_chunk_)->demuxer_configs[0];
180 } 187 }
181 } 188 }
182 return info; 189 return info;
183 } 190 }
184 191
192 void AccessUnitQueue::EmulateConfigChanges(bool value) {
193 emulate_config_changes_ = value;
194 }
195
196 void AccessUnitQueue::SetLastConfigs(const DemuxerConfigs& configs) {
197 if (emulate_config_changes_)
198 last_configs_ = configs;
199 }
200
185 void AccessUnitQueue::SetHistorySizeForTesting(size_t history_chunks_amount) { 201 void AccessUnitQueue::SetHistorySizeForTesting(size_t history_chunks_amount) {
186 history_chunks_amount_ = history_chunks_amount; 202 history_chunks_amount_ = history_chunks_amount;
187 } 203 }
188 204
205 std::vector<DemuxerData*> AccessUnitQueue::CloneData(const DemuxerData& data) {
206 if (emulate_config_changes_ &&
207 (last_configs_.audio_codec != kUnknownAudioCodec ||
208 last_configs_.video_codec != kUnknownVideoCodec)) {
209 std::vector<AccessUnit>::const_iterator begin = data.access_units.begin();
210 std::vector<AccessUnit>::const_iterator end = data.access_units.end();
211 std::vector<AccessUnit>::const_iterator key_frame;
212 for (key_frame = begin; key_frame != end; ++key_frame)
213 if (key_frame->is_key_frame)
214 break;
215
216 if (key_frame != end) {
217 std::vector<DemuxerData*> result;
218
219 result.push_back(new DemuxerData());
220 result.back()->access_units = std::vector<AccessUnit>(begin, key_frame);
221 result.back()->access_units.push_back(AccessUnit());
222 result.back()->access_units.back().status = DemuxerStream::kConfigChanged;
223 result.back()->demuxer_configs.push_back(last_configs_);
224
225 result.push_back(new DemuxerData());
226 result.back()->access_units = std::vector<AccessUnit>(key_frame, end);
227
228 return result;
229 }
230 }
231
232 return std::vector<DemuxerData*>(1, new DemuxerData(data));
233 }
234
189 int AccessUnitQueue::GetUnconsumedAccessUnitLength() const { 235 int AccessUnitQueue::GetUnconsumedAccessUnitLength() const {
190 int result = 0; 236 int result = 0;
191 DataChunkQueue::const_iterator chunk; 237 DataChunkQueue::const_iterator chunk;
192 for (chunk = current_chunk_; chunk != chunks_.end(); ++chunk) 238 for (chunk = current_chunk_; chunk != chunks_.end(); ++chunk) {
193 result += (*chunk)->access_units.size(); 239 result += (*chunk)->access_units.size();
194 240
241 // Do not count configuration changes.
242 if (!(*chunk)->demuxer_configs.empty()) {
243 DCHECK((*chunk)->demuxer_configs.size() == 1);
244 --result;
245 }
246 }
247
195 result -= index_in_chunk_; 248 result -= index_in_chunk_;
196 return result; 249 return result;
197 } 250 }
198 251
199 } // namespace media 252 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698