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