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/ffmpeg_demuxer.h" | 5 #include "media/filters/ffmpeg_demuxer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 // TODO(scherkus): Remove early return and reenable time-based capacity | 316 // TODO(scherkus): Remove early return and reenable time-based capacity |
317 // after our data sources support canceling/concurrent reads, see | 317 // after our data sources support canceling/concurrent reads, see |
318 // http://crbug.com/165762 for details. | 318 // http://crbug.com/165762 for details. |
319 return !read_cb_.is_null(); | 319 return !read_cb_.is_null(); |
320 | 320 |
321 // Try to have one second's worth of encoded data per stream. | 321 // Try to have one second's worth of encoded data per stream. |
322 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1); | 322 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1); |
323 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity; | 323 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity; |
324 } | 324 } |
325 | 325 |
326 int FFmpegDemuxerStream::MemoryUsage() const { | |
327 return buffer_queue_.data_size(); | |
328 } | |
329 | |
326 TextKind FFmpegDemuxerStream::GetTextKind() const { | 330 TextKind FFmpegDemuxerStream::GetTextKind() const { |
327 DCHECK_EQ(type_, DemuxerStream::TEXT); | 331 DCHECK_EQ(type_, DemuxerStream::TEXT); |
328 | 332 |
329 if (stream_->disposition & AV_DISPOSITION_CAPTIONS) | 333 if (stream_->disposition & AV_DISPOSITION_CAPTIONS) |
330 return kTextCaptions; | 334 return kTextCaptions; |
331 | 335 |
332 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS) | 336 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS) |
333 return kTextDescriptions; | 337 return kTextDescriptions; |
334 | 338 |
335 if (stream_->disposition & AV_DISPOSITION_METADATA) | 339 if (stream_->disposition & AV_DISPOSITION_METADATA) |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
793 | 797 |
794 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { | 798 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
795 DCHECK(task_runner_->BelongsToCurrentThread()); | 799 DCHECK(task_runner_->BelongsToCurrentThread()); |
796 DCHECK(pending_read_); | 800 DCHECK(pending_read_); |
797 pending_read_ = false; | 801 pending_read_ = false; |
798 | 802 |
799 if (!blocking_thread_.IsRunning() || pending_seek_) { | 803 if (!blocking_thread_.IsRunning() || pending_seek_) { |
800 return; | 804 return; |
801 } | 805 } |
802 | 806 |
803 if (result < 0) { | 807 // Consider the stream as ended if: |
808 // - either underlying ffmpeg returned an error | |
809 // - or any stream reached its maximum memory usage. | |
810 if (result < 0 || IsMaxMemoryReached()) { | |
804 // Update the duration based on the highest elapsed time across all streams | 811 // Update the duration based on the highest elapsed time across all streams |
805 // if it was previously unknown. | 812 // if it was previously unknown. |
806 if (!duration_known_) { | 813 if (!duration_known_) { |
807 base::TimeDelta max_duration; | 814 base::TimeDelta max_duration; |
808 | 815 |
809 for (StreamVector::iterator iter = streams_.begin(); | 816 for (StreamVector::iterator iter = streams_.begin(); |
810 iter != streams_.end(); | 817 iter != streams_.end(); |
811 ++iter) { | 818 ++iter) { |
812 if (!*iter) | 819 if (!*iter) |
813 continue; | 820 continue; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
900 DCHECK(task_runner_->BelongsToCurrentThread()); | 907 DCHECK(task_runner_->BelongsToCurrentThread()); |
901 StreamVector::iterator iter; | 908 StreamVector::iterator iter; |
902 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 909 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
903 if (*iter && (*iter)->HasAvailableCapacity()) { | 910 if (*iter && (*iter)->HasAvailableCapacity()) { |
904 return true; | 911 return true; |
905 } | 912 } |
906 } | 913 } |
907 return false; | 914 return false; |
908 } | 915 } |
909 | 916 |
917 bool FFmpegDemuxer::IsMaxMemoryReached() { | |
918 DCHECK(task_runner_->BelongsToCurrentThread()); | |
919 const int kMaxMemoryForAudioStream = 12 * 1024 * 1024; | |
920 const int kMaxMemoryForVideoStream = 150 * 1024 * 1024; | |
921 StreamVector::iterator iter; | |
922 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | |
923 if (!(*iter)) | |
924 continue; | |
925 switch ((*iter)->type()) { | |
926 case DemuxerStream::VIDEO: | |
927 if ((*iter)->MemoryUsage() >= kMaxMemoryForVideoStream) | |
928 return true; | |
929 break; | |
930 case DemuxerStream::AUDIO: | |
931 if ((*iter)->MemoryUsage() >= kMaxMemoryForAudioStream) | |
932 return true; | |
933 break; | |
934 default: | |
acolwell GONE FROM CHROMIUM
2014/02/18 22:16:20
nit: Please don't use default here. Explicitly ind
damienv1
2014/02/18 23:38:03
I changed the code so that the contribution of eve
| |
935 break; | |
936 } | |
937 } | |
938 return false; | |
939 } | |
940 | |
910 void FFmpegDemuxer::StreamHasEnded() { | 941 void FFmpegDemuxer::StreamHasEnded() { |
911 DCHECK(task_runner_->BelongsToCurrentThread()); | 942 DCHECK(task_runner_->BelongsToCurrentThread()); |
912 StreamVector::iterator iter; | 943 StreamVector::iterator iter; |
913 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 944 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
914 if (!*iter || | 945 if (!*iter || |
915 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { | 946 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { |
916 continue; | 947 continue; |
917 } | 948 } |
918 (*iter)->SetEndOfStream(); | 949 (*iter)->SetEndOfStream(); |
919 } | 950 } |
(...skipping 27 matching lines...) Expand all Loading... | |
947 } | 978 } |
948 for (size_t i = 0; i < buffered.size(); ++i) | 979 for (size_t i = 0; i < buffered.size(); ++i) |
949 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 980 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
950 } | 981 } |
951 | 982 |
952 void FFmpegDemuxer::OnDataSourceError() { | 983 void FFmpegDemuxer::OnDataSourceError() { |
953 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 984 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
954 } | 985 } |
955 | 986 |
956 } // namespace media | 987 } // namespace media |
OLD | NEW |