Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "media/base/audio_decoder_config.h" | 16 #include "media/base/audio_decoder_config.h" |
| 17 #include "media/base/stream_parser_buffer.h" | 17 #include "media/base/stream_parser_buffer.h" |
| 18 #include "media/base/video_decoder_config.h" | 18 #include "media/base/video_decoder_config.h" |
| 19 #include "media/filters/chunk_demuxer_client.h" | |
| 20 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) | 19 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) |
| 21 #include "media/mp4/mp4_stream_parser.h" | 20 #include "media/mp4/mp4_stream_parser.h" |
| 22 #endif | 21 #endif |
| 23 #include "media/webm/webm_stream_parser.h" | 22 #include "media/webm/webm_stream_parser.h" |
| 24 | 23 |
| 25 using base::TimeDelta; | 24 using base::TimeDelta; |
| 26 | 25 |
| 27 namespace media { | 26 namespace media { |
| 28 | 27 |
| 29 struct CodecInfo { | 28 struct CodecInfo { |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 DCHECK(read_cbs_.empty()); | 521 DCHECK(read_cbs_.empty()); |
| 523 *status = DemuxerStream::kOk; | 522 *status = DemuxerStream::kOk; |
| 524 *buffer = StreamParserBuffer::CreateEOSBuffer(); | 523 *buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 525 return true; | 524 return true; |
| 526 } | 525 } |
| 527 | 526 |
| 528 NOTREACHED(); | 527 NOTREACHED(); |
| 529 return false; | 528 return false; |
| 530 } | 529 } |
| 531 | 530 |
| 532 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 531 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, |
| 532 const NeedKeyCB& need_key_cb) | |
| 533 : state_(WAITING_FOR_INIT), | 533 : state_(WAITING_FOR_INIT), |
| 534 host_(NULL), | 534 host_(NULL), |
| 535 client_(client) { | 535 open_cb_(open_cb), |
| 536 DCHECK(client); | 536 need_key_cb_(need_key_cb) { |
| 537 DCHECK(!open_cb.is_null()); | |
|
Ami GONE FROM CHROMIUM
2012/09/12 18:45:34
s/cb/cb_/ (in general, this style makes it easier
acolwell GONE FROM CHROMIUM
2012/09/12 22:03:53
Done.
| |
| 538 DCHECK(!need_key_cb.is_null()); | |
|
Ami GONE FROM CHROMIUM
2012/09/12 18:45:34
ditto
acolwell GONE FROM CHROMIUM
2012/09/12 22:03:53
Done.
| |
| 537 } | 539 } |
| 538 | 540 |
| 539 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { | 541 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { |
| 540 DVLOG(1) << "Init()"; | 542 DVLOG(1) << "Init()"; |
| 543 base::Closure open_cb; | |
| 541 { | 544 { |
| 542 base::AutoLock auto_lock(lock_); | 545 base::AutoLock auto_lock(lock_); |
| 543 DCHECK_EQ(state_, WAITING_FOR_INIT); | 546 DCHECK_EQ(state_, WAITING_FOR_INIT); |
| 544 host_ = host; | 547 host_ = host; |
| 545 | 548 |
| 546 ChangeState_Locked(INITIALIZING); | 549 ChangeState_Locked(INITIALIZING); |
| 547 init_cb_ = cb; | 550 init_cb_ = cb; |
| 551 | |
| 552 std::swap(open_cb, open_cb_); | |
| 548 } | 553 } |
| 549 | 554 |
| 550 client_->DemuxerOpened(this); | 555 open_cb.Run(); |
|
Ami GONE FROM CHROMIUM
2012/09/12 18:45:34
Is this just good hygiene or is there a reason ope
acolwell GONE FROM CHROMIUM
2012/09/12 22:03:53
This was intended to be a good hygiene thing and w
| |
| 551 } | 556 } |
| 552 | 557 |
| 553 void ChunkDemuxer::Stop(const base::Closure& callback) { | 558 void ChunkDemuxer::Stop(const base::Closure& callback) { |
| 554 DVLOG(1) << "Stop()"; | 559 DVLOG(1) << "Stop()"; |
| 555 Shutdown(); | 560 Shutdown(); |
| 556 callback.Run(); | 561 callback.Run(); |
| 557 } | 562 } |
| 558 | 563 |
| 559 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) { | 564 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) { |
| 560 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; | 565 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 | 683 |
| 679 scoped_ptr<StreamParser> stream_parser(factory_function(codecs)); | 684 scoped_ptr<StreamParser> stream_parser(factory_function(codecs)); |
| 680 CHECK(stream_parser.get()); | 685 CHECK(stream_parser.get()); |
| 681 | 686 |
| 682 stream_parser->Init( | 687 stream_parser->Init( |
| 683 base::Bind(&ChunkDemuxer::OnStreamParserInitDone, base::Unretained(this)), | 688 base::Bind(&ChunkDemuxer::OnStreamParserInitDone, base::Unretained(this)), |
| 684 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), | 689 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), |
| 685 has_audio, has_video), | 690 has_audio, has_video), |
| 686 audio_cb, | 691 audio_cb, |
| 687 video_cb, | 692 video_cb, |
| 688 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), | 693 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), |
|
Ami GONE FROM CHROMIUM
2012/09/12 18:45:34
possible to just pass need_key_cb_ here and drop O
acolwell GONE FROM CHROMIUM
2012/09/12 22:03:53
Not yet. There is signature mismatch here that nee
| |
| 689 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), | 694 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), |
| 690 base::Bind(&ChunkDemuxer::OnEndOfMediaSegment, | 695 base::Bind(&ChunkDemuxer::OnEndOfMediaSegment, |
| 691 base::Unretained(this), id)); | 696 base::Unretained(this), id)); |
| 692 | 697 |
| 693 stream_parser_map_[id] = stream_parser.release(); | 698 stream_parser_map_[id] = stream_parser.release(); |
| 694 SourceInfo info = { base::TimeDelta(), true }; | 699 SourceInfo info = { base::TimeDelta(), true }; |
| 695 source_info_map_[id] = info; | 700 source_info_map_[id] = info; |
| 696 | 701 |
| 697 return kOk; | 702 return kOk; |
| 698 } | 703 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 907 audio_->Shutdown(); | 912 audio_->Shutdown(); |
| 908 | 913 |
| 909 if (video_) | 914 if (video_) |
| 910 video_->Shutdown(); | 915 video_->Shutdown(); |
| 911 | 916 |
| 912 ChangeState_Locked(SHUTDOWN); | 917 ChangeState_Locked(SHUTDOWN); |
| 913 } | 918 } |
| 914 | 919 |
| 915 if (!cb.is_null()) | 920 if (!cb.is_null()) |
| 916 cb.Run(PIPELINE_ERROR_ABORT); | 921 cb.Run(PIPELINE_ERROR_ABORT); |
| 917 | |
| 918 client_->DemuxerClosed(); | |
| 919 } | 922 } |
| 920 | 923 |
| 921 void ChunkDemuxer::ChangeState_Locked(State new_state) { | 924 void ChunkDemuxer::ChangeState_Locked(State new_state) { |
| 922 lock_.AssertAcquired(); | 925 lock_.AssertAcquired(); |
| 923 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " | 926 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " |
| 924 << state_ << " -> " << new_state; | 927 << state_ << " -> " << new_state; |
| 925 state_ = new_state; | 928 state_ = new_state; |
| 926 } | 929 } |
| 927 | 930 |
| 928 ChunkDemuxer::~ChunkDemuxer() { | 931 ChunkDemuxer::~ChunkDemuxer() { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 | 1100 |
| 1098 if (!video_->Append(buffers)) | 1101 if (!video_->Append(buffers)) |
| 1099 return false; | 1102 return false; |
| 1100 | 1103 |
| 1101 IncreaseDurationIfNecessary(buffers, video_); | 1104 IncreaseDurationIfNecessary(buffers, video_); |
| 1102 return true; | 1105 return true; |
| 1103 } | 1106 } |
| 1104 | 1107 |
| 1105 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, | 1108 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, |
| 1106 int init_data_size) { | 1109 int init_data_size) { |
| 1107 client_->DemuxerNeedKey(init_data.Pass(), init_data_size); | 1110 lock_.AssertAcquired(); |
| 1111 need_key_cb_.Run(init_data.Pass(), init_data_size); | |
| 1108 return true; | 1112 return true; |
| 1109 } | 1113 } |
| 1110 | 1114 |
| 1111 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, | 1115 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, |
| 1112 TimeDelta timestamp) { | 1116 TimeDelta timestamp) { |
| 1113 DCHECK(timestamp != kNoTimestamp()); | 1117 DCHECK(timestamp != kNoTimestamp()); |
| 1114 DVLOG(2) << "OnNewMediaSegment(" << source_id << ", " | 1118 DVLOG(2) << "OnNewMediaSegment(" << source_id << ", " |
| 1115 << timestamp.InSecondsF() << ")"; | 1119 << timestamp.InSecondsF() << ")"; |
| 1116 lock_.AssertAcquired(); | 1120 lock_.AssertAcquired(); |
| 1117 | 1121 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1184 | 1188 |
| 1185 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { | 1189 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { |
| 1186 if (audio_ && !video_) | 1190 if (audio_ && !video_) |
| 1187 return audio_->GetBufferedRanges(duration_); | 1191 return audio_->GetBufferedRanges(duration_); |
| 1188 else if (!audio_ && video_) | 1192 else if (!audio_ && video_) |
| 1189 return video_->GetBufferedRanges(duration_); | 1193 return video_->GetBufferedRanges(duration_); |
| 1190 return ComputeIntersection(); | 1194 return ComputeIntersection(); |
| 1191 } | 1195 } |
| 1192 | 1196 |
| 1193 } // namespace media | 1197 } // namespace media |
| OLD | NEW |