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

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

Issue 11137005: Make sure that DecodeAudioFileData() always returns an AudioBus of the exact length of the file (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 2 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 <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 17 matching lines...) Expand all
28 int AudioFileReader::channels() const { 28 int AudioFileReader::channels() const {
29 return codec_context_->channels; 29 return codec_context_->channels;
30 } 30 }
31 31
32 int AudioFileReader::sample_rate() const { 32 int AudioFileReader::sample_rate() const {
33 return codec_context_->sample_rate; 33 return codec_context_->sample_rate;
34 } 34 }
35 35
36 base::TimeDelta AudioFileReader::duration() const { 36 base::TimeDelta AudioFileReader::duration() const {
37 const AVRational av_time_base = {1, AV_TIME_BASE}; 37 const AVRational av_time_base = {1, AV_TIME_BASE};
38 return ConvertFromTimeBase(av_time_base, format_context_->duration); 38
39 // Add one microsecond to avoid rounding-down errors which can occur when
40 // |duration| has been calculated from an exact number of sample-frames.
41 // One microsecond is much less than the time of a single sample-frame
42 // at any real-world sample-rate.
43 return ConvertFromTimeBase(av_time_base, format_context_->duration + 1);
39 } 44 }
40 45
41 int64 AudioFileReader::number_of_frames() const { 46 int64 AudioFileReader::number_of_frames() const {
42 return static_cast<int64>(duration().InSecondsF() * sample_rate()); 47 return static_cast<int64>(duration().InSecondsF() * sample_rate());
43 } 48 }
44 49
45 bool AudioFileReader::Open() { 50 bool AudioFileReader::Open() {
46 // Add our data reader to the protocol list and get our unique key. 51 // Add our data reader to the protocol list and get our unique key.
47 std::string key = FFmpegGlue::GetInstance()->AddProtocol(protocol_); 52 std::string key = FFmpegGlue::GetInstance()->AddProtocol(protocol_);
48 53
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 avcodec_close(codec_context_); 108 avcodec_close(codec_context_);
104 codec_context_ = NULL; 109 codec_context_ = NULL;
105 } 110 }
106 111
107 if (format_context_) { 112 if (format_context_) {
108 avformat_close_input(&format_context_); 113 avformat_close_input(&format_context_);
109 format_context_ = NULL; 114 format_context_ = NULL;
110 } 115 }
111 } 116 }
112 117
113 bool AudioFileReader::Read(AudioBus* audio_bus) { 118 int AudioFileReader::Read(AudioBus* audio_bus) {
114 DCHECK(format_context_ && codec_context_) << 119 DCHECK(format_context_ && codec_context_) <<
115 "AudioFileReader::Read() : reader is not opened!"; 120 "AudioFileReader::Read() : reader is not opened!";
116 121
117 DCHECK_EQ(audio_bus->channels(), channels()); 122 DCHECK_EQ(audio_bus->channels(), channels());
DaleCurtis 2012/10/12 22:42:02 Style violation: Remove DCHECK() since this is han
Chris Rogers 2012/10/12 23:22:29 This isn't part of this CL On 2012/10/12 22:42:02
DaleCurtis 2012/10/13 01:10:35 I know, but it's a good idea to fix these things i
118 if (audio_bus->channels() != channels()) 123 if (audio_bus->channels() != channels())
119 return false; 124 return 0;
120 125
121 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); 126 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
122 127
123 // Holds decoded audio. 128 // Holds decoded audio.
124 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); 129 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame());
125 130
126 // Read until we hit EOF or we've read the requested number of frames. 131 // Read until we hit EOF or we've read the requested number of frames.
127 AVPacket packet; 132 AVPacket packet;
128 int current_frame = 0; 133 int current_frame = 0;
129 bool continue_decoding = true; 134 bool continue_decoding = true;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 185
181 current_frame += frames_read; 186 current_frame += frames_read;
182 } while (packet_temp.size > 0); 187 } while (packet_temp.size > 0);
183 av_free_packet(&packet); 188 av_free_packet(&packet);
184 } 189 }
185 190
186 // Zero any remaining frames. 191 // Zero any remaining frames.
187 audio_bus->ZeroFramesPartial( 192 audio_bus->ZeroFramesPartial(
188 current_frame, audio_bus->frames() - current_frame); 193 current_frame, audio_bus->frames() - current_frame);
189 194
190 // Fail if nothing has been decoded, otherwise return partial data. 195 // Returns the actual number of sample-frames decoded.
191 return current_frame > 0; 196 // Ideally this represents the "true" exact length of the file.
197 return current_frame;
192 } 198 }
193 199
194 } // namespace media 200 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698