Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / media / exynos_video_encode_accelerator.h
1 // Copyright 2013 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 CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
7
8 #include <list>
9 #include <vector>
10
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/threading/thread.h"
14 #include "content/common/content_export.h"
15 #include "media/video/video_encode_accelerator.h"
16 #include "ui/gfx/size.h"
17
18 namespace base {
19
20 class MessageLoopProxy;
21
22 }  // namespace base
23
24 namespace media {
25
26 class BitstreamBuffer;
27
28 }  // namespace media
29
30 namespace content {
31
32 // This class handles Exynos video encode acceleration by interfacing with the
33 // V4L2 devices exported by the Multi Format Codec and GScaler hardware blocks
34 // on the Exynos platform.  The threading model of this class is the same as the
35 // ExynosVideoDecodeAccelerator (from which class this was designed).
36 class CONTENT_EXPORT ExynosVideoEncodeAccelerator
37     : public media::VideoEncodeAccelerator {
38  public:
39   ExynosVideoEncodeAccelerator();
40   virtual ~ExynosVideoEncodeAccelerator();
41
42   // media::VideoEncodeAccelerator implementation.
43   virtual void Initialize(media::VideoFrame::Format format,
44                           const gfx::Size& input_visible_size,
45                           media::VideoCodecProfile output_profile,
46                           uint32 initial_bitrate,
47                           Client* client) OVERRIDE;
48   virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
49                       bool force_keyframe) OVERRIDE;
50   virtual void UseOutputBitstreamBuffer(
51       const media::BitstreamBuffer& buffer) OVERRIDE;
52   virtual void RequestEncodingParametersChange(uint32 bitrate,
53                                                uint32 framerate) OVERRIDE;
54   virtual void Destroy() OVERRIDE;
55
56   static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
57       GetSupportedProfiles();
58
59  private:
60   // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
61   // this instance.
62   struct BitstreamBufferRef;
63
64   // Record for GSC input buffers.
65   struct GscInputRecord {
66     GscInputRecord();
67     bool at_device;
68     scoped_refptr<media::VideoFrame> frame;
69   };
70
71   // Record for GSC output buffers.
72   struct GscOutputRecord {
73     GscOutputRecord();
74     bool at_device;
75     int mfc_input;
76   };
77
78   // Record for MFC input buffers.
79   struct MfcInputRecord {
80     MfcInputRecord();
81     bool at_device;
82     int fd[2];
83   };
84
85   // Record for MFC output buffers.
86   struct MfcOutputRecord {
87     MfcOutputRecord();
88     bool at_device;
89     linked_ptr<BitstreamBufferRef> buffer_ref;
90     void* address;
91     size_t length;
92   };
93
94   enum {
95     kInitialFramerate = 30,
96     // These are rather subjectively tuned.
97     kGscInputBufferCount = 2,
98     kGscOutputBufferCount = 2,
99     kMfcOutputBufferCount = 2,
100     // MFC hardware does not report required output buffer size correctly.
101     // Use maximum theoretical size to avoid hanging the hardware.
102     kMfcOutputBufferSize = (2 * 1024 * 1024),
103   };
104
105   // Internal state of the encoder.
106   enum State {
107     kUninitialized,  // Initialize() not yet called.
108     kInitialized,    // Initialize() returned true; ready to start encoding.
109     kEncoding,       // Encoding frames.
110     kError,          // Error in encoder state.
111   };
112
113   //
114   // Encoding tasks, to be run on encode_thread_.
115   //
116
117   // Encode a GSC input buffer.
118   void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
119                   bool force_keyframe);
120
121   // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
122   // output.
123   void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
124
125   // Device destruction task.
126   void DestroyTask();
127
128   // Service I/O on the V4L2 devices.  This task should only be scheduled from
129   // DevicePollTask().
130   void ServiceDeviceTask();
131
132   // Handle the various device queues.
133   void EnqueueGsc();
134   void DequeueGsc();
135   void EnqueueMfc();
136   void DequeueMfc();
137   // Enqueue a buffer on the corresponding queue.  Returns false on fatal error.
138   bool EnqueueGscInputRecord();
139   bool EnqueueGscOutputRecord();
140   bool EnqueueMfcInputRecord();
141   bool EnqueueMfcOutputRecord();
142
143   // Attempt to start/stop device_poll_thread_.
144   bool StartDevicePoll();
145   bool StopDevicePoll();
146   // Set/clear the device poll interrupt (using device_poll_interrupt_fd_).
147   bool SetDevicePollInterrupt();
148   bool ClearDevicePollInterrupt();
149
150   //
151   // Device tasks, to be run on device_poll_thread_.
152   //
153
154   // The device task.
155   void DevicePollTask(unsigned int poll_fds);
156
157   //
158   // Safe from any thread.
159   //
160
161   // Error notification (using PostTask() to child thread, if necessary).
162   void NotifyError(Error error);
163
164   // Set the encoder_thread_ state (using PostTask to encoder thread, if
165   // necessary).
166   void SetEncoderState(State state);
167
168   //
169   // Other utility functions.  Called on encoder_thread_, unless
170   // encoder_thread_ is not yet started, in which case the child thread can call
171   // these (e.g. in Initialize() or Destroy()).
172   //
173
174   // Change the parameters of encoding.
175   void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
176
177   // Create the buffers we need.
178   bool CreateGscInputBuffers();
179   bool CreateGscOutputBuffers();
180   bool SetMfcFormats();
181   bool InitMfcControls();
182   bool CreateMfcInputBuffers();
183   bool CreateMfcOutputBuffers();
184
185   // Destroy these buffers.
186   void DestroyGscInputBuffers();
187   void DestroyGscOutputBuffers();
188   void DestroyMfcInputBuffers();
189   void DestroyMfcOutputBuffers();
190
191   // Our original calling message loop for the child thread.
192   const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
193
194   // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
195   // device worker threads back to the child thread.  Because the worker threads
196   // are members of this class, any task running on those threads is guaranteed
197   // that this object is still alive.  As a result, tasks posted from the child
198   // thread to the encoder or device thread should use base::Unretained(this),
199   // and tasks posted the other way should use |weak_this_|.
200   base::WeakPtrFactory<ExynosVideoEncodeAccelerator> weak_this_ptr_factory_;
201   base::WeakPtr<ExynosVideoEncodeAccelerator> weak_this_;
202
203   // To expose client callbacks from VideoEncodeAccelerator.
204   // NOTE: all calls to these objects *MUST* be executed on
205   // child_message_loop_proxy_.
206   scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
207   base::WeakPtr<Client> client_;
208
209   //
210   // Encoder state, owned and operated by encoder_thread_.
211   // Before encoder_thread_ has started, the encoder state is managed by
212   // the child (main) thread.  After encoder_thread_ has started, the encoder
213   // thread should be the only one managing these.
214   //
215
216   // This thread services tasks posted from the VEA API entry points by the
217   // child thread and device service callbacks posted from the device thread.
218   base::Thread encoder_thread_;
219   // Encoder state.
220   State encoder_state_;
221   // The visible/allocated sizes of the input frame.
222   gfx::Size input_visible_size_;
223   gfx::Size input_allocated_size_;
224   // The visible/allocated sizes of the color-converted intermediate frame.
225   gfx::Size converted_visible_size_;
226   gfx::Size converted_allocated_size_;
227   // The logical visible size of the output frame.
228   gfx::Size output_visible_size_;
229   // The required byte size of output BitstreamBuffers.
230   size_t output_buffer_byte_size_;
231
232   // We need to provide the stream header with every keyframe, to allow
233   // midstream decoding restarts.  Store it here.
234   scoped_ptr<uint8[]> stream_header_;
235   size_t stream_header_size_;
236
237   // V4L2 formats for input frames and the output stream.
238   uint32 input_format_fourcc_;
239   uint32 output_format_fourcc_;
240
241   // Video frames ready to be encoded.
242   std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
243
244   // GSC color conversion device.
245   int gsc_fd_;
246   // GSC input queue state.
247   bool gsc_input_streamon_;
248   // GSC input buffers enqueued to device.
249   int gsc_input_buffer_queued_count_;
250   // GSC input buffers ready to use; LIFO since we don't care about ordering.
251   std::vector<int> gsc_free_input_buffers_;
252   // Mapping of int index to GSC input buffer record.
253   std::vector<GscInputRecord> gsc_input_buffer_map_;
254
255   // GSC output queue state.
256   bool gsc_output_streamon_;
257   // GSC output buffers enqueued to device.
258   int gsc_output_buffer_queued_count_;
259   // GSC output buffers ready to use; LIFO since we don't care about ordering.
260   std::vector<int> gsc_free_output_buffers_;
261   // Mapping of int index to GSC output buffer record.
262   std::vector<GscOutputRecord> gsc_output_buffer_map_;
263
264   // MFC input buffers filled by GSC, waiting to be queued to MFC.
265   std::list<int> mfc_ready_input_buffers_;
266
267   // MFC video encoding device.
268   int mfc_fd_;
269
270   // MFC input queue state.
271   bool mfc_input_streamon_;
272   // MFC input buffers enqueued to device.
273   int mfc_input_buffer_queued_count_;
274   // MFC input buffers ready to use; LIFO since we don't care about ordering.
275   std::vector<int> mfc_free_input_buffers_;
276   // Mapping of int index to MFC input buffer record.
277   std::vector<MfcInputRecord> mfc_input_buffer_map_;
278
279   // MFC output queue state.
280   bool mfc_output_streamon_;
281   // MFC output buffers enqueued to device.
282   int mfc_output_buffer_queued_count_;
283   // MFC output buffers ready to use; LIFO since we don't care about ordering.
284   std::vector<int> mfc_free_output_buffers_;
285   // Mapping of int index to MFC output buffer record.
286   std::vector<MfcOutputRecord> mfc_output_buffer_map_;
287
288   // Bitstream buffers ready to be used to return encoded output, as a LIFO
289   // since we don't care about ordering.
290   std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
291
292   //
293   // The device polling thread handles notifications of V4L2 device changes.
294   // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
295   //
296
297   // The thread.
298   base::Thread device_poll_thread_;
299   // eventfd fd to signal device poll thread when its poll() should be
300   // interrupted.
301   int device_poll_interrupt_fd_;
302
303   DISALLOW_COPY_AND_ASSIGN(ExynosVideoEncodeAccelerator);
304 };
305
306 }  // namespace content
307
308 #endif  // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_