| 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 <list> | 9 #include <list> |
| 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/message_loop/message_loop_proxy.h" | 14 #include "base/message_loop/message_loop_proxy.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "media/base/audio_decoder_config.h" | 16 #include "media/base/audio_decoder_config.h" |
| 17 #include "media/base/bind_to_current_loop.h" | 17 #include "media/base/bind_to_current_loop.h" |
| 18 #include "media/base/stream_parser_buffer.h" | 18 #include "media/base/stream_parser_buffer.h" |
| 19 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 20 #include "media/filters/frame_processor.h" | 20 #include "media/filters/frame_processor.h" |
| 21 #include "media/filters/legacy_frame_processor.h" | |
| 22 #include "media/filters/stream_parser_factory.h" | 21 #include "media/filters/stream_parser_factory.h" |
| 23 | 22 |
| 24 using base::TimeDelta; | 23 using base::TimeDelta; |
| 25 | 24 |
| 26 namespace media { | 25 namespace media { |
| 27 | 26 |
| 28 static TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) { | 27 static TimeDelta EndTimestamp(const StreamParser::BufferQueue& queue) { |
| 29 return queue.back()->timestamp() + queue.back()->duration(); | 28 return queue.back()->timestamp() + queue.back()->duration(); |
| 30 } | 29 } |
| 31 | 30 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 public: | 88 public: |
| 90 // Callback signature used to create ChunkDemuxerStreams. | 89 // Callback signature used to create ChunkDemuxerStreams. |
| 91 typedef base::Callback<ChunkDemuxerStream*( | 90 typedef base::Callback<ChunkDemuxerStream*( |
| 92 DemuxerStream::Type)> CreateDemuxerStreamCB; | 91 DemuxerStream::Type)> CreateDemuxerStreamCB; |
| 93 | 92 |
| 94 typedef base::Callback<void( | 93 typedef base::Callback<void( |
| 95 ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB; | 94 ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB; |
| 96 | 95 |
| 97 SourceState( | 96 SourceState( |
| 98 scoped_ptr<StreamParser> stream_parser, | 97 scoped_ptr<StreamParser> stream_parser, |
| 99 scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb, | 98 scoped_ptr<FrameProcessor> frame_processor, const LogCB& log_cb, |
| 100 const CreateDemuxerStreamCB& create_demuxer_stream_cb); | 99 const CreateDemuxerStreamCB& create_demuxer_stream_cb); |
| 101 | 100 |
| 102 ~SourceState(); | 101 ~SourceState(); |
| 103 | 102 |
| 104 void Init(const StreamParser::InitCB& init_cb, | 103 void Init(const StreamParser::InitCB& init_cb, |
| 105 bool allow_audio, | 104 bool allow_audio, |
| 106 bool allow_video, | 105 bool allow_video, |
| 107 const StreamParser::NeedKeyCB& need_key_cb, | 106 const StreamParser::NeedKeyCB& need_key_cb, |
| 108 const NewTextTrackCB& new_text_track_cb); | 107 const NewTextTrackCB& new_text_track_cb); |
| 109 | 108 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 220 |
| 222 // The object used to parse appended data. | 221 // The object used to parse appended data. |
| 223 scoped_ptr<StreamParser> stream_parser_; | 222 scoped_ptr<StreamParser> stream_parser_; |
| 224 | 223 |
| 225 ChunkDemuxerStream* audio_; // Not owned by |this|. | 224 ChunkDemuxerStream* audio_; // Not owned by |this|. |
| 226 ChunkDemuxerStream* video_; // Not owned by |this|. | 225 ChunkDemuxerStream* video_; // Not owned by |this|. |
| 227 | 226 |
| 228 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; | 227 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; |
| 229 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers. | 228 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers. |
| 230 | 229 |
| 231 scoped_ptr<FrameProcessorBase> frame_processor_; | 230 scoped_ptr<FrameProcessor> frame_processor_; |
| 232 LogCB log_cb_; | 231 LogCB log_cb_; |
| 233 StreamParser::InitCB init_cb_; | 232 StreamParser::InitCB init_cb_; |
| 234 | 233 |
| 235 // Indicates that timestampOffset should be updated automatically during | 234 // Indicates that timestampOffset should be updated automatically during |
| 236 // OnNewBuffers() based on the earliest end timestamp of the buffers provided. | 235 // OnNewBuffers() based on the earliest end timestamp of the buffers provided. |
| 237 // TODO(wolenetz): Refactor this function while integrating April 29, 2014 | 236 // TODO(wolenetz): Refactor this function while integrating April 29, 2014 |
| 238 // changes to MSE spec. See http://crbug.com/371499. | 237 // changes to MSE spec. See http://crbug.com/371499. |
| 239 bool auto_update_timestamp_offset_; | 238 bool auto_update_timestamp_offset_; |
| 240 | 239 |
| 241 DISALLOW_COPY_AND_ASSIGN(SourceState); | 240 DISALLOW_COPY_AND_ASSIGN(SourceState); |
| 242 }; | 241 }; |
| 243 | 242 |
| 244 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, | 243 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
| 245 scoped_ptr<FrameProcessorBase> frame_processor, | 244 scoped_ptr<FrameProcessor> frame_processor, |
| 246 const LogCB& log_cb, | 245 const LogCB& log_cb, |
| 247 const CreateDemuxerStreamCB& create_demuxer_stream_cb) | 246 const CreateDemuxerStreamCB& create_demuxer_stream_cb) |
| 248 : create_demuxer_stream_cb_(create_demuxer_stream_cb), | 247 : create_demuxer_stream_cb_(create_demuxer_stream_cb), |
| 249 timestamp_offset_during_append_(NULL), | 248 timestamp_offset_during_append_(NULL), |
| 250 new_media_segment_(false), | 249 new_media_segment_(false), |
| 251 parsing_media_segment_(false), | 250 parsing_media_segment_(false), |
| 252 stream_parser_(stream_parser.release()), | 251 stream_parser_(stream_parser.release()), |
| 253 audio_(NULL), | 252 audio_(NULL), |
| 254 video_(NULL), | 253 video_(NULL), |
| 255 frame_processor_(frame_processor.release()), | 254 frame_processor_(frame_processor.release()), |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 SeekAllSources(seek_time); | 1139 SeekAllSources(seek_time); |
| 1141 | 1140 |
| 1142 if (seek_cb_.is_null()) { | 1141 if (seek_cb_.is_null()) { |
| 1143 cancel_next_seek_ = true; | 1142 cancel_next_seek_ = true; |
| 1144 return; | 1143 return; |
| 1145 } | 1144 } |
| 1146 | 1145 |
| 1147 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 1146 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
| 1148 } | 1147 } |
| 1149 | 1148 |
| 1150 ChunkDemuxer::Status ChunkDemuxer::AddId( | 1149 ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id, |
| 1151 const std::string& id, | 1150 const std::string& type, |
| 1152 const std::string& type, | 1151 std::vector<std::string>& codecs) { |
| 1153 std::vector<std::string>& codecs, | |
| 1154 const bool use_legacy_frame_processor) { | |
| 1155 base::AutoLock auto_lock(lock_); | 1152 base::AutoLock auto_lock(lock_); |
| 1156 | 1153 |
| 1157 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id)) | 1154 if ((state_ != WAITING_FOR_INIT && state_ != INITIALIZING) || IsValidId(id)) |
| 1158 return kReachedIdLimit; | 1155 return kReachedIdLimit; |
| 1159 | 1156 |
| 1160 bool has_audio = false; | 1157 bool has_audio = false; |
| 1161 bool has_video = false; | 1158 bool has_video = false; |
| 1162 scoped_ptr<media::StreamParser> stream_parser( | 1159 scoped_ptr<media::StreamParser> stream_parser( |
| 1163 StreamParserFactory::Create(type, codecs, log_cb_, | 1160 StreamParserFactory::Create(type, codecs, log_cb_, |
| 1164 &has_audio, &has_video)); | 1161 &has_audio, &has_video)); |
| 1165 | 1162 |
| 1166 if (!stream_parser) | 1163 if (!stream_parser) |
| 1167 return ChunkDemuxer::kNotSupported; | 1164 return ChunkDemuxer::kNotSupported; |
| 1168 | 1165 |
| 1169 if ((has_audio && !source_id_audio_.empty()) || | 1166 if ((has_audio && !source_id_audio_.empty()) || |
| 1170 (has_video && !source_id_video_.empty())) | 1167 (has_video && !source_id_video_.empty())) |
| 1171 return kReachedIdLimit; | 1168 return kReachedIdLimit; |
| 1172 | 1169 |
| 1173 if (has_audio) | 1170 if (has_audio) |
| 1174 source_id_audio_ = id; | 1171 source_id_audio_ = id; |
| 1175 | 1172 |
| 1176 if (has_video) | 1173 if (has_video) |
| 1177 source_id_video_ = id; | 1174 source_id_video_ = id; |
| 1178 | 1175 |
| 1179 scoped_ptr<FrameProcessorBase> frame_processor; | 1176 scoped_ptr<FrameProcessor> frame_processor( |
| 1180 if (use_legacy_frame_processor) { | 1177 new FrameProcessor(base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, |
| 1181 frame_processor.reset(new LegacyFrameProcessor( | 1178 base::Unretained(this)))); |
| 1182 base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, | |
| 1183 base::Unretained(this)))); | |
| 1184 } else { | |
| 1185 frame_processor.reset(new FrameProcessor( | |
| 1186 base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, | |
| 1187 base::Unretained(this)))); | |
| 1188 } | |
| 1189 | 1179 |
| 1190 scoped_ptr<SourceState> source_state( | 1180 scoped_ptr<SourceState> source_state( |
| 1191 new SourceState(stream_parser.Pass(), | 1181 new SourceState(stream_parser.Pass(), |
| 1192 frame_processor.Pass(), log_cb_, | 1182 frame_processor.Pass(), log_cb_, |
| 1193 base::Bind(&ChunkDemuxer::CreateDemuxerStream, | 1183 base::Bind(&ChunkDemuxer::CreateDemuxerStream, |
| 1194 base::Unretained(this)))); | 1184 base::Unretained(this)))); |
| 1195 | 1185 |
| 1196 SourceState::NewTextTrackCB new_text_track_cb; | 1186 SourceState::NewTextTrackCB new_text_track_cb; |
| 1197 | 1187 |
| 1198 if (enable_text_) { | 1188 if (enable_text_) { |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 } | 1741 } |
| 1752 | 1742 |
| 1753 void ChunkDemuxer::ShutdownAllStreams() { | 1743 void ChunkDemuxer::ShutdownAllStreams() { |
| 1754 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1744 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| 1755 itr != source_state_map_.end(); ++itr) { | 1745 itr != source_state_map_.end(); ++itr) { |
| 1756 itr->second->Shutdown(); | 1746 itr->second->Shutdown(); |
| 1757 } | 1747 } |
| 1758 } | 1748 } |
| 1759 | 1749 |
| 1760 } // namespace media | 1750 } // namespace media |
| OLD | NEW |