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

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

Issue 17408005: Refactored DecoderBuffer to use unix_hacker_style naming. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@localrefactor
Patch Set: Fixed naming error that somehow got reverted" Created 7 years, 6 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 (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 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 bool Append(const uint8* data, size_t length); 43 bool Append(const uint8* data, size_t length);
44 44
45 // Aborts the current append sequence and resets the parser. 45 // Aborts the current append sequence and resets the parser.
46 void Abort(); 46 void Abort();
47 47
48 // Sets |timestamp_offset_| if possible. 48 // Sets |timestamp_offset_| if possible.
49 // Returns if the offset was set. Returns false if the offset could not be 49 // Returns if the offset was set. Returns false if the offset could not be
50 // updated at this time. 50 // updated at this time.
51 bool SetTimestampOffset(TimeDelta timestamp_offset); 51 bool SetTimestampOffset(TimeDelta timestamp_offset);
52 52
53 TimeDelta timestamp_offset() const { return timestamp_offset_; } 53 TimeDelta GetTimestampOffset() const { return timestamp_offset_; }
scherkus (not reviewing) 2013/06/22 00:09:28 wait -- I think this needs to be what it originall
54 54
55 private: 55 private:
56 // Called by the |stream_parser_| at the beginning of a new media segment. 56 // Called by the |stream_parser_| at the beginning of a new media segment.
57 // |timestamp| is the timestamp on the first buffer in the segment. 57 // |timestamp| is the timestamp on the first buffer in the segment.
58 // It modifies the state of this object and then calls |new_segment_cb| with 58 // It modifies the state of this object and then calls |new_segment_cb| with
59 // modified version of |timestamp|. 59 // modified version of |timestamp|.
60 void OnNewMediaSegment(const StreamParser::NewMediaSegmentCB& new_segment_cb, 60 void OnNewMediaSegment(const StreamParser::NewMediaSegmentCB& new_segment_cb,
61 TimeDelta timestamp); 61 TimeDelta timestamp);
62 62
63 // Called by the |stream_parser_| at the end of a media segment. 63 // Called by the |stream_parser_| at the end of a media segment.
(...skipping 25 matching lines...) Expand all
89 // Keeps track of whether |timestamp_offset_| can be modified. 89 // Keeps track of whether |timestamp_offset_| can be modified.
90 bool can_update_offset_; 90 bool can_update_offset_;
91 91
92 // The object used to parse appended data. 92 // The object used to parse appended data.
93 scoped_ptr<StreamParser> stream_parser_; 93 scoped_ptr<StreamParser> stream_parser_;
94 94
95 DISALLOW_COPY_AND_ASSIGN(SourceState); 95 DISALLOW_COPY_AND_ASSIGN(SourceState);
96 }; 96 };
97 97
98 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser) 98 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser)
99 : can_update_offset_(true), 99 : can_update_offset_(true), stream_parser_(stream_parser.release()) {}
100 stream_parser_(stream_parser.release()) {
101 }
102 100
103 void SourceState::Init(const StreamParser::InitCB& init_cb, 101 void SourceState::Init(const StreamParser::InitCB& init_cb,
104 const StreamParser::NewConfigCB& config_cb, 102 const StreamParser::NewConfigCB& config_cb,
105 const StreamParser::NewBuffersCB& audio_cb, 103 const StreamParser::NewBuffersCB& audio_cb,
106 const StreamParser::NewBuffersCB& video_cb, 104 const StreamParser::NewBuffersCB& video_cb,
107 const StreamParser::NewTextBuffersCB& text_cb, 105 const StreamParser::NewTextBuffersCB& text_cb,
108 const StreamParser::NeedKeyCB& need_key_cb, 106 const StreamParser::NeedKeyCB& need_key_cb,
109 const AddTextTrackCB& add_text_track_cb, 107 const AddTextTrackCB& add_text_track_cb,
110 const StreamParser::NewMediaSegmentCB& new_segment_cb, 108 const StreamParser::NewMediaSegmentCB& new_segment_cb,
111 const LogCB& log_cb) { 109 const LogCB& log_cb) {
112 stream_parser_->Init(init_cb, config_cb, 110 stream_parser_->Init(
113 base::Bind(&SourceState::OnBuffers, 111 init_cb,
114 base::Unretained(this), audio_cb), 112 config_cb,
115 base::Bind(&SourceState::OnBuffers, 113 base::Bind(&SourceState::OnBuffers, base::Unretained(this), audio_cb),
116 base::Unretained(this), video_cb), 114 base::Bind(&SourceState::OnBuffers, base::Unretained(this), video_cb),
117 base::Bind(&SourceState::OnTextBuffers, 115 base::Bind(&SourceState::OnTextBuffers, base::Unretained(this), text_cb),
118 base::Unretained(this), text_cb), 116 need_key_cb,
119 need_key_cb, 117 add_text_track_cb,
120 add_text_track_cb, 118 base::Bind(&SourceState::OnNewMediaSegment,
121 base::Bind(&SourceState::OnNewMediaSegment, 119 base::Unretained(this),
122 base::Unretained(this), new_segment_cb), 120 new_segment_cb),
123 base::Bind(&SourceState::OnEndOfMediaSegment, 121 base::Bind(&SourceState::OnEndOfMediaSegment, base::Unretained(this)),
124 base::Unretained(this)), 122 log_cb);
125 log_cb);
126 } 123 }
127 124
128 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { 125 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) {
129 if (!can_update_offset_) 126 if (!can_update_offset_)
130 return false; 127 return false;
131 128
132 timestamp_offset_ = timestamp_offset; 129 timestamp_offset_ = timestamp_offset;
133 return true; 130 return true;
134 } 131 }
135 132
136 bool SourceState::Append(const uint8* data, size_t length) { 133 bool SourceState::Append(const uint8* data, size_t length) {
137 return stream_parser_->Parse(data, length); 134 return stream_parser_->Parse(data, length);
138 } 135 }
139 136
140 void SourceState::Abort() { 137 void SourceState::Abort() {
141 stream_parser_->Flush(); 138 stream_parser_->Flush();
142 can_update_offset_ = true; 139 can_update_offset_ = true;
143 } 140 }
144 141
145 void SourceState::AdjustBufferTimestamps( 142 void SourceState::AdjustBufferTimestamps(
146 const StreamParser::BufferQueue& buffers) { 143 const StreamParser::BufferQueue& buffers) {
147 if (timestamp_offset_ == TimeDelta()) 144 if (timestamp_offset_ == TimeDelta())
148 return; 145 return;
149 146
150 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); 147 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
151 itr != buffers.end(); ++itr) { 148 itr != buffers.end();
152 (*itr)->SetDecodeTimestamp( 149 ++itr) {
153 (*itr)->GetDecodeTimestamp() + timestamp_offset_); 150 (*itr)
154 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset_); 151 ->SetDecodeTimestamp((*itr)->GetDecodeTimestamp() + timestamp_offset_);
152 (*itr)->set_timestamp((*itr)->timestamp() + timestamp_offset_);
155 } 153 }
156 } 154 }
157 155
158 void SourceState::OnNewMediaSegment( 156 void SourceState::OnNewMediaSegment(
159 const StreamParser::NewMediaSegmentCB& new_segment_cb, 157 const StreamParser::NewMediaSegmentCB& new_segment_cb,
160 TimeDelta timestamp) { 158 TimeDelta timestamp) {
161 DCHECK(timestamp != kNoTimestamp()); 159 DCHECK(timestamp != kNoTimestamp());
162 DVLOG(2) << "OnNewMediaSegment(" << timestamp.InSecondsF() << ")"; 160 DVLOG(2) << "OnNewMediaSegment(" << timestamp.InSecondsF() << ")";
163 161
164 can_update_offset_ = false; 162 can_update_offset_ = false;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 272
275 mutable base::Lock lock_; 273 mutable base::Lock lock_;
276 State state_; 274 State state_;
277 ReadCBQueue read_cbs_; 275 ReadCBQueue read_cbs_;
278 276
279 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); 277 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream);
280 }; 278 };
281 279
282 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config, 280 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config,
283 const LogCB& log_cb) 281 const LogCB& log_cb)
284 : type_(AUDIO), 282 : type_(AUDIO), state_(RETURNING_DATA_FOR_READS) {
285 state_(RETURNING_DATA_FOR_READS) {
286 stream_.reset(new SourceBufferStream(audio_config, log_cb)); 283 stream_.reset(new SourceBufferStream(audio_config, log_cb));
287 } 284 }
288 285
289 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config, 286 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config,
290 const LogCB& log_cb) 287 const LogCB& log_cb)
291 : type_(VIDEO), 288 : type_(VIDEO), state_(RETURNING_DATA_FOR_READS) {
292 state_(RETURNING_DATA_FOR_READS) {
293 stream_.reset(new SourceBufferStream(video_config, log_cb)); 289 stream_.reset(new SourceBufferStream(video_config, log_cb));
294 } 290 }
295 291
296 void ChunkDemuxerStream::StartWaitingForSeek() { 292 void ChunkDemuxerStream::StartWaitingForSeek() {
297 DVLOG(1) << "ChunkDemuxerStream::StartWaitingForSeek()"; 293 DVLOG(1) << "ChunkDemuxerStream::StartWaitingForSeek()";
298 ReadCBQueue read_cbs; 294 ReadCBQueue read_cbs;
299 { 295 {
300 base::AutoLock auto_lock(lock_); 296 base::AutoLock auto_lock(lock_);
301 ChangeState_Locked(WAITING_FOR_SEEK); 297 ChangeState_Locked(WAITING_FOR_SEEK);
302 std::swap(read_cbs_, read_cbs); 298 std::swap(read_cbs_, read_cbs);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer()); 427 it->Run(DemuxerStream::kOk, StreamParserBuffer::CreateEOSBuffer());
432 } 428 }
433 429
434 // Helper function that makes sure |read_cb| runs on |message_loop_proxy|. 430 // Helper function that makes sure |read_cb| runs on |message_loop_proxy|.
435 static void RunOnMessageLoop( 431 static void RunOnMessageLoop(
436 const DemuxerStream::ReadCB& read_cb, 432 const DemuxerStream::ReadCB& read_cb,
437 const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, 433 const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
438 DemuxerStream::Status status, 434 DemuxerStream::Status status,
439 const scoped_refptr<DecoderBuffer>& buffer) { 435 const scoped_refptr<DecoderBuffer>& buffer) {
440 if (!message_loop_proxy->BelongsToCurrentThread()) { 436 if (!message_loop_proxy->BelongsToCurrentThread()) {
441 message_loop_proxy->PostTask(FROM_HERE, base::Bind( 437 message_loop_proxy->PostTask(
442 &RunOnMessageLoop, read_cb, message_loop_proxy, status, buffer)); 438 FROM_HERE,
439 base::Bind(
440 &RunOnMessageLoop, read_cb, message_loop_proxy, status, buffer));
443 return; 441 return;
444 } 442 }
445 443
446 read_cb.Run(status, buffer); 444 read_cb.Run(status, buffer);
447 } 445 }
448 446
449 // DemuxerStream methods. 447 // DemuxerStream methods.
450 void ChunkDemuxerStream::Read(const ReadCB& read_cb) { 448 void ChunkDemuxerStream::Read(const ReadCB& read_cb) {
451 DemuxerStream::Status status = kOk; 449 DemuxerStream::Status status = kOk;
452 scoped_refptr<StreamParserBuffer> buffer; 450 scoped_refptr<StreamParserBuffer> buffer;
453 { 451 {
454 base::AutoLock auto_lock(lock_); 452 base::AutoLock auto_lock(lock_);
455 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) { 453 if (!read_cbs_.empty() || !GetNextBuffer_Locked(&status, &buffer)) {
456 DeferRead_Locked(read_cb); 454 DeferRead_Locked(read_cb);
457 return; 455 return;
458 } 456 }
459 } 457 }
460 458
461 base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( 459 base::MessageLoopProxy::current()->PostTask(
462 read_cb, status, buffer)); 460 FROM_HERE, base::Bind(read_cb, status, buffer));
463 } 461 }
464 462
465 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } 463 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; }
466 464
467 void ChunkDemuxerStream::EnableBitstreamConverter() {} 465 void ChunkDemuxerStream::EnableBitstreamConverter() {}
468 466
469 AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() { 467 AudioDecoderConfig ChunkDemuxerStream::audio_decoder_config() {
470 CHECK_EQ(type_, AUDIO); 468 CHECK_EQ(type_, AUDIO);
471 base::AutoLock auto_lock(lock_); 469 base::AutoLock auto_lock(lock_);
472 return stream_->GetCurrentAudioDecoderConfig(); 470 return stream_->GetCurrentAudioDecoderConfig();
473 } 471 }
474 472
475 VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() { 473 VideoDecoderConfig ChunkDemuxerStream::video_decoder_config() {
476 CHECK_EQ(type_, VIDEO); 474 CHECK_EQ(type_, VIDEO);
477 base::AutoLock auto_lock(lock_); 475 base::AutoLock auto_lock(lock_);
478 return stream_->GetCurrentVideoDecoderConfig(); 476 return stream_->GetCurrentVideoDecoderConfig();
479 } 477 }
480 478
481 void ChunkDemuxerStream::ChangeState_Locked(State state) { 479 void ChunkDemuxerStream::ChangeState_Locked(State state) {
482 lock_.AssertAcquired(); 480 lock_.AssertAcquired();
483 DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : " 481 DVLOG(1) << "ChunkDemuxerStream::ChangeState_Locked() : "
484 << "type " << type_ 482 << "type " << type_ << " - " << state_ << " -> " << state;
485 << " - " << state_ << " -> " << state;
486 state_ = state; 483 state_ = state;
487 } 484 }
488 485
489 ChunkDemuxerStream::~ChunkDemuxerStream() {} 486 ChunkDemuxerStream::~ChunkDemuxerStream() {}
490 487
491 void ChunkDemuxerStream::DeferRead_Locked(const ReadCB& read_cb) { 488 void ChunkDemuxerStream::DeferRead_Locked(const ReadCB& read_cb) {
492 lock_.AssertAcquired(); 489 lock_.AssertAcquired();
493 // Wrap & store |read_cb| so that it will 490 // Wrap & store |read_cb| so that it will
494 // get called on the current MessageLoop. 491 // get called on the current MessageLoop.
495 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb, 492 read_cbs_.push_back(base::Bind(
496 base::MessageLoopProxy::current())); 493 &RunOnMessageLoop, read_cb, base::MessageLoopProxy::current()));
497 } 494 }
498 495
499 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) { 496 void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) {
500 lock_.AssertAcquired(); 497 lock_.AssertAcquired();
501 498
502 if (state_ != RETURNING_DATA_FOR_READS) 499 if (state_ != RETURNING_DATA_FOR_READS)
503 return; 500 return;
504 501
505 DemuxerStream::Status status; 502 DemuxerStream::Status status;
506 scoped_refptr<StreamParserBuffer> buffer; 503 scoped_refptr<StreamParserBuffer> buffer;
507 while (!read_cbs_.empty()) { 504 while (!read_cbs_.empty()) {
508 if (!GetNextBuffer_Locked(&status, &buffer)) 505 if (!GetNextBuffer_Locked(&status, &buffer))
509 return; 506 return;
510 closures->push_back(base::Bind(read_cbs_.front(), 507 closures->push_back(base::Bind(read_cbs_.front(), status, buffer));
511 status, buffer));
512 read_cbs_.pop_front(); 508 read_cbs_.pop_front();
513 } 509 }
514 } 510 }
515 511
516 bool ChunkDemuxerStream::GetNextBuffer_Locked( 512 bool ChunkDemuxerStream::GetNextBuffer_Locked(
517 DemuxerStream::Status* status, 513 DemuxerStream::Status* status,
518 scoped_refptr<StreamParserBuffer>* buffer) { 514 scoped_refptr<StreamParserBuffer>* buffer) {
519 lock_.AssertAcquired(); 515 lock_.AssertAcquired();
520 516
521 switch (state_) { 517 switch (state_) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 DCHECK(!open_cb_.is_null()); 568 DCHECK(!open_cb_.is_null());
573 DCHECK(!need_key_cb_.is_null()); 569 DCHECK(!need_key_cb_.is_null());
574 } 570 }
575 571
576 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { 572 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) {
577 DVLOG(1) << "Init()"; 573 DVLOG(1) << "Init()";
578 574
579 base::AutoLock auto_lock(lock_); 575 base::AutoLock auto_lock(lock_);
580 576
581 if (state_ == SHUTDOWN) { 577 if (state_ == SHUTDOWN) {
582 base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( 578 base::MessageLoopProxy::current()->PostTask(
583 cb, DEMUXER_ERROR_COULD_NOT_OPEN)); 579 FROM_HERE, base::Bind(cb, DEMUXER_ERROR_COULD_NOT_OPEN));
584 return; 580 return;
585 } 581 }
586 DCHECK_EQ(state_, WAITING_FOR_INIT); 582 DCHECK_EQ(state_, WAITING_FOR_INIT);
587 host_ = host; 583 host_ = host;
588 584
589 ChangeState_Locked(INITIALIZING); 585 ChangeState_Locked(INITIALIZING);
590 init_cb_ = cb; 586 init_cb_ = cb;
591 587
592 base::ResetAndReturn(&open_cb_).Run(); 588 base::ResetAndReturn(&open_cb_).Run();
593 } 589 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 base::AutoLock auto_lock(lock_); 634 base::AutoLock auto_lock(lock_);
639 if (type == DemuxerStream::VIDEO) 635 if (type == DemuxerStream::VIDEO)
640 return video_.get(); 636 return video_.get();
641 637
642 if (type == DemuxerStream::AUDIO) 638 if (type == DemuxerStream::AUDIO)
643 return audio_.get(); 639 return audio_.get();
644 640
645 return NULL; 641 return NULL;
646 } 642 }
647 643
648 TimeDelta ChunkDemuxer::GetStartTime() const { 644 TimeDelta ChunkDemuxer::GetStartTime() const { return TimeDelta(); }
649 return TimeDelta();
650 }
651 645
652 void ChunkDemuxer::StartWaitingForSeek() { 646 void ChunkDemuxer::StartWaitingForSeek() {
653 DVLOG(1) << "StartWaitingForSeek()"; 647 DVLOG(1) << "StartWaitingForSeek()";
654 base::AutoLock auto_lock(lock_); 648 base::AutoLock auto_lock(lock_);
655 DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN); 649 DCHECK(state_ == INITIALIZED || state_ == ENDED || state_ == SHUTDOWN);
656 650
657 if (state_ == SHUTDOWN) 651 if (state_ == SHUTDOWN)
658 return; 652 return;
659 653
660 if (audio_) 654 if (audio_)
(...skipping 25 matching lines...) Expand all
686 const std::string& type, 680 const std::string& type,
687 std::vector<std::string>& codecs) { 681 std::vector<std::string>& codecs) {
688 DCHECK_GT(codecs.size(), 0u); 682 DCHECK_GT(codecs.size(), 0u);
689 base::AutoLock auto_lock(lock_); 683 base::AutoLock auto_lock(lock_);
690 684
691 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id)) 685 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id))
692 return kReachedIdLimit; 686 return kReachedIdLimit;
693 687
694 bool has_audio = false; 688 bool has_audio = false;
695 bool has_video = false; 689 bool has_video = false;
696 scoped_ptr<media::StreamParser> stream_parser( 690 scoped_ptr<media::StreamParser> stream_parser(StreamParserFactory::Create(
697 StreamParserFactory::Create(type, codecs, log_cb_, 691 type, codecs, log_cb_, &has_audio, &has_video));
698 &has_audio, &has_video));
699 692
700 if (!stream_parser) 693 if (!stream_parser)
701 return ChunkDemuxer::kNotSupported; 694 return ChunkDemuxer::kNotSupported;
702 695
703 if ((has_audio && !source_id_audio_.empty()) || 696 if ((has_audio && !source_id_audio_.empty()) ||
704 (has_video && !source_id_video_.empty())) 697 (has_video && !source_id_video_.empty()))
705 return kReachedIdLimit; 698 return kReachedIdLimit;
706 699
707 StreamParser::NewBuffersCB audio_cb; 700 StreamParser::NewBuffersCB audio_cb;
708 StreamParser::NewBuffersCB video_cb; 701 StreamParser::NewBuffersCB video_cb;
709 702
710 if (has_audio) { 703 if (has_audio) {
711 source_id_audio_ = id; 704 source_id_audio_ = id;
712 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, 705 audio_cb =
713 base::Unretained(this)); 706 base::Bind(&ChunkDemuxer::OnAudioBuffers, base::Unretained(this));
714 } 707 }
715 708
716 if (has_video) { 709 if (has_video) {
717 source_id_video_ = id; 710 source_id_video_ = id;
718 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers, 711 video_cb =
719 base::Unretained(this)); 712 base::Bind(&ChunkDemuxer::OnVideoBuffers, base::Unretained(this));
720 } 713 }
721 714
722 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass())); 715 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass()));
723 source_state->Init( 716 source_state->Init(
724 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), 717 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)),
725 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), 718 base::Bind(&ChunkDemuxer::OnNewConfigs,
726 has_audio, has_video), 719 base::Unretained(this),
720 has_audio,
721 has_video),
727 audio_cb, 722 audio_cb,
728 video_cb, 723 video_cb,
729 base::Bind(&ChunkDemuxer::OnTextBuffers, base::Unretained(this)), 724 base::Bind(&ChunkDemuxer::OnTextBuffers, base::Unretained(this)),
730 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), 725 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)),
731 add_text_track_cb_, 726 add_text_track_cb_,
732 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), 727 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id),
733 log_cb_); 728 log_cb_);
734 729
735 source_state_map_[id] = source_state.release(); 730 source_state_map_[id] = source_state.release();
736 return kOk; 731 return kOk;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 // the streams have slightly different lengths. 788 // the streams have slightly different lengths.
794 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1); 789 TimeDelta audio_start = audio_ranges.start(audio_ranges.size() - 1);
795 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1); 790 TimeDelta audio_end = audio_ranges.end(audio_ranges.size() - 1);
796 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1); 791 TimeDelta video_start = video_ranges.start(video_ranges.size() - 1);
797 TimeDelta video_end = video_ranges.end(video_ranges.size() - 1); 792 TimeDelta video_end = video_ranges.end(video_ranges.size() - 1);
798 793
799 // Verify the last audio range overlaps with the last video range. 794 // Verify the last audio range overlaps with the last video range.
800 // This is enforced by the logic that controls the transition to ENDED. 795 // This is enforced by the logic that controls the transition to ENDED.
801 DCHECK((audio_start <= video_start && video_start <= audio_end) || 796 DCHECK((audio_start <= video_start && video_start <= audio_end) ||
802 (video_start <= audio_start && audio_start <= video_end)); 797 (video_start <= audio_start && audio_start <= video_end));
803 result.Add(result.end(result.size()-1), std::max(audio_end, video_end)); 798 result.Add(result.end(result.size() - 1), std::max(audio_end, video_end));
804 } 799 }
805 800
806 return result; 801 return result;
807 } 802 }
808 803
809 void ChunkDemuxer::AppendData(const std::string& id, 804 void ChunkDemuxer::AppendData(const std::string& id,
810 const uint8* data, 805 const uint8* data,
811 size_t length) { 806 size_t length) {
812 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 807 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
813 808
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 1014
1020 ChangeState_Locked(SHUTDOWN); 1015 ChangeState_Locked(SHUTDOWN);
1021 } 1016 }
1022 1017
1023 if (!cb.is_null()) 1018 if (!cb.is_null())
1024 cb.Run(PIPELINE_ERROR_ABORT); 1019 cb.Run(PIPELINE_ERROR_ABORT);
1025 } 1020 }
1026 1021
1027 void ChunkDemuxer::ChangeState_Locked(State new_state) { 1022 void ChunkDemuxer::ChangeState_Locked(State new_state) {
1028 lock_.AssertAcquired(); 1023 lock_.AssertAcquired();
1029 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " 1024 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " << state_ << " -> "
1030 << state_ << " -> " << new_state; 1025 << new_state;
1031 state_ = new_state; 1026 state_ = new_state;
1032 } 1027 }
1033 1028
1034 ChunkDemuxer::~ChunkDemuxer() { 1029 ChunkDemuxer::~ChunkDemuxer() {
1035 DCHECK_NE(state_, INITIALIZED); 1030 DCHECK_NE(state_, INITIALIZED);
1036 for (SourceStateMap::iterator it = source_state_map_.begin(); 1031 for (SourceStateMap::iterator it = source_state_map_.begin();
1037 it != source_state_map_.end(); ++it) { 1032 it != source_state_map_.end();
1033 ++it) {
1038 delete it->second; 1034 delete it->second;
1039 } 1035 }
1040 source_state_map_.clear(); 1036 source_state_map_.clear();
1041 } 1037 }
1042 1038
1043 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { 1039 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
1044 DVLOG(1) << "ReportError_Locked(" << error << ")"; 1040 DVLOG(1) << "ReportError_Locked(" << error << ")";
1045 lock_.AssertAcquired(); 1041 lock_.AssertAcquired();
1046 DCHECK_NE(error, PIPELINE_OK); 1042 DCHECK_NE(error, PIPELINE_OK);
1047 1043
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 if (audio_) 1075 if (audio_)
1080 seek_pending = audio_->IsSeekPending(); 1076 seek_pending = audio_->IsSeekPending();
1081 1077
1082 if (!seek_pending && video_) 1078 if (!seek_pending && video_)
1083 seek_pending = video_->IsSeekPending(); 1079 seek_pending = video_->IsSeekPending();
1084 1080
1085 return seek_pending; 1081 return seek_pending;
1086 } 1082 }
1087 1083
1088 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) { 1084 void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
1089 DVLOG(1) << "OnSourceInitDone(" << success << ", " 1085 DVLOG(1) << "OnSourceInitDone(" << success << ", " << duration.InSecondsF()
1090 << duration.InSecondsF() << ")"; 1086 << ")";
1091 lock_.AssertAcquired(); 1087 lock_.AssertAcquired();
1092 DCHECK_EQ(state_, INITIALIZING); 1088 DCHECK_EQ(state_, INITIALIZING);
1093 if (!success || (!audio_ && !video_)) { 1089 if (!success || (!audio_ && !video_)) {
1094 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1090 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1095 return; 1091 return;
1096 } 1092 }
1097 1093
1098 if (duration != base::TimeDelta() && duration_ == kNoTimestamp()) 1094 if (duration != base::TimeDelta() && duration_ == kNoTimestamp())
1099 UpdateDuration(duration); 1095 UpdateDuration(duration);
1100 1096
1101 // Wait until all streams have initialized. 1097 // Wait until all streams have initialized.
1102 if ((!source_id_audio_.empty() && !audio_) || 1098 if ((!source_id_audio_.empty() && !audio_) ||
1103 (!source_id_video_.empty() && !video_)) 1099 (!source_id_video_.empty() && !video_))
1104 return; 1100 return;
1105 1101
1106 if (audio_) 1102 if (audio_)
1107 audio_->Seek(TimeDelta()); 1103 audio_->Seek(TimeDelta());
1108 1104
1109 if (video_) 1105 if (video_)
1110 video_->Seek(TimeDelta()); 1106 video_->Seek(TimeDelta());
1111 1107
1112 if (duration_ == kNoTimestamp()) 1108 if (duration_ == kNoTimestamp())
1113 duration_ = kInfiniteDuration(); 1109 duration_ = kInfiniteDuration();
1114 1110
1115 // The demuxer is now initialized after the |start_timestamp_| was set. 1111 // The demuxer is now initialized after the |start_timestamp_| was set.
1116 ChangeState_Locked(INITIALIZED); 1112 ChangeState_Locked(INITIALIZED);
1117 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 1113 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
1118 } 1114 }
1119 1115
1120 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, 1116 bool ChunkDemuxer::OnNewConfigs(bool has_audio,
1117 bool has_video,
1121 const AudioDecoderConfig& audio_config, 1118 const AudioDecoderConfig& audio_config,
1122 const VideoDecoderConfig& video_config) { 1119 const VideoDecoderConfig& video_config) {
1123 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video 1120 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video << ", "
1124 << ", " << audio_config.IsValidConfig() 1121 << audio_config.IsValidConfig() << ", "
1125 << ", " << video_config.IsValidConfig() << ")"; 1122 << video_config.IsValidConfig() << ")";
1126 lock_.AssertAcquired(); 1123 lock_.AssertAcquired();
1127 1124
1128 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) { 1125 if (!audio_config.IsValidConfig() && !video_config.IsValidConfig()) {
1129 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!"; 1126 DVLOG(1) << "OnNewConfigs() : Audio & video config are not valid!";
1130 return false; 1127 return false;
1131 } 1128 }
1132 1129
1133 // Signal an error if we get configuration info for stream types that weren't 1130 // Signal an error if we get configuration info for stream types that weren't
1134 // specified in AddId() or more configs after a stream is initialized. 1131 // specified in AddId() or more configs after a stream is initialized.
1135 // Only allow a single audio config for now. 1132 // Only allow a single audio config for now.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 return false; 1195 return false;
1199 1196
1200 CHECK(IsValidId(source_id_video_)); 1197 CHECK(IsValidId(source_id_video_));
1201 if (!video_->Append(buffers)) 1198 if (!video_->Append(buffers))
1202 return false; 1199 return false;
1203 1200
1204 IncreaseDurationIfNecessary(buffers, video_.get()); 1201 IncreaseDurationIfNecessary(buffers, video_.get());
1205 return true; 1202 return true;
1206 } 1203 }
1207 1204
1208 bool ChunkDemuxer::OnTextBuffers( 1205 bool ChunkDemuxer::OnTextBuffers(TextTrack* text_track,
1209 TextTrack* text_track, 1206 const StreamParser::BufferQueue& buffers) {
1210 const StreamParser::BufferQueue& buffers) {
1211 lock_.AssertAcquired(); 1207 lock_.AssertAcquired();
1212 DCHECK_NE(state_, SHUTDOWN); 1208 DCHECK_NE(state_, SHUTDOWN);
1213 1209
1214 // TODO(matthewjheaney): IncreaseDurationIfNecessary 1210 // TODO(matthewjheaney): IncreaseDurationIfNecessary
1215 1211
1216 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); 1212 for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
1217 itr != buffers.end(); ++itr) { 1213 itr != buffers.end();
1214 ++itr) {
1218 const StreamParserBuffer* const buffer = itr->get(); 1215 const StreamParserBuffer* const buffer = itr->get();
1219 const base::TimeDelta start = buffer->GetTimestamp(); 1216 const base::TimeDelta start = buffer->timestamp();
1220 const base::TimeDelta end = start + buffer->GetDuration(); 1217 const base::TimeDelta end = start + buffer->duration();
1221 1218
1222 std::string id, settings, content; 1219 std::string id, settings, content;
1223 1220
1224 WebMWebVTTParser::Parse(buffer->GetData(), 1221 WebMWebVTTParser::Parse(
1225 buffer->GetDataSize(), 1222 buffer->data(), buffer->data_size(), &id, &settings, &content);
1226 &id, &settings, &content);
1227 1223
1228 text_track->addWebVTTCue(start, end, id, content, settings); 1224 text_track->addWebVTTCue(start, end, id, content, settings);
1229 } 1225 }
1230 1226
1231 return true; 1227 return true;
1232 } 1228 }
1233 1229
1234 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that 1230 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that
1235 // this method can be removed and need_key_cb_ can be passed directly 1231 // this method can be removed and need_key_cb_ can be passed directly
1236 // to the parser. 1232 // to the parser.
(...skipping 28 matching lines...) Expand all
1265 DCHECK(duration_ != new_duration); 1261 DCHECK(duration_ != new_duration);
1266 user_specified_duration_ = -1; 1262 user_specified_duration_ = -1;
1267 duration_ = new_duration; 1263 duration_ = new_duration;
1268 host_->SetDuration(new_duration); 1264 host_->SetDuration(new_duration);
1269 } 1265 }
1270 1266
1271 void ChunkDemuxer::IncreaseDurationIfNecessary( 1267 void ChunkDemuxer::IncreaseDurationIfNecessary(
1272 const StreamParser::BufferQueue& buffers, 1268 const StreamParser::BufferQueue& buffers,
1273 ChunkDemuxerStream* stream) { 1269 ChunkDemuxerStream* stream) {
1274 DCHECK(!buffers.empty()); 1270 DCHECK(!buffers.empty());
1275 if (buffers.back()->GetTimestamp() <= duration_) 1271 if (buffers.back()->timestamp() <= duration_)
1276 return; 1272 return;
1277 1273
1278 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration()); 1274 Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration());
1279 DCHECK_GT(ranges.size(), 0u); 1275 DCHECK_GT(ranges.size(), 0u);
1280 1276
1281 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); 1277 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1282 if (last_timestamp_buffered > duration_) 1278 if (last_timestamp_buffered > duration_)
1283 UpdateDuration(last_timestamp_buffered); 1279 UpdateDuration(last_timestamp_buffered);
1284 } 1280 }
1285 1281
1286 void ChunkDemuxer::DecreaseDurationIfNecessary() { 1282 void ChunkDemuxer::DecreaseDurationIfNecessary() {
1287 Ranges<TimeDelta> ranges = GetBufferedRanges(); 1283 Ranges<TimeDelta> ranges = GetBufferedRanges();
1288 if (ranges.size() == 0u) 1284 if (ranges.size() == 0u)
1289 return; 1285 return;
1290 1286
1291 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); 1287 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1292 if (last_timestamp_buffered < duration_) 1288 if (last_timestamp_buffered < duration_)
1293 UpdateDuration(last_timestamp_buffered); 1289 UpdateDuration(last_timestamp_buffered);
1294 } 1290 }
1295 1291
1296 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { 1292 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
1297 if (audio_ && !video_) 1293 if (audio_ && !video_)
1298 return audio_->GetBufferedRanges(duration_); 1294 return audio_->GetBufferedRanges(duration_);
1299 else if (!audio_ && video_) 1295 else if (!audio_ && video_)
1300 return video_->GetBufferedRanges(duration_); 1296 return video_->GetBufferedRanges(duration_);
1301 return ComputeIntersection(); 1297 return ComputeIntersection();
1302 } 1298 }
1303 1299
1304 } // namespace media 1300 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698