Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/audio_file_reader.h" | 5 #include "media/filters/audio_file_reader.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 DCHECK_EQ(audio_data.size(), channels); | 117 DCHECK_EQ(audio_data.size(), channels); |
| 118 if (audio_data.size() != channels) | 118 if (audio_data.size() != channels) |
| 119 return false; | 119 return false; |
| 120 | 120 |
| 121 DCHECK(format_context_ && codec_context_ && codec_); | 121 DCHECK(format_context_ && codec_context_ && codec_); |
| 122 if (!format_context_ || !codec_context_ || !codec_) { | 122 if (!format_context_ || !codec_context_ || !codec_) { |
| 123 DLOG(WARNING) << "AudioFileReader::Read() : reader is not opened!"; | 123 DLOG(WARNING) << "AudioFileReader::Read() : reader is not opened!"; |
| 124 return false; | 124 return false; |
| 125 } | 125 } |
| 126 | 126 |
| 127 scoped_ptr_malloc<int16, ScopedPtrAVFree> output_buffer( | 127 // Holds decoded audio. |
| 128 static_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); | 128 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); |
| 129 | 129 |
| 130 // Read until we hit EOF or we've read the requested number of frames. | 130 // Read until we hit EOF or we've read the requested number of frames. |
| 131 AVPacket avpkt; | 131 AVPacket packet; |
| 132 int result = 0; | 132 int result = 0; |
| 133 size_t current_frame = 0; | 133 size_t current_frame = 0; |
| 134 | 134 |
| 135 while (current_frame < number_of_frames && | 135 while (current_frame < number_of_frames && |
| 136 (result = av_read_frame(format_context_, &avpkt)) >= 0) { | 136 (result = av_read_frame(format_context_, &packet)) >= 0) { |
| 137 int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; | 137 avcodec_get_frame_defaults(av_frame.get()); |
| 138 result = avcodec_decode_audio3(codec_context_, | 138 int frame_decoded = 0; |
| 139 output_buffer.get(), | 139 int result = avcodec_decode_audio4( |
| 140 &out_size, | 140 codec_context_, av_frame.get(), &frame_decoded, &packet); |
| 141 &avpkt); | 141 av_free_packet(&packet); |
| 142 av_free_packet(&avpkt); | |
| 143 | 142 |
| 144 if (result < 0) { | 143 if (result < 0) { |
| 145 DLOG(WARNING) | 144 DLOG(WARNING) |
| 146 << "AudioFileReader::Read() : error in avcodec_decode_audio3() -" | 145 << "AudioFileReader::Read() : error in avcodec_decode_audio3() -" |
| 147 << result; | 146 << result; |
| 148 | 147 |
| 149 // Fail if nothing has been decoded, otherwise return partial data. | 148 // Fail if nothing has been decoded, otherwise return partial data. |
| 150 return current_frame > 0; | 149 return current_frame > 0; |
| 151 } | 150 } |
| 152 | 151 |
| 152 if (!frame_decoded) | |
| 153 continue; | |
| 154 | |
| 153 // Determine the number of sample-frames we just decoded. | 155 // Determine the number of sample-frames we just decoded. |
| 154 size_t bytes_per_sample = | 156 size_t bytes_per_sample = |
| 155 av_get_bytes_per_sample(codec_context_->sample_fmt); | 157 av_get_bytes_per_sample(codec_context_->sample_fmt); |
| 156 size_t frames_read = out_size / (channels * bytes_per_sample); | 158 size_t frames_read = av_frame->nb_samples; |
| 157 | 159 |
| 158 // Truncate, if necessary, if the destination isn't big enough. | 160 // Truncate, if necessary, if the destination isn't big enough. |
| 159 if (current_frame + frames_read > number_of_frames) | 161 if (current_frame + frames_read > number_of_frames) |
| 160 frames_read = number_of_frames - current_frame; | 162 frames_read = number_of_frames - current_frame; |
| 161 | 163 |
| 162 // Deinterleave each channel and convert to 32bit floating-point | 164 // Deinterleave each channel and convert to 32bit floating-point |
| 163 // with nominal range -1.0 -> +1.0. | 165 // with nominal range -1.0 -> +1.0. |
| 164 for (size_t channel_index = 0; channel_index < channels; | 166 for (size_t channel_index = 0; channel_index < channels; |
| 165 ++channel_index) { | 167 ++channel_index) { |
| 166 if (!DeinterleaveAudioChannel(output_buffer.get(), | 168 if (!DeinterleaveAudioChannel(av_frame->data[0], |
| 167 audio_data[channel_index] + current_frame, | 169 audio_data[channel_index] + current_frame, |
| 168 channels, | 170 channels, |
| 169 channel_index, | 171 channel_index, |
| 170 bytes_per_sample, | 172 bytes_per_sample, |
| 171 frames_read)) { | 173 frames_read)) { |
| 172 DLOG(WARNING) | 174 DLOG(WARNING) |
|
rbultje1
2012/06/08 14:29:01
You know when I see this, I cry, because FFmpeg (o
| |
| 173 << "AudioFileReader::Read() : Unsupported sample format : " | 175 << "AudioFileReader::Read() : Unsupported sample format : " |
| 174 << codec_context_->sample_fmt | 176 << codec_context_->sample_fmt |
| 175 << " codec_->id : " << codec_->id; | 177 << " codec_->id : " << codec_->id; |
| 176 return false; | 178 return false; |
| 177 } | 179 } |
| 178 } | 180 } |
| 179 | 181 |
| 180 current_frame += frames_read; | 182 current_frame += frames_read; |
| 181 } | 183 } |
| 182 | 184 |
| 183 return true; | 185 return true; |
| 184 } | 186 } |
| 185 | 187 |
| 186 } // namespace media | 188 } // namespace media |
| OLD | NEW |