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

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

Issue 9632024: Create video and audio decoder threads on demand. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Log an error when Initialize is called more than once. Created 8 years, 9 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/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/demuxer.h" 10 #include "media/base/demuxer.h"
(...skipping 27 matching lines...) Expand all
38 // Returns true if the decode result was end of stream. 38 // Returns true if the decode result was end of stream.
39 static bool IsEndOfStream(int result, int decoded_size, Buffer* input) { 39 static bool IsEndOfStream(int result, int decoded_size, Buffer* input) {
40 // Three conditions to meet to declare end of stream for this decoder: 40 // Three conditions to meet to declare end of stream for this decoder:
41 // 1. FFmpeg didn't read anything. 41 // 1. FFmpeg didn't read anything.
42 // 2. FFmpeg didn't output anything. 42 // 2. FFmpeg didn't output anything.
43 // 3. An end of stream buffer is received. 43 // 3. An end of stream buffer is received.
44 return result == 0 && decoded_size == 0 && input->IsEndOfStream(); 44 return result == 0 && decoded_size == 0 && input->IsEndOfStream();
45 } 45 }
46 46
47 47
48 FFmpegAudioDecoder::FFmpegAudioDecoder(MessageLoop* message_loop) 48 FFmpegAudioDecoder::FFmpegAudioDecoder(
49 : message_loop_(message_loop), 49 const base::Callback<MessageLoop*()>& message_loop_cb)
50 : message_loop_factory_cb_(message_loop_cb),
51 message_loop_(NULL),
50 codec_context_(NULL), 52 codec_context_(NULL),
51 bits_per_channel_(0), 53 bits_per_channel_(0),
52 channel_layout_(CHANNEL_LAYOUT_NONE), 54 channel_layout_(CHANNEL_LAYOUT_NONE),
53 samples_per_second_(0), 55 samples_per_second_(0),
54 decoded_audio_size_(AVCODEC_MAX_AUDIO_FRAME_SIZE), 56 decoded_audio_size_(AVCODEC_MAX_AUDIO_FRAME_SIZE),
55 decoded_audio_(static_cast<uint8*>(av_malloc(decoded_audio_size_))) { 57 decoded_audio_(static_cast<uint8*>(av_malloc(decoded_audio_size_))) {
56 } 58 }
57 59
58 FFmpegAudioDecoder::~FFmpegAudioDecoder() { 60 FFmpegAudioDecoder::~FFmpegAudioDecoder() {
59 av_free(decoded_audio_); 61 av_free(decoded_audio_);
60 62
61 // TODO(scherkus): should we require Stop() to be called? this might end up 63 // TODO(scherkus): should we require Stop() to be called? this might end up
62 // getting called on a random thread due to refcounting. 64 // getting called on a random thread due to refcounting.
63 if (codec_context_) { 65 if (codec_context_) {
64 av_free(codec_context_->extradata); 66 av_free(codec_context_->extradata);
65 avcodec_close(codec_context_); 67 avcodec_close(codec_context_);
66 av_free(codec_context_); 68 av_free(codec_context_);
67 } 69 }
68 } 70 }
69 71
70 void FFmpegAudioDecoder::Initialize( 72 void FFmpegAudioDecoder::Initialize(
71 const scoped_refptr<DemuxerStream>& stream, 73 const scoped_refptr<DemuxerStream>& stream,
72 const PipelineStatusCB& pipeline_status_cb, 74 const PipelineStatusCB& pipeline_status_cb,
73 const StatisticsCB& statistics_cb) { 75 const StatisticsCB& statistics_cb) {
76 if (!message_loop_) {
77 message_loop_ = message_loop_factory_cb_.Run();
78 message_loop_factory_cb_.Reset();
79 } else {
80 // TODO(scherkus): initialization currently happens more than once in
81 // PipelineIntegrationTest.BasicPlayback.
82 LOG(ERROR) << "Initialize has already been called.";
83 }
74 message_loop_->PostTask( 84 message_loop_->PostTask(
75 FROM_HERE, 85 FROM_HERE,
76 base::Bind(&FFmpegAudioDecoder::DoInitialize, this, 86 base::Bind(&FFmpegAudioDecoder::DoInitialize, this,
77 stream, pipeline_status_cb, statistics_cb)); 87 stream, pipeline_status_cb, statistics_cb));
78 } 88 }
79 89
80 void FFmpegAudioDecoder::Read(const ReadCB& read_cb) { 90 void FFmpegAudioDecoder::Read(const ReadCB& read_cb) {
81 // Complete operation asynchronously on different stack of execution as per 91 // Complete operation asynchronously on different stack of execution as per
82 // the API contract of AudioDecoder::Read() 92 // the API contract of AudioDecoder::Read()
83 message_loop_->PostTask(FROM_HERE, base::Bind( 93 message_loop_->PostTask(FROM_HERE, base::Bind(
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 } 294 }
285 295
286 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) { 296 void FFmpegAudioDecoder::DeliverSamples(const scoped_refptr<Buffer>& samples) {
287 // Reset the callback before running to protect against reentrancy. 297 // Reset the callback before running to protect against reentrancy.
288 ReadCB read_cb = read_cb_; 298 ReadCB read_cb = read_cb_;
289 read_cb_.Reset(); 299 read_cb_.Reset();
290 read_cb.Run(samples); 300 read_cb.Run(samples);
291 } 301 }
292 302
293 } // namespace media 303 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698