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
21namespace base {
22
23class MessageLoopProxy;
24
25}  // namespace base
26
27namespace media {
28
29class BitstreamBuffer;
30
31}  // namespace media
32
33namespace 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.
42class 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_
281