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_VAAPI_VIDEO_ENCODE_ACCELERATOR_H_
      6 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_ENCODE_ACCELERATOR_H_
      7 
      8 #include <list>
      9 #include <queue>
     10 
     11 #include "base/memory/linked_ptr.h"
     12 #include "base/threading/thread.h"
     13 #include "content/common/content_export.h"
     14 #include "content/common/gpu/media/h264_dpb.h"
     15 #include "content/common/gpu/media/va_surface.h"
     16 #include "content/common/gpu/media/vaapi_wrapper.h"
     17 #include "media/filters/h264_bitstream_buffer.h"
     18 #include "media/video/video_encode_accelerator.h"
     19 
     20 namespace content {
     21 
     22 // A VideoEncodeAccelerator implementation that uses VA-API
     23 // (http://www.freedesktop.org/wiki/Software/vaapi) for HW-accelerated
     24 // video encode.
     25 class CONTENT_EXPORT VaapiVideoEncodeAccelerator
     26     : public media::VideoEncodeAccelerator {
     27  public:
     28   explicit VaapiVideoEncodeAccelerator(Display* x_display);
     29   virtual ~VaapiVideoEncodeAccelerator();
     30 
     31   // media::VideoEncodeAccelerator implementation.
     32   virtual std::vector<media::VideoEncodeAccelerator::SupportedProfile>
     33       GetSupportedProfiles() OVERRIDE;
     34   virtual bool Initialize(media::VideoFrame::Format format,
     35                           const gfx::Size& input_visible_size,
     36                           media::VideoCodecProfile output_profile,
     37                           uint32 initial_bitrate,
     38                           Client* client) OVERRIDE;
     39   virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
     40                       bool force_keyframe) OVERRIDE;
     41   virtual void UseOutputBitstreamBuffer(
     42       const media::BitstreamBuffer& buffer) OVERRIDE;
     43   virtual void RequestEncodingParametersChange(uint32 bitrate,
     44                                                uint32 framerate) OVERRIDE;
     45   virtual void Destroy() OVERRIDE;
     46 
     47  private:
     48   // Reference picture list.
     49   typedef std::list<scoped_refptr<VASurface> > RefPicList;
     50 
     51   // Encode job for one frame. Created when an input frame is awaiting and
     52   // enough resources are available to proceed. Once the job is prepared and
     53   // submitted to the hardware, it awaits on the submitted_encode_jobs_ queue
     54   // for an output bitstream buffer to become available. Once one is ready,
     55   // the encoded bytes are downloaded to it and job resources are released
     56   // and become available for reuse.
     57   struct EncodeJob {
     58     // Input surface for video frame data.
     59     scoped_refptr<VASurface> input_surface;
     60     // Surface for a reconstructed picture, which is used for reference
     61     // for subsequent frames.
     62     scoped_refptr<VASurface> recon_surface;
     63     // Buffer that will contain output bitstream for this frame.
     64     VABufferID coded_buffer;
     65     // Reference surfaces required to encode this picture. We keep references
     66     // to them here, because we may discard some of them from ref_pic_list*
     67     // before the HW job is done.
     68     RefPicList reference_surfaces;
     69     // True if this job will produce a keyframe. Used to report
     70     // to BitstreamBufferReady().
     71     bool keyframe;
     72 
     73     EncodeJob();
     74     ~EncodeJob();
     75   };
     76 
     77   // Encoder state.
     78   enum State {
     79     kUninitialized,
     80     kEncoding,
     81     kError,
     82   };
     83 
     84   // Holds input frames coming from the client ready to be encoded.
     85   struct InputFrameRef;
     86   // Holds output buffers coming from the client ready to be filled.
     87   struct BitstreamBufferRef;
     88 
     89   // Tasks for each of the VEA interface calls to be executed on the
     90   // encoder thread.
     91   void InitializeTask();
     92   void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
     93                   bool force_keyframe);
     94   void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
     95   void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
     96   void DestroyTask();
     97 
     98   // Prepare and schedule an encode job if we have an input to encode
     99   // and enough resources to proceed.
    100   void EncodeFrameTask();
    101 
    102   // Fill current_sps_/current_pps_ with current values.
    103   void UpdateSPS();
    104   void UpdatePPS();
    105   void UpdateRates(uint32 bitrate, uint32 framerate);
    106 
    107   // Generate packed SPS and PPS in packed_sps_/packed_pps_, using
    108   // values in current_sps_/current_pps_.
    109   void GeneratePackedSPS();
    110   void GeneratePackedPPS();
    111 
    112   // Check if we have sufficient resources for a new encode job, claim them and
    113   // fill current_encode_job_ with them.
    114   // Return false if we cannot start a new job yet, true otherwise.
    115   bool PrepareNextJob();
    116 
    117   // Begin a new frame, making it a keyframe if |force_keyframe| is true,
    118   // updating current_pic_.
    119   void BeginFrame(bool force_keyframe);
    120 
    121   // End current frame, updating reference picture lists and storing current
    122   // job in the jobs awaiting completion on submitted_encode_jobs_.
    123   void EndFrame();
    124 
    125   // Submit parameters for the current frame to the hardware.
    126   bool SubmitFrameParameters();
    127   // Submit keyframe headers to the hardware if the current frame is a keyframe.
    128   bool SubmitHeadersIfNeeded();
    129 
    130   // Upload image data from |frame| to the input surface for current job.
    131   bool UploadFrame(const scoped_refptr<media::VideoFrame>& frame);
    132 
    133   // Execute encode in hardware. This does not block and will return before
    134   // the job is finished.
    135   bool ExecuteEncode();
    136 
    137   // Callback that returns a no longer used VASurfaceID to
    138   // available_va_surface_ids_ for reuse.
    139   void RecycleVASurfaceID(VASurfaceID va_surface_id);
    140 
    141   // Tries to return a bitstream buffer if both a submitted job awaits to
    142   // be completed and we have bitstream buffers from the client available
    143   // to download the encoded data to.
    144   void TryToReturnBitstreamBuffer();
    145 
    146   // Puts the encoder into en error state and notifies client about the error.
    147   void NotifyError(Error error);
    148 
    149   // Sets the encoder state on the correct thread.
    150   void SetState(State state);
    151 
    152   // VaapiWrapper is the owner of all HW resources (surfaces and buffers)
    153   // and will free them on destruction.
    154   scoped_ptr<VaapiWrapper> vaapi_wrapper_;
    155 
    156   // Input profile and sizes.
    157   media::VideoCodecProfile profile_;
    158   gfx::Size visible_size_;
    159   gfx::Size coded_size_;  // Macroblock-aligned.
    160   // Width/height in macroblocks.
    161   unsigned int mb_width_;
    162   unsigned int mb_height_;
    163 
    164   // Maximum size of the reference list 0.
    165   unsigned int max_ref_idx_l0_size_;
    166 
    167   // Initial QP.
    168   unsigned int qp_;
    169 
    170   // IDR frame period.
    171   unsigned int idr_period_;
    172   // I frame period.
    173   unsigned int i_period_;
    174   // IP period, i.e. how often do we need to have either an I or a P frame in
    175   // the stream. Period of 1 means we can have no B frames.
    176   unsigned int ip_period_;
    177 
    178   // Size in bytes required for input bitstream buffers.
    179   size_t output_buffer_byte_size_;
    180 
    181   Display* x_display_;
    182 
    183   // All of the members below must be accessed on the encoder_thread_,
    184   // while it is running.
    185 
    186   // Encoder state. Encode tasks will only run in kEncoding state.
    187   State state_;
    188 
    189   // frame_num to be used for the next frame.
    190   unsigned int frame_num_;
    191   // frame_num of the previous IDR.
    192   unsigned int last_idr_frame_num_;
    193 
    194   // Current bitrate in bps.
    195   unsigned int bitrate_;
    196   // Current fps.
    197   unsigned int framerate_;
    198   // CPB size in bits, i.e. bitrate in kbps * window size in ms/1000.
    199   unsigned int cpb_size_;
    200   // True if the parameters have changed and we need to submit a keyframe
    201   // with updated parameters.
    202   bool encoding_parameters_changed_;
    203 
    204   // Job currently being prepared for encode.
    205   scoped_ptr<EncodeJob> current_encode_job_;
    206 
    207   // Current SPS, PPS and their packed versions. Packed versions are their NALUs
    208   // in AnnexB format *without* emulation prevention three-byte sequences
    209   // (those will be added by the driver).
    210   media::H264SPS current_sps_;
    211   media::H264BitstreamBuffer packed_sps_;
    212   media::H264PPS current_pps_;
    213   media::H264BitstreamBuffer packed_pps_;
    214 
    215   // Picture currently being prepared for encode.
    216   H264Picture current_pic_;
    217 
    218   // VA surfaces available for reuse.
    219   std::vector<VASurfaceID> available_va_surface_ids_;
    220 
    221   // VA buffers for coded frames.
    222   std::vector<VABufferID> available_va_buffer_ids_;
    223 
    224   // Currently active reference surfaces.
    225   RefPicList ref_pic_list0_;
    226 
    227   // Callback via which finished VA surfaces are returned to us.
    228   VASurface::ReleaseCB va_surface_release_cb_;
    229 
    230   // VideoFrames passed from the client, waiting to be encoded.
    231   std::queue<linked_ptr<InputFrameRef> > encoder_input_queue_;
    232 
    233   // BitstreamBuffers mapped, ready to be filled.
    234   std::queue<linked_ptr<BitstreamBufferRef> > available_bitstream_buffers_;
    235 
    236   // Jobs submitted for encode, awaiting bitstream buffers to become available.
    237   std::queue<linked_ptr<EncodeJob> > submitted_encode_jobs_;
    238 
    239   // Encoder thread. All tasks are executed on it.
    240   base::Thread encoder_thread_;
    241   scoped_refptr<base::MessageLoopProxy> encoder_thread_proxy_;
    242 
    243   const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
    244 
    245   // To expose client callbacks from VideoEncodeAccelerator.
    246   // NOTE: all calls to these objects *MUST* be executed on
    247   // child_message_loop_proxy_.
    248   scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
    249   base::WeakPtr<Client> client_;
    250 
    251   // WeakPtr to post from the encoder thread back to the ChildThread, as it may
    252   // outlive this. Posting from the ChildThread using base::Unretained(this)
    253   // to the encoder thread is safe, because |this| always outlives the encoder
    254   // thread (it's a member of this class).
    255   base::WeakPtr<VaapiVideoEncodeAccelerator> weak_this_;
    256   base::WeakPtrFactory<VaapiVideoEncodeAccelerator> weak_this_ptr_factory_;
    257 
    258   DISALLOW_COPY_AND_ASSIGN(VaapiVideoEncodeAccelerator);
    259 };
    260 
    261 }  // namespace content
    262 
    263 #endif  // CONTENT_COMMON_GPU_MEDIA_VAAPI_VIDEO_ENCODE_ACCELERATOR_H_
    264