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 |