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 static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
49 GetSupportedProfilesStatic();
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)
63 virtual void RequestEncodingParametersChange(uint32 bitrate,
64 uint32 framerate) OVERRIDE;
65 virtual void Destroy() OVERRIDE;
68 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
70 struct BitstreamBufferRef;
72 // Record for codec input buffers.
76 scoped_refptr<media::VideoFrame> frame;
79 // Record for output buffers.
83 linked_ptr<BitstreamBufferRef> buffer_ref;
89 kInitialFramerate = 30,
90 // These are rather subjectively tuned.
91 kInputBufferCount = 2,
92 kOutputBufferCount = 2,
93 kOutputBufferSize = (2 * 1024 * 1024),
96 // Internal state of the encoder.
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.
105 // Callbacks for the image processor, if one is used.
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);
112 // Error callback for handling image processor errors.
113 void ImageProcessorError();
116 // Encoding tasks, to be run on encode_thread_.
119 void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
120 bool force_keyframe);
122 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
124 void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
126 // Device destruction task.
129 // Service I/O on the V4L2 devices. This task should only be scheduled from
131 void ServiceDeviceTask();
133 // Handle the device queues.
136 // Enqueue a buffer on the corresponding queue. Returns false on fatal error.
137 bool EnqueueInputRecord();
138 bool EnqueueOutputRecord();
140 // Attempt to start/stop device_poll_thread_.
141 bool StartDevicePoll();
142 bool StopDevicePoll();
145 // Device tasks, to be run on device_poll_thread_.
149 void DevicePollTask(bool poll_device);
152 // Safe from any thread.
155 // Error notification (using PostTask() to child thread, if necessary).
156 void NotifyError(Error error);
158 // Set the encoder_thread_ state (using PostTask to encoder thread, if
160 void SetEncoderState(State state);
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()).
168 // Change encoding parameters.
169 void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
171 // Set up formats and initialize the device for them.
172 bool SetFormats(media::VideoFrame::Format input_format,
173 media::VideoCodecProfile output_profile);
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);
180 // Set up the device to the output format requested in Initialize().
181 bool SetOutputFormat(media::VideoCodecProfile output_profile);
183 // Initialize device controls with default values.
186 // Create the buffers we need.
187 bool CreateInputBuffers();
188 bool CreateOutputBuffers();
190 // Destroy these buffers.
191 void DestroyInputBuffers();
192 void DestroyOutputBuffers();
194 // Our original calling message loop for the child thread.
195 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
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_;
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_;
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.
215 State encoder_state_;
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_;
222 // Video frames ready to be encoded.
223 std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
226 scoped_ptr<V4L2Device> device_;
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_;
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_;
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_;
251 // Image processor, if one is in use.
252 scoped_ptr<V4L2ImageProcessor> image_processor_;
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_;
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_;
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_;
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_;
275 DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator);
278 } // namespace content
280 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_