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 <limits> | 8 #include <limits> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" |
15 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
16 #include "base/stl_util.h" | |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "media/base/audio_decoder_config.h" | 18 #include "media/base/audio_decoder_config.h" |
19 #include "media/base/bind_to_current_loop.h" | 19 #include "media/base/bind_to_current_loop.h" |
20 #include "media/base/media_tracks.h" | 20 #include "media/base/media_tracks.h" |
21 #include "media/base/mime_util.h" | 21 #include "media/base/mime_util.h" |
22 #include "media/base/stream_parser_buffer.h" | 22 #include "media/base/stream_parser_buffer.h" |
23 #include "media/base/timestamp_constants.h" | 23 #include "media/base/timestamp_constants.h" |
24 #include "media/base/video_codecs.h" | 24 #include "media/base/video_codecs.h" |
25 #include "media/base/video_decoder_config.h" | 25 #include "media/base/video_decoder_config.h" |
26 #include "media/filters/frame_processor.h" | 26 #include "media/filters/frame_processor.h" |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 std::string expected_mss_codecs = codecs; | 614 std::string expected_mss_codecs = codecs; |
615 if (codecs == "" && type == "audio/aac") | 615 if (codecs == "" && type == "audio/aac") |
616 expected_mss_codecs = "aac"; | 616 expected_mss_codecs = "aac"; |
617 if (codecs == "" && (type == "audio/mpeg" || type == "audio/mp3")) | 617 if (codecs == "" && (type == "audio/mpeg" || type == "audio/mp3")) |
618 expected_mss_codecs = "mp3"; | 618 expected_mss_codecs = "mp3"; |
619 | 619 |
620 source_state->Init( | 620 source_state->Init( |
621 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this), id), | 621 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this), id), |
622 expected_mss_codecs, encrypted_media_init_data_cb_, new_text_track_cb); | 622 expected_mss_codecs, encrypted_media_init_data_cb_, new_text_track_cb); |
623 | 623 |
624 source_state_map_[id] = source_state.release(); | 624 source_state_map_[id] = std::move(source_state); |
625 return kOk; | 625 return kOk; |
626 } | 626 } |
627 | 627 |
628 void ChunkDemuxer::SetTracksWatcher( | 628 void ChunkDemuxer::SetTracksWatcher( |
629 const std::string& id, | 629 const std::string& id, |
630 const MediaTracksUpdatedCB& tracks_updated_cb) { | 630 const MediaTracksUpdatedCB& tracks_updated_cb) { |
631 base::AutoLock auto_lock(lock_); | 631 base::AutoLock auto_lock(lock_); |
632 CHECK(IsValidId(id)); | 632 CHECK(IsValidId(id)); |
633 source_state_map_[id]->SetTracksWatcher(tracks_updated_cb); | 633 source_state_map_[id]->SetTracksWatcher(tracks_updated_cb); |
634 } | 634 } |
635 | 635 |
636 void ChunkDemuxer::RemoveId(const std::string& id) { | 636 void ChunkDemuxer::RemoveId(const std::string& id) { |
637 DVLOG(1) << __func__ << " id=" << id; | 637 DVLOG(1) << __func__ << " id=" << id; |
638 base::AutoLock auto_lock(lock_); | 638 base::AutoLock auto_lock(lock_); |
639 CHECK(IsValidId(id)); | 639 CHECK(IsValidId(id)); |
640 | 640 |
641 delete source_state_map_[id]; | |
642 source_state_map_.erase(id); | 641 source_state_map_.erase(id); |
643 pending_source_init_ids_.erase(id); | 642 pending_source_init_ids_.erase(id); |
644 // Remove demuxer streams created for this id. | 643 // Remove demuxer streams created for this id. |
645 for (const ChunkDemuxerStream* s : id_to_streams_map_[id]) { | 644 for (const ChunkDemuxerStream* s : id_to_streams_map_[id]) { |
646 bool stream_found = false; | 645 bool stream_found = false; |
647 for (size_t i = 0; i < audio_streams_.size(); ++i) { | 646 for (size_t i = 0; i < audio_streams_.size(); ++i) { |
648 if (audio_streams_[i].get() == s) { | 647 if (audio_streams_[i].get() == s) { |
649 stream_found = true; | 648 stream_found = true; |
650 removed_streams_.push_back(std::move(audio_streams_[i])); | 649 removed_streams_.push_back(std::move(audio_streams_[i])); |
651 audio_streams_.erase(audio_streams_.begin() + i); | 650 audio_streams_.erase(audio_streams_.begin() + i); |
(...skipping 12 matching lines...) Expand all Loading... |
664 } | 663 } |
665 CHECK(stream_found); | 664 CHECK(stream_found); |
666 } | 665 } |
667 id_to_streams_map_.erase(id); | 666 id_to_streams_map_.erase(id); |
668 } | 667 } |
669 | 668 |
670 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { | 669 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { |
671 base::AutoLock auto_lock(lock_); | 670 base::AutoLock auto_lock(lock_); |
672 DCHECK(!id.empty()); | 671 DCHECK(!id.empty()); |
673 | 672 |
674 MediaSourceStateMap::const_iterator itr = source_state_map_.find(id); | 673 auto itr = source_state_map_.find(id); |
675 | 674 |
676 DCHECK(itr != source_state_map_.end()); | 675 DCHECK(itr != source_state_map_.end()); |
677 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); | 676 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); |
678 } | 677 } |
679 | 678 |
680 base::TimeDelta ChunkDemuxer::GetHighestPresentationTimestamp( | 679 base::TimeDelta ChunkDemuxer::GetHighestPresentationTimestamp( |
681 const std::string& id) const { | 680 const std::string& id) const { |
682 base::AutoLock auto_lock(lock_); | 681 base::AutoLock auto_lock(lock_); |
683 DCHECK(!id.empty()); | 682 DCHECK(!id.empty()); |
684 | 683 |
685 MediaSourceStateMap::const_iterator itr = source_state_map_.find(id); | 684 auto itr = source_state_map_.find(id); |
686 | 685 |
687 DCHECK(itr != source_state_map_.end()); | 686 DCHECK(itr != source_state_map_.end()); |
688 return itr->second->GetHighestPresentationTimestamp(); | 687 return itr->second->GetHighestPresentationTimestamp(); |
689 } | 688 } |
690 | 689 |
691 void ChunkDemuxer::OnEnabledAudioTracksChanged( | 690 void ChunkDemuxer::OnEnabledAudioTracksChanged( |
692 const std::vector<MediaTrack::Id>& track_ids, | 691 const std::vector<MediaTrack::Id>& track_ids, |
693 base::TimeDelta currTime) { | 692 base::TimeDelta currTime) { |
694 base::AutoLock auto_lock(lock_); | 693 base::AutoLock auto_lock(lock_); |
695 std::set<DemuxerStream*> enabled_streams; | 694 std::set<DemuxerStream*> enabled_streams; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 << " newDataSize=" << newDataSize; | 749 << " newDataSize=" << newDataSize; |
751 base::AutoLock auto_lock(lock_); | 750 base::AutoLock auto_lock(lock_); |
752 | 751 |
753 // Note: The direct conversion from PTS to DTS is safe here, since we don't | 752 // Note: The direct conversion from PTS to DTS is safe here, since we don't |
754 // need to know currentTime precisely for GC. GC only needs to know which GOP | 753 // need to know currentTime precisely for GC. GC only needs to know which GOP |
755 // currentTime points to. | 754 // currentTime points to. |
756 DecodeTimestamp media_time_dts = | 755 DecodeTimestamp media_time_dts = |
757 DecodeTimestamp::FromPresentationTime(currentMediaTime); | 756 DecodeTimestamp::FromPresentationTime(currentMediaTime); |
758 | 757 |
759 DCHECK(!id.empty()); | 758 DCHECK(!id.empty()); |
760 MediaSourceStateMap::const_iterator itr = source_state_map_.find(id); | 759 auto itr = source_state_map_.find(id); |
761 if (itr == source_state_map_.end()) { | 760 if (itr == source_state_map_.end()) { |
762 LOG(WARNING) << __func__ << " stream " << id << " not found"; | 761 LOG(WARNING) << __func__ << " stream " << id << " not found"; |
763 return false; | 762 return false; |
764 } | 763 } |
765 return itr->second->EvictCodedFrames(media_time_dts, newDataSize); | 764 return itr->second->EvictCodedFrames(media_time_dts, newDataSize); |
766 } | 765 } |
767 | 766 |
768 bool ChunkDemuxer::AppendData(const std::string& id, | 767 bool ChunkDemuxer::AppendData(const std::string& id, |
769 const uint8_t* data, | 768 const uint8_t* data, |
770 size_t length, | 769 size_t length, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 duration_td = TimeDelta::FromMicroseconds( | 916 duration_td = TimeDelta::FromMicroseconds( |
918 duration * base::Time::kMicrosecondsPerSecond); | 917 duration * base::Time::kMicrosecondsPerSecond); |
919 } | 918 } |
920 | 919 |
921 DCHECK(duration_td > TimeDelta()); | 920 DCHECK(duration_td > TimeDelta()); |
922 | 921 |
923 user_specified_duration_ = duration; | 922 user_specified_duration_ = duration; |
924 duration_ = duration_td; | 923 duration_ = duration_td; |
925 host_->SetDuration(duration_); | 924 host_->SetDuration(duration_); |
926 | 925 |
927 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 926 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
928 itr != source_state_map_.end(); ++itr) { | 927 ++itr) { |
929 itr->second->OnSetDuration(duration_); | 928 itr->second->OnSetDuration(duration_); |
930 } | 929 } |
931 } | 930 } |
932 | 931 |
933 bool ChunkDemuxer::IsParsingMediaSegment(const std::string& id) { | 932 bool ChunkDemuxer::IsParsingMediaSegment(const std::string& id) { |
934 base::AutoLock auto_lock(lock_); | 933 base::AutoLock auto_lock(lock_); |
935 DVLOG(1) << "IsParsingMediaSegment(" << id << ")"; | 934 DVLOG(1) << "IsParsingMediaSegment(" << id << ")"; |
936 CHECK(IsValidId(id)); | 935 CHECK(IsValidId(id)); |
937 | 936 |
938 return source_state_map_[id]->parsing_media_segment(); | 937 return source_state_map_[id]->parsing_media_segment(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 | 969 |
971 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) | 970 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) |
972 return; | 971 return; |
973 | 972 |
974 if (state_ == INITIALIZING) { | 973 if (state_ == INITIALIZING) { |
975 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); | 974 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
976 return; | 975 return; |
977 } | 976 } |
978 | 977 |
979 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); | 978 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); |
980 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 979 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
981 itr != source_state_map_.end(); ++itr) { | 980 ++itr) { |
982 itr->second->MarkEndOfStream(); | 981 itr->second->MarkEndOfStream(); |
983 } | 982 } |
984 | 983 |
985 CompletePendingReadsIfPossible(); | 984 CompletePendingReadsIfPossible(); |
986 | 985 |
987 // Give a chance to resume the pending seek process. | 986 // Give a chance to resume the pending seek process. |
988 if (status != PIPELINE_OK) { | 987 if (status != PIPELINE_OK) { |
989 DCHECK(status == CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR || | 988 DCHECK(status == CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR || |
990 status == CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR); | 989 status == CHUNK_DEMUXER_ERROR_EOS_STATUS_NETWORK_ERROR); |
991 ReportError_Locked(status); | 990 ReportError_Locked(status); |
992 return; | 991 return; |
993 } | 992 } |
994 | 993 |
995 ChangeState_Locked(ENDED); | 994 ChangeState_Locked(ENDED); |
996 DecreaseDurationIfNecessary(); | 995 DecreaseDurationIfNecessary(); |
997 | 996 |
998 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() && | 997 if (old_waiting_for_data && !IsSeekWaitingForData_Locked() && |
999 !seek_cb_.is_null()) { | 998 !seek_cb_.is_null()) { |
1000 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 999 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
1001 } | 1000 } |
1002 } | 1001 } |
1003 | 1002 |
1004 void ChunkDemuxer::UnmarkEndOfStream() { | 1003 void ChunkDemuxer::UnmarkEndOfStream() { |
1005 DVLOG(1) << "UnmarkEndOfStream()"; | 1004 DVLOG(1) << "UnmarkEndOfStream()"; |
1006 base::AutoLock auto_lock(lock_); | 1005 base::AutoLock auto_lock(lock_); |
1007 DCHECK_EQ(state_, ENDED); | 1006 DCHECK_EQ(state_, ENDED); |
1008 | 1007 |
1009 ChangeState_Locked(INITIALIZED); | 1008 ChangeState_Locked(INITIALIZED); |
1010 | 1009 |
1011 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1010 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1012 itr != source_state_map_.end(); ++itr) { | 1011 ++itr) { |
1013 itr->second->UnmarkEndOfStream(); | 1012 itr->second->UnmarkEndOfStream(); |
1014 } | 1013 } |
1015 } | 1014 } |
1016 | 1015 |
1017 void ChunkDemuxer::Shutdown() { | 1016 void ChunkDemuxer::Shutdown() { |
1018 DVLOG(1) << "Shutdown()"; | 1017 DVLOG(1) << "Shutdown()"; |
1019 base::AutoLock auto_lock(lock_); | 1018 base::AutoLock auto_lock(lock_); |
1020 | 1019 |
1021 if (state_ == SHUTDOWN) | 1020 if (state_ == SHUTDOWN) |
1022 return; | 1021 return; |
1023 | 1022 |
1024 ShutdownAllStreams(); | 1023 ShutdownAllStreams(); |
1025 | 1024 |
1026 ChangeState_Locked(SHUTDOWN); | 1025 ChangeState_Locked(SHUTDOWN); |
1027 | 1026 |
1028 if (!seek_cb_.is_null()) | 1027 if (!seek_cb_.is_null()) |
1029 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_ABORT); | 1028 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_ABORT); |
1030 } | 1029 } |
1031 | 1030 |
1032 void ChunkDemuxer::SetMemoryLimitsForTest(DemuxerStream::Type type, | 1031 void ChunkDemuxer::SetMemoryLimitsForTest(DemuxerStream::Type type, |
1033 size_t memory_limit) { | 1032 size_t memory_limit) { |
1034 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1033 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1035 itr != source_state_map_.end(); ++itr) { | 1034 ++itr) { |
1036 itr->second->SetMemoryLimits(type, memory_limit); | 1035 itr->second->SetMemoryLimits(type, memory_limit); |
1037 } | 1036 } |
1038 } | 1037 } |
1039 | 1038 |
1040 void ChunkDemuxer::ChangeState_Locked(State new_state) { | 1039 void ChunkDemuxer::ChangeState_Locked(State new_state) { |
1041 lock_.AssertAcquired(); | 1040 lock_.AssertAcquired(); |
1042 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " | 1041 DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " |
1043 << state_ << " -> " << new_state; | 1042 << state_ << " -> " << new_state; |
1044 state_ = new_state; | 1043 state_ = new_state; |
1045 } | 1044 } |
1046 | 1045 |
1047 ChunkDemuxer::~ChunkDemuxer() { | 1046 ChunkDemuxer::~ChunkDemuxer() { |
1048 DCHECK_NE(state_, INITIALIZED); | 1047 DCHECK_NE(state_, INITIALIZED); |
1049 | |
1050 base::STLDeleteValues(&source_state_map_); | |
1051 } | 1048 } |
1052 | 1049 |
1053 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { | 1050 void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { |
1054 DVLOG(1) << "ReportError_Locked(" << error << ")"; | 1051 DVLOG(1) << "ReportError_Locked(" << error << ")"; |
1055 lock_.AssertAcquired(); | 1052 lock_.AssertAcquired(); |
1056 DCHECK_NE(error, PIPELINE_OK); | 1053 DCHECK_NE(error, PIPELINE_OK); |
1057 | 1054 |
1058 ChangeState_Locked(PARSE_ERROR); | 1055 ChangeState_Locked(PARSE_ERROR); |
1059 | 1056 |
1060 PipelineStatusCB cb; | 1057 PipelineStatusCB cb; |
(...skipping 11 matching lines...) Expand all Loading... |
1072 cb.Run(error); | 1069 cb.Run(error); |
1073 return; | 1070 return; |
1074 } | 1071 } |
1075 | 1072 |
1076 base::AutoUnlock auto_unlock(lock_); | 1073 base::AutoUnlock auto_unlock(lock_); |
1077 host_->OnDemuxerError(error); | 1074 host_->OnDemuxerError(error); |
1078 } | 1075 } |
1079 | 1076 |
1080 bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { | 1077 bool ChunkDemuxer::IsSeekWaitingForData_Locked() const { |
1081 lock_.AssertAcquired(); | 1078 lock_.AssertAcquired(); |
1082 for (MediaSourceStateMap::const_iterator itr = source_state_map_.begin(); | 1079 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1083 itr != source_state_map_.end(); ++itr) { | 1080 ++itr) { |
1084 if (itr->second->IsSeekWaitingForData()) | 1081 if (itr->second->IsSeekWaitingForData()) |
1085 return true; | 1082 return true; |
1086 } | 1083 } |
1087 | 1084 |
1088 return false; | 1085 return false; |
1089 } | 1086 } |
1090 | 1087 |
1091 void ChunkDemuxer::OnSourceInitDone( | 1088 void ChunkDemuxer::OnSourceInitDone( |
1092 const std::string& source_id, | 1089 const std::string& source_id, |
1093 const StreamParser::InitParameters& params) { | 1090 const StreamParser::InitParameters& params) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 ChunkDemuxerStream* ChunkDemuxer::CreateDemuxerStream( | 1165 ChunkDemuxerStream* ChunkDemuxer::CreateDemuxerStream( |
1169 const std::string& source_id, | 1166 const std::string& source_id, |
1170 DemuxerStream::Type type) { | 1167 DemuxerStream::Type type) { |
1171 // New ChunkDemuxerStreams can be created only during initialization segment | 1168 // New ChunkDemuxerStreams can be created only during initialization segment |
1172 // processing, which happens when a new chunk of data is appended and the | 1169 // processing, which happens when a new chunk of data is appended and the |
1173 // lock_ must be held by ChunkDemuxer::AppendData. | 1170 // lock_ must be held by ChunkDemuxer::AppendData. |
1174 lock_.AssertAcquired(); | 1171 lock_.AssertAcquired(); |
1175 | 1172 |
1176 MediaTrack::Id media_track_id = GenerateMediaTrackId(); | 1173 MediaTrack::Id media_track_id = GenerateMediaTrackId(); |
1177 | 1174 |
| 1175 OwnedChunkDemuxerStreamVector* owning_vector = nullptr; |
1178 switch (type) { | 1176 switch (type) { |
1179 case DemuxerStream::AUDIO: { | 1177 case DemuxerStream::AUDIO: |
1180 std::unique_ptr<ChunkDemuxerStream> audio_stream(new ChunkDemuxerStream( | 1178 owning_vector = &audio_streams_; |
1181 DemuxerStream::AUDIO, splice_frames_enabled_, media_track_id)); | 1179 break; |
1182 DCHECK(track_id_to_demux_stream_map_.find(media_track_id) == | 1180 |
1183 track_id_to_demux_stream_map_.end()); | 1181 case DemuxerStream::VIDEO: |
1184 track_id_to_demux_stream_map_[media_track_id] = audio_stream.get(); | 1182 owning_vector = &video_streams_; |
1185 id_to_streams_map_[source_id].push_back(audio_stream.get()); | 1183 break; |
1186 audio_streams_.push_back(std::move(audio_stream)); | 1184 |
1187 return audio_streams_.back().get(); | 1185 case DemuxerStream::TEXT: |
1188 } | 1186 owning_vector = &text_streams_; |
1189 case DemuxerStream::VIDEO: { | 1187 break; |
1190 std::unique_ptr<ChunkDemuxerStream> video_stream(new ChunkDemuxerStream( | 1188 |
1191 DemuxerStream::VIDEO, splice_frames_enabled_, media_track_id)); | |
1192 DCHECK(track_id_to_demux_stream_map_.find(media_track_id) == | |
1193 track_id_to_demux_stream_map_.end()); | |
1194 track_id_to_demux_stream_map_[media_track_id] = video_stream.get(); | |
1195 id_to_streams_map_[source_id].push_back(video_stream.get()); | |
1196 video_streams_.push_back(std::move(video_stream)); | |
1197 return video_streams_.back().get(); | |
1198 } | |
1199 case DemuxerStream::TEXT: { | |
1200 ChunkDemuxerStream* text_stream = new ChunkDemuxerStream( | |
1201 DemuxerStream::TEXT, splice_frames_enabled_, media_track_id); | |
1202 id_to_streams_map_[source_id].push_back(text_stream); | |
1203 return text_stream; | |
1204 } | |
1205 case DemuxerStream::UNKNOWN: | 1189 case DemuxerStream::UNKNOWN: |
1206 case DemuxerStream::NUM_TYPES: | 1190 case DemuxerStream::NUM_TYPES: |
1207 NOTREACHED(); | 1191 NOTREACHED(); |
1208 return NULL; | 1192 return nullptr; |
1209 } | 1193 } |
1210 NOTREACHED(); | 1194 |
1211 return NULL; | 1195 std::unique_ptr<ChunkDemuxerStream> stream = |
| 1196 base::MakeUnique<ChunkDemuxerStream>(type, splice_frames_enabled_, |
| 1197 media_track_id); |
| 1198 DCHECK(track_id_to_demux_stream_map_.find(media_track_id) == |
| 1199 track_id_to_demux_stream_map_.end()); |
| 1200 track_id_to_demux_stream_map_[media_track_id] = stream.get(); |
| 1201 id_to_streams_map_[source_id].push_back(stream.get()); |
| 1202 owning_vector->push_back(std::move(stream)); |
| 1203 return owning_vector->back().get(); |
1212 } | 1204 } |
1213 | 1205 |
1214 void ChunkDemuxer::OnNewTextTrack(ChunkDemuxerStream* text_stream, | 1206 void ChunkDemuxer::OnNewTextTrack(ChunkDemuxerStream* text_stream, |
1215 const TextTrackConfig& config) { | 1207 const TextTrackConfig& config) { |
1216 lock_.AssertAcquired(); | 1208 lock_.AssertAcquired(); |
1217 DCHECK_NE(state_, SHUTDOWN); | 1209 DCHECK_NE(state_, SHUTDOWN); |
1218 host_->AddTextStream(text_stream, config); | 1210 host_->AddTextStream(text_stream, config); |
1219 } | 1211 } |
1220 | 1212 |
1221 bool ChunkDemuxer::IsValidId(const std::string& source_id) const { | 1213 bool ChunkDemuxer::IsValidId(const std::string& source_id) const { |
(...skipping 26 matching lines...) Expand all Loading... |
1248 << " -> " << new_duration.InSecondsF(); | 1240 << " -> " << new_duration.InSecondsF(); |
1249 | 1241 |
1250 UpdateDuration(new_duration); | 1242 UpdateDuration(new_duration); |
1251 } | 1243 } |
1252 | 1244 |
1253 void ChunkDemuxer::DecreaseDurationIfNecessary() { | 1245 void ChunkDemuxer::DecreaseDurationIfNecessary() { |
1254 lock_.AssertAcquired(); | 1246 lock_.AssertAcquired(); |
1255 | 1247 |
1256 TimeDelta max_duration; | 1248 TimeDelta max_duration; |
1257 | 1249 |
1258 for (MediaSourceStateMap::const_iterator itr = source_state_map_.begin(); | 1250 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1259 itr != source_state_map_.end(); ++itr) { | 1251 ++itr) { |
1260 max_duration = std::max(max_duration, | 1252 max_duration = std::max(max_duration, |
1261 itr->second->GetMaxBufferedDuration()); | 1253 itr->second->GetMaxBufferedDuration()); |
1262 } | 1254 } |
1263 | 1255 |
1264 if (max_duration.is_zero()) | 1256 if (max_duration.is_zero()) |
1265 return; | 1257 return; |
1266 | 1258 |
1267 if (max_duration < duration_) | 1259 if (max_duration < duration_) |
1268 UpdateDuration(max_duration); | 1260 UpdateDuration(max_duration); |
1269 } | 1261 } |
1270 | 1262 |
1271 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { | 1263 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { |
1272 base::AutoLock auto_lock(lock_); | 1264 base::AutoLock auto_lock(lock_); |
1273 return GetBufferedRanges_Locked(); | 1265 return GetBufferedRanges_Locked(); |
1274 } | 1266 } |
1275 | 1267 |
1276 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges_Locked() const { | 1268 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges_Locked() const { |
1277 lock_.AssertAcquired(); | 1269 lock_.AssertAcquired(); |
1278 | 1270 |
1279 bool ended = state_ == ENDED; | 1271 bool ended = state_ == ENDED; |
1280 // TODO(acolwell): When we start allowing SourceBuffers that are not active, | 1272 // TODO(acolwell): When we start allowing SourceBuffers that are not active, |
1281 // we'll need to update this loop to only add ranges from active sources. | 1273 // we'll need to update this loop to only add ranges from active sources. |
1282 MediaSourceState::RangesList ranges_list; | 1274 MediaSourceState::RangesList ranges_list; |
1283 for (MediaSourceStateMap::const_iterator itr = source_state_map_.begin(); | 1275 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1284 itr != source_state_map_.end(); ++itr) { | 1276 ++itr) { |
1285 ranges_list.push_back(itr->second->GetBufferedRanges(duration_, ended)); | 1277 ranges_list.push_back(itr->second->GetBufferedRanges(duration_, ended)); |
1286 } | 1278 } |
1287 | 1279 |
1288 return MediaSourceState::ComputeRangesIntersection(ranges_list, ended); | 1280 return MediaSourceState::ComputeRangesIntersection(ranges_list, ended); |
1289 } | 1281 } |
1290 | 1282 |
1291 void ChunkDemuxer::StartReturningData() { | 1283 void ChunkDemuxer::StartReturningData() { |
1292 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1284 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1293 itr != source_state_map_.end(); ++itr) { | 1285 ++itr) { |
1294 itr->second->StartReturningData(); | 1286 itr->second->StartReturningData(); |
1295 } | 1287 } |
1296 } | 1288 } |
1297 | 1289 |
1298 void ChunkDemuxer::AbortPendingReads_Locked() { | 1290 void ChunkDemuxer::AbortPendingReads_Locked() { |
1299 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1291 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1300 itr != source_state_map_.end(); ++itr) { | 1292 ++itr) { |
1301 itr->second->AbortReads(); | 1293 itr->second->AbortReads(); |
1302 } | 1294 } |
1303 } | 1295 } |
1304 | 1296 |
1305 void ChunkDemuxer::SeekAllSources(TimeDelta seek_time) { | 1297 void ChunkDemuxer::SeekAllSources(TimeDelta seek_time) { |
1306 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1298 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1307 itr != source_state_map_.end(); ++itr) { | 1299 ++itr) { |
1308 itr->second->Seek(seek_time); | 1300 itr->second->Seek(seek_time); |
1309 } | 1301 } |
1310 } | 1302 } |
1311 | 1303 |
1312 void ChunkDemuxer::CompletePendingReadsIfPossible() { | 1304 void ChunkDemuxer::CompletePendingReadsIfPossible() { |
1313 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1305 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1314 itr != source_state_map_.end(); ++itr) { | 1306 ++itr) { |
1315 itr->second->CompletePendingReadIfPossible(); | 1307 itr->second->CompletePendingReadIfPossible(); |
1316 } | 1308 } |
1317 } | 1309 } |
1318 | 1310 |
1319 void ChunkDemuxer::ShutdownAllStreams() { | 1311 void ChunkDemuxer::ShutdownAllStreams() { |
1320 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1312 for (auto itr = source_state_map_.begin(); itr != source_state_map_.end(); |
1321 itr != source_state_map_.end(); ++itr) { | 1313 ++itr) { |
1322 itr->second->Shutdown(); | 1314 itr->second->Shutdown(); |
1323 } | 1315 } |
1324 } | 1316 } |
1325 | 1317 |
1326 } // namespace media | 1318 } // namespace media |
OLD | NEW |