| 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 |