| 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 | 
|---|