1 // Copyright (c) 2012 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 // This file contains an implementation of a class that provides H264 decode 6 // support for use with VAAPI hardware video decode acceleration on Intel 7 // systems. 8 9 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 10 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 11 12 #include <vector> 13 14 #include "base/callback_forward.h" 15 #include "base/memory/linked_ptr.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "content/common/gpu/media/h264_dpb.h" 19 #include "content/common/gpu/media/vaapi_wrapper.h" 20 #include "media/base/limits.h" 21 #include "media/filters/h264_parser.h" 22 23 namespace content { 24 25 // An H264 decoder that utilizes VA-API. Provides features not supported by 26 // the VA-API userspace library (libva), including stream parsing, reference 27 // picture management and other operations not supported by the HW codec. 28 // 29 // Provides functionality to allow plugging VAAPI HW acceleration into the 30 // VDA framework. 31 // 32 // Clients of this class are expected to pass H264 Annex-B byte stream and 33 // will receive decoded surfaces via client-provided |OutputPicCB|. 34 // 35 // This class must be created, called and destroyed on a single thread, and 36 // does nothing internally on any other thread. 37 class CONTENT_EXPORT VaapiH264Decoder { 38 public: 39 // Callback invoked on the client when a surface is to be displayed. 40 // Arguments: input buffer id provided at the time of Decode() 41 // and VASurface to output. 42 typedef base::Callback< 43 void(int32, const scoped_refptr<VASurface>&)> OutputPicCB; 44 45 enum VAVDAH264DecoderFailure { 46 FRAME_MBS_ONLY_FLAG_NOT_ONE = 0, 47 GAPS_IN_FRAME_NUM = 1, 48 MID_STREAM_RESOLUTION_CHANGE = 2, 49 INTERLACED_STREAM = 3, 50 VAAPI_ERROR = 4, 51 VAVDA_H264_DECODER_FAILURES_MAX, 52 }; 53 54 // Callback to report errors for UMA purposes, not used to return errors 55 // to clients. 56 typedef base::Callback<void(VAVDAH264DecoderFailure error)> 57 ReportErrorToUmaCB; 58 59 // Decode result codes. 60 enum DecResult { 61 kDecodeError, // Error while decoding. 62 // TODO posciak: unsupported streams are currently treated as error 63 // in decoding; in future it could perhaps be possible to fall back 64 // to software decoding instead. 65 // kStreamError, // Error in stream. 66 kAllocateNewSurfaces, // Need a new set of surfaces to be allocated. 67 kRanOutOfStreamData, // Need more stream data to proceed. 68 kRanOutOfSurfaces, // Waiting for the client to free up output surfaces. 69 }; 70 71 // |vaapi_wrapper| should be initialized. 72 // |output_pic_cb| notifies the client a surface is to be displayed. 73 // |report_error_to_uma_cb| called on errors for UMA purposes, not used 74 // to report errors to clients. 75 VaapiH264Decoder(VaapiWrapper* vaapi_wrapper, 76 const OutputPicCB& output_pic_cb, 77 const ReportErrorToUmaCB& report_error_to_uma_cb); 78 79 ~VaapiH264Decoder(); 80 81 // Have the decoder flush its state and trigger output of all previously 82 // decoded surfaces via OutputPicCB. Return false on failure. 83 bool Flush() WARN_UNUSED_RESULT; 84 85 // To be called during decoding. 86 // Stop (pause) decoding, discarding all remaining inputs and outputs, 87 // but do not flush decoder state, so that the playback can be resumed later, 88 // possibly from a different location. 89 void Reset(); 90 91 // Set current stream data pointer to |ptr| and |size|. Output surfaces 92 // that are decoded from data in this stream chunk are to be returned along 93 // with the given |input_id|. 94 void SetStream(const uint8* ptr, size_t size, int32 input_id); 95 96 // Try to decode more of the stream, returning decoded frames asynchronously 97 // via output_pic_cb_. Return when more stream is needed, when we run out 98 // of free surfaces, when we need a new set of them, or when an error occurs. 99 DecResult Decode() WARN_UNUSED_RESULT; 100 101 // Return dimensions/required number of output surfaces that client should 102 // be ready to provide for the decoder to function properly. 103 // To be used after Decode() returns kNeedNewSurfaces. 104 gfx::Size GetPicSize() { return pic_size_; } 105 size_t GetRequiredNumOfPictures(); 106 107 // To be used by the client to feed decoder with output surfaces. 108 void ReuseSurface(const scoped_refptr<VASurface>& va_surface); 109 110 private: 111 // We need to keep at most kDPBMaxSize pictures in DPB for 112 // reference/to display later and an additional one for the one currently 113 // being decoded. We also ask for some additional ones since VDA needs 114 // to accumulate a few ready-to-output pictures before it actually starts 115 // displaying and giving them back. +2 instead of +1 because of subjective 116 // smoothness improvement during testing. 117 enum { 118 kPicsInPipeline = media::limits::kMaxVideoFrames + 2, 119 kMaxNumReqPictures = H264DPB::kDPBMaxSize + kPicsInPipeline, 120 }; 121 122 // Internal state of the decoder. 123 enum State { 124 kNeedStreamMetadata, // After initialization, need an SPS. 125 kDecoding, // Ready to decode from any point. 126 kAfterReset, // After Reset(), need a resume point. 127 kError, // Error in decode, can't continue. 128 }; 129 130 // Process H264 stream structures. 131 bool ProcessSPS(int sps_id, bool* need_new_buffers); 132 bool ProcessPPS(int pps_id); 133 bool ProcessSlice(media::H264SliceHeader* slice_hdr); 134 135 // Initialize the current picture according to data in |slice_hdr|. 136 bool InitCurrPicture(media::H264SliceHeader* slice_hdr); 137 138 // Calculate picture order counts for the new picture 139 // on initialization of a new frame (see spec). 140 bool CalculatePicOrderCounts(media::H264SliceHeader* slice_hdr); 141 142 // Update PicNum values in pictures stored in DPB on creation of new 143 // frame (see spec). 144 void UpdatePicNums(); 145 146 bool UpdateMaxNumReorderFrames(const media::H264SPS* sps); 147 148 // Prepare reference picture lists (ref_pic_list[01]_). 149 bool PrepareRefPicLists(media::H264SliceHeader* slice_hdr); 150 151 // Construct initial reference picture lists for use in decoding of 152 // P and B pictures (see 8.2.4 in spec). 153 void ConstructReferencePicListsP(media::H264SliceHeader* slice_hdr); 154 void ConstructReferencePicListsB(media::H264SliceHeader* slice_hdr); 155 156 // Helper functions for reference list construction, per spec. 157 int PicNumF(H264Picture *pic); 158 int LongTermPicNumF(H264Picture *pic); 159 160 // Perform the reference picture lists' modification (reordering), as 161 // specified in spec (8.2.4). 162 // 163 // |list| indicates list number and should be either 0 or 1. 164 bool ModifyReferencePicList(media::H264SliceHeader* slice_hdr, int list); 165 166 // Perform reference picture memory management operations (marking/unmarking 167 // of reference pictures, long term picture management, discarding, etc.). 168 // See 8.2.5 in spec. 169 bool HandleMemoryManagementOps(); 170 void ReferencePictureMarking(); 171 172 // Start processing a new frame. 173 bool StartNewFrame(media::H264SliceHeader* slice_hdr); 174 175 // All data for a frame received, process it and decode. 176 bool FinishPrevFrameIfPresent(); 177 178 // Called after decoding, performs all operations to be done after decoding, 179 // including DPB management, reference picture marking and memory management 180 // operations. 181 // This will also output a picture if one is ready for output. 182 bool FinishPicture(); 183 184 // Clear DPB contents and remove all surfaces in DPB from *in_use_ list. 185 // Cleared pictures will be made available for decode, unless they are 186 // at client waiting to be displayed. 187 void ClearDPB(); 188 189 // These queue up data for HW decoder to be committed on running HW decode. 190 bool SendPPS(); 191 bool SendIQMatrix(); 192 bool SendVASliceParam(media::H264SliceHeader* slice_hdr); 193 bool SendSliceData(const uint8* ptr, size_t size); 194 bool QueueSlice(media::H264SliceHeader* slice_hdr); 195 196 // Helper methods for filling HW structures. 197 void FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic); 198 int FillVARefFramesFromDPB(VAPictureH264 *va_pics, int num_pics); 199 200 // Commits all pending data for HW decoder and starts HW decoder. 201 bool DecodePicture(); 202 203 // Notifies client that a picture is ready for output. 204 bool OutputPic(H264Picture* pic); 205 206 // Output all pictures in DPB that have not been outputted yet. 207 bool OutputAllRemainingPics(); 208 209 // Represents a frame being decoded. Will always have a VASurface 210 // assigned to it, which will eventually contain decoded picture data. 211 class DecodeSurface; 212 213 // Assign an available surface to the given PicOrderCnt |poc|, 214 // removing it from the available surfaces pool. Return true if a surface 215 // has been found, false otherwise. 216 bool AssignSurfaceToPoC(int32 input_id, int poc); 217 218 // Indicate that a surface is no longer needed by decoder. 219 void UnassignSurfaceFromPoC(int poc); 220 221 // Return DecodeSurface assigned to |poc|. 222 DecodeSurface* DecodeSurfaceByPoC(int poc); 223 224 // Decoder state. 225 State state_; 226 227 // Parser in use. 228 media::H264Parser parser_; 229 230 // DPB in use. 231 H264DPB dpb_; 232 233 // Picture currently being processed/decoded. 234 scoped_ptr<H264Picture> curr_pic_; 235 236 // Reference picture lists, constructed for each picture before decoding. 237 // Those lists are not owners of the pointers (DPB is). 238 H264Picture::PtrVector ref_pic_list0_; 239 H264Picture::PtrVector ref_pic_list1_; 240 241 // Global state values, needed in decoding. See spec. 242 int max_pic_order_cnt_lsb_; 243 int max_frame_num_; 244 int max_pic_num_; 245 int max_long_term_frame_idx_; 246 size_t max_num_reorder_frames_; 247 248 int frame_num_; 249 int prev_frame_num_; 250 int prev_frame_num_offset_; 251 bool prev_has_memmgmnt5_; 252 253 // Values related to previously decoded reference picture. 254 bool prev_ref_has_memmgmnt5_; 255 int prev_ref_top_field_order_cnt_; 256 int prev_ref_pic_order_cnt_msb_; 257 int prev_ref_pic_order_cnt_lsb_; 258 H264Picture::Field prev_ref_field_; 259 260 // Currently active SPS and PPS. 261 int curr_sps_id_; 262 int curr_pps_id_; 263 264 // Output picture size. 265 gfx::Size pic_size_; 266 267 // Maps H.264 PicOrderCount to currently used DecodeSurfaces; 268 typedef std::map<int, linked_ptr<DecodeSurface> > DecSurfacesInUse; 269 DecSurfacesInUse decode_surfaces_in_use_; 270 271 // Unused VA surfaces returned by client, ready to be reused. 272 std::vector<scoped_refptr<VASurface> > available_va_surfaces_; 273 274 // The id of current input buffer, which will be associated with an 275 // output surface when a frame is successfully decoded. 276 int32 curr_input_id_; 277 278 VaapiWrapper* vaapi_wrapper_; 279 280 // Called by decoder when a surface should be outputted. 281 OutputPicCB output_pic_cb_; 282 283 // Called to report decoding error to UMA, not used to indicate errors 284 // to clients. 285 ReportErrorToUmaCB report_error_to_uma_cb_; 286 287 // PicOrderCount of the previously outputted frame. 288 int last_output_poc_; 289 290 DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder); 291 }; 292 293 } // namespace content 294 295 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 296