Home | History | Annotate | Download | only in media
      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