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 |