- add sources.
[platform/framework/web/crosswalk.git] / src / content / common / gpu / media / vaapi_h264_decoder.h
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/h264_parser.h"
20 #include "content/common/gpu/media/vaapi_wrapper.h"
21 #include "media/base/limits.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 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(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(H264SliceHeader* slice_hdr);
134
135   // Initialize the current picture according to data in |slice_hdr|.
136   bool InitCurrPicture(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(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   // Construct initial reference picture lists for use in decoding of
147   // P and B pictures (see 8.2.4 in spec).
148   void ConstructReferencePicListsP(H264SliceHeader* slice_hdr);
149   void ConstructReferencePicListsB(H264SliceHeader* slice_hdr);
150
151   // Helper functions for reference list construction, per spec.
152   int PicNumF(H264Picture *pic);
153   int LongTermPicNumF(H264Picture *pic);
154
155   // Perform the reference picture lists' modification (reordering), as
156   // specified in spec (8.2.4).
157   //
158   // |list| indicates list number and should be either 0 or 1.
159   bool ModifyReferencePicList(H264SliceHeader *slice_hdr, int list);
160
161   // Perform reference picture memory management operations (marking/unmarking
162   // of reference pictures, long term picture management, discarding, etc.).
163   // See 8.2.5 in spec.
164   bool HandleMemoryManagementOps();
165   void ReferencePictureMarking();
166
167   // Start processing a new frame.
168   bool StartNewFrame(H264SliceHeader* slice_hdr);
169
170   // All data for a frame received, process it and decode.
171   bool FinishPrevFrameIfPresent();
172
173   // Called after decoding, performs all operations to be done after decoding,
174   // including DPB management, reference picture marking and memory management
175   // operations.
176   // This will also output a picture if one is ready for output.
177   bool FinishPicture();
178
179   // Clear DPB contents and remove all surfaces in DPB from *in_use_ list.
180   // Cleared pictures will be made available for decode, unless they are
181   // at client waiting to be displayed.
182   void ClearDPB();
183
184   // These queue up data for HW decoder to be committed on running HW decode.
185   bool SendPPS();
186   bool SendIQMatrix();
187   bool SendVASliceParam(H264SliceHeader* slice_hdr);
188   bool SendSliceData(const uint8* ptr, size_t size);
189   bool QueueSlice(H264SliceHeader* slice_hdr);
190
191   // Helper methods for filling HW structures.
192   void FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic);
193   int FillVARefFramesFromDPB(VAPictureH264 *va_pics, int num_pics);
194
195   // Commits all pending data for HW decoder and starts HW decoder.
196   bool DecodePicture();
197
198   // Notifies client that a picture is ready for output.
199   bool OutputPic(H264Picture* pic);
200
201   // Output all pictures in DPB that have not been outputted yet.
202   bool OutputAllRemainingPics();
203
204   // Represents a frame being decoded. Will always have a VASurface
205   // assigned to it, which will eventually contain decoded picture data.
206   class DecodeSurface;
207
208   // Assign an available surface to the given PicOrderCnt |poc|,
209   // removing it from the available surfaces pool. Return true if a surface
210   // has been found, false otherwise.
211   bool AssignSurfaceToPoC(int32 input_id, int poc);
212
213   // Indicate that a surface is no longer needed by decoder.
214   void UnassignSurfaceFromPoC(int poc);
215
216   // Return DecodeSurface assigned to |poc|.
217   DecodeSurface* DecodeSurfaceByPoC(int poc);
218
219   // Decoder state.
220   State state_;
221
222   // Parser in use.
223   H264Parser parser_;
224
225   // DPB in use.
226   H264DPB dpb_;
227
228   // Picture currently being processed/decoded.
229   scoped_ptr<H264Picture> curr_pic_;
230
231   // Reference picture lists, constructed for each picture before decoding.
232   // Those lists are not owners of the pointers (DPB is).
233   H264Picture::PtrVector ref_pic_list0_;
234   H264Picture::PtrVector ref_pic_list1_;
235
236   // Global state values, needed in decoding. See spec.
237   int max_pic_order_cnt_lsb_;
238   int max_frame_num_;
239   int max_pic_num_;
240   int max_long_term_frame_idx_;
241
242   int frame_num_;
243   int prev_frame_num_;
244   int prev_frame_num_offset_;
245   bool prev_has_memmgmnt5_;
246
247   // Values related to previously decoded reference picture.
248   bool prev_ref_has_memmgmnt5_;
249   int prev_ref_top_field_order_cnt_;
250   int prev_ref_pic_order_cnt_msb_;
251   int prev_ref_pic_order_cnt_lsb_;
252   H264Picture::Field prev_ref_field_;
253
254   // Currently active SPS and PPS.
255   int curr_sps_id_;
256   int curr_pps_id_;
257
258   // Output picture size.
259   gfx::Size pic_size_;
260
261   // Maps H.264 PicOrderCount to currently used DecodeSurfaces;
262   typedef std::map<int, linked_ptr<DecodeSurface> > DecSurfacesInUse;
263   DecSurfacesInUse decode_surfaces_in_use_;
264
265   // Unused VA surfaces returned by client, ready to be reused.
266   std::vector<scoped_refptr<VASurface> > available_va_surfaces_;
267
268   // The id of current input buffer, which will be associated with an
269   // output surface when a frame is successfully decoded.
270   int32 curr_input_id_;
271
272   VaapiWrapper* vaapi_wrapper_;
273
274   // Called by decoder when a surface should be outputted.
275   OutputPicCB output_pic_cb_;
276
277   // Called to report decoding error to UMA, not used to indicate errors
278   // to clients.
279   ReportErrorToUmaCB report_error_to_uma_cb_;
280
281   // PicOrderCount of the previously outputted frame.
282   int last_output_poc_;
283
284   // Maximum size of DPB required by codec level.
285   int max_dpb_size_;
286
287   DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder);
288 };
289
290 }  // namespace content
291
292 #endif  // CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_