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

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

Powered by Google App Engine
This is Rietveld 408576698