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

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

Issue 2719883005: Revert of Replace FFmpegDemuxer thread per element with base::TaskScheduler. (Closed)
Patch Set: Created 3 years, 9 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') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | 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 <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/base64.h" 12 #include "base/base64.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/metrics/sparse_histogram.h" 18 #include "base/metrics/sparse_histogram.h"
19 #include "base/single_thread_task_runner.h" 19 #include "base/single_thread_task_runner.h"
20 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
23 #include "base/sys_byteorder.h" 23 #include "base/sys_byteorder.h"
24 #include "base/task_runner_util.h" 24 #include "base/task_runner_util.h"
25 #include "base/task_scheduler/post_task.h"
26 #include "base/threading/sequenced_worker_pool.h"
27 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/time/time.h" 26 #include "base/time/time.h"
29 #include "media/audio/sample_rates.h" 27 #include "media/audio/sample_rates.h"
30 #include "media/base/bind_to_current_loop.h" 28 #include "media/base/bind_to_current_loop.h"
31 #include "media/base/decrypt_config.h" 29 #include "media/base/decrypt_config.h"
32 #include "media/base/limits.h" 30 #include "media/base/limits.h"
33 #include "media/base/media_log.h" 31 #include "media/base/media_log.h"
34 #include "media/base/media_tracks.h" 32 #include "media/base/media_tracks.h"
35 #include "media/base/timestamp_constants.h" 33 #include "media/base/timestamp_constants.h"
36 #include "media/base/video_codecs.h" 34 #include "media/base/video_codecs.h"
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 // FFmpegDemuxer 838 // FFmpegDemuxer
841 // 839 //
842 FFmpegDemuxer::FFmpegDemuxer( 840 FFmpegDemuxer::FFmpegDemuxer(
843 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 841 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
844 DataSource* data_source, 842 DataSource* data_source,
845 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 843 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb,
846 const MediaTracksUpdatedCB& media_tracks_updated_cb, 844 const MediaTracksUpdatedCB& media_tracks_updated_cb,
847 const scoped_refptr<MediaLog>& media_log) 845 const scoped_refptr<MediaLog>& media_log)
848 : host_(NULL), 846 : host_(NULL),
849 task_runner_(task_runner), 847 task_runner_(task_runner),
850 // FFmpeg has no asynchronous API, so we use base::WaitableEvents inside 848 blocking_thread_("FFmpegDemuxer"),
851 // the BlockingUrlProtocol to handle hops to the render thread for network
852 // reads and seeks.
853 blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
854 base::TaskTraits().MayBlock().WithBaseSyncPrimitives().WithPriority(
855 base::TaskPriority::USER_BLOCKING))),
856 stopped_(false),
857 pending_read_(false), 849 pending_read_(false),
858 data_source_(data_source), 850 data_source_(data_source),
859 media_log_(media_log), 851 media_log_(media_log),
860 bitrate_(0), 852 bitrate_(0),
861 start_time_(kNoTimestamp), 853 start_time_(kNoTimestamp),
862 text_enabled_(false), 854 text_enabled_(false),
863 duration_known_(false), 855 duration_known_(false),
864 encrypted_media_init_data_cb_(encrypted_media_init_data_cb), 856 encrypted_media_init_data_cb_(encrypted_media_init_data_cb),
865 media_tracks_updated_cb_(media_tracks_updated_cb), 857 media_tracks_updated_cb_(media_tracks_updated_cb),
866 cancel_pending_seek_factory_(this), 858 cancel_pending_seek_factory_(this),
867 weak_factory_(this) { 859 weak_factory_(this) {
868 DCHECK(task_runner_.get()); 860 DCHECK(task_runner_.get());
869 DCHECK(data_source_); 861 DCHECK(data_source_);
870 DCHECK(!media_tracks_updated_cb_.is_null()); 862 DCHECK(!media_tracks_updated_cb_.is_null());
871 } 863 }
872 864
873 FFmpegDemuxer::~FFmpegDemuxer() { 865 FFmpegDemuxer::~FFmpegDemuxer() {
874 // NOTE: This class is not destroyed on |task_runner|, so we must ensure that 866 // NOTE: This class is not destroyed on |task_runner|, so we must ensure that
875 // there are no outstanding WeakPtrs by the time we reach here. 867 // there are no outstanding WeakPtrs by the time we reach here.
876 DCHECK(!weak_factory_.HasWeakPtrs()); 868 DCHECK(!weak_factory_.HasWeakPtrs());
877
878 // There may be outstanding tasks in the blocking pool which are trying to use
879 // these members, so release them in sequence with any outstanding calls. The
880 // earlier call to Abort() on |data_source_| prevents further access to it.
881 blocking_task_runner_->DeleteSoon(FROM_HERE, url_protocol_.release());
882 blocking_task_runner_->DeleteSoon(FROM_HERE, glue_.release());
883 } 869 }
884 870
885 std::string FFmpegDemuxer::GetDisplayName() const { 871 std::string FFmpegDemuxer::GetDisplayName() const {
886 return "FFmpegDemuxer"; 872 return "FFmpegDemuxer";
887 } 873 }
888 874
889 void FFmpegDemuxer::Initialize(DemuxerHost* host, 875 void FFmpegDemuxer::Initialize(DemuxerHost* host,
890 const PipelineStatusCB& status_cb, 876 const PipelineStatusCB& status_cb,
891 bool enable_text_tracks) { 877 bool enable_text_tracks) {
892 DCHECK(task_runner_->BelongsToCurrentThread()); 878 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 13 matching lines...) Expand all
906 // available, so add a metadata entry to ensure some is always present. 892 // available, so add a metadata entry to ensure some is always present.
907 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0); 893 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0);
908 894
909 // Ensure ffmpeg doesn't give up too early while looking for stream params; 895 // Ensure ffmpeg doesn't give up too early while looking for stream params;
910 // this does not increase the amount of data downloaded. The default value 896 // this does not increase the amount of data downloaded. The default value
911 // is 5 AV_TIME_BASE units (1 second each), which prevents some oddly muxed 897 // is 5 AV_TIME_BASE units (1 second each), which prevents some oddly muxed
912 // streams from being detected properly; this value was chosen arbitrarily. 898 // streams from being detected properly; this value was chosen arbitrarily.
913 format_context->max_analyze_duration = 60 * AV_TIME_BASE; 899 format_context->max_analyze_duration = 60 * AV_TIME_BASE;
914 900
915 // Open the AVFormatContext using our glue layer. 901 // Open the AVFormatContext using our glue layer.
902 CHECK(blocking_thread_.Start());
916 base::PostTaskAndReplyWithResult( 903 base::PostTaskAndReplyWithResult(
917 blocking_task_runner_.get(), FROM_HERE, 904 blocking_thread_.task_runner().get(), FROM_HERE,
918 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())), 905 base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
919 base::Bind(&FFmpegDemuxer::OnOpenContextDone, weak_factory_.GetWeakPtr(), 906 base::Bind(&FFmpegDemuxer::OnOpenContextDone, weak_factory_.GetWeakPtr(),
920 status_cb)); 907 status_cb));
921 } 908 }
922 909
923 void FFmpegDemuxer::AbortPendingReads() { 910 void FFmpegDemuxer::AbortPendingReads() {
924 DCHECK(task_runner_->BelongsToCurrentThread()); 911 DCHECK(task_runner_->BelongsToCurrentThread());
925 912
926 // If Stop() has been called, then drop this call. 913 // If Stop() has been called, then drop this call.
927 if (stopped_) 914 if (!blocking_thread_.IsRunning())
928 return; 915 return;
929 916
930 // This should only be called after the demuxer has been initialized. 917 // This should only be called after the demuxer has been initialized.
931 DCHECK_GT(streams_.size(), 0u); 918 DCHECK_GT(streams_.size(), 0u);
932 919
933 // Abort all outstanding reads. 920 // Abort all outstanding reads.
934 for (const auto& stream : streams_) { 921 for (const auto& stream : streams_) {
935 if (stream) 922 if (stream)
936 stream->Abort(); 923 stream->Abort();
937 } 924 }
938 925
939 // It's important to invalidate read/seek completion callbacks to avoid any 926 // It's important to invalidate read/seek completion callbacks to avoid any
940 // errors that occur because of the data source abort. 927 // errors that occur because of the data source abort.
941 weak_factory_.InvalidateWeakPtrs(); 928 weak_factory_.InvalidateWeakPtrs();
942 data_source_->Abort(); 929 data_source_->Abort();
943 930
944 // Aborting the read may cause EOF to be marked, undo this. 931 // Aborting the read may cause EOF to be marked, undo this.
945 blocking_task_runner_->PostTask( 932 blocking_thread_.task_runner()->PostTask(
946 FROM_HERE, base::Bind(&UnmarkEndOfStream, glue_->format_context())); 933 FROM_HERE, base::Bind(&UnmarkEndOfStream, glue_->format_context()));
947 pending_read_ = false; 934 pending_read_ = false;
948 935
949 // TODO(dalecurtis): We probably should report PIPELINE_ERROR_ABORT here 936 // TODO(dalecurtis): We probably should report PIPELINE_ERROR_ABORT here
950 // instead to avoid any preroll work that may be started upon return, but 937 // instead to avoid any preroll work that may be started upon return, but
951 // currently the PipelineImpl does not know how to handle this. 938 // currently the PipelineImpl does not know how to handle this.
952 if (!pending_seek_cb_.is_null()) 939 if (!pending_seek_cb_.is_null())
953 base::ResetAndReturn(&pending_seek_cb_).Run(PIPELINE_OK); 940 base::ResetAndReturn(&pending_seek_cb_).Run(PIPELINE_OK);
954 } 941 }
955 942
956 void FFmpegDemuxer::Stop() { 943 void FFmpegDemuxer::Stop() {
957 DCHECK(task_runner_->BelongsToCurrentThread()); 944 DCHECK(task_runner_->BelongsToCurrentThread());
958 945
959 // The order of Stop() and Abort() is important here. If Abort() is called 946 // The order of Stop() and Abort() is important here. If Abort() is called
960 // first, control may pass into FFmpeg where it can destruct buffers that are 947 // first, control may pass into FFmpeg where it can destruct buffers that are
961 // in the process of being fulfilled by the DataSource. 948 // in the process of being fulfilled by the DataSource.
962 data_source_->Stop(); 949 data_source_->Stop();
963 url_protocol_->Abort(); 950 url_protocol_->Abort();
964 951
952 // This will block until all tasks complete. Note that after this returns it's
953 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this
954 // thread. Each of the reply task methods must check whether we've stopped the
955 // thread and drop their results on the floor.
956 blocking_thread_.Stop();
957
965 for (const auto& stream : streams_) { 958 for (const auto& stream : streams_) {
966 if (stream) 959 if (stream)
967 stream->Stop(); 960 stream->Stop();
968 } 961 }
969 962
970 data_source_ = NULL; 963 data_source_ = NULL;
971 964
972 // Invalidate WeakPtrs on |task_runner_|, destruction may happen on another 965 // Invalidate WeakPtrs on |task_runner_|, destruction may happen on another
973 // thread. We don't need to wait for any outstanding tasks since they will all 966 // thread.
974 // fail to return after invalidating WeakPtrs.
975 stopped_ = true;
976 weak_factory_.InvalidateWeakPtrs(); 967 weak_factory_.InvalidateWeakPtrs();
977 cancel_pending_seek_factory_.InvalidateWeakPtrs(); 968 cancel_pending_seek_factory_.InvalidateWeakPtrs();
978 } 969 }
979 970
980 void FFmpegDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {} 971 void FFmpegDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {}
981 972
982 void FFmpegDemuxer::CancelPendingSeek(base::TimeDelta seek_time) { 973 void FFmpegDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {
983 if (task_runner_->BelongsToCurrentThread()) { 974 if (task_runner_->BelongsToCurrentThread()) {
984 AbortPendingReads(); 975 AbortPendingReads();
985 } else { 976 } else {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 // be demuxed. It's an open question whether FFmpeg should fix this: 1015 // be demuxed. It's an open question whether FFmpeg should fix this:
1025 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html 1016 // http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2014-June/159212.html
1026 // Tracked by http://crbug.com/387996. 1017 // Tracked by http://crbug.com/387996.
1027 FFmpegDemuxerStream* demux_stream = FindPreferredStreamForSeeking(seek_time); 1018 FFmpegDemuxerStream* demux_stream = FindPreferredStreamForSeeking(seek_time);
1028 DCHECK(demux_stream); 1019 DCHECK(demux_stream);
1029 const AVStream* seeking_stream = demux_stream->av_stream(); 1020 const AVStream* seeking_stream = demux_stream->av_stream();
1030 DCHECK(seeking_stream); 1021 DCHECK(seeking_stream);
1031 1022
1032 pending_seek_cb_ = cb; 1023 pending_seek_cb_ = cb;
1033 base::PostTaskAndReplyWithResult( 1024 base::PostTaskAndReplyWithResult(
1034 blocking_task_runner_.get(), FROM_HERE, 1025 blocking_thread_.task_runner().get(), FROM_HERE,
1035 base::Bind(&av_seek_frame, glue_->format_context(), seeking_stream->index, 1026 base::Bind(&av_seek_frame, glue_->format_context(), seeking_stream->index,
1036 ConvertToTimeBase(seeking_stream->time_base, seek_time), 1027 ConvertToTimeBase(seeking_stream->time_base, seek_time),
1037 // Always seek to a timestamp <= to the desired timestamp. 1028 // Always seek to a timestamp <= to the desired timestamp.
1038 AVSEEK_FLAG_BACKWARD), 1029 AVSEEK_FLAG_BACKWARD),
1039 base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr())); 1030 base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_factory_.GetWeakPtr()));
1040 } 1031 }
1041 1032
1042 base::Time FFmpegDemuxer::GetTimelineOffset() const { 1033 base::Time FFmpegDemuxer::GetTimelineOffset() const {
1043 return timeline_offset_; 1034 return timeline_offset_;
1044 } 1035 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 // Do math in floating point as we'd overflow an int64_t if the filesize was 1152 // Do math in floating point as we'd overflow an int64_t if the filesize was
1162 // larger than ~1073GB. 1153 // larger than ~1073GB.
1163 double bytes = filesize_in_bytes; 1154 double bytes = filesize_in_bytes;
1164 double duration_us = duration.InMicroseconds(); 1155 double duration_us = duration.InMicroseconds();
1165 return bytes * 8000000.0 / duration_us; 1156 return bytes * 8000000.0 / duration_us;
1166 } 1157 }
1167 1158
1168 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb, 1159 void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
1169 bool result) { 1160 bool result) {
1170 DCHECK(task_runner_->BelongsToCurrentThread()); 1161 DCHECK(task_runner_->BelongsToCurrentThread());
1171 if (stopped_) { 1162 if (!blocking_thread_.IsRunning()) {
1172 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; 1163 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
1173 status_cb.Run(PIPELINE_ERROR_ABORT); 1164 status_cb.Run(PIPELINE_ERROR_ABORT);
1174 return; 1165 return;
1175 } 1166 }
1176 1167
1177 if (!result) { 1168 if (!result) {
1178 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": open context failed"; 1169 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": open context failed";
1179 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN); 1170 status_cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
1180 return; 1171 return;
1181 } 1172 }
1182 1173
1183 // Fully initialize AVFormatContext by parsing the stream a little. 1174 // Fully initialize AVFormatContext by parsing the stream a little.
1184 base::PostTaskAndReplyWithResult( 1175 base::PostTaskAndReplyWithResult(
1185 blocking_task_runner_.get(), FROM_HERE, 1176 blocking_thread_.task_runner().get(),
1186 base::Bind(&avformat_find_stream_info, glue_->format_context(), 1177 FROM_HERE,
1178 base::Bind(&avformat_find_stream_info,
1179 glue_->format_context(),
1187 static_cast<AVDictionary**>(NULL)), 1180 static_cast<AVDictionary**>(NULL)),
1188 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone, 1181 base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone,
1189 weak_factory_.GetWeakPtr(), status_cb)); 1182 weak_factory_.GetWeakPtr(),
1183 status_cb));
1190 } 1184 }
1191 1185
1192 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, 1186 void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
1193 int result) { 1187 int result) {
1194 DCHECK(task_runner_->BelongsToCurrentThread()); 1188 DCHECK(task_runner_->BelongsToCurrentThread());
1195 if (stopped_ || !data_source_) { 1189 if (!blocking_thread_.IsRunning() || !data_source_) {
1196 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; 1190 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
1197 status_cb.Run(PIPELINE_ERROR_ABORT); 1191 status_cb.Run(PIPELINE_ERROR_ABORT);
1198 return; 1192 return;
1199 } 1193 }
1200 1194
1201 if (result < 0) { 1195 if (result < 0) {
1202 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() 1196 MEDIA_LOG(ERROR, media_log_) << GetDisplayName()
1203 << ": find stream info failed"; 1197 << ": find stream info failed";
1204 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE); 1198 status_cb.Run(DEMUXER_ERROR_COULD_NOT_PARSE);
1205 return; 1199 return;
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 } 1599 }
1606 1600
1607 NOTREACHED(); 1601 NOTREACHED();
1608 return nullptr; 1602 return nullptr;
1609 } 1603 }
1610 1604
1611 void FFmpegDemuxer::OnSeekFrameDone(int result) { 1605 void FFmpegDemuxer::OnSeekFrameDone(int result) {
1612 DCHECK(task_runner_->BelongsToCurrentThread()); 1606 DCHECK(task_runner_->BelongsToCurrentThread());
1613 CHECK(!pending_seek_cb_.is_null()); 1607 CHECK(!pending_seek_cb_.is_null());
1614 1608
1615 if (stopped_) { 1609 if (!blocking_thread_.IsRunning()) {
1616 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state"; 1610 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": bad state";
1617 base::ResetAndReturn(&pending_seek_cb_).Run(PIPELINE_ERROR_ABORT); 1611 base::ResetAndReturn(&pending_seek_cb_).Run(PIPELINE_ERROR_ABORT);
1618 return; 1612 return;
1619 } 1613 }
1620 1614
1621 if (result < 0) { 1615 if (result < 0) {
1622 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being 1616 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
1623 // captured from stdout and contaminates testing. 1617 // captured from stdout and contaminates testing.
1624 // TODO(scherkus): Implement this properly and signal error (BUG=23447). 1618 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
1625 VLOG(1) << "Not implemented"; 1619 VLOG(1) << "Not implemented";
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 if (selected_stream) { 1685 if (selected_stream) {
1692 DVLOG(1) << __func__ << ": enabling stream " << selected_stream; 1686 DVLOG(1) << __func__ << ": enabling stream " << selected_stream;
1693 selected_stream->set_enabled(true, curr_time); 1687 selected_stream->set_enabled(true, curr_time);
1694 } 1688 }
1695 } 1689 }
1696 1690
1697 void FFmpegDemuxer::ReadFrameIfNeeded() { 1691 void FFmpegDemuxer::ReadFrameIfNeeded() {
1698 DCHECK(task_runner_->BelongsToCurrentThread()); 1692 DCHECK(task_runner_->BelongsToCurrentThread());
1699 1693
1700 // Make sure we have work to do before reading. 1694 // Make sure we have work to do before reading.
1701 if (stopped_ || !StreamsHaveAvailableCapacity() || pending_read_ || 1695 if (!blocking_thread_.IsRunning() || !StreamsHaveAvailableCapacity() ||
1702 !pending_seek_cb_.is_null()) { 1696 pending_read_ || !pending_seek_cb_.is_null()) {
1703 return; 1697 return;
1704 } 1698 }
1705 1699
1706 // Allocate and read an AVPacket from the media. Save |packet_ptr| since 1700 // Allocate and read an AVPacket from the media. Save |packet_ptr| since
1707 // evaluation order of packet.get() and base::Passed(&packet) is 1701 // evaluation order of packet.get() and base::Passed(&packet) is
1708 // undefined. 1702 // undefined.
1709 ScopedAVPacket packet(new AVPacket()); 1703 ScopedAVPacket packet(new AVPacket());
1710 AVPacket* packet_ptr = packet.get(); 1704 AVPacket* packet_ptr = packet.get();
1711 1705
1712 pending_read_ = true; 1706 pending_read_ = true;
1713 base::PostTaskAndReplyWithResult( 1707 base::PostTaskAndReplyWithResult(
1714 blocking_task_runner_.get(), FROM_HERE, 1708 blocking_thread_.task_runner().get(),
1709 FROM_HERE,
1715 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr), 1710 base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
1716 base::Bind(&FFmpegDemuxer::OnReadFrameDone, weak_factory_.GetWeakPtr(), 1711 base::Bind(&FFmpegDemuxer::OnReadFrameDone,
1712 weak_factory_.GetWeakPtr(),
1717 base::Passed(&packet))); 1713 base::Passed(&packet)));
1718 } 1714 }
1719 1715
1720 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { 1716 void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
1721 DCHECK(task_runner_->BelongsToCurrentThread()); 1717 DCHECK(task_runner_->BelongsToCurrentThread());
1722 DCHECK(pending_read_); 1718 DCHECK(pending_read_);
1723 pending_read_ = false; 1719 pending_read_ = false;
1724 1720
1725 if (stopped_ || !pending_seek_cb_.is_null()) 1721 if (!blocking_thread_.IsRunning() || !pending_seek_cb_.is_null())
1726 return; 1722 return;
1727 1723
1728 // Consider the stream as ended if: 1724 // Consider the stream as ended if:
1729 // - either underlying ffmpeg returned an error 1725 // - either underlying ffmpeg returned an error
1730 // - or FFMpegDemuxer reached the maximum allowed memory usage. 1726 // - or FFMpegDemuxer reached the maximum allowed memory usage.
1731 if (result < 0 || IsMaxMemoryUsageReached()) { 1727 if (result < 0 || IsMaxMemoryUsageReached()) {
1732 DVLOG(1) << __func__ << " result=" << result 1728 DVLOG(1) << __func__ << " result=" << result
1733 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached(); 1729 << " IsMaxMemoryUsageReached=" << IsMaxMemoryUsageReached();
1734 // Update the duration based on the highest elapsed time across all streams. 1730 // Update the duration based on the highest elapsed time across all streams.
1735 base::TimeDelta max_duration; 1731 base::TimeDelta max_duration;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 1836
1841 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1837 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1842 DCHECK(task_runner_->BelongsToCurrentThread()); 1838 DCHECK(task_runner_->BelongsToCurrentThread());
1843 for (const auto& stream : streams_) { 1839 for (const auto& stream : streams_) {
1844 if (stream) 1840 if (stream)
1845 stream->SetLiveness(liveness); 1841 stream->SetLiveness(liveness);
1846 } 1842 }
1847 } 1843 }
1848 1844
1849 } // namespace media 1845 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698