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

Side by Side Diff: media/filters/chunk_demuxer.cc

Issue 110693007: Fix various operations in ChunkDemuxer that were not being applied to text tracks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/filters/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 #include <limits> 9 #include <limits>
10 #include <list> 10 #include <list>
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 const NewTextTrackCB& new_text_track_cb); 107 const NewTextTrackCB& new_text_track_cb);
108 108
109 // Appends new data to the StreamParser. 109 // Appends new data to the StreamParser.
110 // Returns true if the data was successfully appended. Returns false if an 110 // Returns true if the data was successfully appended. Returns false if an
111 // error occurred. 111 // error occurred.
112 bool Append(const uint8* data, size_t length); 112 bool Append(const uint8* data, size_t length);
113 113
114 // Aborts the current append sequence and resets the parser. 114 // Aborts the current append sequence and resets the parser.
115 void Abort(); 115 void Abort();
116 116
117 // Calls Remove(|start|, |end|, |duration|) on all
118 // ChunkDemuxerStreams managed by this object.
119 void Remove(base::TimeDelta start, base::TimeDelta end,
120 base::TimeDelta duration);
xhwang 2013/12/28 01:06:03 Here and in this file, pass base::TimeDelta by con
acolwell GONE FROM CHROMIUM 2013/12/28 02:17:10 I've talked with scherkus@ and fischman@ about thi
xhwang 2013/12/30 17:53:38 sg. thanks for the explanation.
121
117 // Sets |timestamp_offset_| if possible. 122 // Sets |timestamp_offset_| if possible.
118 // Returns if the offset was set. Returns false if the offset could not be 123 // Returns if the offset was set. Returns false if the offset could not be
119 // updated at this time. 124 // updated at this time.
120 bool SetTimestampOffset(TimeDelta timestamp_offset); 125 bool SetTimestampOffset(TimeDelta timestamp_offset);
121 126
122 TimeDelta timestamp_offset() const { return timestamp_offset_; } 127 TimeDelta timestamp_offset() const { return timestamp_offset_; }
123 128
124 void set_append_window_start(TimeDelta start) { 129 void set_append_window_start(TimeDelta start) {
125 append_window_start_ = start; 130 append_window_start_ = start;
126 } 131 }
127 void set_append_window_end(TimeDelta end) { append_window_end_ = end; } 132 void set_append_window_end(TimeDelta end) { append_window_end_ = end; }
128 133
129 // Returns the range of buffered data in this source, capped at |duration|. 134 // Returns the range of buffered data in this source, capped at |duration|.
130 // |ended| - Set to true if end of stream has been signalled and the special 135 // |ended| - Set to true if end of stream has been signalled and the special
131 // end of stream range logic needs to be executed. 136 // end of stream range logic needs to be executed.
132 Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration, bool ended) const; 137 Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration, bool ended) const;
133 138
139 // Helper methods that call methods with similar names on all the
140 // ChunkDemuxerStreams managed by this object.
134 void StartReturningData(); 141 void StartReturningData();
135 void AbortReads(); 142 void AbortReads();
136 void Seek(TimeDelta seek_time); 143 void Seek(TimeDelta seek_time);
137 void CompletePendingReadIfPossible(); 144 void CompletePendingReadIfPossible();
145 void OnSetDuration(TimeDelta duration);
146 void MarkEndOfStream();
147 void UnmarkEndOfStream();
148 void Shutdown();
149 void SetMemoryLimitsForTesting(int memory_limit);
xhwang 2013/12/28 01:06:03 Is |memory_limit| in KB or MB?
acolwell GONE FROM CHROMIUM 2014/01/08 02:16:49 It's bytes. I've added a comment clarifying this h
150 bool IsSeekWaitingForData() const;
138 151
139 private: 152 private:
140 // Called by the |stream_parser_| when a new initialization segment is 153 // Called by the |stream_parser_| when a new initialization segment is
141 // encountered. 154 // encountered.
142 // Returns true on a successful call. Returns false if an error occured while 155 // Returns true on a successful call. Returns false if an error occured while
143 // processing decoder configurations. 156 // processing decoder configurations.
144 bool OnNewConfigs(bool allow_audio, bool allow_video, 157 bool OnNewConfigs(bool allow_audio, bool allow_video,
145 const AudioDecoderConfig& audio_config, 158 const AudioDecoderConfig& audio_config,
146 const VideoDecoderConfig& video_config, 159 const VideoDecoderConfig& video_config,
147 const StreamParser::TextTrackConfigMap& text_configs); 160 const StreamParser::TextTrackConfigMap& text_configs);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 audio_(NULL), 345 audio_(NULL),
333 audio_needs_keyframe_(true), 346 audio_needs_keyframe_(true),
334 video_(NULL), 347 video_(NULL),
335 video_needs_keyframe_(true), 348 video_needs_keyframe_(true),
336 log_cb_(log_cb) { 349 log_cb_(log_cb) {
337 DCHECK(!create_demuxer_stream_cb_.is_null()); 350 DCHECK(!create_demuxer_stream_cb_.is_null());
338 DCHECK(!increase_duration_cb_.is_null()); 351 DCHECK(!increase_duration_cb_.is_null());
339 } 352 }
340 353
341 SourceState::~SourceState() { 354 SourceState::~SourceState() {
342 if (audio_) 355 Shutdown();
343 audio_->Shutdown();
344 356
345 if (video_) 357 STLDeleteValues(&text_stream_map_);
346 video_->Shutdown();
347
348 for (TextStreamMap::iterator itr = text_stream_map_.begin();
349 itr != text_stream_map_.end(); ++itr) {
350 itr->second->Shutdown();
351 delete itr->second;
352 }
353 } 358 }
354 359
355 void SourceState::Init(const StreamParser::InitCB& init_cb, 360 void SourceState::Init(const StreamParser::InitCB& init_cb,
356 bool allow_audio, 361 bool allow_audio,
357 bool allow_video, 362 bool allow_video,
358 const StreamParser::NeedKeyCB& need_key_cb, 363 const StreamParser::NeedKeyCB& need_key_cb,
359 const NewTextTrackCB& new_text_track_cb) { 364 const NewTextTrackCB& new_text_track_cb) {
360 new_text_track_cb_ = new_text_track_cb; 365 new_text_track_cb_ = new_text_track_cb;
361 366
362 StreamParser::NewTextBuffersCB new_text_buffers_cb; 367 StreamParser::NewTextBuffersCB new_text_buffers_cb;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 return stream_parser_->Parse(data, length); 399 return stream_parser_->Parse(data, length);
395 } 400 }
396 401
397 void SourceState::Abort() { 402 void SourceState::Abort() {
398 stream_parser_->Flush(); 403 stream_parser_->Flush();
399 audio_needs_keyframe_ = true; 404 audio_needs_keyframe_ = true;
400 video_needs_keyframe_ = true; 405 video_needs_keyframe_ = true;
401 can_update_offset_ = true; 406 can_update_offset_ = true;
402 } 407 }
403 408
409 void SourceState::Remove(base::TimeDelta start, base::TimeDelta end,
410 base::TimeDelta duration) {
411 if (audio_)
412 audio_->Remove(start, end, duration);
413
414 if (video_)
415 video_->Remove(start, end, duration);
416
417 for (TextStreamMap::iterator itr = text_stream_map_.begin();
418 itr != text_stream_map_.end(); ++itr) {
419 itr->second->Remove(start, end, duration);
420 }
421 }
422
404 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration, 423 Ranges<TimeDelta> SourceState::GetBufferedRanges(TimeDelta duration,
405 bool ended) const { 424 bool ended) const {
406 // TODO(acolwell): When we start allowing disabled tracks we'll need to update 425 // TODO(acolwell): When we start allowing disabled tracks we'll need to update
407 // this code to only add ranges from active tracks. 426 // this code to only add ranges from active tracks.
408 RangesList ranges_list; 427 RangesList ranges_list;
409 if (audio_) 428 if (audio_)
410 ranges_list.push_back(audio_->GetBufferedRanges(duration)); 429 ranges_list.push_back(audio_->GetBufferedRanges(duration));
411 430
412 if (video_) 431 if (video_)
413 ranges_list.push_back(video_->GetBufferedRanges(duration)); 432 ranges_list.push_back(video_->GetBufferedRanges(duration));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 485
467 if (video_) 486 if (video_)
468 video_->CompletePendingReadIfPossible(); 487 video_->CompletePendingReadIfPossible();
469 488
470 for (TextStreamMap::iterator itr = text_stream_map_.begin(); 489 for (TextStreamMap::iterator itr = text_stream_map_.begin();
471 itr != text_stream_map_.end(); ++itr) { 490 itr != text_stream_map_.end(); ++itr) {
472 itr->second->CompletePendingReadIfPossible(); 491 itr->second->CompletePendingReadIfPossible();
473 } 492 }
474 } 493 }
475 494
495 void SourceState::OnSetDuration(TimeDelta duration) {
496 if (audio_)
497 audio_->OnSetDuration(duration);
498
499 if (video_)
500 video_->OnSetDuration(duration);
501
502 for (TextStreamMap::iterator itr = text_stream_map_.begin();
503 itr != text_stream_map_.end(); ++itr) {
504 itr->second->OnSetDuration(duration);
505 }
506 }
507
508 void SourceState::MarkEndOfStream() {
509 if (audio_)
510 audio_->MarkEndOfStream();
511
512 if (video_)
513 video_->MarkEndOfStream();
514
515 for (TextStreamMap::iterator itr = text_stream_map_.begin();
516 itr != text_stream_map_.end(); ++itr) {
517 itr->second->MarkEndOfStream();
518 }
519 }
520
521 void SourceState::UnmarkEndOfStream() {
522 if (audio_)
523 audio_->UnmarkEndOfStream();
524
525 if (video_)
526 video_->UnmarkEndOfStream();
527
528 for (TextStreamMap::iterator itr = text_stream_map_.begin();
529 itr != text_stream_map_.end(); ++itr) {
530 itr->second->UnmarkEndOfStream();
531 }
532 }
533
534 void SourceState::Shutdown() {
535 if (audio_)
536 audio_->Shutdown();
537
538 if (video_)
539 video_->Shutdown();
540
541 for (TextStreamMap::iterator itr = text_stream_map_.begin();
542 itr != text_stream_map_.end(); ++itr) {
543 itr->second->Shutdown();
544 }
545 }
546
547 void SourceState::SetMemoryLimitsForTesting(int memory_limit) {
548 if (audio_)
549 audio_->set_memory_limit_for_testing(memory_limit);
550
551 if (video_)
552 video_->set_memory_limit_for_testing(memory_limit);
553
554 for (TextStreamMap::iterator itr = text_stream_map_.begin();
555 itr != text_stream_map_.end(); ++itr) {
556 itr->second->set_memory_limit_for_testing(memory_limit);
557 }
558 }
559
560 bool SourceState::IsSeekWaitingForData() const {
561 if (audio_ && audio_->IsSeekWaitingForData())
562 return true;
563
564 if (video_ && video_->IsSeekWaitingForData())
565 return true;
566
567 for (TextStreamMap::const_iterator itr = text_stream_map_.begin();
568 itr != text_stream_map_.end(); ++itr) {
569 if (itr->second->IsSeekWaitingForData())
570 return true;
571 }
572
573 return false;
574 }
575
476 void SourceState::AdjustBufferTimestamps( 576 void SourceState::AdjustBufferTimestamps(
477 const StreamParser::BufferQueue& buffers) { 577 const StreamParser::BufferQueue& buffers) {
478 if (timestamp_offset_ == TimeDelta()) 578 if (timestamp_offset_ == TimeDelta())
479 return; 579 return;
480 580
481 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); 581 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
482 itr != buffers.end(); ++itr) { 582 itr != buffers.end(); ++itr) {
483 (*itr)->SetDecodeTimestamp( 583 (*itr)->SetDecodeTimestamp(
484 (*itr)->GetDecodeTimestamp() + timestamp_offset_); 584 (*itr)->GetDecodeTimestamp() + timestamp_offset_);
485 (*itr)->set_timestamp((*itr)->timestamp() + timestamp_offset_); 585 (*itr)->set_timestamp((*itr)->timestamp() + timestamp_offset_);
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 CHECK(IsValidId(id)); 1383 CHECK(IsValidId(id));
1284 source_state_map_[id]->Abort(); 1384 source_state_map_[id]->Abort();
1285 } 1385 }
1286 1386
1287 void ChunkDemuxer::Remove(const std::string& id, base::TimeDelta start, 1387 void ChunkDemuxer::Remove(const std::string& id, base::TimeDelta start,
1288 base::TimeDelta end) { 1388 base::TimeDelta end) {
1289 DVLOG(1) << "Remove(" << id << ", " << start.InSecondsF() 1389 DVLOG(1) << "Remove(" << id << ", " << start.InSecondsF()
1290 << ", " << end.InSecondsF() << ")"; 1390 << ", " << end.InSecondsF() << ")";
1291 base::AutoLock auto_lock(lock_); 1391 base::AutoLock auto_lock(lock_);
1292 1392
1293 if (id == source_id_audio_ && audio_) 1393 DCHECK(!id.empty());
1294 audio_->Remove(start, end, duration_); 1394 CHECK(IsValidId(id));
1295 1395 source_state_map_[id]->Remove(start, end, duration_);
1296 if (id == source_id_video_ && video_)
1297 video_->Remove(start, end, duration_);
1298 } 1396 }
1299 1397
1300 double ChunkDemuxer::GetDuration() { 1398 double ChunkDemuxer::GetDuration() {
1301 base::AutoLock auto_lock(lock_); 1399 base::AutoLock auto_lock(lock_);
1302 return GetDuration_Locked(); 1400 return GetDuration_Locked();
1303 } 1401 }
1304 1402
1305 double ChunkDemuxer::GetDuration_Locked() { 1403 double ChunkDemuxer::GetDuration_Locked() {
1306 lock_.AssertAcquired(); 1404 lock_.AssertAcquired();
1307 if (duration_ == kNoTimestamp()) 1405 if (duration_ == kNoTimestamp())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 duration_td = TimeDelta::FromMicroseconds( 1443 duration_td = TimeDelta::FromMicroseconds(
1346 duration * base::Time::kMicrosecondsPerSecond); 1444 duration * base::Time::kMicrosecondsPerSecond);
1347 } 1445 }
1348 1446
1349 DCHECK(duration_td > TimeDelta()); 1447 DCHECK(duration_td > TimeDelta());
1350 1448
1351 user_specified_duration_ = duration; 1449 user_specified_duration_ = duration;
1352 duration_ = duration_td; 1450 duration_ = duration_td;
1353 host_->SetDuration(duration_); 1451 host_->SetDuration(duration_);
1354 1452
1355 if (audio_) 1453 for (SourceStateMap::iterator itr = source_state_map_.begin();
1356 audio_->OnSetDuration(duration_); 1454 itr != source_state_map_.end(); ++itr) {
1357 1455 itr->second->OnSetDuration(duration_);
1358 if (video_) 1456 }
1359 video_->OnSetDuration(duration_);
1360 } 1457 }
1361 1458
1362 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { 1459 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) {
1363 base::AutoLock auto_lock(lock_); 1460 base::AutoLock auto_lock(lock_);
1364 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; 1461 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")";
1365 CHECK(IsValidId(id)); 1462 CHECK(IsValidId(id));
1366 1463
1367 return source_state_map_[id]->SetTimestampOffset(offset); 1464 return source_state_map_[id]->SetTimestampOffset(offset);
1368 } 1465 }
1369 1466
1370 void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) { 1467 void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) {
1371 DVLOG(1) << "MarkEndOfStream(" << status << ")"; 1468 DVLOG(1) << "MarkEndOfStream(" << status << ")";
1372 base::AutoLock auto_lock(lock_); 1469 base::AutoLock auto_lock(lock_);
1373 DCHECK_NE(state_, WAITING_FOR_INIT); 1470 DCHECK_NE(state_, WAITING_FOR_INIT);
1374 DCHECK_NE(state_, ENDED); 1471 DCHECK_NE(state_, ENDED);
1375 1472
1376 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) 1473 if (state_ == SHUTDOWN || state_ == PARSE_ERROR)
1377 return; 1474 return;
1378 1475
1379 if (state_ == INITIALIZING) { 1476 if (state_ == INITIALIZING) {
1380 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1477 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1381 return; 1478 return;
1382 } 1479 }
1383 1480
1384 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); 1481 bool old_waiting_for_data = IsSeekWaitingForData_Locked();
1385 if (audio_) 1482 for (SourceStateMap::iterator itr = source_state_map_.begin();
1386 audio_->MarkEndOfStream(); 1483 itr != source_state_map_.end(); ++itr) {
1387 1484 itr->second->MarkEndOfStream();
1388 if (video_) 1485 }
1389 video_->MarkEndOfStream();
1390 1486
1391 CompletePendingReadsIfPossible(); 1487 CompletePendingReadsIfPossible();
1392 1488
1393 // Give a chance to resume the pending seek process. 1489 // Give a chance to resume the pending seek process.
1394 if (status != PIPELINE_OK) { 1490 if (status != PIPELINE_OK) {
1395 ReportError_Locked(status); 1491 ReportError_Locked(status);
1396 return; 1492 return;
1397 } 1493 }
1398 1494
1399 ChangeState_Locked(ENDED); 1495 ChangeState_Locked(ENDED);
1400 DecreaseDurationIfNecessary(); 1496 DecreaseDurationIfNecessary();
1401 1497
1402 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() && 1498 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() &&
1403 !seek_cb_.is_null()) { 1499 !seek_cb_.is_null()) {
1404 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); 1500 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
1405 } 1501 }
1406 } 1502 }
1407 1503
1408 void ChunkDemuxer::UnmarkEndOfStream() { 1504 void ChunkDemuxer::UnmarkEndOfStream() {
1409 DVLOG(1) << "UnmarkEndOfStream()"; 1505 DVLOG(1) << "UnmarkEndOfStream()";
1410 base::AutoLock auto_lock(lock_); 1506 base::AutoLock auto_lock(lock_);
1411 DCHECK_EQ(state_, ENDED); 1507 DCHECK_EQ(state_, ENDED);
1412 1508
1413 ChangeState_Locked(INITIALIZED); 1509 ChangeState_Locked(INITIALIZED);
1414 1510
1415 if (audio_) 1511 for (SourceStateMap::iterator itr = source_state_map_.begin();
1416 audio_->UnmarkEndOfStream(); 1512 itr != source_state_map_.end(); ++itr) {
1417 1513 itr->second->UnmarkEndOfStream();
1418 if (video_) 1514 }
1419 video_->UnmarkEndOfStream();
1420 } 1515 }
1421 1516
1422 void ChunkDemuxer::SetAppendWindowStart(const std::string& id, 1517 void ChunkDemuxer::SetAppendWindowStart(const std::string& id,
1423 TimeDelta start) { 1518 TimeDelta start) {
1424 base::AutoLock auto_lock(lock_); 1519 base::AutoLock auto_lock(lock_);
1425 DVLOG(1) << "SetAppendWindowStart(" << id << ", " 1520 DVLOG(1) << "SetAppendWindowStart(" << id << ", "
1426 << start.InSecondsF() << ")"; 1521 << start.InSecondsF() << ")";
1427 CHECK(IsValidId(id)); 1522 CHECK(IsValidId(id));
1428 source_state_map_[id]->set_append_window_start(start); 1523 source_state_map_[id]->set_append_window_start(start);
1429 } 1524 }
1430 1525
1431 void ChunkDemuxer::SetAppendWindowEnd(const std::string& id, TimeDelta end) { 1526 void ChunkDemuxer::SetAppendWindowEnd(const std::string& id, TimeDelta end) {
1432 base::AutoLock auto_lock(lock_); 1527 base::AutoLock auto_lock(lock_);
1433 DVLOG(1) << "SetAppendWindowEnd(" << id << ", " << end.InSecondsF() << ")"; 1528 DVLOG(1) << "SetAppendWindowEnd(" << id << ", " << end.InSecondsF() << ")";
1434 CHECK(IsValidId(id)); 1529 CHECK(IsValidId(id));
1435 source_state_map_[id]->set_append_window_end(end); 1530 source_state_map_[id]->set_append_window_end(end);
1436 } 1531 }
1437 1532
1438 void ChunkDemuxer::Shutdown() { 1533 void ChunkDemuxer::Shutdown() {
1439 DVLOG(1) << "Shutdown()"; 1534 DVLOG(1) << "Shutdown()";
1440 base::AutoLock auto_lock(lock_); 1535 base::AutoLock auto_lock(lock_);
1441 1536
1442 if (state_ == SHUTDOWN) 1537 if (state_ == SHUTDOWN)
1443 return; 1538 return;
1444 1539
1445 if (audio_) 1540 ShutdownAllStreams();
1446 audio_->Shutdown();
1447
1448 if (video_)
1449 video_->Shutdown();
1450 1541
1451 ChangeState_Locked(SHUTDOWN); 1542 ChangeState_Locked(SHUTDOWN);
1452 1543
1453 if(!seek_cb_.is_null()) 1544 if(!seek_cb_.is_null())
1454 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_ABORT); 1545 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_ABORT);
1455 } 1546 }
1456 1547
1457 void ChunkDemuxer::SetMemoryLimitsForTesting(int memory_limit) { 1548 void ChunkDemuxer::SetMemoryLimitsForTesting(int memory_limit) {
1458 if (audio_) 1549 for (SourceStateMap::iterator itr = source_state_map_.begin();
1459 audio_->set_memory_limit_for_testing(memory_limit); 1550 itr != source_state_map_.end(); ++itr) {
1460 1551 itr->second->SetMemoryLimitsForTesting(memory_limit);
1461 if (video_) 1552 }
1462 video_->set_memory_limit_for_testing(memory_limit);
1463 } 1553 }
1464 1554
1465 void ChunkDemuxer::ChangeState_Locked(State new_state) { 1555 void ChunkDemuxer::ChangeState_Locked(State new_state) {
1466 lock_.AssertAcquired(); 1556 lock_.AssertAcquired();
1467 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " 1557 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : "
1468 << state_ << " -> " << new_state; 1558 << state_ << " -> " << new_state;
1469 state_ = new_state; 1559 state_ = new_state;
1470 } 1560 }
1471 1561
1472 ChunkDemuxer::~ChunkDemuxer() { 1562 ChunkDemuxer::~ChunkDemuxer() {
1473 DCHECK_NE(state_, INITIALIZED); 1563 DCHECK_NE(state_, INITIALIZED);
1474 for (SourceStateMap::iterator it = source_state_map_.begin(); 1564
1475 it != source_state_map_.end(); ++it) { 1565 STLDeleteValues(&source_state_map_);
1476 delete it->second;
1477 }
1478 source_state_map_.clear();
1479 } 1566 }
1480 1567
1481 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { 1568 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
1482 DVLOG(1) << "ReportError_Locked(" << error << ")"; 1569 DVLOG(1) << "ReportError_Locked(" << error << ")";
1483 lock_.AssertAcquired(); 1570 lock_.AssertAcquired();
1484 DCHECK_NE(error, PIPELINE_OK); 1571 DCHECK_NE(error, PIPELINE_OK);
1485 1572
1486 ChangeState_Locked(PARSE_ERROR); 1573 ChangeState_Locked(PARSE_ERROR);
1487 1574
1488 PipelineStatusCB cb; 1575 PipelineStatusCB cb;
1489 1576
1490 if (!init_cb_.is_null()) { 1577 if (!init_cb_.is_null()) {
1491 std::swap(cb, init_cb_); 1578 std::swap(cb, init_cb_);
1492 } else { 1579 } else {
1493 if (!seek_cb_.is_null()) 1580 if (!seek_cb_.is_null())
1494 std::swap(cb, seek_cb_); 1581 std::swap(cb, seek_cb_);
1495 1582
1496 if (audio_) 1583 ShutdownAllStreams();
1497 audio_->Shutdown();
1498
1499 if (video_)
1500 video_->Shutdown();
1501 } 1584 }
1502 1585
1503 if (!cb.is_null()) { 1586 if (!cb.is_null()) {
1504 cb.Run(error); 1587 cb.Run(error);
1505 return; 1588 return;
1506 } 1589 }
1507 1590
1508 base::AutoUnlock auto_unlock(lock_); 1591 base::AutoUnlock auto_unlock(lock_);
1509 host_->OnDemuxerError(error); 1592 host_->OnDemuxerError(error);
1510 } 1593 }
1511 1594
1512 bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { 1595 bool ChunkDemuxer::IsSeekWaitingForData_Locked() const {
1513 lock_.AssertAcquired(); 1596 lock_.AssertAcquired();
1514 bool waiting_for_data = false;
1515 1597
1516 if (audio_) 1598 for (SourceStateMap::const_iterator itr = source_state_map_.begin();
1517 waiting_for_data = audio_->IsSeekWaitingForData(); 1599 itr != source_state_map_.end(); ++itr) {
1600 if (itr->second->IsSeekWaitingForData())
1601 return true;
1602 }
1518 1603
1519 if (!waiting_for_data && video_) 1604 return false;
1520 waiting_for_data = video_->IsSeekWaitingForData();
1521
1522 return waiting_for_data;
1523 } 1605 }
1524 1606
1525 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) { 1607 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
1526 DVLOG(1) << "OnSourceInitDone(" << success << ", " 1608 DVLOG(1) << "OnSourceInitDone(" << success << ", "
1527 << duration.InSecondsF() << ")"; 1609 << duration.InSecondsF() << ")";
1528 lock_.AssertAcquired(); 1610 lock_.AssertAcquired();
1529 DCHECK_EQ(state_, INITIALIZING); 1611 DCHECK_EQ(state_, INITIALIZING);
1530 if (!success || (!audio_ && !video_)) { 1612 if (!success || (!audio_ && !video_)) {
1531 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1613 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1532 return; 1614 return;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 } 1747 }
1666 } 1748 }
1667 1749
1668 void ChunkDemuxer::CompletePendingReadsIfPossible() { 1750 void ChunkDemuxer::CompletePendingReadsIfPossible() {
1669 for (SourceStateMap::iterator itr = source_state_map_.begin(); 1751 for (SourceStateMap::iterator itr = source_state_map_.begin();
1670 itr != source_state_map_.end(); ++itr) { 1752 itr != source_state_map_.end(); ++itr) {
1671 itr->second->CompletePendingReadIfPossible(); 1753 itr->second->CompletePendingReadIfPossible();
1672 } 1754 }
1673 } 1755 }
1674 1756
1757 void ChunkDemuxer::ShutdownAllStreams() {
1758 for (SourceStateMap::iterator itr = source_state_map_.begin();
1759 itr != source_state_map_.end(); ++itr) {
1760 itr->second->Shutdown();
1761 }
1762 }
1763
1675 } // namespace media 1764 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698