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

Side by Side Diff: media/filters/audio_file_reader.cc

Issue 12224114: Guard against midstream audio configuration changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/logging.h" 7 #include "base/logging.h"
8 #include "base/time.h" 8 #include "base/time.h"
9 #include "media/base/audio_bus.h" 9 #include "media/base/audio_bus.h"
10 #include "media/ffmpeg/ffmpeg_common.h" 10 #include "media/ffmpeg/ffmpeg_common.h"
11 #include "media/filters/ffmpeg_glue.h" 11 #include "media/filters/ffmpeg_glue.h"
12 12
13 namespace media { 13 namespace media {
14 14
15 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) 15 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
16 : codec_context_(NULL), 16 : codec_context_(NULL),
17 stream_index_(0), 17 stream_index_(0),
18 protocol_(protocol) { 18 protocol_(protocol),
19 channels_(0),
20 sample_rate_(0),
21 av_sample_format_(0) {
19 } 22 }
20 23
21 AudioFileReader::~AudioFileReader() { 24 AudioFileReader::~AudioFileReader() {
22 Close(); 25 Close();
23 } 26 }
24 27
25 int AudioFileReader::channels() const {
26 return codec_context_->channels;
27 }
28
29 int AudioFileReader::sample_rate() const {
30 return codec_context_->sample_rate;
31 }
32
33 base::TimeDelta AudioFileReader::duration() const { 28 base::TimeDelta AudioFileReader::duration() const {
34 const AVRational av_time_base = {1, AV_TIME_BASE}; 29 const AVRational av_time_base = {1, AV_TIME_BASE};
35 30
36 // Add one microsecond to avoid rounding-down errors which can occur when 31 // Add one microsecond to avoid rounding-down errors which can occur when
37 // |duration| has been calculated from an exact number of sample-frames. 32 // |duration| has been calculated from an exact number of sample-frames.
38 // One microsecond is much less than the time of a single sample-frame 33 // One microsecond is much less than the time of a single sample-frame
39 // at any real-world sample-rate. 34 // at any real-world sample-rate.
40 return ConvertFromTimeBase( 35 return ConvertFromTimeBase(
41 av_time_base, glue_->format_context()->duration + 1); 36 av_time_base, glue_->format_context()->duration + 1);
42 } 37 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 } 98 }
104 99
105 // Verify the channel layout is supported by Chrome. Acts as a sanity check 100 // Verify the channel layout is supported by Chrome. Acts as a sanity check
106 // against invalid files. See http://crbug.com/171962 101 // against invalid files. See http://crbug.com/171962
107 if (ChannelLayoutToChromeChannelLayout( 102 if (ChannelLayoutToChromeChannelLayout(
108 codec_context_->channel_layout, codec_context_->channels) == 103 codec_context_->channel_layout, codec_context_->channels) ==
109 CHANNEL_LAYOUT_UNSUPPORTED) { 104 CHANNEL_LAYOUT_UNSUPPORTED) {
110 return false; 105 return false;
111 } 106 }
112 107
108 // Store initial values to guard against mid-frame configuration changes.
109 channels_ = codec_context_->channels;
110 sample_rate_ = codec_context_->sample_rate;
111 av_sample_format_ = codec_context_->sample_fmt;
112
113 return true; 113 return true;
114 } 114 }
115 115
116 void AudioFileReader::Close() { 116 void AudioFileReader::Close() {
117 if (codec_context_) { 117 if (codec_context_) {
118 avcodec_close(codec_context_); 118 avcodec_close(codec_context_);
119 codec_context_ = NULL; 119 codec_context_ = NULL;
120 } 120 }
121 } 121 }
122 122
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 if (!frame_decoded) 172 if (!frame_decoded)
173 continue; 173 continue;
174 174
175 // Determine the number of sample-frames we just decoded. Check overflow. 175 // Determine the number of sample-frames we just decoded. Check overflow.
176 int frames_read = av_frame->nb_samples; 176 int frames_read = av_frame->nb_samples;
177 if (frames_read < 0) { 177 if (frames_read < 0) {
178 continue_decoding = false; 178 continue_decoding = false;
179 break; 179 break;
180 } 180 }
181 181
182 if (av_frame->sample_rate != sample_rate_ ||
183 av_frame->channels != channels_ ||
184 av_frame->format != av_sample_format_) {
185 DLOG(ERROR) << "Unsupported mid-frame configuration change!"
scherkus (not reviewing) 2013/02/12 02:16:56 consistent terminology nit: s/mid-frame/mid-stream
DaleCurtis 2013/02/12 02:41:24 Done.
186 << " Sample Rate: " << av_frame->sample_rate << " vs "
187 << sample_rate_
188 << ", Channels: " << av_frame->channels << " vs "
189 << channels_
190 << ", Sample Format: " << av_frame->format << " vs "
191 << av_sample_format_;
192
193 // This is an unrecoverable error, so bail out.
194 continue_decoding = false;
195 break;
196 }
197
182 // Truncate, if necessary, if the destination isn't big enough. 198 // Truncate, if necessary, if the destination isn't big enough.
183 if (current_frame + frames_read > audio_bus->frames()) 199 if (current_frame + frames_read > audio_bus->frames())
184 frames_read = audio_bus->frames() - current_frame; 200 frames_read = audio_bus->frames() - current_frame;
185 201
186 // Deinterleave each channel and convert to 32bit floating-point with 202 // Deinterleave each channel and convert to 32bit floating-point with
187 // nominal range -1.0 -> +1.0. If the output is already in float planar 203 // nominal range -1.0 -> +1.0. If the output is already in float planar
188 // format, just copy it into the AudioBus. 204 // format, just copy it into the AudioBus.
189 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) { 205 if (codec_context_->sample_fmt == AV_SAMPLE_FMT_FLT) {
190 float* decoded_audio_data = reinterpret_cast<float*>(av_frame->data[0]); 206 float* decoded_audio_data = reinterpret_cast<float*>(av_frame->data[0]);
191 int channels = audio_bus->channels(); 207 int channels = audio_bus->channels();
(...skipping 22 matching lines...) Expand all
214 // Zero any remaining frames. 230 // Zero any remaining frames.
215 audio_bus->ZeroFramesPartial( 231 audio_bus->ZeroFramesPartial(
216 current_frame, audio_bus->frames() - current_frame); 232 current_frame, audio_bus->frames() - current_frame);
217 233
218 // Returns the actual number of sample-frames decoded. 234 // Returns the actual number of sample-frames decoded.
219 // Ideally this represents the "true" exact length of the file. 235 // Ideally this represents the "true" exact length of the file.
220 return current_frame; 236 return current_frame;
221 } 237 }
222 238
223 } // namespace media 239 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698