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 |