Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / media / v4l2_video_encode_accelerator.h
1 // Copyright 2014 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_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
7
8 #include <list>
9 #include <linux/videodev2.h>
10 #include <vector>
11
12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/threading/thread.h"
15 #include "content/common/content_export.h"
16 #include "content/common/gpu/media/v4l2_image_processor.h"
17 #include "content/common/gpu/media/v4l2_video_device.h"
18 #include "media/video/video_encode_accelerator.h"
19 #include "ui/gfx/size.h"
20
21 namespace base {
22
23 class MessageLoopProxy;
24
25 }  // namespace base
26
27 namespace media {
28
29 class BitstreamBuffer;
30
31 }  // namespace media
32
33 namespace content {
34
35 // This class handles video encode acceleration by interfacing with a V4L2
36 // device exposed by the codec hardware driver. The threading model of this
37 // class is the same as in the V4L2VideoDecodeAccelerator (from which class this
38 // was designed).
39 // This class may try to instantiate and use a V4L2ImageProcessor for input
40 // format conversion, if the input format requested via Initialize() is not
41 // accepted by the hardware codec.
42 class CONTENT_EXPORT V4L2VideoEncodeAccelerator
43     : public media::VideoEncodeAccelerator {
44  public:
45   explicit V4L2VideoEncodeAccelerator(scoped_ptr<V4L2Device> device);
46   virtual ~V4L2VideoEncodeAccelerator();
47
48   static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
49       GetSupportedProfilesStatic();
50
51   // media::VideoEncodeAccelerator implementation.
52   virtual std::vector<media::VideoEncodeAccelerator::SupportedProfile>
53       GetSupportedProfiles() OVERRIDE;
54   virtual bool Initialize(media::VideoFrame::Format format,
55                           const gfx::Size& input_visible_size,
56                           media::VideoCodecProfile output_profile,
57                           uint32 initial_bitrate,
58                           Client* client) OVERRIDE;
59   virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
60                       bool force_keyframe) OVERRIDE;
61   virtual void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer)
62       OVERRIDE;
63   virtual void RequestEncodingParametersChange(uint32 bitrate,
64                                                uint32 framerate) OVERRIDE;
65   virtual void Destroy() OVERRIDE;
66
67  private:
68   // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
69   // this instance.
70   struct BitstreamBufferRef;
71
72   // Record for codec input buffers.
73   struct InputRecord {
74     InputRecord();
75     bool at_device;
76     scoped_refptr<media::VideoFrame> frame;
77   };
78
79   // Record for output buffers.
80   struct OutputRecord {
81     OutputRecord();
82     bool at_device;
83     linked_ptr<BitstreamBufferRef> buffer_ref;
84     void* address;
85     size_t length;
86   };
87
88   enum {
89     kInitialFramerate = 30,
90     // These are rather subjectively tuned.
91     kInputBufferCount = 2,
92     kOutputBufferCount = 2,
93     kOutputBufferSize = (2 * 1024 * 1024),
94   };
95
96   // Internal state of the encoder.
97   enum State {
98     kUninitialized,  // Initialize() not yet called.
99     kInitialized,    // Initialize() returned true; ready to start encoding.
100     kEncoding,       // Encoding frames.
101     kError,          // Error in encoder state.
102   };
103
104   //
105   // Callbacks for the image processor, if one is used.
106   //
107
108   // Callback run by the image processor when a frame is ready for us to encode.
109   void FrameProcessed(bool force_keyframe,
110                       const scoped_refptr<media::VideoFrame>& frame);
111
112   // Error callback for handling image processor errors.
113   void ImageProcessorError();
114
115   //
116   // Encoding tasks, to be run on encode_thread_.
117   //
118
119   void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
120                   bool force_keyframe);
121
122   // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
123   // output.
124   void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
125
126   // Device destruction task.
127   void DestroyTask();
128
129   // Service I/O on the V4L2 devices.  This task should only be scheduled from
130   // DevicePollTask().
131   void ServiceDeviceTask();
132
133   // Handle the device queues.
134   void Enqueue();
135   void Dequeue();
136   // Enqueue a buffer on the corresponding queue.  Returns false on fatal error.
137   bool EnqueueInputRecord();
138   bool EnqueueOutputRecord();
139
140   // Attempt to start/stop device_poll_thread_.
141   bool StartDevicePoll();
142   bool StopDevicePoll();
143
144   //
145   // Device tasks, to be run on device_poll_thread_.
146   //
147
148   // The device task.
149   void DevicePollTask(bool poll_device);
150
151   //
152   // Safe from any thread.
153   //
154
155   // Error notification (using PostTask() to child thread, if necessary).
156   void NotifyError(Error error);
157
158   // Set the encoder_thread_ state (using PostTask to encoder thread, if
159   // necessary).
160   void SetEncoderState(State state);
161
162   //
163   // Other utility functions.  Called on encoder_thread_, unless
164   // encoder_thread_ is not yet started, in which case the child thread can call
165   // these (e.g. in Initialize() or Destroy()).
166   //
167
168   // Change encoding parameters.
169   void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
170
171   // Set up formats and initialize the device for them.
172   bool SetFormats(media::VideoFrame::Format input_format,
173                   media::VideoCodecProfile output_profile);
174
175   // Try to set up the device to the input format we were Initialized() with,
176   // or if the device doesn't support it, use one it can support, so that we
177   // can later instantiate a V4L2ImageProcessor to convert to it.
178   bool NegotiateInputFormat(media::VideoFrame::Format input_format);
179
180   // Set up the device to the output format requested in Initialize().
181   bool SetOutputFormat(media::VideoCodecProfile output_profile);
182
183   // Initialize device controls with default values.
184   bool InitControls();
185
186   // Create the buffers we need.
187   bool CreateInputBuffers();
188   bool CreateOutputBuffers();
189
190   // Destroy these buffers.
191   void DestroyInputBuffers();
192   void DestroyOutputBuffers();
193
194   // Our original calling message loop for the child thread.
195   const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
196
197   gfx::Size visible_size_;
198   // Input allocated size required by the device.
199   gfx::Size input_allocated_size_;
200   size_t output_buffer_byte_size_;
201
202   // Formats for input frames and the output stream.
203   media::VideoFrame::Format device_input_format_;
204   size_t input_planes_count_;
205   uint32 output_format_fourcc_;
206
207   //
208   // Encoder state, owned and operated by encoder_thread_.
209   // Before encoder_thread_ has started, the encoder state is managed by
210   // the child (main) thread.  After encoder_thread_ has started, the encoder
211   // thread should be the only one managing these.
212   //
213
214   // Encoder state.
215   State encoder_state_;
216
217   // We need to provide the stream header with every keyframe, to allow
218   // midstream decoding restarts.  Store it here.
219   scoped_ptr<uint8[]> stream_header_;
220   size_t stream_header_size_;
221
222   // Video frames ready to be encoded.
223   std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
224
225   // Encoder device.
226   scoped_ptr<V4L2Device> device_;
227
228   // Input queue state.
229   bool input_streamon_;
230   // Input buffers enqueued to device.
231   int input_buffer_queued_count_;
232   // Input buffers ready to use; LIFO since we don't care about ordering.
233   std::vector<int> free_input_buffers_;
234   // Mapping of int index to input buffer record.
235   std::vector<InputRecord> input_buffer_map_;
236   enum v4l2_memory input_memory_type_;
237
238   // Output queue state.
239   bool output_streamon_;
240   // Output buffers enqueued to device.
241   int output_buffer_queued_count_;
242   // Output buffers ready to use; LIFO since we don't care about ordering.
243   std::vector<int> free_output_buffers_;
244   // Mapping of int index to output buffer record.
245   std::vector<OutputRecord> output_buffer_map_;
246
247   // Bitstream buffers ready to be used to return encoded output, as a LIFO
248   // since we don't care about ordering.
249   std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
250
251   // Image processor, if one is in use.
252   scoped_ptr<V4L2ImageProcessor> image_processor_;
253
254   // This thread services tasks posted from the VEA API entry points by the
255   // child thread and device service callbacks posted from the device thread.
256   base::Thread encoder_thread_;
257
258   // The device polling thread handles notifications of V4L2 device changes.
259   // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
260   base::Thread device_poll_thread_;
261
262   // To expose client callbacks from VideoEncodeAccelerator.
263   // NOTE: all calls to these objects *MUST* be executed on
264   // child_message_loop_proxy_.
265   base::WeakPtr<Client> client_;
266   scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
267
268   // WeakPtr<> pointing to |this| for use in posting tasks from the
269   // image_processor_ back to the child thread.
270   // Tasks posted onto encoder and poll threads can use base::Unretained(this),
271   // as both threads will not outlive this object.
272   base::WeakPtr<V4L2VideoEncodeAccelerator> weak_this_;
273   base::WeakPtrFactory<V4L2VideoEncodeAccelerator> weak_this_ptr_factory_;
274
275   DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator);
276 };
277
278 }  // namespace content
279
280 #endif  // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_