| 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 #include <utility> | 10 #include <utility> |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 scoped_refptr<StreamParserBuffer> buffer; | 347 scoped_refptr<StreamParserBuffer> buffer; |
| 348 | 348 |
| 349 switch (state_) { | 349 switch (state_) { |
| 350 case UNINITIALIZED: | 350 case UNINITIALIZED: |
| 351 NOTREACHED(); | 351 NOTREACHED(); |
| 352 return; | 352 return; |
| 353 case RETURNING_DATA_FOR_READS: | 353 case RETURNING_DATA_FOR_READS: |
| 354 switch (stream_->GetNextBuffer(&buffer)) { | 354 switch (stream_->GetNextBuffer(&buffer)) { |
| 355 case SourceBufferStream::kSuccess: | 355 case SourceBufferStream::kSuccess: |
| 356 status = DemuxerStream::kOk; | 356 status = DemuxerStream::kOk; |
| 357 DVLOG(2) << __FUNCTION__ << ": returning kOk, type " << type_ | 357 DVLOG(2) << __func__ << ": returning kOk, type " << type_ << ", dts " |
| 358 << ", dts " << buffer->GetDecodeTimestamp().InSecondsF() | 358 << buffer->GetDecodeTimestamp().InSecondsF() << ", pts " |
| 359 << ", pts " << buffer->timestamp().InSecondsF() | 359 << buffer->timestamp().InSecondsF() << ", dur " |
| 360 << ", dur " << buffer->duration().InSecondsF() | 360 << buffer->duration().InSecondsF() << ", key " |
| 361 << ", key " << buffer->is_key_frame(); | 361 << buffer->is_key_frame(); |
| 362 break; | 362 break; |
| 363 case SourceBufferStream::kNeedBuffer: | 363 case SourceBufferStream::kNeedBuffer: |
| 364 // Return early without calling |read_cb_| since we don't have | 364 // Return early without calling |read_cb_| since we don't have |
| 365 // any data to return yet. | 365 // any data to return yet. |
| 366 DVLOG(2) << __FUNCTION__ << ": returning kNeedBuffer, type " | 366 DVLOG(2) << __func__ << ": returning kNeedBuffer, type " << type_; |
| 367 << type_; | |
| 368 return; | 367 return; |
| 369 case SourceBufferStream::kEndOfStream: | 368 case SourceBufferStream::kEndOfStream: |
| 370 status = DemuxerStream::kOk; | 369 status = DemuxerStream::kOk; |
| 371 buffer = StreamParserBuffer::CreateEOSBuffer(); | 370 buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 372 DVLOG(2) << __FUNCTION__ << ": returning kOk with EOS buffer, type " | 371 DVLOG(2) << __func__ << ": returning kOk with EOS buffer, type " |
| 373 << type_; | 372 << type_; |
| 374 break; | 373 break; |
| 375 case SourceBufferStream::kConfigChange: | 374 case SourceBufferStream::kConfigChange: |
| 376 status = kConfigChanged; | 375 status = kConfigChanged; |
| 377 buffer = NULL; | 376 buffer = NULL; |
| 378 DVLOG(2) << __FUNCTION__ << ": returning kConfigChange, type " | 377 DVLOG(2) << __func__ << ": returning kConfigChange, type " << type_; |
| 379 << type_; | |
| 380 break; | 378 break; |
| 381 } | 379 } |
| 382 break; | 380 break; |
| 383 case RETURNING_ABORT_FOR_READS: | 381 case RETURNING_ABORT_FOR_READS: |
| 384 // Null buffers should be returned in this state since we are waiting | 382 // Null buffers should be returned in this state since we are waiting |
| 385 // for a seek. Any buffers in the SourceBuffer should NOT be returned | 383 // for a seek. Any buffers in the SourceBuffer should NOT be returned |
| 386 // because they are associated with the seek. | 384 // because they are associated with the seek. |
| 387 status = DemuxerStream::kAborted; | 385 status = DemuxerStream::kAborted; |
| 388 buffer = NULL; | 386 buffer = NULL; |
| 389 DVLOG(2) << __FUNCTION__ << ": returning kAborted, type " << type_; | 387 DVLOG(2) << __func__ << ": returning kAborted, type " << type_; |
| 390 break; | 388 break; |
| 391 case SHUTDOWN: | 389 case SHUTDOWN: |
| 392 status = DemuxerStream::kOk; | 390 status = DemuxerStream::kOk; |
| 393 buffer = StreamParserBuffer::CreateEOSBuffer(); | 391 buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 394 DVLOG(2) << __FUNCTION__ << ": returning kOk with EOS buffer, type " | 392 DVLOG(2) << __func__ << ": returning kOk with EOS buffer, type " << type_; |
| 395 << type_; | |
| 396 break; | 393 break; |
| 397 } | 394 } |
| 398 | 395 |
| 399 base::ResetAndReturn(&read_cb_).Run(status, buffer); | 396 base::ResetAndReturn(&read_cb_).Run(status, buffer); |
| 400 } | 397 } |
| 401 | 398 |
| 402 ChunkDemuxer::ChunkDemuxer( | 399 ChunkDemuxer::ChunkDemuxer( |
| 403 const base::Closure& open_cb, | 400 const base::Closure& open_cb, |
| 404 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, | 401 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, |
| 405 const scoped_refptr<MediaLog>& media_log, | 402 const scoped_refptr<MediaLog>& media_log, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 bool enabled = false; | 652 bool enabled = false; |
| 656 CHECK(audio_stream); | 653 CHECK(audio_stream); |
| 657 DCHECK_LE(track_ids.size(), 1u); | 654 DCHECK_LE(track_ids.size(), 1u); |
| 658 if (track_ids.size() > 0) { | 655 if (track_ids.size() > 0) { |
| 659 #if DCHECK_IS_ON() | 656 #if DCHECK_IS_ON() |
| 660 base::AutoLock auto_lock(lock_); | 657 base::AutoLock auto_lock(lock_); |
| 661 DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == audio_stream); | 658 DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == audio_stream); |
| 662 #endif | 659 #endif |
| 663 enabled = true; | 660 enabled = true; |
| 664 } | 661 } |
| 665 DVLOG(1) << __FUNCTION__ << ": " << (enabled ? "enabling" : "disabling") | 662 DVLOG(1) << __func__ << ": " << (enabled ? "enabling" : "disabling") |
| 666 << " audio stream"; | 663 << " audio stream"; |
| 667 audio_stream->set_enabled(enabled, currTime); | 664 audio_stream->set_enabled(enabled, currTime); |
| 668 } | 665 } |
| 669 | 666 |
| 670 void ChunkDemuxer::OnSelectedVideoTrackChanged( | 667 void ChunkDemuxer::OnSelectedVideoTrackChanged( |
| 671 const std::vector<MediaTrack::Id>& track_ids, | 668 const std::vector<MediaTrack::Id>& track_ids, |
| 672 base::TimeDelta currTime) { | 669 base::TimeDelta currTime) { |
| 673 // Note: We intentionally don't lock here, since we are not accessing any | 670 // Note: We intentionally don't lock here, since we are not accessing any |
| 674 // members directly. | 671 // members directly. |
| 675 DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO); | 672 DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO); |
| 676 bool enabled = false; | 673 bool enabled = false; |
| 677 CHECK(video_stream); | 674 CHECK(video_stream); |
| 678 DCHECK_LE(track_ids.size(), 1u); | 675 DCHECK_LE(track_ids.size(), 1u); |
| 679 if (track_ids.size() > 0) { | 676 if (track_ids.size() > 0) { |
| 680 #if DCHECK_IS_ON() | 677 #if DCHECK_IS_ON() |
| 681 base::AutoLock auto_lock(lock_); | 678 base::AutoLock auto_lock(lock_); |
| 682 DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == video_stream); | 679 DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == video_stream); |
| 683 #endif | 680 #endif |
| 684 enabled = true; | 681 enabled = true; |
| 685 } | 682 } |
| 686 DVLOG(1) << __FUNCTION__ << ": " << (enabled ? "enabling" : "disabling") | 683 DVLOG(1) << __func__ << ": " << (enabled ? "enabling" : "disabling") |
| 687 << " video stream"; | 684 << " video stream"; |
| 688 video_stream->set_enabled(enabled, currTime); | 685 video_stream->set_enabled(enabled, currTime); |
| 689 } | 686 } |
| 690 | 687 |
| 691 bool ChunkDemuxer::EvictCodedFrames(const std::string& id, | 688 bool ChunkDemuxer::EvictCodedFrames(const std::string& id, |
| 692 base::TimeDelta currentMediaTime, | 689 base::TimeDelta currentMediaTime, |
| 693 size_t newDataSize) { | 690 size_t newDataSize) { |
| 694 DVLOG(1) << __FUNCTION__ << "(" << id << ")" | 691 DVLOG(1) << __func__ << "(" << id << ")" |
| 695 << " media_time=" << currentMediaTime.InSecondsF() | 692 << " media_time=" << currentMediaTime.InSecondsF() |
| 696 << " newDataSize=" << newDataSize; | 693 << " newDataSize=" << newDataSize; |
| 697 base::AutoLock auto_lock(lock_); | 694 base::AutoLock auto_lock(lock_); |
| 698 | 695 |
| 699 // Note: The direct conversion from PTS to DTS is safe here, since we don't | 696 // Note: The direct conversion from PTS to DTS is safe here, since we don't |
| 700 // need to know currentTime precisely for GC. GC only needs to know which GOP | 697 // need to know currentTime precisely for GC. GC only needs to know which GOP |
| 701 // currentTime points to. | 698 // currentTime points to. |
| 702 DecodeTimestamp media_time_dts = | 699 DecodeTimestamp media_time_dts = |
| 703 DecodeTimestamp::FromPresentationTime(currentMediaTime); | 700 DecodeTimestamp::FromPresentationTime(currentMediaTime); |
| 704 | 701 |
| 705 DCHECK(!id.empty()); | 702 DCHECK(!id.empty()); |
| 706 MediaSourceStateMap::const_iterator itr = source_state_map_.find(id); | 703 MediaSourceStateMap::const_iterator itr = source_state_map_.find(id); |
| 707 if (itr == source_state_map_.end()) { | 704 if (itr == source_state_map_.end()) { |
| 708 LOG(WARNING) << __FUNCTION__ << " stream " << id << " not found"; | 705 LOG(WARNING) << __func__ << " stream " << id << " not found"; |
| 709 return false; | 706 return false; |
| 710 } | 707 } |
| 711 return itr->second->EvictCodedFrames(media_time_dts, newDataSize); | 708 return itr->second->EvictCodedFrames(media_time_dts, newDataSize); |
| 712 } | 709 } |
| 713 | 710 |
| 714 bool ChunkDemuxer::AppendData(const std::string& id, | 711 bool ChunkDemuxer::AppendData(const std::string& id, |
| 715 const uint8_t* data, | 712 const uint8_t* data, |
| 716 size_t length, | 713 size_t length, |
| 717 TimeDelta append_window_start, | 714 TimeDelta append_window_start, |
| 718 TimeDelta append_window_end, | 715 TimeDelta append_window_end, |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 // Per April 1, 2014 MSE spec editor's draft: | 1179 // Per April 1, 2014 MSE spec editor's draft: |
| 1183 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/ | 1180 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/ |
| 1184 // media-source.html#sourcebuffer-coded-frame-processing | 1181 // media-source.html#sourcebuffer-coded-frame-processing |
| 1185 // 5. If the media segment contains data beyond the current duration, then run | 1182 // 5. If the media segment contains data beyond the current duration, then run |
| 1186 // the duration change algorithm with new duration set to the maximum of | 1183 // the duration change algorithm with new duration set to the maximum of |
| 1187 // the current duration and the group end timestamp. | 1184 // the current duration and the group end timestamp. |
| 1188 | 1185 |
| 1189 if (new_duration <= duration_) | 1186 if (new_duration <= duration_) |
| 1190 return; | 1187 return; |
| 1191 | 1188 |
| 1192 DVLOG(2) << __FUNCTION__ << ": Increasing duration: " | 1189 DVLOG(2) << __func__ << ": Increasing duration: " << duration_.InSecondsF() |
| 1193 << duration_.InSecondsF() << " -> " << new_duration.InSecondsF(); | 1190 << " -> " << new_duration.InSecondsF(); |
| 1194 | 1191 |
| 1195 UpdateDuration(new_duration); | 1192 UpdateDuration(new_duration); |
| 1196 } | 1193 } |
| 1197 | 1194 |
| 1198 void ChunkDemuxer::DecreaseDurationIfNecessary() { | 1195 void ChunkDemuxer::DecreaseDurationIfNecessary() { |
| 1199 lock_.AssertAcquired(); | 1196 lock_.AssertAcquired(); |
| 1200 | 1197 |
| 1201 TimeDelta max_duration; | 1198 TimeDelta max_duration; |
| 1202 | 1199 |
| 1203 for (MediaSourceStateMap::const_iterator itr = source_state_map_.begin(); | 1200 for (MediaSourceStateMap::const_iterator itr = source_state_map_.begin(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 } | 1259 } |
| 1263 | 1260 |
| 1264 void ChunkDemuxer::ShutdownAllStreams() { | 1261 void ChunkDemuxer::ShutdownAllStreams() { |
| 1265 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); | 1262 for (MediaSourceStateMap::iterator itr = source_state_map_.begin(); |
| 1266 itr != source_state_map_.end(); ++itr) { | 1263 itr != source_state_map_.end(); ++itr) { |
| 1267 itr->second->Shutdown(); | 1264 itr->second->Shutdown(); |
| 1268 } | 1265 } |
| 1269 } | 1266 } |
| 1270 | 1267 |
| 1271 } // namespace media | 1268 } // namespace media |
| OLD | NEW |