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 |