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

Unified Diff: media/filters/ffmpeg_audio_decoder.cc

Issue 259453003: Introduce AudioDiscardHelper. Refactor audio decoders to use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix x64 type. Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/opus_audio_decoder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_audio_decoder.cc
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index 02af059ac2db969f48ae0b7b9426b1c8f0732b78..fec5da52b81d894d034413fabb36deb9cd86e684 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -9,7 +9,7 @@
#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_decoder_config.h"
-#include "media/base/audio_timestamp_helper.h"
+#include "media/base/audio_discard_helper.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/limits.h"
@@ -127,11 +127,8 @@ static int GetAudioBuffer(struct AVCodecContext* s, AVFrame* frame, int flags) {
FFmpegAudioDecoder::FFmpegAudioDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
- : task_runner_(task_runner),
- state_(kUninitialized),
- av_sample_format_(0),
- last_input_timestamp_(kNoTimestamp()),
- output_frames_to_drop_(0) {}
+ : task_runner_(task_runner), state_(kUninitialized), av_sample_format_(0) {
+}
FFmpegAudioDecoder::~FFmpegAudioDecoder() {
DCHECK_EQ(state_, kUninitialized);
@@ -254,42 +251,20 @@ void FFmpegAudioDecoder::DecodeBuffer(
// Make sure we are notified if http://crbug.com/49709 returns. Issue also
// occurs with some damaged files.
- if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp() &&
- output_timestamp_helper_->base_timestamp() == kNoTimestamp()) {
+ if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp()) {
DVLOG(1) << "Received a buffer without timestamps!";
decode_cb.Run(kDecodeError, NULL);
return;
}
- if (!buffer->end_of_stream()) {
- DCHECK(buffer->timestamp() != kNoTimestamp());
- const bool first_buffer =
- last_input_timestamp_ == kNoTimestamp() &&
- output_timestamp_helper_->base_timestamp() == kNoTimestamp();
- if (first_buffer && codec_context_->codec_id == AV_CODEC_ID_VORBIS &&
- buffer->timestamp() < base::TimeDelta()) {
- // Dropping frames for negative timestamps as outlined in section A.2
- // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html
- DCHECK_EQ(output_frames_to_drop_, 0);
- output_frames_to_drop_ =
- 0.5 +
- -buffer->timestamp().InSecondsF() * config_.samples_per_second();
-
- // If we are dropping samples for Vorbis, the timeline always starts at 0.
- output_timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
- } else {
- if (first_buffer) {
- output_timestamp_helper_->SetBaseTimestamp(buffer->timestamp());
- } else if (buffer->timestamp() < last_input_timestamp_) {
- const base::TimeDelta diff =
- buffer->timestamp() - last_input_timestamp_;
- DLOG(WARNING) << "Input timestamps are not monotonically increasing! "
- << " ts " << buffer->timestamp().InMicroseconds() << " us"
- << " diff " << diff.InMicroseconds() << " us";
- }
-
- last_input_timestamp_ = buffer->timestamp();
- }
+ if (!buffer->end_of_stream() && !discard_helper_->initialized() &&
+ codec_context_->codec_id == AV_CODEC_ID_VORBIS &&
+ buffer->timestamp() < base::TimeDelta()) {
+ // Dropping frames for negative timestamps as outlined in section A.2
+ // in the Vorbis spec. http://xiph.org/vorbis/doc/Vorbis_I_spec.html
+ const int discard_frames =
+ discard_helper_->TimeDeltaToFrames(-buffer->timestamp());
+ discard_helper_->Reset(discard_frames);
}
// Transition to kFlushCodec on the first end of stream buffer.
@@ -321,7 +296,6 @@ void FFmpegAudioDecoder::DecodeBuffer(
bool FFmpegAudioDecoder::FFmpegDecode(
const scoped_refptr<DecoderBuffer>& buffer) {
-
DCHECK(queued_audio_.empty());
AVPacket packet;
@@ -340,7 +314,7 @@ bool FFmpegAudioDecoder::FFmpegDecode(
// skipping end of stream packets since they have a size of zero.
do {
int frame_decoded = 0;
- int result = avcodec_decode_audio4(
+ const int result = avcodec_decode_audio4(
codec_context_.get(), av_frame_.get(), &frame_decoded, &packet);
if (result < 0) {
@@ -364,9 +338,7 @@ bool FFmpegAudioDecoder::FFmpegDecode(
packet.data += result;
scoped_refptr<AudioBuffer> output;
- int decoded_frames = 0;
- int original_frames = 0;
- int channels = DetermineChannels(av_frame_.get());
+ const int channels = DetermineChannels(av_frame_.get());
if (frame_decoded) {
if (av_frame_->sample_rate != config_.samples_per_second() ||
channels != ChannelLayoutToChannelCount(config_.channel_layout()) ||
@@ -392,43 +364,22 @@ bool FFmpegAudioDecoder::FFmpegDecode(
DCHECK_EQ(ChannelLayoutToChannelCount(config_.channel_layout()),
output->channel_count());
- original_frames = av_frame_->nb_samples;
- int unread_frames = output->frame_count() - original_frames;
+ const int unread_frames = output->frame_count() - av_frame_->nb_samples;
DCHECK_GE(unread_frames, 0);
if (unread_frames > 0)
output->TrimEnd(unread_frames);
- // If there are frames to drop, get rid of as many as we can.
- if (output_frames_to_drop_ > 0) {
- int drop = std::min(output->frame_count(), output_frames_to_drop_);
- output->TrimStart(drop);
- output_frames_to_drop_ -= drop;
- }
-
- decoded_frames = output->frame_count();
av_frame_unref(av_frame_.get());
}
// WARNING: |av_frame_| no longer has valid data at this point.
-
- if (decoded_frames > 0) {
- // Set the timestamp/duration once all the extra frames have been
- // discarded.
- output->set_timestamp(output_timestamp_helper_->GetTimestamp());
- output->set_duration(
- output_timestamp_helper_->GetFrameDuration(decoded_frames));
- output_timestamp_helper_->AddFrames(decoded_frames);
- } else if (IsEndOfStream(result, original_frames, buffer)) {
+ const int decoded_frames = frame_decoded ? output->frame_count() : 0;
+ if (IsEndOfStream(result, decoded_frames, buffer)) {
DCHECK_EQ(packet.size, 0);
- output = AudioBuffer::CreateEOSBuffer();
- } else {
- // In case all the frames in the buffer were dropped.
- output = NULL;
- }
-
- if (output.get())
+ queued_audio_.push_back(AudioBuffer::CreateEOSBuffer());
+ } else if (discard_helper_->ProcessBuffers(buffer, output)) {
queued_audio_.push_back(output);
-
+ }
} while (packet.size > 0);
return true;
@@ -476,10 +427,7 @@ bool FFmpegAudioDecoder::ConfigureDecoder() {
// Success!
av_frame_.reset(av_frame_alloc());
- output_timestamp_helper_.reset(
- new AudioTimestampHelper(config_.samples_per_second()));
- ResetTimestampState();
-
+ discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second()));
av_sample_format_ = codec_context_->sample_fmt;
if (codec_context_->channels !=
@@ -493,14 +441,12 @@ bool FFmpegAudioDecoder::ConfigureDecoder() {
return false;
}
- output_frames_to_drop_ = config_.codec_delay();
+ ResetTimestampState();
return true;
}
void FFmpegAudioDecoder::ResetTimestampState() {
- output_timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
- last_input_timestamp_ = kNoTimestamp();
- output_frames_to_drop_ = 0;
+ discard_helper_->Reset(config_.codec_delay());
}
} // namespace media
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/opus_audio_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698