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