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 <limits> | |
8 #include <string> | 9 #include <string> |
9 | 10 |
10 #include "base/base64.h" | 11 #include "base/base64.h" |
11 #include "base/bind.h" | 12 #include "base/bind.h" |
12 #include "base/callback.h" | 13 #include "base/callback.h" |
13 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 16 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/metrics/sparse_histogram.h" | 17 #include "base/metrics/sparse_histogram.h" |
17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 // TODO(scherkus): Remove early return and reenable time-based capacity | 317 // TODO(scherkus): Remove early return and reenable time-based capacity |
317 // after our data sources support canceling/concurrent reads, see | 318 // after our data sources support canceling/concurrent reads, see |
318 // http://crbug.com/165762 for details. | 319 // http://crbug.com/165762 for details. |
319 return !read_cb_.is_null(); | 320 return !read_cb_.is_null(); |
320 | 321 |
321 // Try to have one second's worth of encoded data per stream. | 322 // Try to have one second's worth of encoded data per stream. |
322 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1); | 323 const base::TimeDelta kCapacity = base::TimeDelta::FromSeconds(1); |
323 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity; | 324 return buffer_queue_.IsEmpty() || buffer_queue_.Duration() < kCapacity; |
324 } | 325 } |
325 | 326 |
327 int FFmpegDemuxerStream::MemoryUsage() const { | |
328 return buffer_queue_.data_size(); | |
329 } | |
330 | |
326 TextKind FFmpegDemuxerStream::GetTextKind() const { | 331 TextKind FFmpegDemuxerStream::GetTextKind() const { |
327 DCHECK_EQ(type_, DemuxerStream::TEXT); | 332 DCHECK_EQ(type_, DemuxerStream::TEXT); |
328 | 333 |
329 if (stream_->disposition & AV_DISPOSITION_CAPTIONS) | 334 if (stream_->disposition & AV_DISPOSITION_CAPTIONS) |
330 return kTextCaptions; | 335 return kTextCaptions; |
331 | 336 |
332 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS) | 337 if (stream_->disposition & AV_DISPOSITION_DESCRIPTIONS) |
333 return kTextDescriptions; | 338 return kTextDescriptions; |
334 | 339 |
335 if (stream_->disposition & AV_DISPOSITION_METADATA) | 340 if (stream_->disposition & AV_DISPOSITION_METADATA) |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
793 | 798 |
794 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { | 799 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
795 DCHECK(task_runner_->BelongsToCurrentThread()); | 800 DCHECK(task_runner_->BelongsToCurrentThread()); |
796 DCHECK(pending_read_); | 801 DCHECK(pending_read_); |
797 pending_read_ = false; | 802 pending_read_ = false; |
798 | 803 |
799 if (!blocking_thread_.IsRunning() || pending_seek_) { | 804 if (!blocking_thread_.IsRunning() || pending_seek_) { |
800 return; | 805 return; |
801 } | 806 } |
802 | 807 |
803 if (result < 0) { | 808 // Consider the stream as ended if: |
809 // - either underlying ffmpeg returned an error | |
810 // - or FFMpegDemuxer reached the maximum allowed memory usage. | |
811 if (result < 0 || IsMaxMemoryReached()) { | |
804 // Update the duration based on the highest elapsed time across all streams | 812 // Update the duration based on the highest elapsed time across all streams |
805 // if it was previously unknown. | 813 // if it was previously unknown. |
806 if (!duration_known_) { | 814 if (!duration_known_) { |
807 base::TimeDelta max_duration; | 815 base::TimeDelta max_duration; |
808 | 816 |
809 for (StreamVector::iterator iter = streams_.begin(); | 817 for (StreamVector::iterator iter = streams_.begin(); |
810 iter != streams_.end(); | 818 iter != streams_.end(); |
811 ++iter) { | 819 ++iter) { |
812 if (!*iter) | 820 if (!*iter) |
813 continue; | 821 continue; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
900 DCHECK(task_runner_->BelongsToCurrentThread()); | 908 DCHECK(task_runner_->BelongsToCurrentThread()); |
901 StreamVector::iterator iter; | 909 StreamVector::iterator iter; |
902 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 910 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
903 if (*iter && (*iter)->HasAvailableCapacity()) { | 911 if (*iter && (*iter)->HasAvailableCapacity()) { |
904 return true; | 912 return true; |
905 } | 913 } |
906 } | 914 } |
907 return false; | 915 return false; |
908 } | 916 } |
909 | 917 |
918 bool FFmpegDemuxer::IsMaxMemoryReached() { | |
damienv1
2014/02/19 00:15:09
Better design: have a MemoryUsage function (just l
damienv1
2014/02/19 00:27:13
Done.
| |
919 DCHECK(task_runner_->BelongsToCurrentThread()); | |
920 // Max allowed memory usage, all streams combined. | |
921 const int kMemoryLimit = 150 * 1024 * 1024; | |
922 int memory_usage = 0; | |
923 StreamVector::iterator iter; | |
damienv1
2014/02/19 00:27:13
To be removed (already in the for loop).
| |
924 for (StreamVector::iterator iter = streams_.begin(); | |
925 iter != streams_.end(); ++iter) { | |
926 if (!(*iter)) | |
927 continue; | |
928 DCHECK_LE((*iter)->MemoryUsage(), | |
929 std::numeric_limits<int>::max() - memory_usage); | |
930 memory_usage += (*iter)->MemoryUsage(); | |
acolwell GONE FROM CHROMIUM
2014/02/18 23:57:49
nit: I'm a little more worried about overflow here
damienv1
2014/02/19 00:27:13
I was a bit worried as well. So I agree and I am g
| |
931 } | |
932 return (memory_usage >= kMemoryLimit); | |
933 } | |
934 | |
910 void FFmpegDemuxer::StreamHasEnded() { | 935 void FFmpegDemuxer::StreamHasEnded() { |
911 DCHECK(task_runner_->BelongsToCurrentThread()); | 936 DCHECK(task_runner_->BelongsToCurrentThread()); |
912 StreamVector::iterator iter; | 937 StreamVector::iterator iter; |
913 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 938 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
914 if (!*iter || | 939 if (!*iter || |
915 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { | 940 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { |
916 continue; | 941 continue; |
917 } | 942 } |
918 (*iter)->SetEndOfStream(); | 943 (*iter)->SetEndOfStream(); |
919 } | 944 } |
(...skipping 27 matching lines...) Expand all Loading... | |
947 } | 972 } |
948 for (size_t i = 0; i < buffered.size(); ++i) | 973 for (size_t i = 0; i < buffered.size(); ++i) |
949 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 974 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
950 } | 975 } |
951 | 976 |
952 void FFmpegDemuxer::OnDataSourceError() { | 977 void FFmpegDemuxer::OnDataSourceError() { |
953 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 978 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
954 } | 979 } |
955 | 980 |
956 } // namespace media | 981 } // namespace media |
OLD | NEW |