| 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 <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 AVPacket packet; | 124 AVPacket packet; |
| 125 int current_frame = 0; | 125 int current_frame = 0; |
| 126 bool continue_decoding = true; | 126 bool continue_decoding = true; |
| 127 | 127 |
| 128 while (current_frame < audio_bus->frames() && continue_decoding && | 128 while (current_frame < audio_bus->frames() && continue_decoding && |
| 129 ReadPacket(&packet)) { | 129 ReadPacket(&packet)) { |
| 130 // Make a shallow copy of packet so we can slide packet.data as frames are | 130 // Make a shallow copy of packet so we can slide packet.data as frames are |
| 131 // decoded from the packet; otherwise av_free_packet() will corrupt memory. | 131 // decoded from the packet; otherwise av_free_packet() will corrupt memory. |
| 132 AVPacket packet_temp = packet; | 132 AVPacket packet_temp = packet; |
| 133 do { | 133 do { |
| 134 avcodec_get_frame_defaults(av_frame.get()); | |
| 135 int frame_decoded = 0; | 134 int frame_decoded = 0; |
| 136 int result = avcodec_decode_audio4( | 135 int result = avcodec_decode_audio4( |
| 137 codec_context_, av_frame.get(), &frame_decoded, &packet_temp); | 136 codec_context_, av_frame.get(), &frame_decoded, &packet_temp); |
| 138 | 137 |
| 139 if (result < 0) { | 138 if (result < 0) { |
| 140 DLOG(WARNING) | 139 DLOG(WARNING) |
| 141 << "AudioFileReader::Read() : error in avcodec_decode_audio4() -" | 140 << "AudioFileReader::Read() : error in avcodec_decode_audio4() -" |
| 142 << result; | 141 << result; |
| 143 break; | 142 break; |
| 144 } | 143 } |
| 145 | 144 |
| 146 // Update packet size and data pointer in case we need to call the decoder | 145 // Update packet size and data pointer in case we need to call the decoder |
| 147 // with the remaining bytes from this packet. | 146 // with the remaining bytes from this packet. |
| 148 packet_temp.size -= result; | 147 packet_temp.size -= result; |
| 149 packet_temp.data += result; | 148 packet_temp.data += result; |
| 150 | 149 |
| 151 if (!frame_decoded) | 150 if (!frame_decoded) |
| 152 continue; | 151 continue; |
| 153 | 152 |
| 154 // Determine the number of sample-frames we just decoded. Check overflow. | 153 // Determine the number of sample-frames we just decoded. Check overflow. |
| 155 int frames_read = av_frame->nb_samples; | 154 int frames_read = av_frame->nb_samples; |
| 156 if (frames_read < 0) { | 155 if (frames_read < 0) { |
| 157 continue_decoding = false; | 156 continue_decoding = false; |
| 157 av_frame_unref(av_frame.get()); |
| 158 break; | 158 break; |
| 159 } | 159 } |
| 160 | 160 |
| 161 #ifdef CHROMIUM_NO_AVFRAME_CHANNELS | 161 #ifdef CHROMIUM_NO_AVFRAME_CHANNELS |
| 162 int channels = av_get_channel_layout_nb_channels( | 162 int channels = av_get_channel_layout_nb_channels( |
| 163 av_frame->channel_layout); | 163 av_frame->channel_layout); |
| 164 #else | 164 #else |
| 165 int channels = av_frame->channels; | 165 int channels = av_frame->channels; |
| 166 #endif | 166 #endif |
| 167 if (av_frame->sample_rate != sample_rate_ || | 167 if (av_frame->sample_rate != sample_rate_ || |
| 168 channels != channels_ || | 168 channels != channels_ || |
| 169 av_frame->format != av_sample_format_) { | 169 av_frame->format != av_sample_format_) { |
| 170 DLOG(ERROR) << "Unsupported midstream configuration change!" | 170 DLOG(ERROR) << "Unsupported midstream configuration change!" |
| 171 << " Sample Rate: " << av_frame->sample_rate << " vs " | 171 << " Sample Rate: " << av_frame->sample_rate << " vs " |
| 172 << sample_rate_ | 172 << sample_rate_ |
| 173 << ", Channels: " << channels << " vs " | 173 << ", Channels: " << channels << " vs " |
| 174 << channels_ | 174 << channels_ |
| 175 << ", Sample Format: " << av_frame->format << " vs " | 175 << ", Sample Format: " << av_frame->format << " vs " |
| 176 << av_sample_format_; | 176 << av_sample_format_; |
| 177 | 177 |
| 178 // This is an unrecoverable error, so bail out. | 178 // This is an unrecoverable error, so bail out. |
| 179 continue_decoding = false; | 179 continue_decoding = false; |
| 180 av_frame_unref(av_frame.get()); |
| 180 break; | 181 break; |
| 181 } | 182 } |
| 182 | 183 |
| 183 // Truncate, if necessary, if the destination isn't big enough. | 184 // Truncate, if necessary, if the destination isn't big enough. |
| 184 if (current_frame + frames_read > audio_bus->frames()) { | 185 if (current_frame + frames_read > audio_bus->frames()) { |
| 185 DLOG(ERROR) << "Truncating decoded data due to output size."; | 186 DLOG(ERROR) << "Truncating decoded data due to output size."; |
| 186 frames_read = audio_bus->frames() - current_frame; | 187 frames_read = audio_bus->frames() - current_frame; |
| 187 } | 188 } |
| 188 | 189 |
| 189 // Deinterleave each channel and convert to 32bit floating-point with | 190 // Deinterleave each channel and convert to 32bit floating-point with |
| (...skipping 13 matching lines...) Expand all Loading... |
| 203 for (int ch = 0; ch < audio_bus->channels(); ++ch) { | 204 for (int ch = 0; ch < audio_bus->channels(); ++ch) { |
| 204 memcpy(audio_bus->channel(ch) + current_frame, | 205 memcpy(audio_bus->channel(ch) + current_frame, |
| 205 av_frame->extended_data[ch], sizeof(float) * frames_read); | 206 av_frame->extended_data[ch], sizeof(float) * frames_read); |
| 206 } | 207 } |
| 207 } else { | 208 } else { |
| 208 audio_bus->FromInterleavedPartial( | 209 audio_bus->FromInterleavedPartial( |
| 209 av_frame->data[0], current_frame, frames_read, bytes_per_sample); | 210 av_frame->data[0], current_frame, frames_read, bytes_per_sample); |
| 210 } | 211 } |
| 211 | 212 |
| 212 current_frame += frames_read; | 213 current_frame += frames_read; |
| 214 av_frame_unref(av_frame.get()); |
| 213 } while (packet_temp.size > 0); | 215 } while (packet_temp.size > 0); |
| 214 av_free_packet(&packet); | 216 av_free_packet(&packet); |
| 215 } | 217 } |
| 216 | 218 |
| 217 // Zero any remaining frames. | 219 // Zero any remaining frames. |
| 218 audio_bus->ZeroFramesPartial( | 220 audio_bus->ZeroFramesPartial( |
| 219 current_frame, audio_bus->frames() - current_frame); | 221 current_frame, audio_bus->frames() - current_frame); |
| 220 | 222 |
| 221 // Returns the actual number of sample-frames decoded. | 223 // Returns the actual number of sample-frames decoded. |
| 222 // Ideally this represents the "true" exact length of the file. | 224 // Ideally this represents the "true" exact length of the file. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 249 if (output_packet->stream_index != stream_index_) { | 251 if (output_packet->stream_index != stream_index_) { |
| 250 av_free_packet(output_packet); | 252 av_free_packet(output_packet); |
| 251 continue; | 253 continue; |
| 252 } | 254 } |
| 253 return true; | 255 return true; |
| 254 } | 256 } |
| 255 return false; | 257 return false; |
| 256 } | 258 } |
| 257 | 259 |
| 258 } // namespace media | 260 } // namespace media |
| OLD | NEW |