| 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()); |
| 538 DCHECK(!need_key_cb_.is_null()); |
| 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()"; |
| 541 { | |
| 542 base::AutoLock auto_lock(lock_); | |
| 543 DCHECK_EQ(state_, WAITING_FOR_INIT); | |
| 544 host_ = host; | |
| 545 | 543 |
| 546 ChangeState_Locked(INITIALIZING); | 544 base::AutoLock auto_lock(lock_); |
| 547 init_cb_ = cb; | 545 DCHECK_EQ(state_, WAITING_FOR_INIT); |
| 548 } | 546 host_ = host; |
| 549 | 547 |
| 550 client_->DemuxerOpened(this); | 548 ChangeState_Locked(INITIALIZING); |
| 549 init_cb_ = cb; |
| 550 |
| 551 base::ResetAndReturn(&open_cb_).Run(); |
| 551 } | 552 } |
| 552 | 553 |
| 553 void ChunkDemuxer::Stop(const base::Closure& callback) { | 554 void ChunkDemuxer::Stop(const base::Closure& callback) { |
| 554 DVLOG(1) << "Stop()"; | 555 DVLOG(1) << "Stop()"; |
| 555 Shutdown(); | 556 Shutdown(); |
| 556 callback.Run(); | 557 callback.Run(); |
| 557 } | 558 } |
| 558 | 559 |
| 559 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) { | 560 void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) { |
| 560 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; | 561 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 audio_->Shutdown(); | 908 audio_->Shutdown(); |
| 908 | 909 |
| 909 if (video_) | 910 if (video_) |
| 910 video_->Shutdown(); | 911 video_->Shutdown(); |
| 911 | 912 |
| 912 ChangeState_Locked(SHUTDOWN); | 913 ChangeState_Locked(SHUTDOWN); |
| 913 } | 914 } |
| 914 | 915 |
| 915 if (!cb.is_null()) | 916 if (!cb.is_null()) |
| 916 cb.Run(PIPELINE_ERROR_ABORT); | 917 cb.Run(PIPELINE_ERROR_ABORT); |
| 917 | |
| 918 client_->DemuxerClosed(); | |
| 919 } | 918 } |
| 920 | 919 |
| 921 void ChunkDemuxer::ChangeState_Locked(State new_state) { | 920 void ChunkDemuxer::ChangeState_Locked(State new_state) { |
| 922 lock_.AssertAcquired(); | 921 lock_.AssertAcquired(); |
| 923 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " | 922 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " |
| 924 << state_ << " -> " << new_state; | 923 << state_ << " -> " << new_state; |
| 925 state_ = new_state; | 924 state_ = new_state; |
| 926 } | 925 } |
| 927 | 926 |
| 928 ChunkDemuxer::~ChunkDemuxer() { | 927 ChunkDemuxer::~ChunkDemuxer() { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 AdjustBufferTimestamps( | 1094 AdjustBufferTimestamps( |
| 1096 buffers, source_info_map_[source_id_video_].timestamp_offset); | 1095 buffers, source_info_map_[source_id_video_].timestamp_offset); |
| 1097 | 1096 |
| 1098 if (!video_->Append(buffers)) | 1097 if (!video_->Append(buffers)) |
| 1099 return false; | 1098 return false; |
| 1100 | 1099 |
| 1101 IncreaseDurationIfNecessary(buffers, video_); | 1100 IncreaseDurationIfNecessary(buffers, video_); |
| 1102 return true; | 1101 return true; |
| 1103 } | 1102 } |
| 1104 | 1103 |
| 1104 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that |
| 1105 // this method can be removed and need_key_cb_ can be passed directly |
| 1106 // to the parser. |
| 1105 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, | 1107 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, |
| 1106 int init_data_size) { | 1108 int init_data_size) { |
| 1107 client_->DemuxerNeedKey(init_data.Pass(), init_data_size); | 1109 lock_.AssertAcquired(); |
| 1110 need_key_cb_.Run(init_data.Pass(), init_data_size); |
| 1108 return true; | 1111 return true; |
| 1109 } | 1112 } |
| 1110 | 1113 |
| 1111 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, | 1114 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, |
| 1112 TimeDelta timestamp) { | 1115 TimeDelta timestamp) { |
| 1113 DCHECK(timestamp != kNoTimestamp()); | 1116 DCHECK(timestamp != kNoTimestamp()); |
| 1114 DVLOG(2) << "OnNewMediaSegment(" << source_id << ", " | 1117 DVLOG(2) << "OnNewMediaSegment(" << source_id << ", " |
| 1115 << timestamp.InSecondsF() << ")"; | 1118 << timestamp.InSecondsF() << ")"; |
| 1116 lock_.AssertAcquired(); | 1119 lock_.AssertAcquired(); |
| 1117 | 1120 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 | 1187 |
| 1185 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { | 1188 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { |
| 1186 if (audio_ && !video_) | 1189 if (audio_ && !video_) |
| 1187 return audio_->GetBufferedRanges(duration_); | 1190 return audio_->GetBufferedRanges(duration_); |
| 1188 else if (!audio_ && video_) | 1191 else if (!audio_ && video_) |
| 1189 return video_->GetBufferedRanges(duration_); | 1192 return video_->GetBufferedRanges(duration_); |
| 1190 return ComputeIntersection(); | 1193 return ComputeIntersection(); |
| 1191 } | 1194 } |
| 1192 | 1195 |
| 1193 } // namespace media | 1196 } // namespace media |
| OLD | NEW |