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

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: AVIO! 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 : glue_(new FFmpegGlue(protocol)),
19 format_context_(NULL),
20 codec_context_(NULL), 17 codec_context_(NULL),
21 stream_index_(0) { 18 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 DCHECK(glue_.get());
scherkus (not reviewing) 2012/10/02 00:20:56 dcheck not useful
DaleCurtis 2012/10/02 01:24:23 Done.
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 int result = glue_->OpenContext();
51 AVFormatContext* context = NULL;
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) { 48 if (result) {
60 DLOG(WARNING) 49 DLOG(WARNING)
61 << "AudioFileReader::Open() : error in avformat_open_input() -" 50 << "AudioFileReader::Open() : error in avformat_open_input() -"
62 << " result: " << result; 51 << " result: " << result;
63 return false; 52 return false;
64 } 53 }
65 54
66 DCHECK(context);
67 format_context_ = context;
68
69 // Get the codec context. 55 // Get the codec context.
70 codec_context_ = NULL; 56 codec_context_ = NULL;
71 for (size_t i = 0; i < format_context_->nb_streams; ++i) { 57 for (size_t i = 0; i < format_context->nb_streams; ++i) {
72 AVCodecContext* c = format_context_->streams[i]->codec; 58 AVCodecContext* c = format_context->streams[i]->codec;
73 if (c->codec_type == AVMEDIA_TYPE_AUDIO) { 59 if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
74 codec_context_ = c; 60 codec_context_ = c;
75 stream_index_ = i; 61 stream_index_ = i;
76 break; 62 break;
77 } 63 }
78 } 64 }
79 65
80 // Get the codec. 66 // Get the codec.
81 if (!codec_context_) 67 if (!codec_context_)
82 return false; 68 return false;
83 69
84 avformat_find_stream_info(format_context_, NULL); 70 avformat_find_stream_info(format_context, NULL);
85 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 71 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
86 if (codec) { 72 if (codec) {
87 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) { 73 if ((result = avcodec_open2(codec_context_, codec, NULL)) < 0) {
88 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -" 74 DLOG(WARNING) << "AudioFileReader::Open() : could not open codec -"
89 << " result: " << result; 75 << " result: " << result;
90 return false; 76 return false;
91 } 77 }
92 } else { 78 } else {
93 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -" 79 DLOG(WARNING) << "AudioFileReader::Open() : could not find codec -"
94 << " result: " << result; 80 << " result: " << result;
95 return false; 81 return false;
96 } 82 }
97 83
98 return true; 84 return true;
99 } 85 }
100 86
101 void AudioFileReader::Close() { 87 void AudioFileReader::Close() {
102 if (codec_context_) { 88 if (codec_context_) {
103 avcodec_close(codec_context_); 89 avcodec_close(codec_context_);
104 codec_context_ = NULL; 90 codec_context_ = NULL;
105 } 91 }
106
107 if (format_context_) {
108 avformat_close_input(&format_context_);
109 format_context_ = NULL;
110 }
111 } 92 }
112 93
113 bool AudioFileReader::Read(AudioBus* audio_bus) { 94 bool AudioFileReader::Read(AudioBus* audio_bus) {
114 DCHECK(format_context_ && codec_context_) << 95 DCHECK(glue_.get() && codec_context_) <<
115 "AudioFileReader::Read() : reader is not opened!"; 96 "AudioFileReader::Read() : reader is not opened!";
116 97
117 DCHECK_EQ(audio_bus->channels(), channels()); 98 DCHECK_EQ(audio_bus->channels(), channels());
118 if (audio_bus->channels() != channels()) 99 if (audio_bus->channels() != channels())
119 return false; 100 return false;
120 101
121 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt); 102 size_t bytes_per_sample = av_get_bytes_per_sample(codec_context_->sample_fmt);
122 103
123 // Holds decoded audio. 104 // Holds decoded audio.
124 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame()); 105 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> av_frame(avcodec_alloc_frame());
125 106
126 // Read until we hit EOF or we've read the requested number of frames. 107 // Read until we hit EOF or we've read the requested number of frames.
127 AVPacket packet; 108 AVPacket packet;
128 int current_frame = 0; 109 int current_frame = 0;
129 bool continue_decoding = true; 110 bool continue_decoding = true;
130 111
131 while (current_frame < audio_bus->frames() && continue_decoding && 112 while (current_frame < audio_bus->frames() && continue_decoding &&
132 av_read_frame(format_context_, &packet) >= 0 && 113 av_read_frame(glue_->format_context(), &packet) >= 0 &&
133 av_dup_packet(&packet) >= 0) { 114 av_dup_packet(&packet) >= 0) {
134 // Skip packets from other streams. 115 // Skip packets from other streams.
135 if (packet.stream_index != stream_index_) { 116 if (packet.stream_index != stream_index_) {
136 av_free_packet(&packet); 117 av_free_packet(&packet);
137 continue; 118 continue;
138 } 119 }
139 120
140 // Make a shallow copy of packet so we can slide packet.data as frames are 121 // 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. 122 // decoded from the packet; otherwise av_free_packet() will corrupt memory.
142 AVPacket packet_temp = packet; 123 AVPacket packet_temp = packet;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 166
186 // Zero any remaining frames. 167 // Zero any remaining frames.
187 audio_bus->ZeroFramesPartial( 168 audio_bus->ZeroFramesPartial(
188 current_frame, audio_bus->frames() - current_frame); 169 current_frame, audio_bus->frames() - current_frame);
189 170
190 // Fail if nothing has been decoded, otherwise return partial data. 171 // Fail if nothing has been decoded, otherwise return partial data.
191 return current_frame > 0; 172 return current_frame > 0;
192 } 173 }
193 174
194 } // namespace media 175 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698