Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: content/common/gpu/media/vaapi_h264_decoder.h

Issue 14914009: VAVDA: Redesign stage 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added DCHECKs for ChildThread in TFPPicture Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file contains an implementation of a class that provides H264 decode 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 6 // support for use with VAAPI hardware video decode acceleration on Intel
7 // systems. 7 // systems.
8 8
9 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 9 #ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_
10 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 10 #define CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_
11 11
12 #include <GL/glx.h> 12 #include <vector>
13
14 #include <queue>
15 13
16 #include "base/callback_forward.h" 14 #include "base/callback_forward.h"
17 #include "base/lazy_instance.h"
18 #include "base/memory/linked_ptr.h" 15 #include "base/memory/linked_ptr.h"
16 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
20 #include "content/common/gpu/media/h264_dpb.h" 18 #include "content/common/gpu/media/h264_dpb.h"
21 #include "content/common/gpu/media/h264_parser.h" 19 #include "content/common/gpu/media/h264_parser.h"
22 #include "media/base/video_decoder_config.h" 20 #include "content/common/gpu/media/vaapi_wrapper.h"
23 #include "media/base/limits.h" 21 #include "media/base/limits.h"
24 #include "third_party/libva/va/va.h"
25 22
26 namespace content { 23 namespace content {
27 24
28 // An H264 decoder for use for VA-API-specific decoding. Provides features not 25 // An H264 decoder that utilizes VA-API. Provides features not supported by
29 // supported by libva, including stream parsing, reference picture management 26 // the VA-API userspace library (libva), including stream parsing, reference
30 // and other operations not supported by the HW codec. 27 // picture management and other operations not supported by the HW codec.
31 // 28 //
32 // Provides functionality to allow plugging VAAPI HW acceleration into the 29 // Provides functionality to allow plugging VAAPI HW acceleration into the
33 // VDA framework. 30 // VDA framework.
34 // 31 //
35 // Clients of this class are expected to pass H264 Annex-B byte stream and 32 // Clients of this class are expected to pass H264 Annex-B byte stream and
36 // will receive decoded pictures via client-provided |OutputPicCB|. 33 // will receive decoded surfaces via client-provided |OutputPicCB|.
37 // 34 //
38 // If used in multi-threaded environment, some of the functions have to be 35 // This class must be created, called and destroyed on a single thread, and
39 // called on the child thread, i.e. the main thread of the GPU process 36 // does nothing internally on any other thread.
40 // (the one that has the GLX context passed to Initialize() set as current).
41 // This is essential so that the GLX calls can work properly.
42 // Decoder thread, on the other hand, does not require a GLX context and should
43 // be the same as the one on which Decode*() functions are called.
44 class VaapiH264Decoder { 37 class VaapiH264Decoder {
45 public: 38 public:
46 // Callback invoked on the client when a picture is to be displayed. 39 // Callback invoked on the client when a surface is to be displayed.
47 // Arguments: input buffer id, output buffer id (both provided by the client 40 // Arguments: input buffer id provided at the time of Decode()
48 // at the time of Decode() and AssignPictureBuffer() calls). 41 // and VASurface to output.
49 typedef base::Callback<void(int32, int32)> OutputPicCB; 42 typedef base::Callback<
43 void(int32, const scoped_refptr<VASurface>&)> OutputPicCB;
50 44
51 // Callback invoked on the client to start a GPU job to decode and render 45 enum VAVDAH264DecoderFailure {
52 // a video frame into a pixmap/texture. Callee has to call SubmitDecode() 46 FRAME_MBS_ONLY_FLAG_NOT_ONE = 0,
53 // for the given picture. 47 GAPS_IN_FRAME_NUM = 1,
54 // Arguments: output buffer id (provided by the client at the time of 48 MID_STREAM_RESOLUTION_CHANGE = 2,
55 // AssignPictureBuffer() call), va buffer and slice buffer queues to be 49 INTERLACED_STREAM = 3,
56 // passed to SubmitDecode(). 50 VAAPI_ERROR = 4,
57 typedef base::Callback< 51 VAVDA_H264_DECODER_FAILURES_MAX,
58 void(int32, 52 };
59 scoped_ptr<std::queue<VABufferID> >, 53
60 scoped_ptr<std::queue<VABufferID> >)> SubmitDecodeCB; 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;
61 58
62 // Decode result codes. 59 // Decode result codes.
63 enum DecResult { 60 enum DecResult {
64 kDecodeError, // Error while decoding. 61 kDecodeError, // Error while decoding.
65 // TODO posciak: unsupported streams are currently treated as error 62 // TODO posciak: unsupported streams are currently treated as error
66 // in decoding; in future it could perhaps be possible to fall back 63 // in decoding; in future it could perhaps be possible to fall back
67 // to software decoding instead. 64 // to software decoding instead.
68 // kStreamError, // Error in stream. 65 // kStreamError, // Error in stream.
69 kReadyToDecode, // Successfully initialized. 66 kReadyToDecode, // Successfully initialized.
70 kDecodedFrame, // Successfully decoded a frame.
71 kNeedMoreStreamData, // Need more stream data to decode the next frame. 67 kNeedMoreStreamData, // Need more stream data to decode the next frame.
72 kNoOutputAvailable, // Waiting for the client to free up output surfaces. 68 kNoOutputAvailable, // Waiting for the client to free up output surfaces.
73 }; 69 };
74 70
75 VaapiH264Decoder(); 71 // |vaapi_wrapper| should be initialized.
76 // Should be called on the GLX thread, for the surface cleanup to work 72 // |output_pic_cb| notifies the client a surface is to be displayed.
77 // properly. 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
78 ~VaapiH264Decoder(); 79 ~VaapiH264Decoder();
79 80
80 // Initializes and sets up libva connection and GL/X11 resources.
81 // Must be called on the GLX thread with |glx_context| being current and
82 // with decoder thread not yet running.
83 // |output_pic_cb| will be called to notify when a picture can be displayed.
84 bool Initialize(media::VideoCodecProfile profile,
85 Display* x_display,
86 GLXContext glx_context,
87 const base::Callback<bool(void)>& make_context_current,
88 const OutputPicCB& output_pic_cb,
89 const SubmitDecodeCB& submit_decode_cb) WARN_UNUSED_RESULT;
90 void Destroy();
91
92 // Notify the decoder that this output buffer has been consumed and
93 // can be reused (overwritten).
94 // Must be run on the decoder thread.
95 void ReusePictureBuffer(int32 picture_buffer_id);
96
97 // Give a new picture buffer (texture) to decoder for use.
98 // Must be run on the GLX thread with decoder thread not yet running.
99 bool AssignPictureBuffer(int32 picture_buffer_id, uint32 texture_id)
100 WARN_UNUSED_RESULT;
101
102 // Decode and put results into texture associated with given
103 // |picture_buffer_id|, using the buffers provided as arguments. Takes
104 // ownership of queues' memory and frees it once done.
105 // Must be run on the GLX thread.
106 bool SubmitDecode(
107 int32 picture_buffer_id,
108 scoped_ptr<std::queue<VABufferID> > va_bufs,
109 scoped_ptr<std::queue<VABufferID> > slice_bufs) WARN_UNUSED_RESULT;
110
111 // Have the decoder flush its state and trigger output of all previously 81 // Have the decoder flush its state and trigger output of all previously
112 // decoded pictures via OutputPicCB. 82 // decoded surfaces via OutputPicCB. Return false on failure.
113 // Returns false if any of the resulting invocations of the callback fail.
114 bool Flush() WARN_UNUSED_RESULT; 83 bool Flush() WARN_UNUSED_RESULT;
115 84
116 // Called while decoding. 85 // To be called during decoding.
117 // Stop decoding, discarding all remaining input/output, but do not flush 86 // Stop (pause) decoding, discarding all remaining inputs and outputs,
118 // state, so the playback of the same stream can be resumed (possibly from 87 // but do not flush decoder state, so that the playback can be resumed later,
119 // another location). 88 // possibly from a different location.
120 void Reset(); 89 void Reset();
121 90
122 // Set current stream data pointer to |ptr| and |size|. 91 // Set current stream data pointer to |ptr| and |size|.
123 // Must be run on decoder thread.
124 void SetStream(uint8* ptr, size_t size); 92 void SetStream(uint8* ptr, size_t size);
125 93
126 // Start parsing stream to detect picture sizes. Does not produce any 94 // To be called at the start of decode or after reset.
127 // decoded pictures and can be called without providing output textures. 95 // When this call returns kReadyToDecode, the decoder is in a suitable
128 // Also to be used after Reset() to find a suitable location in the 96 // location in the stream to begin/resume decoding from and subsequent
129 // stream to resume playback from. 97 // decode requests should go via DecodeOneFrame.
130 DecResult DecodeInitial(int32 input_id) WARN_UNUSED_RESULT; 98 DecResult DecodeInitial(int32 input_id) WARN_UNUSED_RESULT;
131 99
132 // Runs until a frame is decoded or end of provided stream data buffer 100 // Runs until a frame is decoded or end of provided stream data buffer
133 // is reached. Decoded pictures will be returned asynchronously via 101 // is reached. Decoded surfaces will be returned asynchronously via
134 // OutputPicCB. 102 // OutputPicCB. Should be called after DecodeInitial returns kReadyToDecode.
135 DecResult DecodeOneFrame(int32 input_id) WARN_UNUSED_RESULT; 103 DecResult DecodeOneFrame(int32 input_id) WARN_UNUSED_RESULT;
Ami GONE FROM CHROMIUM 2013/05/29 19:59:04 Yes.
136 104
137 // Return dimensions for output buffer (texture) allocation. 105 // Return dimensions/required number of output surfaces that client should
106 // be ready to provide for the decoder to function properly.
138 // Valid only after a successful DecodeInitial(). 107 // Valid only after a successful DecodeInitial().
139 int pic_height() { return pic_height_; } 108 gfx::Size GetPicSize() { return pic_size_; }
140 int pic_width() { return pic_width_; }
141
142 // Return the number of output pictures required for decoding.
143 // Valid after a successful DecodeInitial().
144 size_t GetRequiredNumOfPictures(); 109 size_t GetRequiredNumOfPictures();
145 110
146 // Do any necessary initialization before the sandbox is enabled. 111 // To be used by the client to feed decoder with output surfaces.
147 static void PreSandboxInitialization(); 112 void ReuseSurface(const scoped_refptr<VASurface>& va_surface);
148
149 // Lazily initialize static data after sandbox is enabled. Return false on
150 // init failure.
151 static bool PostSandboxInitialization();
152 113
153 private: 114 private:
154 // We need to keep at most kDPBMaxSize pictures in DPB for 115 // We need to keep at most kDPBMaxSize pictures in DPB for
155 // reference/to display later and an additional one for the one currently 116 // reference/to display later and an additional one for the one currently
156 // being decoded. We also ask for some additional ones since VDA needs 117 // being decoded. We also ask for some additional ones since VDA needs
157 // to accumulate a few ready-to-output pictures before it actually starts 118 // to accumulate a few ready-to-output pictures before it actually starts
158 // displaying and giving them back. +2 instead of +1 because of subjective 119 // displaying and giving them back. +2 instead of +1 because of subjective
159 // smoothness improvement during testing. 120 // smoothness improvement during testing.
160 enum { 121 enum {
161 kPicsInPipeline = media::limits::kMaxVideoFrames + 2, 122 kPicsInPipeline = media::limits::kMaxVideoFrames + 2,
162 kMaxNumReqPictures = H264DPB::kDPBMaxSize + kPicsInPipeline, 123 kMaxNumReqPictures = H264DPB::kDPBMaxSize + kPicsInPipeline,
163 }; 124 };
164 125
165 // Internal state of the decoder. 126 // Internal state of the decoder.
166 enum State { 127 enum State {
167 kUninitialized, // Initialize() not yet called. 128 kIdle, // After initialization or after Reset(), need a resume point.
168 kInitialized, // Initialize() called, pictures requested. 129 kDecoding, // DecodeInitial() successful, ready to decode.
169 kDecoding, // DecodeInitial() successful, output surfaces allocated. 130 kError, // Error in decode, can't continue.
170 kAfterReset, // After Reset() during decoding.
171 kError, // Error in kDecoding state.
172 }; 131 };
173 132
174 // Get usable framebuffer configuration for use in binding textures
175 // or return false on failure.
176 bool InitializeFBConfig();
177
178 // Process H264 stream structures. 133 // Process H264 stream structures.
179 bool ProcessSPS(int sps_id); 134 bool ProcessSPS(int sps_id);
180 bool ProcessPPS(int pps_id); 135 bool ProcessPPS(int pps_id);
181 bool ProcessSlice(H264SliceHeader* slice_hdr); 136 bool ProcessSlice(H264SliceHeader* slice_hdr);
182 137
183 // Initialize the current picture according to data in |slice_hdr|. 138 // Initialize the current picture according to data in |slice_hdr|.
184 bool InitCurrPicture(H264SliceHeader* slice_hdr); 139 bool InitCurrPicture(H264SliceHeader* slice_hdr);
185 140
186 // Calculate picture order counts for the new picture 141 // Calculate picture order counts for the new picture
187 // on initialization of a new frame (see spec). 142 // on initialization of a new frame (see spec).
(...skipping 29 matching lines...) Expand all
217 172
218 // All data for a frame received, process it and decode. 173 // All data for a frame received, process it and decode.
219 bool FinishPrevFrameIfPresent(); 174 bool FinishPrevFrameIfPresent();
220 175
221 // Called after decoding, performs all operations to be done after decoding, 176 // Called after decoding, performs all operations to be done after decoding,
222 // including DPB management, reference picture marking and memory management 177 // including DPB management, reference picture marking and memory management
223 // operations. 178 // operations.
224 // This will also output a picture if one is ready for output. 179 // This will also output a picture if one is ready for output.
225 bool FinishPicture(); 180 bool FinishPicture();
226 181
227 // Convert VideoCodecProfile to VAProfile and set it as active. 182 // Clear DPB contents and remove all surfaces in DPB from *in_use_ list.
228 bool SetProfile(media::VideoCodecProfile profile); 183 // Cleared pictures will be made available for decode, unless they are
229 184 // at client waiting to be displayed.
230 // Vaapi-related functions. 185 void ClearDPB();
231
232 // Allocates VASurfaces and creates a VAContext for them.
233 bool CreateVASurfaces();
234
235 // Destroys allocated VASurfaces and related VAContext.
236 void DestroyVASurfaces();
237 // Destroys all buffers in |pending_slice_bufs_| and |pending_va_bufs_|.
238 void DestroyPendingBuffers();
239 // Destroys a list of buffers.
240 void DestroyBuffers(size_t num_va_buffers, const VABufferID* va_buffers);
241 186
242 // These queue up data for HW decoder to be committed on running HW decode. 187 // These queue up data for HW decoder to be committed on running HW decode.
243 bool SendPPS(); 188 bool SendPPS();
244 bool SendIQMatrix(); 189 bool SendIQMatrix();
245 bool SendVASliceParam(H264SliceHeader* slice_hdr); 190 bool SendVASliceParam(H264SliceHeader* slice_hdr);
246 bool SendSliceData(const uint8* ptr, size_t size); 191 bool SendSliceData(const uint8* ptr, size_t size);
247 bool QueueSlice(H264SliceHeader* slice_hdr); 192 bool QueueSlice(H264SliceHeader* slice_hdr);
248 193
249 // Helper methods for filling HW structures. 194 // Helper methods for filling HW structures.
250 void FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic); 195 void FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic);
251 int FillVARefFramesFromDPB(VAPictureH264 *va_pics, int num_pics); 196 int FillVARefFramesFromDPB(VAPictureH264 *va_pics, int num_pics);
252 197
253 // Commits all pending data for HW decoder and starts HW decoder. 198 // Commits all pending data for HW decoder and starts HW decoder.
254 bool DecodePicture(); 199 bool DecodePicture();
255 200
256 // Notifies client that a picture is ready for output. 201 // Notifies client that a picture is ready for output.
257 bool OutputPic(H264Picture* pic); 202 bool OutputPic(H264Picture* pic);
258 203
204 // Output all pictures in DPB that have not been outputted yet.
205 bool OutputAllRemainingPics();
206
207 // Represents a frame being decoded. Will always have a VASurface
208 // assigned to it, which will eventually contain decoded picture data.
209 class DecodeSurface;
210
211 // Assign an available surface to the given PicOrderCnt |poc|,
212 // removing it from the available surfaces pool. Return true if a surface
213 // has been found, false otherwise.
214 bool AssignSurfaceToPoC(int32 input_id, int poc);
215
216 // Indicate that a surface is no longer needed by decoder.
217 void UnassignSurfaceFromPoC(int poc);
218
219 // Return DecodeSurface assigned to |poc|.
220 DecodeSurface* DecodeSurfaceByPoC(int poc);
221
222 // Decoder state.
259 State state_; 223 State state_;
260 224
261 // A frame has been sent to hardware as the result of the last
262 // DecodeOneFrame() call.
263 bool frame_ready_at_hw_;
264
265 // Parser in use. 225 // Parser in use.
266 H264Parser parser_; 226 H264Parser parser_;
267 227
268 // DPB in use. 228 // DPB in use.
269 H264DPB dpb_; 229 H264DPB dpb_;
270 230
271 // Picture currently being processed/decoded. 231 // Picture currently being processed/decoded.
272 scoped_ptr<H264Picture> curr_pic_; 232 scoped_ptr<H264Picture> curr_pic_;
273 233
274 // Reference picture lists, constructed for each picture before decoding. 234 // Reference picture lists, constructed for each picture before decoding.
(...skipping 17 matching lines...) Expand all
292 int prev_ref_top_field_order_cnt_; 252 int prev_ref_top_field_order_cnt_;
293 int prev_ref_pic_order_cnt_msb_; 253 int prev_ref_pic_order_cnt_msb_;
294 int prev_ref_pic_order_cnt_lsb_; 254 int prev_ref_pic_order_cnt_lsb_;
295 H264Picture::Field prev_ref_field_; 255 H264Picture::Field prev_ref_field_;
296 256
297 // Currently active SPS and PPS. 257 // Currently active SPS and PPS.
298 int curr_sps_id_; 258 int curr_sps_id_;
299 int curr_pps_id_; 259 int curr_pps_id_;
300 260
301 // Output picture size. 261 // Output picture size.
302 int pic_width_; 262 gfx::Size pic_size_;
303 int pic_height_;
304 263
305 // Data queued up for HW decoder, to be committed on next HW decode. 264 // Maps H.264 PicOrderCount to currently used DecodeSurfaces;
306 std::queue<VABufferID> pending_slice_bufs_; 265 typedef std::map<int, linked_ptr<DecodeSurface> > DecSurfacesInUse;
307 std::queue<VABufferID> pending_va_bufs_; 266 DecSurfacesInUse decode_surfaces_in_use_;
308 267
309 // Manages binding of a client-provided output buffer (texture) to VASurface. 268 // Unused VA surfaces returned by client, ready to be reused.
310 class DecodeSurface; 269 std::vector<scoped_refptr<VASurface> > available_va_surfaces_;
311
312 // Maps output_buffer_id to a decode surface. Used to look up surfaces
313 // on requests from the client.
314 typedef std::map<int32, linked_ptr<DecodeSurface> > DecodeSurfaces;
315 DecodeSurfaces decode_surfaces_;
316
317 // Number of decode surface currently available for decoding.
318 int num_available_decode_surfaces_;
319
320 // Maps decode surfaces to PicOrderCount, used to look up output buffers
321 // when a decision to output a picture has been made.
322 typedef std::map<int, DecodeSurface*> POCToDecodeSurfaces;
323 POCToDecodeSurfaces poc_to_decode_surfaces_;
324
325 // Find an available surface and assign it to given PicOrderCnt |poc|,
326 // removing it from the available surfaces pool. Return true if a surface
327 // has been found, false otherwise.
328 bool AssignSurfaceToPoC(int poc);
329
330 // Mark a surface as unused for decoding, unassigning it from |poc|. If the
331 // corresponding picture is not at client to be displayed,
332 // release the surface.
333 void UnassignSurfaceFromPoC(int poc);
334 270
335 // The id of current input buffer, which will be associated with an 271 // The id of current input buffer, which will be associated with an
336 // output picture if a frame is decoded successfully. 272 // output surface when a frame is successfully decoded.
337 int32 curr_input_id_; 273 int32 curr_input_id_;
338 274
339 // Any method that uses GL/VA routines probably wants to make sure 275 VaapiWrapper* vaapi_wrapper_;
340 // make_context_current_.Run() is called at the top of the method.
341 // X/GLX handles.
342 Display* x_display_;
343 base::Callback<bool(void)> make_context_current_;
344 GLXFBConfig fb_config_;
345 276
346 // VA handles. 277 // Called by decoder when a surface should be outputted.
347 VADisplay va_display_;
348 VAConfigID va_config_id_;
349 VAContextID va_context_id_;
350 VAProfile profile_;
351 bool va_context_created_;
352
353 // Allocated VASurfaces.
354 VASurfaceID va_surface_ids_[kMaxNumReqPictures];
355
356 // Called by decoder when a picture should be outputted.
357 OutputPicCB output_pic_cb_; 278 OutputPicCB output_pic_cb_;
358 279
359 // Called by decoder to post a decode job on the ChildThread. 280 // Called to report decoding error to UMA, not used to indicate errors
360 SubmitDecodeCB submit_decode_cb_; 281 // to clients.
282 ReportErrorToUmaCB report_error_to_uma_cb_;
361 283
362 // PicOrderCount of the previously outputted frame. 284 // PicOrderCount of the previously outputted frame.
363 int last_output_poc_; 285 int last_output_poc_;
364 286
365 // Maximum size of DPB required by codec level. 287 // Maximum size of DPB required by codec level.
366 int max_dpb_size_; 288 int max_dpb_size_;
367 289
368 // Has static initialization of pre-sandbox components completed successfully?
369 static bool pre_sandbox_init_done_;
370
371 DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder); 290 DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder);
372 }; 291 };
373 292
374 } // namespace content 293 } // namespace content
375 294
376 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ 295 #endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698