| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 // A base class that provides the plumbing for a decoder filters. | 5 // A base class that provides the plumbing for a decoder filters. |
| 6 | 6 |
| 7 #ifndef MEDIA_FILTERS_DECODER_BASE_H_ | 7 #ifndef MEDIA_FILTERS_DECODER_BASE_H_ |
| 8 #define MEDIA_FILTERS_DECODER_BASE_H_ | 8 #define MEDIA_FILTERS_DECODER_BASE_H_ |
| 9 | 9 |
| 10 #include <deque> | 10 #include <deque> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 class DecoderBase : public Decoder { | 26 class DecoderBase : public Decoder { |
| 27 public: | 27 public: |
| 28 typedef CallbackRunner< Tuple1<Output*> > ReadCallback; | 28 typedef CallbackRunner< Tuple1<Output*> > ReadCallback; |
| 29 | 29 |
| 30 // MediaFilter implementation. | 30 // MediaFilter implementation. |
| 31 virtual void Stop() { | 31 virtual void Stop() { |
| 32 this->message_loop()->PostTask(FROM_HERE, | 32 this->message_loop()->PostTask(FROM_HERE, |
| 33 NewRunnableMethod(this, &DecoderBase::StopTask)); | 33 NewRunnableMethod(this, &DecoderBase::StopTask)); |
| 34 } | 34 } |
| 35 | 35 |
| 36 virtual void Seek(base::TimeDelta time) { | 36 virtual void Seek(base::TimeDelta time, |
| 37 FilterCallback* callback) { |
| 37 this->message_loop()->PostTask(FROM_HERE, | 38 this->message_loop()->PostTask(FROM_HERE, |
| 38 NewRunnableMethod(this, &DecoderBase::SeekTask, time)); | 39 NewRunnableMethod(this, &DecoderBase::SeekTask, time, callback)); |
| 39 } | 40 } |
| 40 | 41 |
| 41 // Decoder implementation. | 42 // Decoder implementation. |
| 42 virtual bool Initialize(DemuxerStream* demuxer_stream) { | 43 virtual void Initialize(DemuxerStream* demuxer_stream, |
| 44 FilterCallback* callback) { |
| 43 this->message_loop()->PostTask(FROM_HERE, | 45 this->message_loop()->PostTask(FROM_HERE, |
| 44 NewRunnableMethod(this, &DecoderBase::InitializeTask, demuxer_stream)); | 46 NewRunnableMethod(this, &DecoderBase::InitializeTask, demuxer_stream, |
| 45 return true; | 47 callback)); |
| 46 } | 48 } |
| 47 | 49 |
| 48 virtual const MediaFormat& media_format() { return media_format_; } | 50 virtual const MediaFormat& media_format() { return media_format_; } |
| 49 | 51 |
| 50 // Audio or video decoder. | 52 // Audio or video decoder. |
| 51 virtual void Read(ReadCallback* read_callback) { | 53 virtual void Read(ReadCallback* read_callback) { |
| 52 this->message_loop()->PostTask(FROM_HERE, | 54 this->message_loop()->PostTask(FROM_HERE, |
| 53 NewRunnableMethod(this, &DecoderBase::ReadTask, read_callback)); | 55 NewRunnableMethod(this, &DecoderBase::ReadTask, read_callback)); |
| 54 } | 56 } |
| 55 | 57 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 122 |
| 121 // Delegate to the subclass first. | 123 // Delegate to the subclass first. |
| 122 OnStop(); | 124 OnStop(); |
| 123 | 125 |
| 124 // Throw away all buffers in all queues. | 126 // Throw away all buffers in all queues. |
| 125 result_queue_.clear(); | 127 result_queue_.clear(); |
| 126 STLDeleteElements(&read_queue_); | 128 STLDeleteElements(&read_queue_); |
| 127 state_ = STOPPED; | 129 state_ = STOPPED; |
| 128 } | 130 } |
| 129 | 131 |
| 130 void SeekTask(base::TimeDelta time) { | 132 void SeekTask(base::TimeDelta time, FilterCallback* callback) { |
| 131 DCHECK_EQ(MessageLoop::current(), this->message_loop()); | 133 DCHECK_EQ(MessageLoop::current(), this->message_loop()); |
| 134 scoped_ptr<FilterCallback> c(callback); |
| 132 | 135 |
| 133 // Delegate to the subclass first. | 136 // Delegate to the subclass first. |
| 134 OnSeek(time); | 137 OnSeek(time); |
| 135 | 138 |
| 136 // Flush the result queue. | 139 // Flush the result queue. |
| 137 result_queue_.clear(); | 140 result_queue_.clear(); |
| 138 | 141 |
| 139 // Turn on the seeking flag so that we can discard buffers until a | 142 // Turn on the seeking flag so that we can discard buffers until a |
| 140 // discontinuous buffer is received. | 143 // discontinuous buffer is received. |
| 141 seeking_ = true; | 144 seeking_ = true; |
| 145 |
| 146 // For now, signal that we're done seeking. |
| 147 // TODO(scherkus): implement asynchronous seeking for decoder_base.h |
| 148 callback->Run(); |
| 142 } | 149 } |
| 143 | 150 |
| 144 void InitializeTask(DemuxerStream* demuxer_stream) { | 151 void InitializeTask(DemuxerStream* demuxer_stream, FilterCallback* callback) { |
| 145 DCHECK_EQ(MessageLoop::current(), this->message_loop()); | 152 DCHECK_EQ(MessageLoop::current(), this->message_loop()); |
| 146 DCHECK(state_ == UNINITIALIZED); | 153 DCHECK(state_ == UNINITIALIZED); |
| 147 DCHECK(!demuxer_stream_); | 154 DCHECK(!demuxer_stream_); |
| 155 scoped_ptr<FilterCallback> c(callback); |
| 148 demuxer_stream_ = demuxer_stream; | 156 demuxer_stream_ = demuxer_stream; |
| 149 | 157 |
| 150 // Delegate to subclass first. | 158 // Delegate to subclass first. |
| 151 if (!OnInitialize(demuxer_stream_)) { | 159 if (!OnInitialize(demuxer_stream_)) { |
| 152 this->host()->Error(PIPELINE_ERROR_DECODE); | 160 this->host()->Error(PIPELINE_ERROR_DECODE); |
| 161 callback->Run(); |
| 153 return; | 162 return; |
| 154 } | 163 } |
| 155 | 164 |
| 156 // TODO(scherkus): subclass shouldn't mutate superclass media format. | 165 // TODO(scherkus): subclass shouldn't mutate superclass media format. |
| 157 DCHECK(!media_format_.empty()) << "Subclass did not set media_format_"; | 166 DCHECK(!media_format_.empty()) << "Subclass did not set media_format_"; |
| 158 state_ = INITIALIZED; | 167 state_ = INITIALIZED; |
| 159 this->host()->InitializationComplete(); | 168 callback->Run(); |
| 160 } | 169 } |
| 161 | 170 |
| 162 void ReadTask(ReadCallback* read_callback) { | 171 void ReadTask(ReadCallback* read_callback) { |
| 163 DCHECK_EQ(MessageLoop::current(), this->message_loop()); | 172 DCHECK_EQ(MessageLoop::current(), this->message_loop()); |
| 164 | 173 |
| 165 // TODO(scherkus): should reply with a null operation (empty buffer). | 174 // TODO(scherkus): should reply with a null operation (empty buffer). |
| 166 if (IsStopped()) { | 175 if (IsStopped()) { |
| 167 delete read_callback; | 176 delete read_callback; |
| 168 return; | 177 return; |
| 169 } | 178 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 STOPPED, | 281 STOPPED, |
| 273 }; | 282 }; |
| 274 State state_; | 283 State state_; |
| 275 | 284 |
| 276 DISALLOW_COPY_AND_ASSIGN(DecoderBase); | 285 DISALLOW_COPY_AND_ASSIGN(DecoderBase); |
| 277 }; | 286 }; |
| 278 | 287 |
| 279 } // namespace media | 288 } // namespace media |
| 280 | 289 |
| 281 #endif // MEDIA_FILTERS_DECODER_BASE_H_ | 290 #endif // MEDIA_FILTERS_DECODER_BASE_H_ |
| OLD | NEW |