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 media_log_->SetStringProperty( | |
DaleCurtis
2014/11/19 00:03:57
This works today since we don't allow codec switch
watk
2014/11/19 19:18:09
Good point. I did talk to wolenetz@ about this, an
| |
601 "audio_codec_name", | |
602 AudioCodecName(audio_config.codec(), audio_config.sample_format())); | |
595 audio_ = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO); | 603 audio_ = create_demuxer_stream_cb_.Run(DemuxerStream::AUDIO); |
596 | 604 |
597 if (!audio_) { | 605 if (!audio_) { |
598 DVLOG(1) << "Failed to create an audio stream."; | 606 DVLOG(1) << "Failed to create an audio stream."; |
599 return false; | 607 return false; |
600 } | 608 } |
601 | 609 |
602 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { | 610 if (!frame_processor_->AddTrack(FrameProcessor::kAudioTrackId, audio_)) { |
603 DVLOG(1) << "Failed to add audio track to frame processor."; | 611 DVLOG(1) << "Failed to add audio track to frame processor."; |
604 return false; | 612 return false; |
605 } | 613 } |
606 } | 614 } |
607 | 615 |
608 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); | 616 frame_processor_->OnPossibleAudioConfigUpdate(audio_config); |
609 success &= audio_->UpdateAudioConfig(audio_config, log_cb_); | 617 success &= audio_->UpdateAudioConfig(audio_config, log_cb_); |
610 } | 618 } |
611 | 619 |
612 if (video_config.IsValidConfig()) { | 620 if (video_config.IsValidConfig()) { |
613 if (!video_) { | 621 if (!video_) { |
622 media_log_->SetBooleanProperty("found_video_stream", true); | |
623 media_log_->SetStringProperty("video_codec_name", | |
624 VideoCodecName(video_config.codec())); | |
614 video_ = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO); | 625 video_ = create_demuxer_stream_cb_.Run(DemuxerStream::VIDEO); |
615 | 626 |
616 if (!video_) { | 627 if (!video_) { |
617 DVLOG(1) << "Failed to create a video stream."; | 628 DVLOG(1) << "Failed to create a video stream."; |
618 return false; | 629 return false; |
619 } | 630 } |
620 | 631 |
621 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { | 632 if (!frame_processor_->AddTrack(FrameProcessor::kVideoTrackId, video_)) { |
622 DVLOG(1) << "Failed to add video track to frame processor."; | 633 DVLOG(1) << "Failed to add video track to frame processor."; |
623 return false; | 634 return false; |
624 } | 635 } |
625 } | 636 } |
626 | |
627 success &= video_->UpdateVideoConfig(video_config, log_cb_); | 637 success &= video_->UpdateVideoConfig(video_config, log_cb_); |
628 } | 638 } |
629 | 639 |
630 typedef StreamParser::TextTrackConfigMap::const_iterator TextConfigItr; | 640 typedef StreamParser::TextTrackConfigMap::const_iterator TextConfigItr; |
631 if (text_stream_map_.empty()) { | 641 if (text_stream_map_.empty()) { |
632 for (TextConfigItr itr = text_configs.begin(); | 642 for (TextConfigItr itr = text_configs.begin(); |
633 itr != text_configs.end(); ++itr) { | 643 itr != text_configs.end(); ++itr) { |
634 ChunkDemuxerStream* const text_stream = | 644 ChunkDemuxerStream* const text_stream = |
635 create_demuxer_stream_cb_.Run(DemuxerStream::TEXT); | 645 create_demuxer_stream_cb_.Run(DemuxerStream::TEXT); |
636 if (!frame_processor_->AddTrack(itr->first, text_stream)) { | 646 if (!frame_processor_->AddTrack(itr->first, text_stream)) { |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1058 buffer = StreamParserBuffer::CreateEOSBuffer(); | 1068 buffer = StreamParserBuffer::CreateEOSBuffer(); |
1059 break; | 1069 break; |
1060 } | 1070 } |
1061 | 1071 |
1062 base::ResetAndReturn(&read_cb_).Run(status, buffer); | 1072 base::ResetAndReturn(&read_cb_).Run(status, buffer); |
1063 } | 1073 } |
1064 | 1074 |
1065 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, | 1075 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, |
1066 const NeedKeyCB& need_key_cb, | 1076 const NeedKeyCB& need_key_cb, |
1067 const LogCB& log_cb, | 1077 const LogCB& log_cb, |
1078 const scoped_refptr<MediaLog>& media_log, | |
1068 bool splice_frames_enabled) | 1079 bool splice_frames_enabled) |
1069 : state_(WAITING_FOR_INIT), | 1080 : state_(WAITING_FOR_INIT), |
1070 cancel_next_seek_(false), | 1081 cancel_next_seek_(false), |
1071 host_(NULL), | 1082 host_(NULL), |
1072 open_cb_(open_cb), | 1083 open_cb_(open_cb), |
1073 need_key_cb_(need_key_cb), | 1084 need_key_cb_(need_key_cb), |
1074 enable_text_(false), | 1085 enable_text_(false), |
1075 log_cb_(log_cb), | 1086 log_cb_(log_cb), |
1087 media_log_(media_log), | |
1076 duration_(kNoTimestamp()), | 1088 duration_(kNoTimestamp()), |
1077 user_specified_duration_(-1), | 1089 user_specified_duration_(-1), |
1078 liveness_(DemuxerStream::LIVENESS_UNKNOWN), | 1090 liveness_(DemuxerStream::LIVENESS_UNKNOWN), |
1079 splice_frames_enabled_(splice_frames_enabled) { | 1091 splice_frames_enabled_(splice_frames_enabled) { |
1080 DCHECK(!open_cb_.is_null()); | 1092 DCHECK(!open_cb_.is_null()); |
1081 DCHECK(!need_key_cb_.is_null()); | 1093 DCHECK(!need_key_cb_.is_null()); |
1082 } | 1094 } |
1083 | 1095 |
1084 void ChunkDemuxer::Initialize( | 1096 void ChunkDemuxer::Initialize( |
1085 DemuxerHost* host, | 1097 DemuxerHost* host, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 source_id_video_ = id; | 1236 source_id_video_ = id; |
1225 | 1237 |
1226 scoped_ptr<FrameProcessor> frame_processor( | 1238 scoped_ptr<FrameProcessor> frame_processor( |
1227 new FrameProcessor(base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, | 1239 new FrameProcessor(base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary, |
1228 base::Unretained(this)))); | 1240 base::Unretained(this)))); |
1229 | 1241 |
1230 scoped_ptr<SourceState> source_state( | 1242 scoped_ptr<SourceState> source_state( |
1231 new SourceState(stream_parser.Pass(), | 1243 new SourceState(stream_parser.Pass(), |
1232 frame_processor.Pass(), log_cb_, | 1244 frame_processor.Pass(), log_cb_, |
1233 base::Bind(&ChunkDemuxer::CreateDemuxerStream, | 1245 base::Bind(&ChunkDemuxer::CreateDemuxerStream, |
1234 base::Unretained(this)))); | 1246 base::Unretained(this)), |
1247 media_log_)); | |
1235 | 1248 |
1236 SourceState::NewTextTrackCB new_text_track_cb; | 1249 SourceState::NewTextTrackCB new_text_track_cb; |
1237 | 1250 |
1238 if (enable_text_) { | 1251 if (enable_text_) { |
1239 new_text_track_cb = base::Bind(&ChunkDemuxer::OnNewTextTrack, | 1252 new_text_track_cb = base::Bind(&ChunkDemuxer::OnNewTextTrack, |
1240 base::Unretained(this)); | 1253 base::Unretained(this)); |
1241 } | 1254 } |
1242 | 1255 |
1243 source_state->Init( | 1256 source_state->Init( |
1244 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), | 1257 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1805 } | 1818 } |
1806 | 1819 |
1807 void ChunkDemuxer::ShutdownAllStreams() { | 1820 void ChunkDemuxer::ShutdownAllStreams() { |
1808 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1821 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1809 itr != source_state_map_.end(); ++itr) { | 1822 itr != source_state_map_.end(); ++itr) { |
1810 itr->second->Shutdown(); | 1823 itr->second->Shutdown(); |
1811 } | 1824 } |
1812 } | 1825 } |
1813 | 1826 |
1814 } // namespace media | 1827 } // namespace media |
OLD | NEW |