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