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

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

Issue 10447035: Introducing DecoderBuffer and general Buffer cleanup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: s/2011/2012/ Created 8 years, 6 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
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/ffmpeg_audio_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ffmpeg_audio_decoder.h" 5 #include "media/filters/ffmpeg_audio_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "media/base/audio_decoder_config.h" 8 #include "media/base/audio_decoder_config.h"
9 #include "media/base/data_buffer.h" 9 #include "media/base/data_buffer.h"
10 #include "media/base/decoder_buffer.h"
10 #include "media/base/demuxer.h" 11 #include "media/base/demuxer.h"
11 #include "media/base/pipeline.h" 12 #include "media/base/pipeline.h"
12 #include "media/ffmpeg/ffmpeg_common.h" 13 #include "media/ffmpeg/ffmpeg_common.h"
13 14
14 namespace media { 15 namespace media {
15 16
16 // Returns true if the decode result was an error. 17 // Returns true if the decode result was an error.
17 static bool IsErrorResult(int result, int decoded_size) { 18 static bool IsErrorResult(int result, int decoded_size) {
18 return result < 0 || 19 return result < 0 ||
19 decoded_size < 0 || 20 decoded_size < 0 ||
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 162
162 void FFmpegAudioDecoder::DoRead(const ReadCB& read_cb) { 163 void FFmpegAudioDecoder::DoRead(const ReadCB& read_cb) {
163 DCHECK_EQ(MessageLoop::current(), message_loop_); 164 DCHECK_EQ(MessageLoop::current(), message_loop_);
164 DCHECK(!read_cb.is_null()); 165 DCHECK(!read_cb.is_null());
165 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 166 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
166 167
167 read_cb_ = read_cb; 168 read_cb_ = read_cb;
168 ReadFromDemuxerStream(); 169 ReadFromDemuxerStream();
169 } 170 }
170 171
171 void FFmpegAudioDecoder::DoDecodeBuffer(const scoped_refptr<Buffer>& input) { 172 void FFmpegAudioDecoder::DoDecodeBuffer(
173 const scoped_refptr<DecoderBuffer>& input) {
172 DCHECK_EQ(MessageLoop::current(), message_loop_); 174 DCHECK_EQ(MessageLoop::current(), message_loop_);
173 DCHECK(!read_cb_.is_null()); 175 DCHECK(!read_cb_.is_null());
174 176
175 if (!input) { 177 if (!input) {
176 // DemuxeStream::Read() was aborted so we abort the decoder's pending read. 178 // DemuxeStream::Read() was aborted so we abort the decoder's pending read.
177 DeliverSamples(NULL); 179 DeliverSamples(NULL);
178 return; 180 return;
179 } 181 }
180 182
181 // FFmpeg tends to seek Ogg audio streams in the middle of nowhere, giving us 183 // FFmpeg tends to seek Ogg audio streams in the middle of nowhere, giving us
182 // a whole bunch of AV_NOPTS_VALUE packets. Discard them until we find 184 // a whole bunch of AV_NOPTS_VALUE packets. Discard them until we find
183 // something valid. Refer to http://crbug.com/49709 185 // something valid. Refer to http://crbug.com/49709
184 if (input->GetTimestamp() == kNoTimestamp() && 186 if (input->GetTimestamp() == kNoTimestamp() &&
185 estimated_next_timestamp_ == kNoTimestamp() && 187 estimated_next_timestamp_ == kNoTimestamp() &&
186 !input->IsEndOfStream()) { 188 !input->IsEndOfStream()) {
187 ReadFromDemuxerStream(); 189 ReadFromDemuxerStream();
188 return; 190 return;
189 } 191 }
190 192
191 AVPacket packet; 193 AVPacket packet;
192 av_init_packet(&packet); 194 av_init_packet(&packet);
193 if (input->IsEndOfStream()) { 195 packet.data = const_cast<uint8*>(input->GetData());
194 packet.data = NULL; 196 packet.size = input->GetDataSize();
195 packet.size = 0;
196 } else {
197 packet.data = const_cast<uint8*>(input->GetData());
198 packet.size = input->GetDataSize();
199 }
200 197
201 PipelineStatistics statistics; 198 PipelineStatistics statistics;
202 statistics.audio_bytes_decoded = input->GetDataSize(); 199 statistics.audio_bytes_decoded = input->GetDataSize();
203 200
204 int decoded_audio_size = decoded_audio_size_; 201 int decoded_audio_size = decoded_audio_size_;
205 int result = avcodec_decode_audio3( 202 int result = avcodec_decode_audio3(
206 codec_context_, reinterpret_cast<int16_t*>(decoded_audio_), 203 codec_context_, reinterpret_cast<int16_t*>(decoded_audio_),
207 &decoded_audio_size, &packet); 204 &decoded_audio_size, &packet);
208 205
209 if (IsErrorResult(result, decoded_audio_size)) { 206 if (IsErrorResult(result, decoded_audio_size)) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 ReadFromDemuxerStream(); 246 ReadFromDemuxerStream();
250 } 247 }
251 } 248 }
252 249
253 void FFmpegAudioDecoder::ReadFromDemuxerStream() { 250 void FFmpegAudioDecoder::ReadFromDemuxerStream() {
254 DCHECK(!read_cb_.is_null()); 251 DCHECK(!read_cb_.is_null());
255 252
256 demuxer_stream_->Read(base::Bind(&FFmpegAudioDecoder::DecodeBuffer, this)); 253 demuxer_stream_->Read(base::Bind(&FFmpegAudioDecoder::DecodeBuffer, this));
257 } 254 }
258 255
259 void FFmpegAudioDecoder::DecodeBuffer(const scoped_refptr<Buffer>& buffer) { 256 void FFmpegAudioDecoder::DecodeBuffer(
257 const scoped_refptr<DecoderBuffer>& buffer) {
260 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read 258 // TODO(scherkus): fix FFmpegDemuxerStream::Read() to not execute our read
261 // callback on the same execution stack so we can get rid of forced task post. 259 // callback on the same execution stack so we can get rid of forced task post.
262 message_loop_->PostTask(FROM_HERE, base::Bind( 260 message_loop_->PostTask(FROM_HERE, base::Bind(
263 &FFmpegAudioDecoder::DoDecodeBuffer, this, buffer)); 261 &FFmpegAudioDecoder::DoDecodeBuffer, this, buffer));
264 } 262 }
265 263
266 void FFmpegAudioDecoder::UpdateDurationAndTimestamp( 264 void FFmpegAudioDecoder::UpdateDurationAndTimestamp(
267 const Buffer* input, 265 const Buffer* input,
268 DataBuffer* output) { 266 DataBuffer* output) {
269 // Always calculate duration based on the actual number of samples decoded. 267 // Always calculate duration based on the actual number of samples decoded.
(...skipping 24 matching lines...) Expand all
294 } 292 }
295 293
296 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) { 294 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) {
297 // Reset the callback before running to protect against reentrancy. 295 // Reset the callback before running to protect against reentrancy.
298 ReadCB read_cb = read_cb_; 296 ReadCB read_cb = read_cb_;
299 read_cb_.Reset(); 297 read_cb_.Reset();
300 read_cb.Run(samples); 298 read_cb.Run(samples);
301 } 299 }
302 300
303 } // namespace media 301 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_audio_decoder.h ('k') | media/filters/ffmpeg_audio_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698