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_
9 #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_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"
23 class MessageLoopProxy
;
29 class BitstreamBuffer
;
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
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
{
45 explicit V4L2VideoEncodeAccelerator(scoped_ptr
<V4L2Device
> device
);
46 virtual ~V4L2VideoEncodeAccelerator();
48 // media::VideoEncodeAccelerator implementation.
49 virtual bool Initialize(media::VideoFrame::Format format
,
50 const gfx::Size
& input_visible_size
,
51 media::VideoCodecProfile output_profile
,
52 uint32 initial_bitrate
,
53 Client
* client
) OVERRIDE
;
54 virtual void Encode(const scoped_refptr
<media::VideoFrame
>& frame
,
55 bool force_keyframe
) OVERRIDE
;
56 virtual void UseOutputBitstreamBuffer(const media::BitstreamBuffer
& buffer
)
58 virtual void RequestEncodingParametersChange(uint32 bitrate
,
59 uint32 framerate
) OVERRIDE
;
60 virtual void Destroy() OVERRIDE
;
62 static std::vector
<media::VideoEncodeAccelerator::SupportedProfile
>
63 GetSupportedProfiles();
66 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
68 struct BitstreamBufferRef
;
70 // Record for codec input buffers.
74 scoped_refptr
<media::VideoFrame
> frame
;
77 // Record for output buffers.
81 linked_ptr
<BitstreamBufferRef
> buffer_ref
;
87 kInitialFramerate
= 30,
88 // These are rather subjectively tuned.
89 kInputBufferCount
= 2,
90 kOutputBufferCount
= 2,
91 kOutputBufferSize
= (2 * 1024 * 1024),
94 // Internal state of the encoder.
96 kUninitialized
, // Initialize() not yet called.
97 kInitialized
, // Initialize() returned true; ready to start encoding.
98 kEncoding
, // Encoding frames.
99 kError
, // Error in encoder state.
103 // Callbacks for the image processor, if one is used.
106 // Callback run by the image processor when a frame is ready for us to encode.
107 void FrameProcessed(bool force_keyframe
,
108 const scoped_refptr
<media::VideoFrame
>& frame
);
110 // Error callback for handling image processor errors.
111 void ImageProcessorError();
114 // Encoding tasks, to be run on encode_thread_.
117 void EncodeTask(const scoped_refptr
<media::VideoFrame
>& frame
,
118 bool force_keyframe
);
120 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
122 void UseOutputBitstreamBufferTask(scoped_ptr
<BitstreamBufferRef
> buffer_ref
);
124 // Device destruction task.
127 // Service I/O on the V4L2 devices. This task should only be scheduled from
129 void ServiceDeviceTask();
131 // Handle the device queues.
134 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
135 bool EnqueueInputRecord();
136 bool EnqueueOutputRecord();
138 // Attempt to start/stop device_poll_thread_.
139 bool StartDevicePoll();
140 bool StopDevicePoll();
143 // Device tasks, to be run on device_poll_thread_.
147 void DevicePollTask(bool poll_device
);
150 // Safe from any thread.
153 // Error notification (using PostTask() to child thread, if necessary).
154 void NotifyError(Error error
);
156 // Set the encoder_thread_ state (using PostTask to encoder thread, if
158 void SetEncoderState(State state
);
161 // Other utility functions. Called on encoder_thread_, unless
162 // encoder_thread_ is not yet started, in which case the child thread can call
163 // these (e.g. in Initialize() or Destroy()).
166 // Change encoding parameters.
167 void RequestEncodingParametersChangeTask(uint32 bitrate
, uint32 framerate
);
169 // Set up formats and initialize the device for them.
170 bool SetFormats(media::VideoFrame::Format input_format
,
171 media::VideoCodecProfile output_profile
);
173 // Try to set up the device to the input format we were Initialized() with,
174 // or if the device doesn't support it, use one it can support, so that we
175 // can later instantiate a V4L2ImageProcessor to convert to it.
176 bool NegotiateInputFormat(media::VideoFrame::Format input_format
);
178 // Set up the device to the output format requested in Initialize().
179 bool SetOutputFormat(media::VideoCodecProfile output_profile
);
181 // Initialize device controls with default values.
184 // Create the buffers we need.
185 bool CreateInputBuffers();
186 bool CreateOutputBuffers();
188 // Destroy these buffers.
189 void DestroyInputBuffers();
190 void DestroyOutputBuffers();
192 // Our original calling message loop for the child thread.
193 const scoped_refptr
<base::MessageLoopProxy
> child_message_loop_proxy_
;
195 gfx::Size visible_size_
;
196 // Input allocated size required by the device.
197 gfx::Size input_allocated_size_
;
198 size_t output_buffer_byte_size_
;
200 // Formats for input frames and the output stream.
201 media::VideoFrame::Format device_input_format_
;
202 size_t input_planes_count_
;
203 uint32 output_format_fourcc_
;
206 // Encoder state, owned and operated by encoder_thread_.
207 // Before encoder_thread_ has started, the encoder state is managed by
208 // the child (main) thread. After encoder_thread_ has started, the encoder
209 // thread should be the only one managing these.
213 State encoder_state_
;
215 // We need to provide the stream header with every keyframe, to allow
216 // midstream decoding restarts. Store it here.
217 scoped_ptr
<uint8
[]> stream_header_
;
218 size_t stream_header_size_
;
220 // Video frames ready to be encoded.
221 std::list
<scoped_refptr
<media::VideoFrame
> > encoder_input_queue_
;
224 scoped_ptr
<V4L2Device
> device_
;
226 // Input queue state.
227 bool input_streamon_
;
228 // Input buffers enqueued to device.
229 int input_buffer_queued_count_
;
230 // Input buffers ready to use; LIFO since we don't care about ordering.
231 std::vector
<int> free_input_buffers_
;
232 // Mapping of int index to input buffer record.
233 std::vector
<InputRecord
> input_buffer_map_
;
234 enum v4l2_memory input_memory_type_
;
236 // Output queue state.
237 bool output_streamon_
;
238 // Output buffers enqueued to device.
239 int output_buffer_queued_count_
;
240 // Output buffers ready to use; LIFO since we don't care about ordering.
241 std::vector
<int> free_output_buffers_
;
242 // Mapping of int index to output buffer record.
243 std::vector
<OutputRecord
> output_buffer_map_
;
245 // Bitstream buffers ready to be used to return encoded output, as a LIFO
246 // since we don't care about ordering.
247 std::vector
<linked_ptr
<BitstreamBufferRef
> > encoder_output_queue_
;
249 // Image processor, if one is in use.
250 scoped_ptr
<V4L2ImageProcessor
> image_processor_
;
252 // This thread services tasks posted from the VEA API entry points by the
253 // child thread and device service callbacks posted from the device thread.
254 base::Thread encoder_thread_
;
256 // The device polling thread handles notifications of V4L2 device changes.
257 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
258 base::Thread device_poll_thread_
;
260 // To expose client callbacks from VideoEncodeAccelerator.
261 // NOTE: all calls to these objects *MUST* be executed on
262 // child_message_loop_proxy_.
263 base::WeakPtr
<Client
> client_
;
264 scoped_ptr
<base::WeakPtrFactory
<Client
> > client_ptr_factory_
;
266 // WeakPtr<> pointing to |this| for use in posting tasks from the
267 // image_processor_ back to the child thread.
268 // Tasks posted onto encoder and poll threads can use base::Unretained(this),
269 // as both threads will not outlive this object.
270 base::WeakPtr
<V4L2VideoEncodeAccelerator
> weak_this_
;
271 base::WeakPtrFactory
<V4L2VideoEncodeAccelerator
> weak_this_ptr_factory_
;
273 DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator
);
276 } // namespace content
278 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_