diff options
Diffstat (limited to 'media/omx/omx_codec.h')
-rw-r--r-- | media/omx/omx_codec.h | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/media/omx/omx_codec.h b/media/omx/omx_codec.h deleted file mode 100644 index 70e02db..0000000 --- a/media/omx/omx_codec.h +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// TODO(ajwong): Generalize this class (fix comments, API, and extract -// implemntation) so that it can be used for encoding & decoding of both -// Video and Audio. -// -// An object that works with an OpenMAX component for video decoding. -// Operations on this object are all asynchronous and this object -// requires a message loop that it works on. -// -// OWNERSHIP -// -// The OmxCodec works with external objects -// OmxConfigurator -// This object is given to OmxCodec to perform port configuration. -// This object is provided and destroyed externally. Its references -// are given to OmxCodec and client application is responsible -// for cleaning them. -// -// INTERACTION WITH EXTERNAL OBJECTS -// -// ................ ............ -// | Configurator | <------------- | OmxCodec | -// ................ ............ -// Read / Feed -----------' ' -// .-----------' v Buffer Allocation -// .......... ............... -// | Client | ------------------> | OutputSink | -// .......... Buffer Ready ............... -// -// THREADING -// -// OmxCodec is given a message loop to run on. There is a strong gurantee -// that all callbacks given to it will be executed on this message loop. -// Communicatations with OmxConfigurator and OmxOutputSink are also done -// on this thread. -// -// Public methods can be called on any thread. -// -// USAGES -// -// // Initialization. -// MessageLoop message_loop; -// OmxCodec* decoder = new OmxCodec(&message_loop); -// -// OmxConfigurator::MediaFormat input_format, output_format; -// input_format.codec = OmxCodec::kCodecH264; -// output_format.codec = OmxCodec::kCodecRaw; -// scoped_ptr<OmxConfigurator> configurator( -// new OmxDecoderConfigurator(input_format, output_format)); -// -// decoder->Setup(configurator.get()); -// decoder->SetErrorCallback(NewCallback(this, &Client::ErrorCallback)); -// decoder->SetFormatCallback(NewCallback(this, &Client::FormatCallback)); -// -// // Start is asynchronous. We don't need to wait for it to proceed. -// decoder->Start(); -// -// // We can start giving buffer to the decoder right after start. It will -// // queue the input buffers and output requests and process them until -// // the decoder can actually process them. -// for (int i = 0; i < kInitialBuffers; ++i) { -// OmxInputBuffer* buffer = PrepareInitialInputBuffer(); -// decoder->Feed(buffer, NewCallback(this, &Client::FeedCallback)); -// } -// -// // We can also issue read requests to the decoder. -// decoder->Read(NewCallback(this, &Client::ReadCallback)); -// -// // Make the following call to stop the decoder: -// decoder->Stop(NewCallback(this, &Client::StopCallback)); -// -// A typical FeedCallback will look like: -// void Client::FeedCallback(OmxInputBuffer* buffer) { -// // We have read to the end so stop feeding. -// if (buffer->IsEndOfStream()) -// return; -// PrepareInputBuffer(buffer); -// decoder->Feed(buffer, NewCallback(this, &Client::FeedCallback)); -// } -// -// A typical ReadCallback will look like: -// void Client::ReadCallback(int buffer_id, -// OmxOutputSink::BufferUsedCallback* callback) { -// // Detect end-of-stream state. -// if (buffer_id == OmxCodec::kEosBuffer) -// return; -// -// // Issue a new read immediately. -// decoder->Read(NewCallback(this, &Client::ReadCallback)); -// -// // Pass the buffer to OmxOutputSink. -// output_sink->BufferReady(buffer_id, callback); -// } -// -// EXTERNAL STATES -// -// Client of this class will only see four states from the decoder: -// ......... -// | Error | -// ......... -// ^ -// `-. -// ......... ......... ........ -// | Empty | -> | Start | -> | Stop | -// ......... ......... ........ -// -// How to operate this object in these four states can be described by -// usage above. -// -// INTERNAL STATES -// -// There are multiple internal states to keep track of state transitions -// of the OpenMAX component. The state transitions and the task during -// the transition can be summerized by the following state diagram: -// -// ......... -> .......... -> ........ -> ............. -// | Empty | | Loaded | | Idle | | Executing | -// ......... <- .......... <- ........ <- ............. -// ^ ` -// ` v -// ......... ............. .............. -// | Error | | Port Enable | | Port Disable | -// ......... ............. .............. -// -// We need to perform specific tasks in order to transition from one state -// to another. When an error is received, this object will transition to -// the error state. - -#ifndef MEDIA_OMX_OMX_CODEC_H_ -#define MEDIA_OMX_OMX_CODEC_H_ - -#include <queue> -#include <vector> - -#include "base/callback.h" -#include "base/scoped_ptr.h" -#include "media/omx/omx_configurator.h" -#include "third_party/openmax/il/OMX_Component.h" -#include "third_party/openmax/il/OMX_Core.h" -#include "third_party/openmax/il/OMX_Video.h" - -class MessageLoop; - -namespace media { - -class Buffer; - -class OmxCodec : public base::RefCountedThreadSafe<OmxCodec> { - public: - // TODO(jiesun): remove callback parameters. - typedef Callback2< - const OmxConfigurator::MediaFormat&, - const OmxConfigurator::MediaFormat&>::Type FormatCallback; - typedef Callback1<scoped_refptr<Buffer> >::Type FeedDoneCallback; - typedef Callback1<OMX_BUFFERHEADERTYPE*>::Type FillDoneCallback; - typedef Callback0::Type Callback; - - // Initialize an OmxCodec object that runs on |message_loop|. It is - // guaranteed that callbacks are executed on this message loop. - explicit OmxCodec(MessageLoop* message_loop); - virtual ~OmxCodec(); - - // Setup OmxCodec using |configurator|. |configurator| and |output_sink| - // are not owned by this class and should be cleaned up externally. - void Setup(OmxConfigurator* configurator, - FeedDoneCallback* feed_done_callback, - FillDoneCallback* fill_done_callback); - - // Set the error callback. In case of error the callback will be called. - void SetErrorCallback(Callback* callback); - - // Set the format change callback. In case of input stream changes. - void SetFormatCallback(FormatCallback* callback); - - // Start the decoder, this will start the initialization asynchronously. - // Client can start feeding to and reading from the decoder. - void Start(); - - // Stop the decoder. When the decoder is fully stopped, |callback| - // is called. - void Stop(Callback* callback); - - // Feed the decoder with |buffer|. When the decoder has consumed the - // buffer |feed_done_callback_| is called with |buffer|. - void Feed(scoped_refptr<Buffer> buffer); - - // Flush the decoder and reset its end-of-stream state. - void Flush(Callback* callback); - - // Subclass can provide a different value. - virtual int current_omx_spec_version() const { return 0x00000101; } - - static const int kEosBuffer = -1; - - private: - enum State { - kEmpty, - kLoaded, - kIdle, - kExecuting, - kPortSettingEnable, - kPortSettingDisable, - kError, - }; - - // Getter and setter for the state. - State GetState() const; - void SetState(State state); - State GetNextState() const; - void SetNextState(State state); - - // Methods to be executed in |message_loop_|, they correspond to the - // public methods. - void StartTask(); - void StopTask(Callback* callback); - void FeedTask(scoped_refptr<Buffer> buffer); - - // Helper method to perform tasks when this object is stopped. - void DoneStop(); - - // Helper method to call |error_callback_| after transition to error - // state is done. - void ReportError(); - - // Helper method to call |format_callback_| after a format change. - // used when decoder output port had done with port reconfigure and - // return to enabled state. - void ReportFormatChange( - const OmxConfigurator::MediaFormat& input_format, - const OmxConfigurator::MediaFormat& output_format); - - // Helper method to configure port format at LOADED state. - bool ConfigureIOPorts(); - - // Methods and free input and output buffers. - bool AllocateInputBuffers(); - bool AllocateOutputBuffers(); - void FreeInputBuffers(); - void FreeOutputBuffers(); - void FreeInputQueue(); - - // Transition methods define the specific tasks needs to be done - // in order transition to the next state. - void Transition_EmptyToLoaded(); - void Transition_LoadedToIdle(); - void Transition_IdleToExecuting(); - void Transition_ExecutingToDisable(); - void Transition_DisableToEnable(); - void Transition_DisableToIdle(); - void Transition_EnableToExecuting(); - void Transition_EnableToIdle(); - void Transition_ExecutingToIdle(); - void Transition_IdleToLoaded(); - void Transition_LoadedToEmpty(); - void Transition_Error(); - - // State transition routines. They control which task to perform based - // on the current state and the next state. - void PostStateTransitionTask(State state); - void StateTransitionTask(State state); - - // This method does an automatic state transition after the last - // state transition was completed. For example, after the decoder - // has transitioned from kEmpty to kLoaded, this method will order - // transition from kLoaded to kIdle. - void PostDoneStateTransitionTask(); - void DoneStateTransitionTask(); - - // Determine whether we can issue fill buffer or empty buffer - // to the decoder based on the current state and next state. - bool CanFillBuffer(); - bool CanEmptyBuffer(); - - // Determine whether we can use |input_queue_| and |output_queue_| - // based on the current state. - bool CanAcceptInput(); - bool CanAcceptOutput(); - - // Methods to handle incoming (encoded) buffers. - void EmptyBufferCompleteTask(OMX_BUFFERHEADERTYPE* buffer); - void EmptyBufferTask(); - - // Methods to handle outgoing (decoded) buffers. - void FillBufferCompleteTask(OMX_BUFFERHEADERTYPE* buffer); - - // Take on decoded buffer to fulfill one read request. - void FulfillOneRead(); - - // Callback method to be called from a buffer output sink. - // BufferUsedTask() is the corresponding task that runs on - // |message_loop_|. - void BufferUsedCallback(int buffer_id); - void BufferUsedTask(int buffer_id); - - // Methods that do initial reads to kick start the decoding process. - void InitialFillBuffer(); - void InitialEmptyBuffer(); - - // Member functions to handle events from the OMX component. They - // are called on the thread that the OMX component runs on, thus - // it is not safe to perform any operations on them. They simply - // post a task on |message_loop_| to do the actual work. - void EventHandlerInternal(OMX_HANDLETYPE component, - OMX_EVENTTYPE event, - OMX_U32 data1, OMX_U32 data2, - OMX_PTR event_data); - - void EmptyBufferCallbackInternal(OMX_HANDLETYPE component, - OMX_BUFFERHEADERTYPE* buffer); - - void FillBufferCallbackInternal(OMX_HANDLETYPE component, - OMX_BUFFERHEADERTYPE* buffer); - - // The following three methods are static callback methods - // for the OMX component. When these callbacks are received, the - // call is delegated to the three internal methods above. - static OMX_ERRORTYPE EventHandler(OMX_HANDLETYPE component, - OMX_PTR priv_data, - OMX_EVENTTYPE event, - OMX_U32 data1, OMX_U32 data2, - OMX_PTR event_data); - - static OMX_ERRORTYPE EmptyBufferCallback(OMX_HANDLETYPE component, - OMX_PTR priv_data, - OMX_BUFFERHEADERTYPE* buffer); - - static OMX_ERRORTYPE FillBufferCallback(OMX_HANDLETYPE component, - OMX_PTR priv_data, - OMX_BUFFERHEADERTYPE* buffer); - - std::vector<OMX_BUFFERHEADERTYPE*> input_buffers_; - int input_buffer_count_; - int input_buffer_size_; - int input_port_; - bool input_eos_; - - std::vector<OMX_BUFFERHEADERTYPE*> output_buffers_; - int output_buffer_count_; - int output_buffer_size_; - int output_port_; - bool output_eos_; - - // |state_| records the current state. During state transition - // |next_state_| is the next state that this machine will transition - // to. After a state transition is completed and the state becomes - // stable then |next_state_| equals |state_|. Inequality can be - // used to detect a state transition. - // These two members are read and written only on |message_loop_|. - State state_; - State next_state_; - - OMX_COMPONENTTYPE* component_handle_; - OmxConfigurator* configurator_; - MessageLoop* message_loop_; - - scoped_ptr<FormatCallback> format_callback_; - scoped_ptr<Callback> stop_callback_; - scoped_ptr<Callback> error_callback_; - scoped_ptr<FeedDoneCallback> feed_done_callback_; - scoped_ptr<FillDoneCallback> fill_done_callback_; - - // Input queue for encoded data. - // The input buffers will be sent to OMX component via OMX_EmptyThisBuffer() - std::queue<scoped_refptr<Buffer> > pending_input_queue_; - - // Input queue for encoded data. - // Those buffers have been sent to OMX component, but not returned - // by EmptyBufferDone callback. Once returned from OMX component, they - // will be returned to owner. - std::queue<scoped_refptr<Buffer> > processing_input_queue_; - - // Available input OpenMAX buffers that we can use to issue - // OMX_EmptyThisBuffer() call. - std::queue<OMX_BUFFERHEADERTYPE*> available_input_buffers_; - - // A queue of buffers that carries decoded video frames. They are - // ready to return to client. - // TOOD(hclam): extract it to a separate class. - std::queue<int> output_buffers_ready_; - - private: - DISALLOW_COPY_AND_ASSIGN(OmxCodec); -}; - -} // namespace media - -#endif // MEDIA_OMX_OMX_CODEC_H_ |