OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // TODO(ajwong): Generalize this class (fix comments, API, and extract | 5 // TODO(ajwong): Generalize this class (fix comments, API, and extract |
6 // implemntation) so that it can be used for encoding & decoding of both | 6 // implemntation) so that it can be used for encoding & decoding of both |
7 // Video and Audio. | 7 // Video and Audio. |
8 // | 8 // |
9 // An object that works with an OpenMAX component for video decoding. | 9 // An object that works with an OpenMAX component for video decoding. |
10 // Operations on this object are all asynchronous and this object | 10 // Operations on this object are all asynchronous and this object |
11 // requires a message loop that it works on. | 11 // requires a message loop that it works on. |
12 // | 12 // |
13 // OWNERSHIP | 13 // OWNERSHIP |
14 // | 14 // |
15 // The OmxCodec works with two external objects, they are: | 15 // The OmxCodec works with external objects |
16 // 1. OmxConfigurator | 16 // OmxConfigurator |
17 // This object is given to OmxCodec to perform port configuration. | 17 // This object is given to OmxCodec to perform port configuration. |
18 // 2. OmxOutputSink | 18 // This object is provided and destroyed externally. Its references |
19 // This object is given to OmxCodec to perform output buffer negotiation. | 19 // are given to OmxCodec and client application is responsible |
20 // | 20 // for cleaning them. |
21 // These two external objects are provided and destroyed externally. Their | |
22 // references are given to OmxCodec and client application is responsible | |
23 // for cleaning them. | |
24 // | 21 // |
25 // INTERACTION WITH EXTERNAL OBJECTS | 22 // INTERACTION WITH EXTERNAL OBJECTS |
26 // | 23 // |
27 // ................ ............ | 24 // ................ ............ |
28 // | Configurator | <------------- | OmxCodec | | 25 // | Configurator | <------------- | OmxCodec | |
29 // ................ ............ | 26 // ................ ............ |
30 // Read / Feed -----------' ' | 27 // Read / Feed -----------' ' |
31 // .-----------' v Buffer Allocation | 28 // .-----------' v Buffer Allocation |
32 // .......... ............... | 29 // .......... ............... |
33 // | Client | ------------------> | OutputSink | | 30 // | Client | ------------------> | OutputSink | |
(...skipping 12 matching lines...) Expand all Loading... |
46 // | 43 // |
47 // // Initialization. | 44 // // Initialization. |
48 // MessageLoop message_loop; | 45 // MessageLoop message_loop; |
49 // OmxCodec* decoder = new OmxCodec(&message_loop); | 46 // OmxCodec* decoder = new OmxCodec(&message_loop); |
50 // | 47 // |
51 // OmxConfigurator::MediaFormat input_format, output_format; | 48 // OmxConfigurator::MediaFormat input_format, output_format; |
52 // input_format.codec = OmxCodec::kCodecH264; | 49 // input_format.codec = OmxCodec::kCodecH264; |
53 // output_format.codec = OmxCodec::kCodecRaw; | 50 // output_format.codec = OmxCodec::kCodecRaw; |
54 // scoped_ptr<OmxConfigurator> configurator( | 51 // scoped_ptr<OmxConfigurator> configurator( |
55 // new OmxDecoderConfigurator(input_format, output_format)); | 52 // new OmxDecoderConfigurator(input_format, output_format)); |
56 // scoped_ptr<OmxOutputSink> output_sink(new CustomOutputSink()); | |
57 // | 53 // |
58 // decoder->Setup(configurator.get(), output_sink.get()); | 54 // decoder->Setup(configurator.get()); |
59 // decoder->SetErrorCallback(NewCallback(this, &Client::ErrorCallback)); | 55 // decoder->SetErrorCallback(NewCallback(this, &Client::ErrorCallback)); |
60 // decoder->SetFormatCallback(NewCallback(this, &Client::FormatCallback)); | 56 // decoder->SetFormatCallback(NewCallback(this, &Client::FormatCallback)); |
61 // | 57 // |
62 // // Start is asynchronous. We don't need to wait for it to proceed. | 58 // // Start is asynchronous. We don't need to wait for it to proceed. |
63 // decoder->Start(); | 59 // decoder->Start(); |
64 // | 60 // |
65 // // We can start giving buffer to the decoder right after start. It will | 61 // // We can start giving buffer to the decoder right after start. It will |
66 // // queue the input buffers and output requests and process them until | 62 // // queue the input buffers and output requests and process them until |
67 // // the decoder can actually process them. | 63 // // the decoder can actually process them. |
68 // for (int i = 0; i < kInitialBuffers; ++i) { | 64 // for (int i = 0; i < kInitialBuffers; ++i) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 131 |
136 #ifndef MEDIA_OMX_OMX_CODEC_H_ | 132 #ifndef MEDIA_OMX_OMX_CODEC_H_ |
137 #define MEDIA_OMX_OMX_CODEC_H_ | 133 #define MEDIA_OMX_OMX_CODEC_H_ |
138 | 134 |
139 #include <queue> | 135 #include <queue> |
140 #include <vector> | 136 #include <vector> |
141 | 137 |
142 #include "base/callback.h" | 138 #include "base/callback.h" |
143 #include "base/scoped_ptr.h" | 139 #include "base/scoped_ptr.h" |
144 #include "media/omx/omx_configurator.h" | 140 #include "media/omx/omx_configurator.h" |
145 #include "media/omx/omx_output_sink.h" | |
146 #include "third_party/openmax/il/OMX_Component.h" | 141 #include "third_party/openmax/il/OMX_Component.h" |
147 #include "third_party/openmax/il/OMX_Core.h" | 142 #include "third_party/openmax/il/OMX_Core.h" |
148 #include "third_party/openmax/il/OMX_Video.h" | 143 #include "third_party/openmax/il/OMX_Video.h" |
149 | 144 |
150 class MessageLoop; | 145 class MessageLoop; |
151 | 146 |
152 namespace media { | 147 namespace media { |
153 | 148 |
154 class Buffer; | 149 class Buffer; |
155 | 150 |
156 class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> { | 151 class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> { |
157 public: | 152 public: |
158 // TODO(jiesun): remove callback parameters. | 153 // TODO(jiesun): remove callback parameters. |
159 typedef Callback2< | 154 typedef Callback2< |
160 const OmxConfigurator::MediaFormat&, | 155 const OmxConfigurator::MediaFormat&, |
161 const OmxConfigurator::MediaFormat&>::Type FormatCallback; | 156 const OmxConfigurator::MediaFormat&>::Type FormatCallback; |
162 typedef Callback1<Buffer*>::Type FeedCallback; | 157 typedef Callback1<Buffer*>::Type FeedCallback; |
163 typedef Callback2<int, | 158 typedef Callback1<OMX_BUFFERHEADERTYPE*>::Type ReadCallback; |
164 OmxOutputSink::BufferUsedCallback*>::Type ReadCallback; | |
165 typedef Callback0::Type Callback; | 159 typedef Callback0::Type Callback; |
166 | 160 |
167 // Initialize an OmxCodec object that runs on |message_loop|. It is | 161 // Initialize an OmxCodec object that runs on |message_loop|. It is |
168 // guaranteed that callbacks are executed on this message loop. | 162 // guaranteed that callbacks are executed on this message loop. |
169 explicit OmxCodec(MessageLoop* message_loop); | 163 explicit OmxCodec(MessageLoop* message_loop); |
170 virtual ~OmxCodec(); | 164 virtual ~OmxCodec(); |
171 | 165 |
172 // Setup OmxCodec using |configurator|. |configurator| and |output_sink| | 166 // Setup OmxCodec using |configurator|. |configurator| and |output_sink| |
173 // are not owned by this class and should be cleaned up externally. | 167 // are not owned by this class and should be cleaned up externally. |
174 void Setup(OmxConfigurator* configurator, OmxOutputSink* output_sink); | 168 void Setup(OmxConfigurator* configurator); |
175 | 169 |
176 // Set the error callback. In case of error the callback will be called. | 170 // Set the error callback. In case of error the callback will be called. |
177 void SetErrorCallback(Callback* callback); | 171 void SetErrorCallback(Callback* callback); |
178 | 172 |
179 // Set the format change callback. In case of input stream changes. | 173 // Set the format change callback. In case of input stream changes. |
180 void SetFormatCallback(FormatCallback* callback); | 174 void SetFormatCallback(FormatCallback* callback); |
181 | 175 |
182 // Start the decoder, this will start the initialization asynchronously. | 176 // Start the decoder, this will start the initialization asynchronously. |
183 // Client can start feeding to and reading from the decoder. | 177 // Client can start feeding to and reading from the decoder. |
184 void Start(); | 178 void Start(); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 // |next_state_| is the next state that this machine will transition | 360 // |next_state_| is the next state that this machine will transition |
367 // to. After a state transition is completed and the state becomes | 361 // to. After a state transition is completed and the state becomes |
368 // stable then |next_state_| equals |state_|. Inequality can be | 362 // stable then |next_state_| equals |state_|. Inequality can be |
369 // used to detect a state transition. | 363 // used to detect a state transition. |
370 // These two members are read and written only on |message_loop_|. | 364 // These two members are read and written only on |message_loop_|. |
371 State state_; | 365 State state_; |
372 State next_state_; | 366 State next_state_; |
373 | 367 |
374 OMX_COMPONENTTYPE* component_handle_; | 368 OMX_COMPONENTTYPE* component_handle_; |
375 OmxConfigurator* configurator_; | 369 OmxConfigurator* configurator_; |
376 OmxOutputSink* output_sink_; | |
377 MessageLoop* message_loop_; | 370 MessageLoop* message_loop_; |
378 | 371 |
379 scoped_ptr<FormatCallback> format_callback_; | 372 scoped_ptr<FormatCallback> format_callback_; |
380 scoped_ptr<Callback> stop_callback_; | 373 scoped_ptr<Callback> stop_callback_; |
381 scoped_ptr<Callback> error_callback_; | 374 scoped_ptr<Callback> error_callback_; |
382 | 375 |
383 typedef std::pair<scoped_refptr<Buffer>, FeedCallback*> InputUnit; | 376 typedef std::pair<scoped_refptr<Buffer>, FeedCallback*> InputUnit; |
384 | 377 |
385 // Input queue for encoded data. | 378 // Input queue for encoded data. |
386 // The input buffers will be sent to OMX component via OMX_EmptyThisBuffer() | 379 // The input buffers will be sent to OMX component via OMX_EmptyThisBuffer() |
(...skipping 10 matching lines...) Expand all Loading... |
397 | 390 |
398 // Available input OpenMAX buffers that we can use to issue | 391 // Available input OpenMAX buffers that we can use to issue |
399 // OMX_EmptyThisBuffer() call. | 392 // OMX_EmptyThisBuffer() call. |
400 std::queue<OMX_BUFFERHEADERTYPE*> available_input_buffers_; | 393 std::queue<OMX_BUFFERHEADERTYPE*> available_input_buffers_; |
401 | 394 |
402 // A queue of buffers that carries decoded video frames. They are | 395 // A queue of buffers that carries decoded video frames. They are |
403 // ready to return to client. | 396 // ready to return to client. |
404 // TOOD(hclam): extract it to a separate class. | 397 // TOOD(hclam): extract it to a separate class. |
405 std::queue<int> output_buffers_ready_; | 398 std::queue<int> output_buffers_ready_; |
406 | 399 |
407 // A set of buffers that are currently in use by the client. | |
408 // TODO(hclam): extract it to a separate class. | |
409 typedef std::vector<int> OutputBuffersInUseSet; | |
410 OutputBuffersInUseSet output_buffers_in_use_; | |
411 | |
412 private: | 400 private: |
413 DISALLOW_COPY_AND_ASSIGN(OmxCodec); | 401 DISALLOW_COPY_AND_ASSIGN(OmxCodec); |
414 }; | 402 }; |
415 | 403 |
416 } // namespace media | 404 } // namespace media |
417 | 405 |
418 #endif // MEDIA_OMX_OMX_CODEC_H_ | 406 #endif // MEDIA_OMX_OMX_CODEC_H_ |
OLD | NEW |