| Index: media/filters/ffmpeg_demuxer.cc
|
| diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
|
| index 83b1879d1e4eb687f4ca3e3e4f10cb44ee4d1ca0..76411cf0a6f8790555fb7b39c3b99846b5ce8c6f 100644
|
| --- a/media/filters/ffmpeg_demuxer.cc
|
| +++ b/media/filters/ffmpeg_demuxer.cc
|
| @@ -272,6 +272,8 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
|
| last_packet_timestamp_(kNoTimestamp()),
|
| last_packet_duration_(kNoTimestamp()),
|
| video_rotation_(VIDEO_ROTATION_0),
|
| + is_enabled_(true),
|
| + waiting_for_keyframe_(false),
|
| fixup_negative_timestamps_(false) {
|
| DCHECK(demuxer_);
|
|
|
| @@ -358,6 +360,15 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
|
| return;
|
| }
|
|
|
| + if (waiting_for_keyframe_) {
|
| + if (packet.get()->flags & AV_PKT_FLAG_KEY)
|
| + waiting_for_keyframe_ = false;
|
| + else {
|
| + DVLOG(3) << "Dropped non-keyframe pts=" << packet->pts;
|
| + return;
|
| + }
|
| + }
|
| +
|
| #if defined(USE_PROPRIETARY_CODECS)
|
| // Convert the packet if there is a bitstream filter.
|
| if (packet->data && bitstream_converter_ &&
|
| @@ -618,6 +629,12 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
|
| return;
|
| }
|
|
|
| + if (!is_enabled_) {
|
| + DVLOG(1) << "Read from disabled stream, returning EOS";
|
| + base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer());
|
| + return;
|
| + }
|
| +
|
| SatisfyPendingRead();
|
| }
|
|
|
| @@ -681,6 +698,34 @@ VideoRotation FFmpegDemuxerStream::video_rotation() {
|
| return video_rotation_;
|
| }
|
|
|
| +bool FFmpegDemuxerStream::enabled() const {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + return is_enabled_;
|
| +}
|
| +
|
| +void FFmpegDemuxerStream::set_enabled(bool enabled, base::TimeDelta timestamp) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + if (enabled == is_enabled_)
|
| + return;
|
| +
|
| + is_enabled_ = enabled;
|
| + if (is_enabled_) {
|
| + waiting_for_keyframe_ = true;
|
| + if (!stream_restarted_cb_.is_null())
|
| + stream_restarted_cb_.Run(this, timestamp);
|
| + }
|
| + if (!is_enabled_ && !read_cb_.is_null()) {
|
| + DVLOG(1) << "Read from disabled stream, returning EOS";
|
| + base::ResetAndReturn(&read_cb_).Run(kOk, DecoderBuffer::CreateEOSBuffer());
|
| + return;
|
| + }
|
| +}
|
| +
|
| +void FFmpegDemuxerStream::SetStreamRestartedCB(const StreamRestartedCB& cb) {
|
| + DCHECK(!cb.is_null());
|
| + stream_restarted_cb_ = cb;
|
| +}
|
| +
|
| void FFmpegDemuxerStream::SetLiveness(Liveness liveness) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK_EQ(liveness_, LIVENESS_UNKNOWN);
|
| @@ -1131,6 +1176,8 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
|
| AVStream* video_stream = NULL;
|
| VideoDecoderConfig video_config;
|
|
|
| + DCHECK(track_id_to_demux_stream_map_.empty());
|
| +
|
| // If available, |start_time_| will be set to the lowest stream start time.
|
| start_time_ = kInfiniteDuration();
|
|
|
| @@ -1246,6 +1293,9 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
|
| media_track = media_tracks->AddAudioTrack(audio_config, track_id, "main",
|
| track_label, track_language);
|
| media_track->set_id(base::UintToString(track_id));
|
| + DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
|
| + track_id_to_demux_stream_map_.end());
|
| + track_id_to_demux_stream_map_[media_track->id()] = streams_[i];
|
| } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
|
| CHECK(!video_stream);
|
| video_stream = stream;
|
| @@ -1257,6 +1307,9 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
|
| media_track = media_tracks->AddVideoTrack(video_config, track_id, "main",
|
| track_label, track_language);
|
| media_track->set_id(base::UintToString(track_id));
|
| + DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
|
| + track_id_to_demux_stream_map_.end());
|
| + track_id_to_demux_stream_map_[media_track->id()] = streams_[i];
|
| }
|
|
|
| max_duration = std::max(max_duration, streams_[i]->duration());
|
| @@ -1469,6 +1522,38 @@ void FFmpegDemuxer::OnSeekFrameDone(const PipelineStatusCB& cb, int result) {
|
| cb.Run(PIPELINE_OK);
|
| }
|
|
|
| +void FFmpegDemuxer::OnEnabledAudioTracksChanged(
|
| + const std::vector<MediaTrack::Id>& track_ids,
|
| + base::TimeDelta currTime) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + bool enabled = false;
|
| + DemuxerStream* audio_stream = GetStream(DemuxerStream::AUDIO);
|
| + CHECK(audio_stream);
|
| + if (track_ids.size() > 0) {
|
| + DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == audio_stream);
|
| + enabled = true;
|
| + }
|
| + DVLOG(1) << __FUNCTION__ << ": " << (enabled ? "enabling" : "disabling")
|
| + << " audio stream";
|
| + audio_stream->set_enabled(enabled, currTime);
|
| +}
|
| +
|
| +void FFmpegDemuxer::OnSelectedVideoTrackChanged(
|
| + const std::vector<MediaTrack::Id>& track_ids,
|
| + base::TimeDelta currTime) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + bool enabled = false;
|
| + DemuxerStream* video_stream = GetStream(DemuxerStream::VIDEO);
|
| + CHECK(video_stream);
|
| + if (track_ids.size() > 0) {
|
| + DCHECK(track_id_to_demux_stream_map_[track_ids[0]] == video_stream);
|
| + enabled = true;
|
| + }
|
| + DVLOG(1) << __FUNCTION__ << ": " << (enabled ? "enabling" : "disabling")
|
| + << " video stream";
|
| + video_stream->set_enabled(enabled, currTime);
|
| +}
|
| +
|
| void FFmpegDemuxer::ReadFrameIfNeeded() {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| @@ -1556,7 +1641,8 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
|
| }
|
|
|
| FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
|
| - demuxer_stream->EnqueuePacket(std::move(packet));
|
| + if (demuxer_stream->enabled())
|
| + demuxer_stream->EnqueuePacket(std::move(packet));
|
| }
|
|
|
| // Keep reading until we've reached capacity.
|
|
|