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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 516 } |
517 | 517 |
518 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 518 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
519 : state_(WAITING_FOR_INIT), | 519 : state_(WAITING_FOR_INIT), |
520 host_(NULL), | 520 host_(NULL), |
521 client_(client), | 521 client_(client), |
522 start_time_(kNoTimestamp()) { | 522 start_time_(kNoTimestamp()) { |
523 DCHECK(client); | 523 DCHECK(client); |
524 } | 524 } |
525 | 525 |
526 void ChunkDemuxer::Initialize(DemuxerHost* host, | 526 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { |
527 const PipelineStatusCB& cb) { | |
528 DVLOG(1) << "Init()"; | 527 DVLOG(1) << "Init()"; |
529 { | 528 { |
530 base::AutoLock auto_lock(lock_); | 529 base::AutoLock auto_lock(lock_); |
531 DCHECK_EQ(state_, WAITING_FOR_INIT); | 530 DCHECK_EQ(state_, WAITING_FOR_INIT); |
532 host_ = host; | 531 host_ = host; |
533 | 532 |
534 ChangeState_Locked(INITIALIZING); | 533 ChangeState_Locked(INITIALIZING); |
535 init_cb_ = cb; | 534 init_cb_ = cb; |
536 } | 535 } |
537 | 536 |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 789 |
791 if (audio_ && !video_) { | 790 if (audio_ && !video_) { |
792 ranges = audio_->GetBufferedRanges(); | 791 ranges = audio_->GetBufferedRanges(); |
793 } else if (!audio_ && video_) { | 792 } else if (!audio_ && video_) { |
794 ranges = video_->GetBufferedRanges(); | 793 ranges = video_->GetBufferedRanges(); |
795 } else { | 794 } else { |
796 ranges = ComputeIntersection(); | 795 ranges = ComputeIntersection(); |
797 } | 796 } |
798 } | 797 } |
799 | 798 |
| 799 if (ranges.size() > 0) { |
| 800 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); |
| 801 if (last_timestamp_buffered > duration_) |
| 802 UpdateDuration(last_timestamp_buffered); |
| 803 } |
| 804 |
800 for (size_t i = 0; i < ranges.size(); ++i) | 805 for (size_t i = 0; i < ranges.size(); ++i) |
801 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i)); | 806 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i)); |
802 | 807 |
803 if (!cb.is_null()) | 808 if (!cb.is_null()) |
804 cb.Run(PIPELINE_OK); | 809 cb.Run(PIPELINE_OK); |
805 | 810 |
806 return true; | 811 return true; |
807 } | 812 } |
808 | 813 |
809 void ChunkDemuxer::Abort(const std::string& id) { | 814 void ChunkDemuxer::Abort(const std::string& id) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 DVLOG(1) << "OnStreamParserInitDone(" << success << ", " | 966 DVLOG(1) << "OnStreamParserInitDone(" << success << ", " |
962 << duration.InSecondsF() << ")"; | 967 << duration.InSecondsF() << ")"; |
963 lock_.AssertAcquired(); | 968 lock_.AssertAcquired(); |
964 DCHECK_EQ(state_, INITIALIZING); | 969 DCHECK_EQ(state_, INITIALIZING); |
965 if (!success || (!audio_ && !video_)) { | 970 if (!success || (!audio_ && !video_)) { |
966 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | 971 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
967 return; | 972 return; |
968 } | 973 } |
969 | 974 |
970 if (duration > duration_) | 975 if (duration > duration_) |
971 duration_ = duration; | 976 UpdateDuration(duration); |
972 | 977 |
973 // Wait until all streams have initialized. | 978 // Wait until all streams have initialized. |
974 if ((!source_id_audio_.empty() && !audio_) || | 979 if ((!source_id_audio_.empty() && !audio_) || |
975 (!source_id_video_.empty() && !video_)) | 980 (!source_id_video_.empty() && !video_)) |
976 return; | 981 return; |
977 | 982 |
978 host_->SetDuration(duration_); | |
979 | |
980 ChangeState_Locked(WAITING_FOR_START_TIME); | 983 ChangeState_Locked(WAITING_FOR_START_TIME); |
981 } | 984 } |
982 | 985 |
983 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, | 986 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, |
984 const AudioDecoderConfig& audio_config, | 987 const AudioDecoderConfig& audio_config, |
985 const VideoDecoderConfig& video_config) { | 988 const VideoDecoderConfig& video_config) { |
986 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video | 989 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video |
987 << ", " << audio_config.IsValidConfig() | 990 << ", " << audio_config.IsValidConfig() |
988 << ", " << video_config.IsValidConfig() << ")"; | 991 << ", " << video_config.IsValidConfig() << ")"; |
989 CHECK(audio_config.IsValidConfig() || video_config.IsValidConfig()); | 992 CHECK(audio_config.IsValidConfig() || video_config.IsValidConfig()); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 | 1089 |
1087 if (audio_) { | 1090 if (audio_) { |
1088 audio_->SetStartTime(start_time_); | 1091 audio_->SetStartTime(start_time_); |
1089 audio_->Seek(start_time_); | 1092 audio_->Seek(start_time_); |
1090 } | 1093 } |
1091 if (video_) { | 1094 if (video_) { |
1092 video_->SetStartTime(start_time_); | 1095 video_->SetStartTime(start_time_); |
1093 video_->Seek(start_time_); | 1096 video_->Seek(start_time_); |
1094 } | 1097 } |
1095 | 1098 |
| 1099 if (start_time_ > duration_) |
| 1100 UpdateDuration(start_time_); |
| 1101 |
1096 // The demuxer is now initialized after the |start_timestamp_| was set. | 1102 // The demuxer is now initialized after the |start_timestamp_| was set. |
1097 ChangeState_Locked(INITIALIZED); | 1103 ChangeState_Locked(INITIALIZED); |
1098 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 1104 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
1099 } | 1105 } |
1100 | 1106 |
1101 void ChunkDemuxer::OnEndOfMediaSegment(const std::string& source_id) { | 1107 void ChunkDemuxer::OnEndOfMediaSegment(const std::string& source_id) { |
1102 DVLOG(2) << "OnEndOfMediaSegment(" << source_id << ")"; | 1108 DVLOG(2) << "OnEndOfMediaSegment(" << source_id << ")"; |
1103 CHECK(IsValidId(source_id)); | 1109 CHECK(IsValidId(source_id)); |
1104 source_info_map_[source_id].can_update_offset = true; | 1110 source_info_map_[source_id].can_update_offset = true; |
1105 } | 1111 } |
(...skipping 10 matching lines...) Expand all Loading... |
1116 (*itr)->GetDecodeTimestamp() + timestamp_offset); | 1122 (*itr)->GetDecodeTimestamp() + timestamp_offset); |
1117 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset); | 1123 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset); |
1118 } | 1124 } |
1119 } | 1125 } |
1120 | 1126 |
1121 bool ChunkDemuxer::IsValidId(const std::string& source_id) const { | 1127 bool ChunkDemuxer::IsValidId(const std::string& source_id) const { |
1122 return source_info_map_.count(source_id) > 0u && | 1128 return source_info_map_.count(source_id) > 0u && |
1123 stream_parser_map_.count(source_id) > 0u; | 1129 stream_parser_map_.count(source_id) > 0u; |
1124 } | 1130 } |
1125 | 1131 |
| 1132 void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) { |
| 1133 duration_ = new_duration; |
| 1134 host_->SetDuration(new_duration); |
| 1135 } |
| 1136 |
1126 } // namespace media | 1137 } // namespace media |
OLD | NEW |