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

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: Use size_t instead of int. 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
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 size_t FFmpegDemuxerStream::MemoryUsage() const {
DaleCurtis 2014/02/19 20:56:21 You can declare this inline as memory_usage() if y
damienv1 2014/02/19 22:07:28 Prefer to keep the current approach (similar to Ha
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 10 matching lines...) Expand all
346 350
347 // static 351 // static
348 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp( 352 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
349 const AVRational& time_base, int64 timestamp) { 353 const AVRational& time_base, int64 timestamp) {
350 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE)) 354 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
351 return kNoTimestamp(); 355 return kNoTimestamp();
352 356
353 return ConvertFromTimeBase(time_base, timestamp); 357 return ConvertFromTimeBase(time_base, timestamp);
354 } 358 }
355 359
360 // Max allowed memory usage, all streams combined.
361 static const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024;
DaleCurtis 2014/02/19 20:56:21 Since this is only used in one spot, just stick it
damienv1 2014/02/19 22:07:28 Done.
362
356 // 363 //
357 // FFmpegDemuxer 364 // FFmpegDemuxer
358 // 365 //
359 FFmpegDemuxer::FFmpegDemuxer( 366 FFmpegDemuxer::FFmpegDemuxer(
360 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 367 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
361 DataSource* data_source, 368 DataSource* data_source,
362 const NeedKeyCB& need_key_cb, 369 const NeedKeyCB& need_key_cb,
363 const scoped_refptr<MediaLog>& media_log) 370 const scoped_refptr<MediaLog>& media_log)
364 : host_(NULL), 371 : host_(NULL),
365 task_runner_(task_runner), 372 task_runner_(task_runner),
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 800
794 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { 801 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
795 DCHECK(task_runner_->BelongsToCurrentThread()); 802 DCHECK(task_runner_->BelongsToCurrentThread());
796 DCHECK(pending_read_); 803 DCHECK(pending_read_);
797 pending_read_ = false; 804 pending_read_ = false;
798 805
799 if (!blocking_thread_.IsRunning() || pending_seek_) { 806 if (!blocking_thread_.IsRunning() || pending_seek_) {
800 return; 807 return;
801 } 808 }
802 809
803 if (result < 0) { 810 // Consider the stream as ended if:
811 // - either underlying ffmpeg returned an error
812 // - or FFMpegDemuxer reached the maximum allowed memory usage.
813 if (result < 0 || IsMaxMemoryUsageReached()) {
804 // Update the duration based on the highest elapsed time across all streams 814 // Update the duration based on the highest elapsed time across all streams
805 // if it was previously unknown. 815 // if it was previously unknown.
806 if (!duration_known_) { 816 if (!duration_known_) {
807 base::TimeDelta max_duration; 817 base::TimeDelta max_duration;
808 818
809 for (StreamVector::iterator iter = streams_.begin(); 819 for (StreamVector::iterator iter = streams_.begin();
810 iter != streams_.end(); 820 iter != streams_.end();
811 ++iter) { 821 ++iter) {
812 if (!*iter) 822 if (!*iter)
813 continue; 823 continue;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 DCHECK(task_runner_->BelongsToCurrentThread()); 910 DCHECK(task_runner_->BelongsToCurrentThread());
901 StreamVector::iterator iter; 911 StreamVector::iterator iter;
902 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 912 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
903 if (*iter && (*iter)->HasAvailableCapacity()) { 913 if (*iter && (*iter)->HasAvailableCapacity()) {
904 return true; 914 return true;
905 } 915 }
906 } 916 }
907 return false; 917 return false;
908 } 918 }
909 919
920 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
921 DCHECK(task_runner_->BelongsToCurrentThread());
922 size_t memory_left = kDemuxerMemoryLimit;
923 for (StreamVector::const_iterator iter = streams_.begin();
924 iter != streams_.end(); ++iter) {
925 if (!(*iter))
926 continue;
927
928 size_t stream_memory_usage = (*iter)->MemoryUsage();
929 if (stream_memory_usage > memory_left)
930 return true;
931 memory_left -= stream_memory_usage;
932 }
933 return false;
934 }
935
910 void FFmpegDemuxer::StreamHasEnded() { 936 void FFmpegDemuxer::StreamHasEnded() {
911 DCHECK(task_runner_->BelongsToCurrentThread()); 937 DCHECK(task_runner_->BelongsToCurrentThread());
912 StreamVector::iterator iter; 938 StreamVector::iterator iter;
913 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 939 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
914 if (!*iter || 940 if (!*iter ||
915 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { 941 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) {
916 continue; 942 continue;
917 } 943 }
918 (*iter)->SetEndOfStream(); 944 (*iter)->SetEndOfStream();
919 } 945 }
(...skipping 27 matching lines...) Expand all
947 } 973 }
948 for (size_t i = 0; i < buffered.size(); ++i) 974 for (size_t i = 0; i < buffered.size(); ++i)
949 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); 975 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
950 } 976 }
951 977
952 void FFmpegDemuxer::OnDataSourceError() { 978 void FFmpegDemuxer::OnDataSourceError() {
953 host_->OnDemuxerError(PIPELINE_ERROR_READ); 979 host_->OnDemuxerError(PIPELINE_ERROR_READ);
954 } 980 }
955 981
956 } // namespace media 982 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698