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

Unified Diff: media/filters/audio_file_reader.cc

Issue 10869085: Update FFmpegAudioDecoder to support multi-frame packets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Fix WebAudio. Created 8 years, 4 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
Index: media/filters/audio_file_reader.cc
diff --git a/media/filters/audio_file_reader.cc b/media/filters/audio_file_reader.cc
index a3bb92e1dce829b302f9c49e2036d99b8587fc05..3c9ce58cdeeca310b4442598d24ba160a05103dc 100644
--- a/media/filters/audio_file_reader.cc
+++ b/media/filters/audio_file_reader.cc
@@ -17,7 +17,8 @@ namespace media {
AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
: protocol_(protocol),
format_context_(NULL),
- codec_context_(NULL) {
+ codec_context_(NULL),
+ stream_index_(0) {
}
AudioFileReader::~AudioFileReader() {
@@ -71,6 +72,7 @@ bool AudioFileReader::Open() {
AVCodecContext* c = format_context_->streams[i]->codec;
if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
codec_context_ = c;
+ stream_index_ = i;
break;
}
}
@@ -124,42 +126,62 @@ bool AudioFileReader::Read(AudioBus* audio_bus) {
// Read until we hit EOF or we've read the requested number of frames.
AVPacket packet;
- int result = 0;
int current_frame = 0;
-
- while (current_frame < audio_bus->frames() &&
- (result = av_read_frame(format_context_, &packet)) >= 0) {
- avcodec_get_frame_defaults(av_frame.get());
- int frame_decoded = 0;
- int result = avcodec_decode_audio4(
- codec_context_, av_frame.get(), &frame_decoded, &packet);
- av_free_packet(&packet);
-
- if (result < 0) {
- DLOG(WARNING)
- << "AudioFileReader::Read() : error in avcodec_decode_audio3() -"
- << result;
- break;
- }
-
- if (!frame_decoded)
+ bool continue_decoding = true;
+
+ while (current_frame < audio_bus->frames() && continue_decoding &&
+ av_read_frame(format_context_, &packet) >= 0 &&
+ av_dup_packet(&packet) >= 0) {
+ // Skip packets from other streams.
DaleCurtis 2012/08/28 20:19:17 Noticed this while testing, previously handing a c
+ if (packet.stream_index != stream_index_) {
+ av_free_packet(&packet);
continue;
+ }
- // Determine the number of sample-frames we just decoded. Check overflow.
- int frames_read = av_frame->nb_samples;
- if (frames_read < 0)
- break;
-
- // Truncate, if necessary, if the destination isn't big enough.
- if (current_frame + frames_read > audio_bus->frames())
- frames_read = audio_bus->frames() - current_frame;
-
- // Deinterleave each channel and convert to 32bit floating-point
- // with nominal range -1.0 -> +1.0.
- audio_bus->FromInterleavedPartial(
- av_frame->data[0], current_frame, frames_read, bytes_per_sample);
-
- current_frame += frames_read;
+ // Make a shallow copy of packet so we can slide packet.data as frames are
+ // decoded from the packet; otherwise av_free_packet() will corrupt memory.
+ AVPacket packet_temp = packet;
+ do {
+ avcodec_get_frame_defaults(av_frame.get());
+ int frame_decoded = 0;
+ int result = avcodec_decode_audio4(
+ codec_context_, av_frame.get(), &frame_decoded, &packet_temp);
+
+ if (result < 0) {
+ DLOG(WARNING)
+ << "AudioFileReader::Read() : error in avcodec_decode_audio4() -"
+ << result;
+ continue_decoding = false;
+ break;
+ }
+
+ // Update packet size and data pointer in case we need to call the decoder
+ // with the remaining bytes from this packet.
+ packet_temp.size -= result;
+ packet_temp.data += result;
+
+ if (!frame_decoded)
acolwell GONE FROM CHROMIUM 2012/08/28 20:31:53 Does there need to be a if (packet_temp.size == 0)
DaleCurtis 2012/08/28 21:41:17 I'm not sure I follow; this continue affects the i
acolwell GONE FROM CHROMIUM 2012/08/28 21:45:04 oh.. right..nevermind. I'm so used to 'continue' m
+ continue;
+
+ // Determine the number of sample-frames we just decoded. Check overflow.
+ int frames_read = av_frame->nb_samples;
+ if (frames_read < 0) {
+ continue_decoding = false;
+ break;
+ }
+
+ // Truncate, if necessary, if the destination isn't big enough.
+ if (current_frame + frames_read > audio_bus->frames())
+ frames_read = audio_bus->frames() - current_frame;
+
+ // Deinterleave each channel and convert to 32bit floating-point
+ // with nominal range -1.0 -> +1.0.
+ audio_bus->FromInterleavedPartial(
+ av_frame->data[0], current_frame, frames_read, bytes_per_sample);
+
+ current_frame += frames_read;
+ } while (packet_temp.size > 0);
+ av_free_packet(&packet);
}
// Zero any remaining frames.

Powered by Google App Engine
This is Rietveld 408576698