Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(440)

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 164233005: Cap the memory usage in FFMpegDemuxer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW
« media/base/decoder_buffer_queue.cc ('K') | « media/filters/ffmpeg_demuxer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698