Chromium Code Reviews| Index: media/filters/ffmpeg_demuxer.cc |
| diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc |
| index 80cb7adcbee7a0c13c7630b2d14d4b676db7af61..346a9146511ca449b4867d2cda22c1565095505f 100644 |
| --- a/media/filters/ffmpeg_demuxer.cc |
| +++ b/media/filters/ffmpeg_demuxer.cc |
| @@ -270,6 +270,21 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) { |
| buffer->set_discard_padding(std::make_pair( |
| FramesToTimeDelta(discard_front_samples, samples_per_second), |
| FramesToTimeDelta(discard_end_samples, samples_per_second))); |
| + } else if (type() == AUDIO && stream_->codec->delay > 0 && |
| + packet->pts <= stream_->start_time && |
| + stream_->codec->codec_id == AV_CODEC_ID_OPUS) { |
| + // FFmpeg does not encode the opus pre-skip value within the packet side |
| + // data, so when we encounter the first packet in a stream ensure the |
| + // codec delay is applied per spec. |
| + // |
| + // |stream_->codec->delay| has been added to packet->pts automatically by |
| + // ffmpeg, so the delta between the start time and the packet pts is the |
| + // amount of delay remaining to trim. |
| + buffer->set_discard_padding(std::make_pair( |
| + FramesToTimeDelta(std::min(static_cast<int64_t>(packet->duration), |
| + stream_->start_time - packet->pts), |
| + audio_decoder_config().samples_per_second()), |
| + base::TimeDelta())); |
|
wolenetz
2015/07/29 21:57:27
Could there be a single packet that is both the st
DaleCurtis
2015/07/30 01:28:14
Done.
|
| } |
| if (decrypt_config) |
| @@ -628,9 +643,19 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
| // Additionally, to workaround limitations in how we expose seekable ranges to |
| // Blink (http://crbug.com/137275), we also want to clamp seeks before the |
| // start time to the start time. |
| - const base::TimeDelta seek_time = |
| - start_time_ < base::TimeDelta() ? time + start_time_ |
| - : time < start_time_ ? start_time_ : time; |
| + base::TimeDelta seek_time = start_time_ < base::TimeDelta() |
| + ? time + start_time_ |
| + : time < start_time_ ? start_time_ : time; |
| + |
| + // When seeking in an opus stream we need to ensure we deliver enough data to |
| + // satisfy the seek preroll; otherwise the audio at the actual seek time will |
| + // not be entirely accurate. |
| + FFmpegDemuxerStream* audio_stream = GetFFmpegStream(DemuxerStream::AUDIO); |
| + if (audio_stream) { |
| + const AudioDecoderConfig& config = audio_stream->audio_decoder_config(); |
| + if (config.codec() == kCodecOpus) |
| + seek_time = std::max(start_time_, seek_time - config.seek_preroll()); |
| + } |
| // Choose the seeking stream based on whether it contains the seek time, if no |
| // match can be found prefer the preferred stream. |
| @@ -1204,19 +1229,6 @@ void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { |
| packet.swap(new_packet); |
| } |
| - // Special case for opus in ogg. FFmpeg is pre-trimming the codec delay |
| - // from the packet timestamp. Chrome expects to handle this itself inside |
| - // the decoder, so shift timestamps by the delay in this case. |
| - // TODO(dalecurtis): Try to get fixed upstream. See http://crbug.com/328207 |
| - if (strcmp(glue_->format_context()->iformat->name, "ogg") == 0) { |
| - const AVCodecContext* codec_context = |
| - glue_->format_context()->streams[packet->stream_index]->codec; |
| - if (codec_context->codec_id == AV_CODEC_ID_OPUS && |
| - codec_context->delay > 0) { |
| - packet->pts += codec_context->delay; |
| - } |
| - } |
| - |
| FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; |
| demuxer_stream->EnqueuePacket(packet.Pass()); |
| } |