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 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 pending_seek_(false), | 741 pending_seek_(false), |
742 data_source_(data_source), | 742 data_source_(data_source), |
743 media_log_(media_log), | 743 media_log_(media_log), |
744 bitrate_(0), | 744 bitrate_(0), |
745 start_time_(kNoTimestamp()), | 745 start_time_(kNoTimestamp()), |
746 preferred_stream_for_seeking_(-1, kNoTimestamp()), | 746 preferred_stream_for_seeking_(-1, kNoTimestamp()), |
747 fallback_stream_for_seeking_(-1, kNoTimestamp()), | 747 fallback_stream_for_seeking_(-1, kNoTimestamp()), |
748 text_enabled_(false), | 748 text_enabled_(false), |
749 duration_known_(false), | 749 duration_known_(false), |
750 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), | 750 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), |
751 stream_memory_usage_(0), | |
752 weak_factory_(this) { | 751 weak_factory_(this) { |
753 DCHECK(task_runner_.get()); | 752 DCHECK(task_runner_.get()); |
754 DCHECK(data_source_); | 753 DCHECK(data_source_); |
755 } | 754 } |
756 | 755 |
757 FFmpegDemuxer::~FFmpegDemuxer() {} | 756 FFmpegDemuxer::~FFmpegDemuxer() {} |
758 | 757 |
759 void FFmpegDemuxer::Stop() { | 758 void FFmpegDemuxer::Stop() { |
760 DCHECK(task_runner_->BelongsToCurrentThread()); | 759 DCHECK(task_runner_->BelongsToCurrentThread()); |
761 | 760 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 std::string language = stream->GetMetadata("language"); | 917 std::string language = stream->GetMetadata("language"); |
919 | 918 |
920 // TODO: Implement "id" metadata in FFMPEG. | 919 // TODO: Implement "id" metadata in FFMPEG. |
921 // See: http://crbug.com/323183 | 920 // See: http://crbug.com/323183 |
922 host_->AddTextStream(stream, TextTrackConfig(kind, title, language, | 921 host_->AddTextStream(stream, TextTrackConfig(kind, title, language, |
923 std::string())); | 922 std::string())); |
924 } | 923 } |
925 } | 924 } |
926 | 925 |
927 int64_t FFmpegDemuxer::GetMemoryUsage() const { | 926 int64_t FFmpegDemuxer::GetMemoryUsage() const { |
928 base::AutoLock locker(stream_memory_usage_lock_); | 927 int64_t allocation_size = 0; |
929 return stream_memory_usage_; | 928 for (const auto& stream : streams_) { |
| 929 if (stream) |
| 930 allocation_size += stream->MemoryUsage(); |
| 931 } |
| 932 return allocation_size; |
930 } | 933 } |
931 | 934 |
932 // Helper for calculating the bitrate of the media based on information stored | 935 // Helper for calculating the bitrate of the media based on information stored |
933 // in |format_context| or failing that the size and duration of the media. | 936 // in |format_context| or failing that the size and duration of the media. |
934 // | 937 // |
935 // Returns 0 if a bitrate could not be determined. | 938 // Returns 0 if a bitrate could not be determined. |
936 static int CalculateBitrate( | 939 static int CalculateBitrate( |
937 AVFormatContext* format_context, | 940 AVFormatContext* format_context, |
938 const base::TimeDelta& duration, | 941 const base::TimeDelta& duration, |
939 int64 filesize_in_bytes) { | 942 int64 filesize_in_bytes) { |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 | 1375 |
1373 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { | 1376 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
1374 DCHECK(task_runner_->BelongsToCurrentThread()); | 1377 DCHECK(task_runner_->BelongsToCurrentThread()); |
1375 DCHECK(pending_read_); | 1378 DCHECK(pending_read_); |
1376 pending_read_ = false; | 1379 pending_read_ = false; |
1377 | 1380 |
1378 if (!blocking_thread_.IsRunning() || pending_seek_) { | 1381 if (!blocking_thread_.IsRunning() || pending_seek_) { |
1379 return; | 1382 return; |
1380 } | 1383 } |
1381 | 1384 |
1382 // Max allowed memory usage, all streams combined. | |
1383 const int64_t kDemuxerMemoryLimit = 150 * 1024 * 1024; | |
1384 const bool is_max_memory_usage_reached = | |
1385 UpdateMemoryUsage() > kDemuxerMemoryLimit; | |
1386 | |
1387 // Consider the stream as ended if: | 1385 // Consider the stream as ended if: |
1388 // - either underlying ffmpeg returned an error | 1386 // - either underlying ffmpeg returned an error |
1389 // - or FFMpegDemuxer reached the maximum allowed memory usage. | 1387 // - or FFMpegDemuxer reached the maximum allowed memory usage. |
1390 if (result < 0 || is_max_memory_usage_reached) { | 1388 if (result < 0 || IsMaxMemoryUsageReached()) { |
1391 // Update the duration based on the highest elapsed time across all streams | 1389 // Update the duration based on the highest elapsed time across all streams |
1392 // if it was previously unknown. | 1390 // if it was previously unknown. |
1393 if (!duration_known_) { | 1391 if (!duration_known_) { |
1394 base::TimeDelta max_duration; | 1392 base::TimeDelta max_duration; |
1395 | 1393 |
1396 for (StreamVector::iterator iter = streams_.begin(); | 1394 for (StreamVector::iterator iter = streams_.begin(); |
1397 iter != streams_.end(); | 1395 iter != streams_.end(); |
1398 ++iter) { | 1396 ++iter) { |
1399 if (!*iter) | 1397 if (!*iter) |
1400 continue; | 1398 continue; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 DCHECK(task_runner_->BelongsToCurrentThread()); | 1444 DCHECK(task_runner_->BelongsToCurrentThread()); |
1447 StreamVector::iterator iter; | 1445 StreamVector::iterator iter; |
1448 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 1446 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
1449 if (*iter && (*iter)->HasAvailableCapacity()) { | 1447 if (*iter && (*iter)->HasAvailableCapacity()) { |
1450 return true; | 1448 return true; |
1451 } | 1449 } |
1452 } | 1450 } |
1453 return false; | 1451 return false; |
1454 } | 1452 } |
1455 | 1453 |
1456 int64_t FFmpegDemuxer::UpdateMemoryUsage() { | 1454 bool FFmpegDemuxer::IsMaxMemoryUsageReached() const { |
1457 DCHECK(task_runner_->BelongsToCurrentThread()); | 1455 DCHECK(task_runner_->BelongsToCurrentThread()); |
1458 | 1456 |
1459 base::AutoLock locker(stream_memory_usage_lock_); | 1457 // Max allowed memory usage, all streams combined. |
1460 stream_memory_usage_ = 0; | 1458 const size_t kDemuxerMemoryLimit = 150 * 1024 * 1024; |
1461 for (const auto& stream : streams_) { | 1459 |
1462 if (stream) | 1460 size_t memory_left = kDemuxerMemoryLimit; |
1463 stream_memory_usage_ += stream->MemoryUsage(); | 1461 for (StreamVector::const_iterator iter = streams_.begin(); |
| 1462 iter != streams_.end(); ++iter) { |
| 1463 if (!(*iter)) |
| 1464 continue; |
| 1465 |
| 1466 size_t stream_memory_usage = (*iter)->MemoryUsage(); |
| 1467 if (stream_memory_usage > memory_left) |
| 1468 return true; |
| 1469 memory_left -= stream_memory_usage; |
1464 } | 1470 } |
1465 return stream_memory_usage_; | 1471 return false; |
1466 } | 1472 } |
1467 | 1473 |
1468 void FFmpegDemuxer::StreamHasEnded() { | 1474 void FFmpegDemuxer::StreamHasEnded() { |
1469 DCHECK(task_runner_->BelongsToCurrentThread()); | 1475 DCHECK(task_runner_->BelongsToCurrentThread()); |
1470 StreamVector::iterator iter; | 1476 StreamVector::iterator iter; |
1471 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 1477 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
1472 if (!*iter) | 1478 if (!*iter) |
1473 continue; | 1479 continue; |
1474 (*iter)->SetEndOfStream(); | 1480 (*iter)->SetEndOfStream(); |
1475 } | 1481 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 | 1518 |
1513 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { | 1519 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { |
1514 DCHECK(task_runner_->BelongsToCurrentThread()); | 1520 DCHECK(task_runner_->BelongsToCurrentThread()); |
1515 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. | 1521 for (const auto& stream : streams_) { // |stream| is a ref to a pointer. |
1516 if (stream) | 1522 if (stream) |
1517 stream->SetLiveness(liveness); | 1523 stream->SetLiveness(liveness); |
1518 } | 1524 } |
1519 } | 1525 } |
1520 | 1526 |
1521 } // namespace media | 1527 } // namespace media |
OLD | NEW |