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.
5 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
6 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
8 #include <linux/videodev2.h>
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_device.h"
17 #include "content/common/gpu/media/v4l2_image_processor.h"
18 #include "media/video/video_encode_accelerator.h"
19 #include "ui/gfx/geometry/size.h"
23 class BitstreamBuffer
;
29 // This class handles video encode acceleration by interfacing with a V4L2
30 // device exposed by the codec hardware driver. The threading model of this
31 // class is the same as in the V4L2VideoDecodeAccelerator (from which class this
33 // This class may try to instantiate and use a V4L2ImageProcessor for input
34 // format conversion, if the input format requested via Initialize() is not
35 // accepted by the hardware codec.
36 class CONTENT_EXPORT V4L2VideoEncodeAccelerator
37 : public media::VideoEncodeAccelerator
{
39 explicit V4L2VideoEncodeAccelerator(const scoped_refptr
<V4L2Device
>& device
);
40 ~V4L2VideoEncodeAccelerator() override
;
42 // media::VideoEncodeAccelerator implementation.
43 media::VideoEncodeAccelerator::SupportedProfiles
GetSupportedProfiles()
45 bool Initialize(media::VideoPixelFormat format
,
46 const gfx::Size
& input_visible_size
,
47 media::VideoCodecProfile output_profile
,
48 uint32 initial_bitrate
,
49 Client
* client
) override
;
50 void Encode(const scoped_refptr
<media::VideoFrame
>& frame
,
51 bool force_keyframe
) override
;
52 void UseOutputBitstreamBuffer(const media::BitstreamBuffer
& buffer
)
54 void RequestEncodingParametersChange(uint32 bitrate
,
55 uint32 framerate
) override
;
56 void Destroy() override
;
59 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
61 struct BitstreamBufferRef
;
63 // Record for codec input buffers.
68 scoped_refptr
<media::VideoFrame
> frame
;
71 // Record for output buffers.
76 linked_ptr
<BitstreamBufferRef
> buffer_ref
;
82 kInitialFramerate
= 30,
83 // These are rather subjectively tuned.
84 kInputBufferCount
= 2,
85 kOutputBufferCount
= 2,
86 kOutputBufferSize
= (2 * 1024 * 1024),
89 // Internal state of the encoder.
91 kUninitialized
, // Initialize() not yet called.
92 kInitialized
, // Initialize() returned true; ready to start encoding.
93 kEncoding
, // Encoding frames.
94 kError
, // Error in encoder state.
98 // Callbacks for the image processor, if one is used.
101 // Callback run by the image processor when a frame is ready for us to encode.
102 void FrameProcessed(bool force_keyframe
,
103 const scoped_refptr
<media::VideoFrame
>& frame
);
105 // Error callback for handling image processor errors.
106 void ImageProcessorError();
109 // Encoding tasks, to be run on encode_thread_.
112 void EncodeTask(const scoped_refptr
<media::VideoFrame
>& frame
,
113 bool force_keyframe
);
115 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
117 void UseOutputBitstreamBufferTask(scoped_ptr
<BitstreamBufferRef
> buffer_ref
);
119 // Device destruction task.
122 // Service I/O on the V4L2 devices. This task should only be scheduled from
124 void ServiceDeviceTask();
126 // Handle the device queues.
129 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
130 bool EnqueueInputRecord();
131 bool EnqueueOutputRecord();
133 // Attempt to start/stop device_poll_thread_.
134 bool StartDevicePoll();
135 bool StopDevicePoll();
138 // Device tasks, to be run on device_poll_thread_.
142 void DevicePollTask(bool poll_device
);
145 // Safe from any thread.
148 // Error notification (using PostTask() to child thread, if necessary).
149 void NotifyError(Error error
);
151 // Set the encoder_state_ to kError and notify the client (if necessary).
152 void SetErrorState(Error error
);
155 // Other utility functions. Called on encoder_thread_, unless
156 // encoder_thread_ is not yet started, in which case the child thread can call
157 // these (e.g. in Initialize() or Destroy()).
160 // Change encoding parameters.
161 void RequestEncodingParametersChangeTask(uint32 bitrate
, uint32 framerate
);
163 // Set up formats and initialize the device for them.
164 bool SetFormats(media::VideoPixelFormat input_format
,
165 media::VideoCodecProfile output_profile
);
167 // Try to set up the device to the input format we were Initialized() with,
168 // or if the device doesn't support it, use one it can support, so that we
169 // can later instantiate a V4L2ImageProcessor to convert to it.
170 bool NegotiateInputFormat(media::VideoPixelFormat input_format
);
172 // Set up the device to the output format requested in Initialize().
173 bool SetOutputFormat(media::VideoCodecProfile output_profile
);
175 // Initialize device controls with default values.
178 // Create the buffers we need.
179 bool CreateInputBuffers();
180 bool CreateOutputBuffers();
182 // Destroy these buffers.
183 void DestroyInputBuffers();
184 void DestroyOutputBuffers();
186 // Set controls in |ctrls| and return true if successful.
187 bool SetExtCtrls(std::vector
<struct v4l2_ext_control
> ctrls
);
189 // Our original calling task runner for the child thread.
190 const scoped_refptr
<base::SingleThreadTaskRunner
> child_task_runner_
;
192 gfx::Size visible_size_
;
193 // Input allocated size required by the device.
194 gfx::Size input_allocated_size_
;
195 size_t output_buffer_byte_size_
;
197 // Formats for input frames and the output stream.
198 media::VideoPixelFormat device_input_format_
;
199 size_t input_planes_count_
;
200 uint32 output_format_fourcc_
;
203 // Encoder state, owned and operated by encoder_thread_.
204 // Before encoder_thread_ has started, the encoder state is managed by
205 // the child (main) thread. After encoder_thread_ has started, the encoder
206 // thread should be the only one managing these.
210 State encoder_state_
;
212 // We need to provide the stream header with every keyframe, to allow
213 // midstream decoding restarts. Store it here.
214 scoped_ptr
<uint8
[]> stream_header_
;
215 size_t stream_header_size_
;
217 // Video frames ready to be encoded.
218 std::list
<scoped_refptr
<media::VideoFrame
> > encoder_input_queue_
;
221 scoped_refptr
<V4L2Device
> device_
;
223 // Input queue state.
224 bool input_streamon_
;
225 // Input buffers enqueued to device.
226 int input_buffer_queued_count_
;
227 // Input buffers ready to use; LIFO since we don't care about ordering.
228 std::vector
<int> free_input_buffers_
;
229 // Mapping of int index to input buffer record.
230 std::vector
<InputRecord
> input_buffer_map_
;
231 enum v4l2_memory input_memory_type_
;
233 // Output queue state.
234 bool output_streamon_
;
235 // Output buffers enqueued to device.
236 int output_buffer_queued_count_
;
237 // Output buffers ready to use; LIFO since we don't care about ordering.
238 std::vector
<int> free_output_buffers_
;
239 // Mapping of int index to output buffer record.
240 std::vector
<OutputRecord
> output_buffer_map_
;
242 // Bitstream buffers ready to be used to return encoded output, as a LIFO
243 // since we don't care about ordering.
244 std::vector
<linked_ptr
<BitstreamBufferRef
> > encoder_output_queue_
;
246 // Image processor, if one is in use.
247 scoped_ptr
<V4L2ImageProcessor
> image_processor_
;
249 // This thread services tasks posted from the VEA API entry points by the
250 // child thread and device service callbacks posted from the device thread.
251 base::Thread encoder_thread_
;
253 // The device polling thread handles notifications of V4L2 device changes.
254 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
255 base::Thread device_poll_thread_
;
257 // To expose client callbacks from VideoEncodeAccelerator.
258 // NOTE: all calls to these objects *MUST* be executed on
259 // child_task_runner_.
260 base::WeakPtr
<Client
> client_
;
261 scoped_ptr
<base::WeakPtrFactory
<Client
> > client_ptr_factory_
;
263 // WeakPtr<> pointing to |this| for use in posting tasks from the
264 // image_processor_ back to the child thread.
265 // Tasks posted onto encoder and poll threads can use base::Unretained(this),
266 // as both threads will not outlive this object.
267 base::WeakPtr
<V4L2VideoEncodeAccelerator
> weak_this_
;
268 base::WeakPtrFactory
<V4L2VideoEncodeAccelerator
> weak_this_ptr_factory_
;
270 DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator
);
273 } // namespace content
275 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_