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

Unified Diff: media/filters/audio_file_reader.cc

Issue 2655783004: Decode entire in-memory file for WebAudio (Closed)
Patch Set: Use int, not size_t. Created 3 years, 10 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/audio_file_reader.h ('k') | media/filters/audio_file_reader_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/audio_file_reader.cc
diff --git a/media/filters/audio_file_reader.cc b/media/filters/audio_file_reader.cc
index 582ca9cdc7fbbde62cbefc4bea56a84563da4ebc..3878f436d7b495e238d5541117093d4183eaefcb 100644
--- a/media/filters/audio_file_reader.cc
+++ b/media/filters/audio_file_reader.cc
@@ -7,11 +7,13 @@
#include <stddef.h>
#include <cmath>
+#include <vector>
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/time/time.h"
#include "media/base/audio_bus.h"
+#include "media/base/audio_sample_types.h"
#include "media/ffmpeg/ffmpeg_common.h"
namespace media {
@@ -33,14 +35,7 @@ AudioFileReader::~AudioFileReader() {
}
bool AudioFileReader::Open() {
- if (!OpenDemuxer())
- return false;
- if (!OpenDecoder())
- return false;
-
- // If the duration is unknown, fail out; this API can not work with streams of
- // unknown duration currently.
- return glue_->format_context()->duration != AV_NOPTS_VALUE;
+ return OpenDemuxer() && OpenDecoder();
}
bool AudioFileReader::OpenDemuxer() {
@@ -127,31 +122,29 @@ bool AudioFileReader::OpenDecoder() {
return true;
}
+bool AudioFileReader::HasKnownDuration() const {
+ return glue_->format_context()->duration != AV_NOPTS_VALUE;
+}
+
void AudioFileReader::Close() {
codec_context_.reset();
glue_.reset();
}
-int AudioFileReader::Read(AudioBus* audio_bus) {
- DCHECK(glue_.get() && codec_context_) <<
- "AudioFileReader::Read() : reader is not opened!";
-
- DCHECK_EQ(audio_bus->channels(), channels());
- if (audio_bus->channels() != channels())
- return 0;
-
+int AudioFileReader::Read(
+ std::vector<std::unique_ptr<AudioBus>>* decoded_audio_packets) {
+ DCHECK(glue_.get() && codec_context_)
+ << "AudioFileReader::Read() : reader is not opened!";
size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
// Holds decoded audio.
std::unique_ptr<AVFrame, ScopedPtrAVFreeFrame> av_frame(av_frame_alloc());
- // Read until we hit EOF or we've read the requested number of frames.
AVPacket packet;
- int current_frame = 0;
+ int total_frames = 0;
bool continue_decoding = true;
- while (current_frame < audio_bus->frames() && continue_decoding &&
- ReadPacket(&packet)) {
+ while (continue_decoding && ReadPacket(&packet)) {
// Make a shallow copy of packet so we can slide packet.data as frames are
// decoded from the packet; otherwise av_packet_unref() will corrupt memory.
AVPacket packet_temp = packet;
@@ -164,6 +157,8 @@ int AudioFileReader::Read(AudioBus* audio_bus) {
&frame_decoded, &packet_temp);
if (result < 0) {
+ // Unable to decode this current packet. We'll skip it and
+ // continue decoding the next packet.
DLOG(WARNING)
<< "AudioFileReader::Read() : error in avcodec_decode_audio4() -"
<< result;
@@ -186,68 +181,51 @@ int AudioFileReader::Read(AudioBus* audio_bus) {
}
#ifdef CHROMIUM_NO_AVFRAME_CHANNELS
- int channels = av_get_channel_layout_nb_channels(
- av_frame->channel_layout);
+ int channels =
+ av_get_channel_layout_nb_channels(av_frame->channel_layout);
#else
int channels = av_frame->channels;
#endif
- if (av_frame->sample_rate != sample_rate_ ||
- channels != channels_ ||
+ if (av_frame->sample_rate != sample_rate_ || channels != channels_ ||
av_frame->format != av_sample_format_) {
DLOG(ERROR) << "Unsupported midstream configuration change!"
<< " Sample Rate: " << av_frame->sample_rate << " vs "
- << sample_rate_
- << ", Channels: " << channels << " vs "
- << channels_
- << ", Sample Format: " << av_frame->format << " vs "
- << av_sample_format_;
+ << sample_rate_ << ", Channels: " << channels << " vs "
+ << channels_ << ", Sample Format: " << av_frame->format
+ << " vs " << av_sample_format_;
- // This is an unrecoverable error, so bail out.
+ // This is an unrecoverable error, so bail out. We'll return
+ // whatever we've decoded up to this point.
continue_decoding = false;
break;
}
- // Truncate, if necessary, if the destination isn't big enough.
- if (current_frame + frames_read > audio_bus->frames()) {
- DLOG(ERROR) << "Truncating decoded data due to output size.";
- frames_read = audio_bus->frames() - current_frame;
- }
-
// Deinterleave each channel and convert to 32bit floating-point with
// nominal range -1.0 -> +1.0. If the output is already in float planar
// format, just copy it into the AudioBus.
+ decoded_audio_packets->emplace_back(
+ AudioBus::Create(channels, frames_read));
+ AudioBus* audio_bus = decoded_audio_packets->back().get();
+
if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) {
- float* decoded_audio_data = reinterpret_cast<float*>(av_frame->data[0]);
- int channels = audio_bus->channels();
- for (int ch = 0; ch < channels; ++ch) {
- float* bus_data = audio_bus->channel(ch) + current_frame;
- for (int i = 0, offset = ch; i < frames_read;
- ++i, offset += channels) {
- bus_data[i] = decoded_audio_data[offset];
- }
- }
+ audio_bus->FromInterleaved<Float32SampleTypeTraits>(
+ reinterpret_cast<float*>(av_frame->data[0]), frames_read);
} else if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLTP) {
for (int ch = 0; ch < audio_bus->channels(); ++ch) {
- memcpy(audio_bus->channel(ch) + current_frame,
- av_frame->extended_data[ch], sizeof(float) * frames_read);
+ memcpy(audio_bus->channel(ch), av_frame->extended_data[ch],
+ sizeof(float) * frames_read);
}
} else {
- audio_bus->FromInterleavedPartial(
- av_frame->data[0], current_frame, frames_read, bytes_per_sample);
+ audio_bus->FromInterleaved(av_frame->data[0], frames_read,
+ bytes_per_sample);
}
- current_frame += frames_read;
+ total_frames += frames_read;
} while (packet_temp.size > 0);
av_packet_unref(&packet);
}
- // Zero any remaining frames.
- audio_bus->ZeroFramesPartial(
- current_frame, audio_bus->frames() - current_frame);
-
- // Returns the actual number of sample-frames decoded.
- // Ideally this represents the "true" exact length of the file.
- return current_frame;
+ return total_frames;
}
base::TimeDelta AudioFileReader::GetDuration() const {
« no previous file with comments | « media/filters/audio_file_reader.h ('k') | media/filters/audio_file_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698