| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef MEDIA_VIDEO_OMX_VIDEO_DECODE_ENGINE_H_ | |
| 6 #define MEDIA_VIDEO_OMX_VIDEO_DECODE_ENGINE_H_ | |
| 7 | |
| 8 #include <queue> | |
| 9 #include <utility> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/callback_old.h" | |
| 13 #include "base/memory/scoped_ptr.h" | |
| 14 #include "media/omx/omx_configurator.h" | |
| 15 #include "media/video/video_decode_engine.h" | |
| 16 #include "third_party/openmax/il/OMX_Component.h" | |
| 17 #include "third_party/openmax/il/OMX_Core.h" | |
| 18 #include "third_party/openmax/il/OMX_Video.h" | |
| 19 | |
| 20 namespace media { | |
| 21 | |
| 22 class OmxVideoDecodeEngine : public VideoDecodeEngine { | |
| 23 public: | |
| 24 OmxVideoDecodeEngine(); | |
| 25 virtual ~OmxVideoDecodeEngine(); | |
| 26 | |
| 27 // Implementation of the VideoDecodeEngine Interface. | |
| 28 virtual void Initialize(MessageLoop* message_loop, | |
| 29 VideoDecodeEngine::EventHandler* event_handler, | |
| 30 VideoDecodeContext* context, | |
| 31 const VideoDecoderConfig& config); | |
| 32 virtual void ConsumeVideoSample(scoped_refptr<Buffer> buffer); | |
| 33 virtual void ProduceVideoFrame(scoped_refptr<VideoFrame> frame); | |
| 34 virtual void Uninitialize(); | |
| 35 virtual void Flush(); | |
| 36 virtual void Seek(); | |
| 37 | |
| 38 // Subclass can provide a different value. | |
| 39 virtual int current_omx_spec_version() const; | |
| 40 | |
| 41 private: | |
| 42 enum OmxIlState { | |
| 43 kIlNone, | |
| 44 kIlLoaded, | |
| 45 kIlIdle, | |
| 46 kIlExecuting, | |
| 47 kIlPause, | |
| 48 kIlInvalid, | |
| 49 kIlUnknown, | |
| 50 }; | |
| 51 | |
| 52 enum OmxIlClientState { | |
| 53 kClientNotInitialized, | |
| 54 kClientInitializing, | |
| 55 kClientRunning, | |
| 56 kClientStopping, | |
| 57 kClientStopped, | |
| 58 kClientPausing, | |
| 59 kClientFlushing, | |
| 60 kClientError, | |
| 61 }; | |
| 62 | |
| 63 enum OmxIlPortState { | |
| 64 kPortDisabled, | |
| 65 kPortEnabling, | |
| 66 kPortEnabled, | |
| 67 kPortDisabling, | |
| 68 }; | |
| 69 | |
| 70 typedef Callback0::Type Callback; | |
| 71 | |
| 72 // calls into other classes | |
| 73 void FinishEmptyBuffer(scoped_refptr<Buffer> buffer); | |
| 74 void FinishFillBuffer(OMX_BUFFERHEADERTYPE* buffer); | |
| 75 // Helper method to perform tasks when this object is stopped. | |
| 76 void OnStopDone(); | |
| 77 | |
| 78 // Transition method sequence for initialization | |
| 79 bool CreateComponent(); | |
| 80 void DoneSetStateIdle(OMX_STATETYPE state); | |
| 81 void DoneSetStateExecuting(OMX_STATETYPE state); | |
| 82 void OnPortSettingsChangedRun(int port, OMX_INDEXTYPE index); | |
| 83 void OnPortDisableEventRun(int port); | |
| 84 void SetupOutputPort(); | |
| 85 void OnPortEnableEventRun(int port); | |
| 86 | |
| 87 // Transition methods for shutdown | |
| 88 void DeinitFromExecuting(OMX_STATETYPE state); | |
| 89 void DeinitFromIdle(OMX_STATETYPE state); | |
| 90 void DeinitFromLoaded(OMX_STATETYPE state); | |
| 91 void PauseFromExecuting(OMX_STATETYPE state); | |
| 92 void StartFlush(); | |
| 93 void PortFlushDone(int port); | |
| 94 void ComponentFlushDone(); | |
| 95 | |
| 96 void StopOnError(); | |
| 97 | |
| 98 void InitializeTask(); | |
| 99 | |
| 100 // Methods to free input and output buffers. | |
| 101 bool AllocateInputBuffers(); | |
| 102 bool AllocateOutputBuffers(); | |
| 103 void FreeInputBuffers(); | |
| 104 void FreeOutputBuffers(); | |
| 105 void FreeInputQueue(); | |
| 106 | |
| 107 // Helper method to configure port format at LOADED state. | |
| 108 bool ConfigureIOPorts(); | |
| 109 | |
| 110 // Determine whether we can issue fill buffer or empty buffer | |
| 111 // to the decoder based on the current state and port state. | |
| 112 bool CanEmptyBuffer(); | |
| 113 bool CanFillBuffer(); | |
| 114 | |
| 115 // Determine whether we can use |input_queue_| and |output_queue_| | |
| 116 // based on the current state. | |
| 117 bool CanAcceptInput(); | |
| 118 bool CanAcceptOutput(); | |
| 119 | |
| 120 bool InputPortFlushed(); | |
| 121 bool OutputPortFlushed(); | |
| 122 | |
| 123 // Method to send input buffers to component | |
| 124 void EmptyBufferTask(); | |
| 125 | |
| 126 // Method doing initial reads to get bit stream from demuxer. | |
| 127 void InitialReadBuffer(); | |
| 128 | |
| 129 // Method doing initial fills to kick start the decoding process. | |
| 130 void InitialFillBuffer(); | |
| 131 | |
| 132 // helper functions | |
| 133 void ChangePort(OMX_COMMANDTYPE cmd, int port_index); | |
| 134 OMX_BUFFERHEADERTYPE* FindOmxBuffer(scoped_refptr<VideoFrame> video_frame); | |
| 135 OMX_STATETYPE GetComponentState(); | |
| 136 void SendOutputBufferToComponent(OMX_BUFFERHEADERTYPE *omx_buffer); | |
| 137 bool TransitionToState(OMX_STATETYPE new_state); | |
| 138 virtual VideoFrame::Format GetSurfaceFormat() const; | |
| 139 | |
| 140 // Method to handle events | |
| 141 void EventHandlerCompleteTask(OMX_EVENTTYPE event, | |
| 142 OMX_U32 data1, | |
| 143 OMX_U32 data2); | |
| 144 | |
| 145 // Method to receive buffers from component's input port | |
| 146 void EmptyBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer); | |
| 147 | |
| 148 // Method to receive buffers from component's output port | |
| 149 void FillBufferDoneTask(OMX_BUFFERHEADERTYPE* buffer); | |
| 150 | |
| 151 // The following three methods are static callback methods | |
| 152 // for the OMX component. When these callbacks are received, the | |
| 153 // call is delegated to the three internal methods above. | |
| 154 static OMX_ERRORTYPE EventHandler(OMX_HANDLETYPE component, | |
| 155 OMX_PTR priv_data, | |
| 156 OMX_EVENTTYPE event, | |
| 157 OMX_U32 data1, OMX_U32 data2, | |
| 158 OMX_PTR event_data); | |
| 159 | |
| 160 static OMX_ERRORTYPE EmptyBufferCallback(OMX_HANDLETYPE component, | |
| 161 OMX_PTR priv_data, | |
| 162 OMX_BUFFERHEADERTYPE* buffer); | |
| 163 | |
| 164 static OMX_ERRORTYPE FillBufferCallback(OMX_HANDLETYPE component, | |
| 165 OMX_PTR priv_data, | |
| 166 OMX_BUFFERHEADERTYPE* buffer); | |
| 167 | |
| 168 // Member function pointers to respond to events | |
| 169 void (OmxVideoDecodeEngine::*OnPortDisableEventFunc)(int port); | |
| 170 void (OmxVideoDecodeEngine::*OnPortEnableEventFunc)(int port); | |
| 171 void (OmxVideoDecodeEngine::*OnStateSetEventFunc)(OMX_STATETYPE state); | |
| 172 void (OmxVideoDecodeEngine::*OnFlushEventFunc)(int port); | |
| 173 | |
| 174 // Helper function | |
| 175 scoped_refptr<VideoFrame> CreateOmxBufferVideoFrame( | |
| 176 OMX_BUFFERHEADERTYPE* omx_buffer); | |
| 177 | |
| 178 int width_; | |
| 179 int height_; | |
| 180 | |
| 181 MessageLoop* message_loop_; | |
| 182 | |
| 183 std::vector<OMX_BUFFERHEADERTYPE*> input_buffers_; | |
| 184 int input_buffer_count_; | |
| 185 int input_buffer_size_; | |
| 186 int input_port_; | |
| 187 int input_buffers_at_component_; | |
| 188 int input_pending_request_; | |
| 189 bool input_queue_has_eos_; | |
| 190 bool input_has_fed_eos_; | |
| 191 bool input_port_flushed_; | |
| 192 | |
| 193 int output_buffer_count_; | |
| 194 int output_buffer_size_; | |
| 195 int output_port_; | |
| 196 int output_buffers_at_component_; | |
| 197 int output_pending_request_; | |
| 198 bool output_eos_; | |
| 199 bool output_port_flushed_; | |
| 200 bool uses_egl_image_; | |
| 201 base::TimeDelta last_pts_; | |
| 202 | |
| 203 // |il_state_| records the current component state. During state transition | |
| 204 // |expected_il_state_| is the next state that the component will transition | |
| 205 // to. After a state transition is completed, |il_state_| equals | |
| 206 // |expected_il_state_|. Inequality can be used to detect a state transition. | |
| 207 // These two members are read and written only on |message_loop_|. | |
| 208 OmxIlState il_state_; | |
| 209 OmxIlState expected_il_state_; | |
| 210 OmxIlClientState client_state_; | |
| 211 | |
| 212 OMX_HANDLETYPE component_handle_; | |
| 213 scoped_ptr<media::OmxConfigurator> configurator_; | |
| 214 | |
| 215 // Free input OpenMAX buffers that can be used to take input bitstream from | |
| 216 // demuxer. | |
| 217 std::queue<OMX_BUFFERHEADERTYPE*> free_input_buffers_; | |
| 218 | |
| 219 // Available input OpenMAX buffers that we can use to issue | |
| 220 // OMX_EmptyThisBuffer() call. | |
| 221 std::queue<OMX_BUFFERHEADERTYPE*> available_input_buffers_; | |
| 222 | |
| 223 // flag for freeing input/output buffers | |
| 224 bool need_free_input_buffers_; | |
| 225 bool need_free_output_buffers_; | |
| 226 | |
| 227 // for calling flush callback only once. | |
| 228 bool flush_pending_; | |
| 229 | |
| 230 // For output buffer recycling cases. | |
| 231 typedef std::pair<scoped_refptr<VideoFrame>, | |
| 232 OMX_BUFFERHEADERTYPE*> OutputFrame; | |
| 233 std::vector<OutputFrame> output_frames_; | |
| 234 bool output_frames_allocated_; | |
| 235 | |
| 236 // port related | |
| 237 bool need_setup_output_port_; | |
| 238 OmxIlPortState output_port_state_; | |
| 239 VideoDecodeEngine::EventHandler* event_handler_; | |
| 240 | |
| 241 DISALLOW_COPY_AND_ASSIGN(OmxVideoDecodeEngine); | |
| 242 }; | |
| 243 | |
| 244 } // namespace media | |
| 245 | |
| 246 #endif // MEDIA_VIDEO_OMX_VIDEO_DECODE_ENGINE_H_ | |
| OLD | NEW |