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

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

Issue 10912080: Switch to AVIO instead of a custom FFmpeg URLProtocol handler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Comments. 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
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 "base/logging.h"
8 #include "base/basictypes.h"
9 #include "base/string_util.h"
10 #include "base/time.h" 8 #include "base/time.h"
11 #include "media/base/audio_bus.h" 9 #include "media/base/audio_bus.h"
12 #include "media/ffmpeg/ffmpeg_common.h" 10 #include "media/ffmpeg/ffmpeg_common.h"
13 #include "media/filters/ffmpeg_glue.h" 11 #include "media/filters/ffmpeg_glue.h"
14 12
15 namespace media { 13 namespace media {
16 14
17 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol) 15 AudioFileReader::AudioFileReader(FFmpegURLProtocol* protocol)
18 : protocol_(protocol), 16 : codec_context_(NULL),
19 format_context_(NULL), 17 stream_index_(0),
20 codec_context_(NULL), 18 protocol_(protocol) {
21 stream_index_(0) {
22 } 19 }
23 20
24 AudioFileReader::~AudioFileReader() { 21 AudioFileReader::~AudioFileReader() {
25 Close(); 22 Close();
26 } 23 }
27 24
28 int AudioFileReader::channels() const { 25 int AudioFileReader::channels() const {
29 return codec_context_->channels; 26 return codec_context_->channels;
30 } 27 }
31 28
32 int AudioFileReader::sample_rate() const { 29 int AudioFileReader::sample_rate() const {
33 return codec_context_->sample_rate; 30 return codec_context_->sample_rate;
34 } 31 }
35 32
36 base::TimeDelta AudioFileReader::duration() const { 33 base::TimeDelta AudioFileReader::duration() const {
37 const AVRational av_time_base = {1, AV_TIME_BASE}; 34 const AVRational av_time_base = {1, AV_TIME_BASE};
38 return ConvertFromTimeBase(av_time_base, format_context_->duration); 35 return ConvertFromTimeBase(av_time_base, glue_->format_context()->duration);
39 } 36 }
40 37
41 int64 AudioFileReader::number_of_frames() const { 38 int64 AudioFileReader::number_of_frames() const {
42 return static_cast<int64>(duration().InSecondsF() * sample_rate()); 39 return static_cast<int64>(duration().InSecondsF() * sample_rate());
43 } 40 }
44 41
45 bool AudioFileReader::Open() { 42 bool AudioFileReader::Open() {
46 // Add our data reader to the protocol list and get our unique key. 43 glue_.reset(new FFmpegGlue(protocol_));
47 std::string key = FFmpegGlue::GetInstance()->AddProtocol(protocol_); 44 AVFormatContext* format_context = glue_->format_context();
48 45
49 // Open FFmpeg AVFormatContext. 46 // Open FFmpeg AVFormatContext.
50 DCHECK(!format_context_); 47 if (!glue_->OpenContext()) {
51 AVFormatContext* context = NULL; 48 DLOG(WARNING) << "AudioFileReader::Open() : error in avformat_open_input()";
52
53 int result = avformat_open_input(&context, key.c_str(), NULL, NULL);
54
55 // Remove our data reader from protocol list since avformat_open_input() setup
56 // the AVFormatContext with the data reader.
57 FFmpegGlue::GetInstance()->RemoveProtocol(protocol_);
58
59 if (result) {
60 DLOG(WARNING)
61 << "AudioFileReader::Open() : error in avformat_open_input() -"
62 << " result: " << result;
63 return false; 49 return false;
64 } 50 }
65 51
66 DCHECK(context);
67 format_context_ = context;
68
69 // Get the codec context. 52 // Get the codec context.
70 codec_context_ = NULL; 53 codec_context_ = NULL;
71 for (size_t i = 0; i < format_context_->nb_streams; ++i) { 54 for (size_t i = 0; i < format_context->nb_streams; ++i) {
72 AVCodecContext* c = format_context_->streams[i]->codec; 55 AVCodecContext* c = format_context->streams[i]->codec;
73 if (c->codec_type == AVMEDIA_TYPE_AUDIO) { 56 if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
74 codec_context_ = c; 57 codec_context_ = c;
75 stream_index_ = i; 58 stream_index_ = i;
76 break; 59 break;
77 } 60 }
78 } 61 }
79 62
80 // Get the codec. 63 // Get the codec.
81 if (!codec_context_) 64 if (!codec_context_)
82 return false; 65 return false;
83 66
84 avformat_find_stream_info(format_context_, NULL); 67 int result = avformat_find_stream_info(format_context, NULL);
68 if (result < 0) {
69 DLOG(WARNING)
70 << "AudioFileReader::Open() : error in avformat_find_stream_info()";
71 return false;
72 }
73
85 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 74 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
86 if (codec) { 75 if (codec) {
87 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) { 76 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) {
88 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -" 77 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -"
89 << " result: " << result; 78 << " result: " << result;
90 return false; 79 return false;
91 } 80 }
92 } else { 81 } else {
93 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -" 82 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -"
94 << " result: " << result; 83 << " result: " << result;
95 return false; 84 return false;
96 } 85 }
97 86
98 return true; 87 return true;
99 } 88 }
100 89
101 void AudioFileReader::Close() { 90 void AudioFileReader::Close() {
102 if (codec_context_) { 91 if (codec_context_) {
103 avcodec_close(codec_context_); 92 avcodec_close(codec_context_);
104 codec_context_ = NULL; 93 codec_context_ = NULL;
105 } 94 }
106
107 if (format_context_) {
108 avformat_close_input(&format_context_);
109 format_context_ = NULL;
110 }
111 } 95 }
112 96
113 bool AudioFileReader::Read(AudioBus* audio_bus) { 97 bool AudioFileReader::Read(AudioBus* audio_bus) {
114 DCHECK(format_context_ && codec_context_) << 98 DCHECK(glue_.get() && codec_context_) <<
115 "AudioFileReader::Read() : reader is not opened!"; 99 "AudioFileReader::Read() : reader is not opened!";
116 100
117 DCHECK_EQ(audio_bus->channels(), channels()); 101 DCHECK_EQ(audio_bus->channels(), channels());
118 if (audio_bus->channels() != channels()) 102 if (audio_bus->channels() != channels())
119 return false; 103 return false;
120 104
121 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); 105 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
122 106
123 // Holds decoded audio. 107 // Holds decoded audio.
124 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); 108 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame());
125 109
126 // Read until we hit EOF or we've read the requested number of frames. 110 // Read until we hit EOF or we've read the requested number of frames.
127 AVPacket packet; 111 AVPacket packet;
128 int current_frame = 0; 112 int current_frame = 0;
129 bool continue_decoding = true; 113 bool continue_decoding = true;
130 114
131 while (current_frame < audio_bus->frames() && continue_decoding && 115 while (current_frame < audio_bus->frames() && continue_decoding &&
132 av_read_frame(format_context_, &packet) >= 0 && 116 av_read_frame(glue_->format_context(), &packet) >= 0 &&
133 av_dup_packet(&packet) >= 0) { 117 av_dup_packet(&packet) >= 0) {
134 // Skip packets from other streams. 118 // Skip packets from other streams.
135 if (packet.stream_index != stream_index_) { 119 if (packet.stream_index != stream_index_) {
136 av_free_packet(&packet); 120 av_free_packet(&packet);
137 continue; 121 continue;
138 } 122 }
139 123
140 // Make a shallow copy of packet so we can slide packet.data as frames are 124 // Make a shallow copy of packet so we can slide packet.data as frames are
141 // decoded from the packet; otherwise av_free_packet() will corrupt memory. 125 // decoded from the packet; otherwise av_free_packet() will corrupt memory.
142 AVPacket packet_temp = packet; 126 AVPacket packet_temp = packet;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 169
186 // Zero any remaining frames. 170 // Zero any remaining frames.
187 audio_bus->ZeroFramesPartial( 171 audio_bus->ZeroFramesPartial(
188 current_frame, audio_bus->frames() - current_frame); 172 current_frame, audio_bus->frames() - current_frame);
189 173
190 // Fail if nothing has been decoded, otherwise return partial data. 174 // Fail if nothing has been decoded, otherwise return partial data.
191 return current_frame > 0; 175 return current_frame > 0;
192 } 176 }
193 177
194 } // namespace media 178 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698