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 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 DemuxerStream::Type)> CreateDemuxerStreamCB; | 91 DemuxerStream::Type)> CreateDemuxerStreamCB; |
92 | 92 |
93 typedef ChunkDemuxer::InitSegmentReceivedCB InitSegmentReceivedCB; | 93 typedef ChunkDemuxer::InitSegmentReceivedCB InitSegmentReceivedCB; |
94 | 94 |
95 typedef base::Callback<void( | 95 typedef base::Callback<void( |
96 ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB; | 96 ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB; |
97 | 97 |
98 SourceState( | 98 SourceState( |
99 scoped_ptr<StreamParser> stream_parser, | 99 scoped_ptr<StreamParser> stream_parser, |
100 scoped_ptr<FrameProcessor> frame_processor, const LogCB& log_cb, | 100 scoped_ptr<FrameProcessor> frame_processor, const LogCB& log_cb, |
101 const CreateDemuxerStreamCB& create_demuxer_stream_cb); | 101 const CreateDemuxerStreamCB& create_demuxer_stream_cb, |
| 102 const scoped_refptr<MediaLog>& media_log); |
102 | 103 |
103 ~SourceState(); | 104 ~SourceState(); |
104 | 105 |
105 void Init(const StreamParser::InitCB& init_cb, | 106 void Init(const StreamParser::InitCB& init_cb, |
106 bool allow_audio, | 107 bool allow_audio, |
107 bool allow_video, | 108 bool allow_video, |
108 const StreamParser::NeedKeyCB& need_key_cb, | 109 const StreamParser::NeedKeyCB& need_key_cb, |
109 const NewTextTrackCB& new_text_track_cb); | 110 const NewTextTrackCB& new_text_track_cb); |
110 | 111 |
111 // Appends new data to the StreamParser. | 112 // Appends new data to the StreamParser. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 scoped_ptr<StreamParser> stream_parser_; | 229 scoped_ptr<StreamParser> stream_parser_; |
229 | 230 |
230 ChunkDemuxerStream* audio_; // Not owned by |this|. | 231 ChunkDemuxerStream* audio_; // Not owned by |this|. |
231 ChunkDemuxerStream* video_; // Not owned by |this|. | 232 ChunkDemuxerStream* video_; // Not owned by |this|. |
232 | 233 |
233 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; | 234 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; |
234 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers. | 235 TextStreamMap text_stream_map_; // |this| owns the map's stream pointers. |
235 | 236 |
236 scoped_ptr<FrameProcessor> frame_processor_; | 237 scoped_ptr<FrameProcessor> frame_processor_; |
237 LogCB log_cb_; | 238 LogCB log_cb_; |
| 239 scoped_refptr<MediaLog> media_log_; |
238 StreamParser::InitCB init_cb_; | 240 StreamParser::InitCB init_cb_; |
239 | 241 |
240 // During Append(), OnNewConfigs() will trigger the initialization segment | 242 // During Append(), OnNewConfigs() will trigger the initialization segment |
241 // received algorithm. This callback is only non-NULL during the lifetime of | 243 // received algorithm. This callback is only non-NULL during the lifetime of |
242 // an Append() call. Note, the MSE spec explicitly disallows this algorithm | 244 // an Append() call. Note, the MSE spec explicitly disallows this algorithm |
243 // during an Abort(), since Abort() is allowed only to emit coded frames, and | 245 // during an Abort(), since Abort() is allowed only to emit coded frames, and |
244 // only if the parser is PARSING_MEDIA_SEGMENT (not an INIT segment). | 246 // only if the parser is PARSING_MEDIA_SEGMENT (not an INIT segment). |
245 InitSegmentReceivedCB init_segment_received_cb_; | 247 InitSegmentReceivedCB init_segment_received_cb_; |
246 | 248 |
247 // Indicates that timestampOffset should be updated automatically during | 249 // Indicates that timestampOffset should be updated automatically during |
248 // OnNewBuffers() based on the earliest end timestamp of the buffers provided. | 250 // OnNewBuffers() based on the earliest end timestamp of the buffers provided. |
249 // TODO(wolenetz): Refactor this function while integrating April 29, 2014 | 251 // TODO(wolenetz): Refactor this function while integrating April 29, 2014 |
250 // changes to MSE spec. See http://crbug.com/371499. | 252 // changes to MSE spec. See http://crbug.com/371499. |
251 bool auto_update_timestamp_offset_; | 253 bool auto_update_timestamp_offset_; |
252 | 254 |
253 DISALLOW_COPY_AND_ASSIGN(SourceState); | 255 DISALLOW_COPY_AND_ASSIGN(SourceState); |
254 }; | 256 }; |
255 | 257 |
256 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, | 258 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
257 scoped_ptr<FrameProcessor> frame_processor, | 259 scoped_ptr<FrameProcessor> frame_processor, |
258 const LogCB& log_cb, | 260 const LogCB& log_cb, |
259 const CreateDemuxerStreamCB& create_demuxer_stream_cb) | 261 const CreateDemuxerStreamCB& create_demuxer_stream_cb, |
| 262 const scoped_refptr<MediaLog>& media_log) |
260 : create_demuxer_stream_cb_(create_demuxer_stream_cb), | 263 : create_demuxer_stream_cb_(create_demuxer_stream_cb), |
261 timestamp_offset_during_append_(NULL), | 264 timestamp_offset_during_append_(NULL), |
262 new_media_segment_(false), | 265 new_media_segment_(false), |
263 parsing_media_segment_(false), | 266 parsing_media_segment_(false), |
264 stream_parser_(stream_parser.release()), | 267 stream_parser_(stream_parser.release()), |
265 audio_(NULL), | 268 audio_(NULL), |
266 video_(NULL), | 269 video_(NULL), |
267 frame_processor_(frame_processor.release()), | 270 frame_processor_(frame_processor.release()), |
268 log_cb_(log_cb), | 271 log_cb_(log_cb), |
| 272 media_log_(media_log), |
269 auto_update_timestamp_offset_(false) { | 273 auto_update_timestamp_offset_(false) { |
270 DCHECK(!create_demuxer_stream_cb_.is_null()); | 274 DCHECK(!create_demuxer_stream_cb_.is_null()); |
271 DCHECK(frame_processor_); | 275 DCHECK(frame_processor_); |
272 } | 276 } |
273 | 277 |
274 SourceState::~SourceState() { | 278 SourceState::~SourceState() { |
275 Shutdown(); | 279 Shutdown(); |
276 | 280 |
277 STLDeleteValues(&text_stream_map_); | 281 STLDeleteValues(&text_stream_map_); |
278 } | 282 } |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 << (video_config.IsValidConfig() ? " has" : " does not have") | 589 << (video_config.IsValidConfig() ? " has" : " does not have") |
586 << " a video track, but the mimetype" | 590 << " a video track, but the mimetype" |
587 << (allow_video ? " specifies" : " does not specify") | 591 << (allow_video ? " specifies" : " does not specify") |
588 << " a video codec."; | 592 << " a video codec."; |
589 return false; | 593 return false; |
590 } | 594 } |
591 | 595 |
592 bool success = true; | 596 bool success = true; |
593 if (audio_config.IsValidConfig()) { | 597 if (audio_config.IsValidConfig()) { |
594 if (!audio_) { | 598 if (!audio_) { |
| 599 media_log_->SetBooleanProperty("found_audio_stream", true); |
| 600 } |
| 601 if (!audio_ || |
| 602 audio_->audio_decoder_config().codec() != audio_config.codec()) { |
| 603 media_log_->SetStringProperty("audio_codec_name", |
| 604 audio_config.GetHumanReadableCodecName()); |
| 605 } |
| 606 |
| 607 if (!audio_) { |
595 audio_ = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO); | 608 audio_ = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO); |
596 | 609 |
597 if (!audio_) { | 610 if (!audio_) { |
598 DVLOG(1) << "Failed to create an audio stream."; | 611 DVLOG(1) << "Failed to create an audio stream."; |
599 return false; | 612 return false; |
600 } | 613 } |
601 | 614 |
602 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { | 615 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { |
603 DVLOG(1) << "Failed to add audio track to frame processor."; | 616 DVLOG(1) << "Failed to add audio track to frame processor."; |
604 return false; | 617 return false; |
605 } | 618 } |
606 } | 619 } |
607 | 620 |
608 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); | 621 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); |
609 success &= audio_->UpdateAudioConfig(audio_config, log_cb_); | 622 success &= audio_->UpdateAudioConfig(audio_config, log_cb_); |
610 } | 623 } |
611 | 624 |
612 if (video_config.IsValidConfig()) { | 625 if (video_config.IsValidConfig()) { |
613 if (!video_) { | 626 if (!video_) { |
| 627 media_log_->SetBooleanProperty("found_video_stream", true); |
| 628 } |
| 629 if (!video_ || |
| 630 video_->video_decoder_config().codec() != video_config.codec()) { |
| 631 media_log_->SetStringProperty("video_codec_name", |
| 632 video_config.GetHumanReadableCodecName()); |
| 633 } |
| 634 |
| 635 if (!video_) { |
614 video_ = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO); | 636 video_ = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO); |
615 | 637 |
616 if (!video_) { | 638 if (!video_) { |
617 DVLOG(1) << "Failed to create a video stream."; | 639 DVLOG(1) << "Failed to create a video stream."; |
618 return false; | 640 return false; |
619 } | 641 } |
620 | 642 |
621 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { | 643 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { |
622 DVLOG(1) << "Failed to add video track to frame processor."; | 644 DVLOG(1) << "Failed to add video track to frame processor."; |
623 return false; | 645 return false; |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 buffer = StreamParserBuffer::CreateEOSBuffer(); | 1080 buffer = StreamParserBuffer::CreateEOSBuffer(); |
1059 break; | 1081 break; |
1060 } | 1082 } |
1061 | 1083 |
1062 base::ResetAndReturn(&read_cb_).Run(status, buffer); | 1084 base::ResetAndReturn(&read_cb_).Run(status, buffer); |
1063 } | 1085 } |
1064 | 1086 |
1065 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, | 1087 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, |
1066 const NeedKeyCB& need_key_cb, | 1088 const NeedKeyCB& need_key_cb, |
1067 const LogCB& log_cb, | 1089 const LogCB& log_cb, |
| 1090 const scoped_refptr<MediaLog>& media_log, |
1068 bool splice_frames_enabled) | 1091 bool splice_frames_enabled) |
1069 : state_(WAITING_FOR_INIT), | 1092 : state_(WAITING_FOR_INIT), |
1070 cancel_next_seek_(false), | 1093 cancel_next_seek_(false), |
1071 host_(NULL), | 1094 host_(NULL), |
1072 open_cb_(open_cb), | 1095 open_cb_(open_cb), |
1073 need_key_cb_(need_key_cb), | 1096 need_key_cb_(need_key_cb), |
1074 enable_text_(false), | 1097 enable_text_(false), |
1075 log_cb_(log_cb), | 1098 log_cb_(log_cb), |
| 1099 media_log_(media_log), |
1076 duration_(kNoTimestamp()), | 1100 duration_(kNoTimestamp()), |
1077 user_specified_duration_(-1), | 1101 user_specified_duration_(-1), |
1078 liveness_(DemuxerStream::LIVENESS_UNKNOWN), | 1102 liveness_(DemuxerStream::LIVENESS_UNKNOWN), |
1079 splice_frames_enabled_(splice_frames_enabled) { | 1103 splice_frames_enabled_(splice_frames_enabled) { |
1080 DCHECK(!open_cb_.is_null()); | 1104 DCHECK(!open_cb_.is_null()); |
1081 DCHECK(!need_key_cb_.is_null()); | 1105 DCHECK(!need_key_cb_.is_null()); |
1082 } | 1106 } |
1083 | 1107 |
1084 void ChunkDemuxer::Initialize( | 1108 void ChunkDemuxer::Initialize( |
1085 DemuxerHost* host, | 1109 DemuxerHost* host, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 source_id_video_ = id; | 1248 source_id_video_ = id; |
1225 | 1249 |
1226 scoped_ptr<FrameProcessor> frame_processor( | 1250 scoped_ptr<FrameProcessor> frame_processor( |
1227 new FrameProcessor(base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, | 1251 new FrameProcessor(base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, |
1228 base::Unretained(this)))); | 1252 base::Unretained(this)))); |
1229 | 1253 |
1230 scoped_ptr<SourceState> source_state( | 1254 scoped_ptr<SourceState> source_state( |
1231 new SourceState(stream_parser.Pass(), | 1255 new SourceState(stream_parser.Pass(), |
1232 frame_processor.Pass(), log_cb_, | 1256 frame_processor.Pass(), log_cb_, |
1233 base::Bind(&ChunkDemuxer::CreateDemuxerStream, | 1257 base::Bind(&ChunkDemuxer::CreateDemuxerStream, |
1234 base::Unretained(this)))); | 1258 base::Unretained(this)), |
| 1259 media_log_)); |
1235 | 1260 |
1236 SourceState::NewTextTrackCB new_text_track_cb; | 1261 SourceState::NewTextTrackCB new_text_track_cb; |
1237 | 1262 |
1238 if (enable_text_) { | 1263 if (enable_text_) { |
1239 new_text_track_cb = base::Bind(&ChunkDemuxer::OnNewTextTrack, | 1264 new_text_track_cb = base::Bind(&ChunkDemuxer::OnNewTextTrack, |
1240 base::Unretained(this)); | 1265 base::Unretained(this)); |
1241 } | 1266 } |
1242 | 1267 |
1243 source_state->Init( | 1268 source_state->Init( |
1244 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), | 1269 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 } | 1830 } |
1806 | 1831 |
1807 void ChunkDemuxer::ShutdownAllStreams() { | 1832 void ChunkDemuxer::ShutdownAllStreams() { |
1808 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1833 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1809 itr != source_state_map_.end(); ++itr) { | 1834 itr != source_state_map_.end(); ++itr) { |
1810 itr->second->Shutdown(); | 1835 itr->second->Shutdown(); |
1811 } | 1836 } |
1812 } | 1837 } |
1813 | 1838 |
1814 } // namespace media | 1839 } // namespace media |
OLD | NEW |