| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 private: | 179 private: |
| 180 // Called by the |stream_parser_| when a new initialization segment is | 180 // Called by the |stream_parser_| when a new initialization segment is |
| 181 // encountered. | 181 // encountered. |
| 182 // Returns true on a successful call. Returns false if an error occurred while | 182 // Returns true on a successful call. Returns false if an error occurred while |
| 183 // processing decoder configurations. | 183 // processing decoder configurations. |
| 184 bool OnNewConfigs(bool allow_audio, bool allow_video, | 184 bool OnNewConfigs(bool allow_audio, bool allow_video, |
| 185 const AudioDecoderConfig& audio_config, | 185 const AudioDecoderConfig& audio_config, |
| 186 const VideoDecoderConfig& video_config, | 186 const VideoDecoderConfig& video_config, |
| 187 const StreamParser::TextTrackConfigMap& text_configs); | 187 const StreamParser::TextTrackConfigMap& text_configs); |
| 188 | 188 |
| 189 // Called by the |stream_parser_| at the beginning of a new media segment. | 189 // Called by the |stream_parser_| at the start of a new media segment. |
| 190 void OnNewMediaSegment(); | 190 void OnStartOfMediaSegment(); |
| 191 | 191 |
| 192 // Called by the |stream_parser_| at the end of a media segment. | 192 // Called by the |stream_parser_| at the end of a media segment. |
| 193 void OnEndOfMediaSegment(); | 193 void OnEndOfMediaSegment(); |
| 194 | 194 |
| 195 // Called by the |stream_parser_| when new buffers have been parsed. | 195 // Called by the |stream_parser_| when new buffers have been parsed. |
| 196 // It processes the new buffers using |frame_processor_|, which includes | 196 // It processes the new buffers using |frame_processor_|, which includes |
| 197 // appending the processed frames to associated demuxer streams for each | 197 // appending the processed frames to associated demuxer streams for each |
| 198 // frame's track. | 198 // frame's track. |
| 199 // Returns true on a successful call. Returns false if an error occurred while | 199 // Returns true on a successful call. Returns false if an error occurred while |
| 200 // processing the buffers. | 200 // processing the buffers. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 218 // so Append()'s caller can know the new offset. This pointer is only non-NULL | 218 // so Append()'s caller can know the new offset. This pointer is only non-NULL |
| 219 // during the lifetime of an Append() call. | 219 // during the lifetime of an Append() call. |
| 220 TimeDelta* timestamp_offset_during_append_; | 220 TimeDelta* timestamp_offset_during_append_; |
| 221 | 221 |
| 222 // During Append(), coded frame processing triggered by OnNewBuffers() | 222 // During Append(), coded frame processing triggered by OnNewBuffers() |
| 223 // requires these two attributes. These are only valid during the lifetime of | 223 // requires these two attributes. These are only valid during the lifetime of |
| 224 // an Append() call. | 224 // an Append() call. |
| 225 TimeDelta append_window_start_during_append_; | 225 TimeDelta append_window_start_during_append_; |
| 226 TimeDelta append_window_end_during_append_; | 226 TimeDelta append_window_end_during_append_; |
| 227 | 227 |
| 228 // Set to true if the next buffers appended within the append window | |
| 229 // represent the start of a new media segment. This flag being set | |
| 230 // triggers a call to |new_segment_cb_| when the new buffers are | |
| 231 // appended. The flag is set on actual media segment boundaries and | |
| 232 // when the "append window" filtering causes discontinuities in the | |
| 233 // appended data. | |
| 234 // TODO(wolenetz/acolwell): Investigate if we need this, or if coded frame | |
| 235 // processing's discontinuity logic is enough. See http://crbug.com/351489. | |
| 236 bool new_media_segment_; | |
| 237 | |
| 238 // Keeps track of whether a media segment is being parsed. | 228 // Keeps track of whether a media segment is being parsed. |
| 239 bool parsing_media_segment_; | 229 bool parsing_media_segment_; |
| 240 | 230 |
| 241 // The object used to parse appended data. | 231 // The object used to parse appended data. |
| 242 scoped_ptr<StreamParser> stream_parser_; | 232 scoped_ptr<StreamParser> stream_parser_; |
| 243 | 233 |
| 244 ChunkDemuxerStream* audio_; // Not owned by |this|. | 234 ChunkDemuxerStream* audio_; // Not owned by |this|. |
| 245 ChunkDemuxerStream* video_; // Not owned by |this|. | 235 ChunkDemuxerStream* video_; // Not owned by |this|. |
| 246 | 236 |
| 247 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; | 237 typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 266 | 256 |
| 267 DISALLOW_COPY_AND_ASSIGN(SourceState); | 257 DISALLOW_COPY_AND_ASSIGN(SourceState); |
| 268 }; | 258 }; |
| 269 | 259 |
| 270 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, | 260 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
| 271 scoped_ptr<FrameProcessor> frame_processor, | 261 scoped_ptr<FrameProcessor> frame_processor, |
| 272 const CreateDemuxerStreamCB& create_demuxer_stream_cb, | 262 const CreateDemuxerStreamCB& create_demuxer_stream_cb, |
| 273 const scoped_refptr<MediaLog>& media_log) | 263 const scoped_refptr<MediaLog>& media_log) |
| 274 : create_demuxer_stream_cb_(create_demuxer_stream_cb), | 264 : create_demuxer_stream_cb_(create_demuxer_stream_cb), |
| 275 timestamp_offset_during_append_(NULL), | 265 timestamp_offset_during_append_(NULL), |
| 276 new_media_segment_(false), | |
| 277 parsing_media_segment_(false), | 266 parsing_media_segment_(false), |
| 278 stream_parser_(stream_parser.release()), | 267 stream_parser_(stream_parser.release()), |
| 279 audio_(NULL), | 268 audio_(NULL), |
| 280 video_(NULL), | 269 video_(NULL), |
| 281 frame_processor_(frame_processor.release()), | 270 frame_processor_(frame_processor.release()), |
| 282 media_log_(media_log), | 271 media_log_(media_log), |
| 283 auto_update_timestamp_offset_(false) { | 272 auto_update_timestamp_offset_(false) { |
| 284 DCHECK(!create_demuxer_stream_cb_.is_null()); | 273 DCHECK(!create_demuxer_stream_cb_.is_null()); |
| 285 DCHECK(frame_processor_); | 274 DCHECK(frame_processor_); |
| 286 } | 275 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 299 const NewTextTrackCB& new_text_track_cb) { | 288 const NewTextTrackCB& new_text_track_cb) { |
| 300 new_text_track_cb_ = new_text_track_cb; | 289 new_text_track_cb_ = new_text_track_cb; |
| 301 init_cb_ = init_cb; | 290 init_cb_ = init_cb; |
| 302 | 291 |
| 303 stream_parser_->Init( | 292 stream_parser_->Init( |
| 304 base::Bind(&SourceState::OnSourceInitDone, base::Unretained(this)), | 293 base::Bind(&SourceState::OnSourceInitDone, base::Unretained(this)), |
| 305 base::Bind(&SourceState::OnNewConfigs, base::Unretained(this), | 294 base::Bind(&SourceState::OnNewConfigs, base::Unretained(this), |
| 306 allow_audio, allow_video), | 295 allow_audio, allow_video), |
| 307 base::Bind(&SourceState::OnNewBuffers, base::Unretained(this)), | 296 base::Bind(&SourceState::OnNewBuffers, base::Unretained(this)), |
| 308 new_text_track_cb_.is_null(), encrypted_media_init_data_cb, | 297 new_text_track_cb_.is_null(), encrypted_media_init_data_cb, |
| 309 base::Bind(&SourceState::OnNewMediaSegment, base::Unretained(this)), | 298 base::Bind(&SourceState::OnStartOfMediaSegment, base::Unretained(this)), |
| 310 base::Bind(&SourceState::OnEndOfMediaSegment, base::Unretained(this)), | 299 base::Bind(&SourceState::OnEndOfMediaSegment, base::Unretained(this)), |
| 311 media_log_); | 300 media_log_); |
| 312 } | 301 } |
| 313 | 302 |
| 314 void SourceState::SetSequenceMode(bool sequence_mode) { | 303 void SourceState::SetSequenceMode(bool sequence_mode) { |
| 315 DCHECK(!parsing_media_segment_); | 304 DCHECK(!parsing_media_segment_); |
| 316 | 305 |
| 317 frame_processor_->SetSequenceMode(sequence_mode); | 306 frame_processor_->SetSequenceMode(sequence_mode); |
| 318 } | 307 } |
| 319 | 308 |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 | 801 |
| 813 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); | 802 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); |
| 814 | 803 |
| 815 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); | 804 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); |
| 816 if (success) | 805 if (success) |
| 817 init_segment_received_cb_.Run(); | 806 init_segment_received_cb_.Run(); |
| 818 | 807 |
| 819 return success; | 808 return success; |
| 820 } | 809 } |
| 821 | 810 |
| 822 void SourceState::OnNewMediaSegment() { | 811 void SourceState::OnStartOfMediaSegment() { |
| 823 DVLOG(2) << "OnNewMediaSegment()"; | 812 DVLOG(2) << "OnStartOfMediaSegment()"; |
| 824 parsing_media_segment_ = true; | 813 parsing_media_segment_ = true; |
| 825 new_media_segment_ = true; | |
| 826 } | 814 } |
| 827 | 815 |
| 828 void SourceState::OnEndOfMediaSegment() { | 816 void SourceState::OnEndOfMediaSegment() { |
| 829 DVLOG(2) << "OnEndOfMediaSegment()"; | 817 DVLOG(2) << "OnEndOfMediaSegment()"; |
| 830 parsing_media_segment_ = false; | 818 parsing_media_segment_ = false; |
| 831 new_media_segment_ = false; | |
| 832 } | 819 } |
| 833 | 820 |
| 834 bool SourceState::OnNewBuffers( | 821 bool SourceState::OnNewBuffers( |
| 835 const StreamParser::BufferQueue& audio_buffers, | 822 const StreamParser::BufferQueue& audio_buffers, |
| 836 const StreamParser::BufferQueue& video_buffers, | 823 const StreamParser::BufferQueue& video_buffers, |
| 837 const StreamParser::TextBufferQueueMap& text_map) { | 824 const StreamParser::TextBufferQueueMap& text_map) { |
| 838 DVLOG(2) << "OnNewBuffers()"; | 825 DVLOG(2) << "OnNewBuffers()"; |
| 839 DCHECK(timestamp_offset_during_append_); | 826 DCHECK(timestamp_offset_during_append_); |
| 840 DCHECK(parsing_media_segment_); | 827 DCHECK(parsing_media_segment_); |
| 841 | 828 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 856 } else if (have_video_buffers) { | 843 } else if (have_video_buffers) { |
| 857 new_timestamp_offset += EndTimestamp(video_buffers); | 844 new_timestamp_offset += EndTimestamp(video_buffers); |
| 858 } | 845 } |
| 859 } | 846 } |
| 860 | 847 |
| 861 if (!frame_processor_->ProcessFrames(audio_buffers, | 848 if (!frame_processor_->ProcessFrames(audio_buffers, |
| 862 video_buffers, | 849 video_buffers, |
| 863 text_map, | 850 text_map, |
| 864 append_window_start_during_append_, | 851 append_window_start_during_append_, |
| 865 append_window_end_during_append_, | 852 append_window_end_during_append_, |
| 866 &new_media_segment_, | |
| 867 timestamp_offset_during_append_)) { | 853 timestamp_offset_during_append_)) { |
| 868 return false; | 854 return false; |
| 869 } | 855 } |
| 870 | 856 |
| 871 // Only update the timestamp offset if the frame processor hasn't already. | 857 // Only update the timestamp offset if the frame processor hasn't already. |
| 872 if (auto_update_timestamp_offset_ && | 858 if (auto_update_timestamp_offset_ && |
| 873 timestamp_offset_before_processing == *timestamp_offset_during_append_) { | 859 timestamp_offset_before_processing == *timestamp_offset_during_append_) { |
| 874 *timestamp_offset_during_append_ = new_timestamp_offset; | 860 *timestamp_offset_during_append_ = new_timestamp_offset; |
| 875 } | 861 } |
| 876 | 862 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 } | 995 } |
| 1010 | 996 |
| 1011 TimeDelta ChunkDemuxerStream::GetBufferedDuration() const { | 997 TimeDelta ChunkDemuxerStream::GetBufferedDuration() const { |
| 1012 return stream_->GetBufferedDuration(); | 998 return stream_->GetBufferedDuration(); |
| 1013 } | 999 } |
| 1014 | 1000 |
| 1015 size_t ChunkDemuxerStream::GetBufferedSize() const { | 1001 size_t ChunkDemuxerStream::GetBufferedSize() const { |
| 1016 return stream_->GetBufferedSize(); | 1002 return stream_->GetBufferedSize(); |
| 1017 } | 1003 } |
| 1018 | 1004 |
| 1019 void ChunkDemuxerStream::OnNewMediaSegment(DecodeTimestamp start_timestamp) { | 1005 void ChunkDemuxerStream::OnStartOfCodedFrameGroup( |
| 1020 DVLOG(2) << "ChunkDemuxerStream::OnNewMediaSegment(" | 1006 DecodeTimestamp start_timestamp) { |
| 1007 DVLOG(2) << "ChunkDemuxerStream::OnStartOfCodedFrameGroup(" |
| 1021 << start_timestamp.InSecondsF() << ")"; | 1008 << start_timestamp.InSecondsF() << ")"; |
| 1022 base::AutoLock auto_lock(lock_); | 1009 base::AutoLock auto_lock(lock_); |
| 1023 stream_->OnNewMediaSegment(start_timestamp); | 1010 stream_->OnStartOfCodedFrameGroup(start_timestamp); |
| 1024 } | 1011 } |
| 1025 | 1012 |
| 1026 bool ChunkDemuxerStream::UpdateAudioConfig( | 1013 bool ChunkDemuxerStream::UpdateAudioConfig( |
| 1027 const AudioDecoderConfig& config, | 1014 const AudioDecoderConfig& config, |
| 1028 const scoped_refptr<MediaLog>& media_log) { | 1015 const scoped_refptr<MediaLog>& media_log) { |
| 1029 DCHECK(config.IsValidConfig()); | 1016 DCHECK(config.IsValidConfig()); |
| 1030 DCHECK_EQ(type_, AUDIO); | 1017 DCHECK_EQ(type_, AUDIO); |
| 1031 base::AutoLock auto_lock(lock_); | 1018 base::AutoLock auto_lock(lock_); |
| 1032 if (!stream_) { | 1019 if (!stream_) { |
| 1033 DCHECK_EQ(state_, UNINITIALIZED); | 1020 DCHECK_EQ(state_, UNINITIALIZED); |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1958 } | 1945 } |
| 1959 | 1946 |
| 1960 void ChunkDemuxer::ShutdownAllStreams() { | 1947 void ChunkDemuxer::ShutdownAllStreams() { |
| 1961 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1948 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| 1962 itr != source_state_map_.end(); ++itr) { | 1949 itr != source_state_map_.end(); ++itr) { |
| 1963 itr->second->Shutdown(); | 1950 itr->second->Shutdown(); |
| 1964 } | 1951 } |
| 1965 } | 1952 } |
| 1966 | 1953 |
| 1967 } // namespace media | 1954 } // namespace media |
| OLD | NEW |