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 21 namespace base { 22 23 class MessageLoopProxy; 24 25 } // namespace base 26 27 namespace media { 28 29 class BitstreamBuffer; 30 31 } // namespace media 32 33 namespace 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. 42 class CONTENT_EXPORT V4L2VideoEncodeAccelerator 43 : public media::VideoEncodeAccelerator { 44 public: 45 explicit V4L2VideoEncodeAccelerator(scoped_ptr<V4L2Device> device); 46 virtual ~V4L2VideoEncodeAccelerator(); 47 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) 57 OVERRIDE; 58 virtual void RequestEncodingParametersChange(uint32 bitrate, 59 uint32 framerate) OVERRIDE; 60 virtual void Destroy() OVERRIDE; 61 62 static std::vector<media::VideoEncodeAccelerator::SupportedProfile> 63 GetSupportedProfiles(); 64 65 private: 66 // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to 67 // this instance. 68 struct BitstreamBufferRef; 69 70 // Record for codec input buffers. 71 struct InputRecord { 72 InputRecord(); 73 bool at_device; 74 scoped_refptr<media::VideoFrame> frame; 75 }; 76 77 // Record for output buffers. 78 struct OutputRecord { 79 OutputRecord(); 80 bool at_device; 81 linked_ptr<BitstreamBufferRef> buffer_ref; 82 void* address; 83 size_t length; 84 }; 85 86 enum { 87 kInitialFramerate = 30, 88 // These are rather subjectively tuned. 89 kInputBufferCount = 2, 90 kOutputBufferCount = 2, 91 kOutputBufferSize = (2 * 1024 * 1024), 92 }; 93 94 // Internal state of the encoder. 95 enum State { 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. 100 }; 101 102 // 103 // Callbacks for the image processor, if one is used. 104 // 105 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); 109 110 // Error callback for handling image processor errors. 111 void ImageProcessorError(); 112 113 // 114 // Encoding tasks, to be run on encode_thread_. 115 // 116 117 void EncodeTask(const scoped_refptr<media::VideoFrame>& frame, 118 bool force_keyframe); 119 120 // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder 121 // output. 122 void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref); 123 124 // Device destruction task. 125 void DestroyTask(); 126 127 // Service I/O on the V4L2 devices. This task should only be scheduled from 128 // DevicePollTask(). 129 void ServiceDeviceTask(); 130 131 // Handle the device queues. 132 void Enqueue(); 133 void Dequeue(); 134 // Enqueue a buffer on the corresponding queue. Returns false on fatal error. 135 bool EnqueueInputRecord(); 136 bool EnqueueOutputRecord(); 137 138 // Attempt to start/stop device_poll_thread_. 139 bool StartDevicePoll(); 140 bool StopDevicePoll(); 141 142 // 143 // Device tasks, to be run on device_poll_thread_. 144 // 145 146 // The device task. 147 void DevicePollTask(bool poll_device); 148 149 // 150 // Safe from any thread. 151 // 152 153 // Error notification (using PostTask() to child thread, if necessary). 154 void NotifyError(Error error); 155 156 // Set the encoder_thread_ state (using PostTask to encoder thread, if 157 // necessary). 158 void SetEncoderState(State state); 159 160 // 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()). 164 // 165 166 // Change encoding parameters. 167 void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate); 168 169 // Set up formats and initialize the device for them. 170 bool SetFormats(media::VideoFrame::Format input_format, 171 media::VideoCodecProfile output_profile); 172 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); 177 178 // Set up the device to the output format requested in Initialize(). 179 bool SetOutputFormat(media::VideoCodecProfile output_profile); 180 181 // Initialize device controls with default values. 182 bool InitControls(); 183 184 // Create the buffers we need. 185 bool CreateInputBuffers(); 186 bool CreateOutputBuffers(); 187 188 // Destroy these buffers. 189 void DestroyInputBuffers(); 190 void DestroyOutputBuffers(); 191 192 // Our original calling message loop for the child thread. 193 const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_; 194 195 // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or 196 // device worker threads back to the child thread. Because the worker threads 197 // are members of this class, any task running on those threads is guaranteed 198 // that this object is still alive. As a result, tasks posted from the child 199 // thread to the encoder or device thread should use base::Unretained(this), 200 // and tasks posted the other way should use |weak_this_|. 201 base::WeakPtrFactory<V4L2VideoEncodeAccelerator> weak_this_ptr_factory_; 202 base::WeakPtr<V4L2VideoEncodeAccelerator> weak_this_; 203 204 // To expose client callbacks from VideoEncodeAccelerator. 205 // NOTE: all calls to these objects *MUST* be executed on 206 // child_message_loop_proxy_. 207 scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; 208 base::WeakPtr<Client> client_; 209 210 gfx::Size visible_size_; 211 // Input allocated size required by the device. 212 gfx::Size input_allocated_size_; 213 size_t output_buffer_byte_size_; 214 215 // Formats for input frames and the output stream. 216 media::VideoFrame::Format device_input_format_; 217 size_t input_planes_count_; 218 uint32 output_format_fourcc_; 219 220 // 221 // Encoder state, owned and operated by encoder_thread_. 222 // Before encoder_thread_ has started, the encoder state is managed by 223 // the child (main) thread. After encoder_thread_ has started, the encoder 224 // thread should be the only one managing these. 225 // 226 227 // This thread services tasks posted from the VEA API entry points by the 228 // child thread and device service callbacks posted from the device thread. 229 base::Thread encoder_thread_; 230 // Encoder state. 231 State encoder_state_; 232 233 // We need to provide the stream header with every keyframe, to allow 234 // midstream decoding restarts. Store it here. 235 scoped_ptr<uint8[]> stream_header_; 236 size_t stream_header_size_; 237 238 // Video frames ready to be encoded. 239 std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_; 240 241 // Encoder device. 242 scoped_ptr<V4L2Device> device_; 243 244 // Input queue state. 245 bool input_streamon_; 246 // Input buffers enqueued to device. 247 int input_buffer_queued_count_; 248 // Input buffers ready to use; LIFO since we don't care about ordering. 249 std::vector<int> free_input_buffers_; 250 // Mapping of int index to input buffer record. 251 std::vector<InputRecord> input_buffer_map_; 252 enum v4l2_memory input_memory_type_; 253 254 // Output queue state. 255 bool output_streamon_; 256 // Output buffers enqueued to device. 257 int output_buffer_queued_count_; 258 // Output buffers ready to use; LIFO since we don't care about ordering. 259 std::vector<int> free_output_buffers_; 260 // Mapping of int index to output buffer record. 261 std::vector<OutputRecord> output_buffer_map_; 262 263 // Bitstream buffers ready to be used to return encoded output, as a LIFO 264 // since we don't care about ordering. 265 std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_; 266 267 // 268 // The device polling thread handles notifications of V4L2 device changes. 269 // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_. 270 // 271 272 // The thread. 273 base::Thread device_poll_thread_; 274 275 // Image processor, if one is in use. 276 scoped_ptr<V4L2ImageProcessor> image_processor_; 277 278 DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator); 279 }; 280 281 } // namespace content 282 283 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_ 284