Index: content/common/gpu/media/vaapi_h264_decoder.h |
=================================================================== |
--- content/common/gpu/media/vaapi_h264_decoder.h (revision 138207) |
+++ content/common/gpu/media/vaapi_h264_decoder.h (working copy) |
@@ -1,335 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
-// |
-// This file contains an implementation of a class that provides H264 decode |
-// support for use with VAAPI hardware video decode acceleration on Intel |
-// systems. |
- |
-#ifndef CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ |
-#define CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ |
- |
-#include <GL/glx.h> |
- |
-#include <queue> |
- |
-#include "base/callback_forward.h" |
-#include "base/lazy_instance.h" |
-#include "base/memory/linked_ptr.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "content/common/gpu/media/h264_dpb.h" |
-#include "content/common/gpu/media/h264_parser.h" |
-#include "media/base/video_decoder_config.h" |
-#include "media/base/limits.h" |
-#include "third_party/libva/va/va.h" |
- |
-namespace content { |
- |
-// An H264 decoder for use for VA-API-specific decoding. Provides features not |
-// supported by libva, including stream parsing, reference picture management |
-// and other operations not supported by the HW codec. |
-// |
-// Provides functionality to allow plugging VAAPI HW acceleration into the |
-// VDA framework. |
-// |
-// Clients of this class are expected to pass H264 Annex-B byte stream and |
-// will receive decoded pictures via client-provided |OutputPicCB|. |
-// |
-// If used in multi-threaded environment, some of the functions have to be |
-// called on the child thread, i.e. the main thread of the GPU process |
-// (the one that has the GLX context passed to Initialize() set as current). |
-// This is essential so that the GLX calls can work properly. |
-// Decoder thread, on the other hand, does not require a GLX context and should |
-// be the same as the one on which Decode*() functions are called. |
-class VaapiH264Decoder { |
- public: |
- // Callback invoked on the client when a picture is to be displayed. |
- // Callee has to call PutPicToTexture() for the given picture before |
- // displaying it, to ensure the contents have been synced properly. |
- // Arguments: input buffer id, output buffer id (both provided by the client |
- // at the time of Decode() and AssignPictureBuffer() calls). |
- typedef base::Callback<void(int32, int32)> OutputPicCB; |
- |
- // Decode result codes. |
- enum DecResult { |
- kDecodeError, // Error while decoding. |
- // TODO posciak: unsupported streams are currently treated as error |
- // in decoding; in future it could perhaps be possible to fall back |
- // to software decoding instead. |
- // kStreamError, // Error in stream. |
- kReadyToDecode, // Successfully initialized. |
- kDecodedFrame, // Successfully decoded a frame. |
- kNeedMoreStreamData, // Need more stream data to decode the next frame. |
- kNoOutputAvailable, // Waiting for the client to free up output surfaces. |
- }; |
- |
- VaapiH264Decoder(); |
- // Should be called on the GLX thread, for the surface cleanup to work |
- // properly. |
- ~VaapiH264Decoder(); |
- |
- // Initializes and sets up libva connection and GL/X11 resources. |
- // Must be called on the GLX thread with |glx_context| being current and |
- // with decoder thread not yet running. |
- // |output_pic_cb| will be called to notify when a picture can be displayed. |
- bool Initialize(media::VideoCodecProfile profile, |
- Display* x_display, |
- GLXContext glx_context, |
- const OutputPicCB& output_pic_cb) WARN_UNUSED_RESULT; |
- void Destroy(); |
- |
- // Notify the decoder that this output buffer has been consumed and |
- // can be reused (overwritten). |
- // Must be run on the decoder thread. |
- void ReusePictureBuffer(int32 picture_buffer_id); |
- |
- // Give a new picture buffer (texture) to decoder for use. |
- // Must be run on the GLX thread with decoder thread not yet running. |
- bool AssignPictureBuffer(int32 picture_buffer_id, uint32 texture_id) |
- WARN_UNUSED_RESULT; |
- |
- // Sync the data so that the texture for given |picture_buffer_id| can |
- // be displayed. |
- // Must be run on the GLX thread. |
- bool PutPicToTexture(int32 picture_buffer_id) WARN_UNUSED_RESULT; |
- |
- // Have the decoder flush its state and trigger output of all previously |
- // decoded pictures via OutputPicCB. |
- // Returns false if any of the resulting invocations of the callback fail. |
- bool Flush() WARN_UNUSED_RESULT; |
- |
- // Called while decoding. |
- // Stop decoding, discarding all remaining input/output, but do not flush |
- // state, so the playback of the same stream can be resumed (possibly from |
- // another location). |
- void Reset(); |
- |
- // Set current stream data pointer to |ptr| and |size|. |
- // Must be run on decoder thread. |
- void SetStream(uint8* ptr, size_t size); |
- |
- // Start parsing stream to detect picture sizes. Does not produce any |
- // decoded pictures and can be called without providing output textures. |
- // Also to be used after Reset() to find a suitable location in the |
- // stream to resume playback from. |
- DecResult DecodeInitial(int32 input_id) WARN_UNUSED_RESULT; |
- |
- // Runs until a frame is decoded or end of provided stream data buffer |
- // is reached. Decoded pictures will be returned asynchronously via |
- // OutputPicCB. |
- DecResult DecodeOneFrame(int32 input_id) WARN_UNUSED_RESULT; |
- |
- // Return dimensions for output buffer (texture) allocation. |
- // Valid only after a successful DecodeInitial(). |
- int pic_height() { return pic_height_; } |
- int pic_width() { return pic_width_; } |
- |
- // Return the number of output pictures required for decoding. |
- // Valid after a successful DecodeInitial(). |
- static size_t GetRequiredNumOfPictures(); |
- |
- private: |
- // We need to keep at least kDPBMaxSize pictures in DPB for |
- // reference/to display later and an additional one for the one currently |
- // being decoded. We also ask for some additional ones since VDA needs |
- // to accumulate a few ready-to-output pictures before it actually starts |
- // displaying and giving them back. +2 instead of +1 because of subjective |
- // smoothness improvement during testing. |
- enum { kNumReqPictures = H264DPB::kDPBMaxSize + |
- media::limits::kMaxVideoFrames + 2 }; |
- |
- // Internal state of the decoder. |
- enum State { |
- kUninitialized, // Initialize() not yet called. |
- kInitialized, // Initialize() called, pictures requested. |
- kDecoding, // DecodeInitial() successful, output surfaces allocated. |
- kAfterReset, // After Reset() during decoding. |
- kError, // Error in kDecoding state. |
- }; |
- |
- // Get usable framebuffer configuration for use in binding textures |
- // or return false on failure. |
- bool InitializeFBConfig(); |
- |
- // Process H264 stream structures. |
- bool ProcessSPS(int sps_id); |
- bool ProcessPPS(int pps_id); |
- bool ProcessSlice(H264SliceHeader* slice_hdr); |
- |
- // Initialize the current picture according to data in |slice_hdr|. |
- bool InitCurrPicture(H264SliceHeader* slice_hdr); |
- |
- // Calculate picture order counts for the new picture |
- // on initialization of a new frame (see spec). |
- bool CalculatePicOrderCounts(H264SliceHeader* slice_hdr); |
- |
- // Update PicNum values in pictures stored in DPB on creation of new |
- // frame (see spec). |
- void UpdatePicNums(); |
- |
- // Construct initial reference picture lists for use in decoding of |
- // P and B pictures (see 8.2.4 in spec). |
- void ConstructReferencePicListsP(H264SliceHeader* slice_hdr); |
- void ConstructReferencePicListsB(H264SliceHeader* slice_hdr); |
- |
- // Helper functions for reference list construction, per spec. |
- int PicNumF(H264Picture *pic); |
- int LongTermPicNumF(H264Picture *pic); |
- |
- // Perform the reference picture lists' modification (reordering), as |
- // specified in spec (8.2.4). |
- // |
- // |list| indicates list number and should be either 0 or 1. |
- bool ModifyReferencePicList(H264SliceHeader *slice_hdr, int list); |
- |
- // Perform reference picture memory management operations (marking/unmarking |
- // of reference pictures, long term picture management, discarding, etc.). |
- // See 8.2.5 in spec. |
- bool HandleMemoryManagementOps(); |
- void ReferencePictureMarking(); |
- |
- // Start processing a new frame. |
- bool StartNewFrame(H264SliceHeader* slice_hdr); |
- |
- // All data for a frame received, process it and decode. |
- bool FinishPrevFrameIfPresent(); |
- |
- // Called after decoding, performs all operations to be done after decoding, |
- // including DPB management, reference picture marking and memory management |
- // operations. |
- // This will also output a picture if one is ready for output. |
- bool FinishPicture(); |
- |
- // Convert VideoCodecProfile to VAProfile and set it as active. |
- bool SetProfile(media::VideoCodecProfile profile); |
- |
- // Vaapi-related functions. |
- |
- // Allocates VASurfaces and creates a VAContext for them. |
- bool CreateVASurfaces(); |
- |
- // Destroys allocated VASurfaces and related VAContext. |
- void DestroyVASurfaces(); |
- |
- // These queue up data for HW decoder to be committed on running HW decode. |
- bool SendPPS(); |
- bool SendIQMatrix(); |
- bool SendVASliceParam(H264SliceHeader* slice_hdr); |
- bool SendSliceData(const uint8* ptr, size_t size); |
- bool QueueSlice(H264SliceHeader* slice_hdr); |
- |
- // Helper methods for filling HW structures. |
- void FillVAPicture(VAPictureH264 *va_pic, H264Picture* pic); |
- int FillVARefFramesFromDPB(VAPictureH264 *va_pics, int num_pics); |
- |
- // Commits all pending data for HW decoder and starts HW decoder. |
- bool DecodePicture(); |
- |
- // Notifies client that a picture is ready for output. |
- bool OutputPic(H264Picture* pic); |
- |
- State state_; |
- |
- // A frame has been sent to hardware as the result of the last |
- // DecodeOneFrame() call. |
- bool frame_ready_at_hw_; |
- |
- // Parser in use. |
- H264Parser parser_; |
- |
- // DPB in use. |
- H264DPB dpb_; |
- |
- // Picture currently being processed/decoded. |
- scoped_ptr<H264Picture> curr_pic_; |
- |
- // Reference picture lists, constructed for each picture before decoding. |
- // Those lists are not owners of the pointers (DPB is). |
- H264Picture::PtrVector ref_pic_list0_; |
- H264Picture::PtrVector ref_pic_list1_; |
- |
- // Global state values, needed in decoding. See spec. |
- int max_pic_order_cnt_lsb_; |
- int max_frame_num_; |
- int max_pic_num_; |
- int max_long_term_frame_idx_; |
- |
- int frame_num_; |
- int prev_frame_num_; |
- int prev_frame_num_offset_; |
- |
- // Values related to previously decoded reference picture. |
- bool prev_ref_has_memmgmnt5_; |
- int prev_ref_top_field_order_cnt_; |
- int prev_ref_pic_order_cnt_msb_; |
- int prev_ref_pic_order_cnt_lsb_; |
- H264Picture::Field prev_ref_field_; |
- |
- // Currently active SPS and PPS. |
- int curr_sps_id_; |
- int curr_pps_id_; |
- |
- // Output picture size. |
- int pic_width_; |
- int pic_height_; |
- |
- // Data queued up for HW decoder, to be commited on next HW decode. |
- std::queue<VABufferID> pending_slice_bufs_; |
- std::queue<VABufferID> pending_va_bufs_; |
- |
- // Manages binding of a client-provided output buffer (texture) to VASurface. |
- class DecodeSurface; |
- |
- // Maps output_buffer_id to a decode surface. Used to look up surfaces |
- // on requests from the client. |
- typedef std::map<int32, linked_ptr<DecodeSurface> > DecodeSurfaces; |
- DecodeSurfaces decode_surfaces_; |
- |
- // Number of decode surface currently available for decoding. |
- int num_available_decode_surfaces_; |
- |
- // Maps decode surfaces to PicOrderCount, used to look up output buffers |
- // when a decision to output a picture has been made. |
- typedef std::map<int, DecodeSurface*> POCToDecodeSurfaces; |
- POCToDecodeSurfaces poc_to_decode_surfaces_; |
- |
- // Find an available surface and assign it to given PicOrderCnt |poc|, |
- // removing it from the available surfaces pool. Return true if a surface |
- // has been found, false otherwise. |
- bool AssignSurfaceToPoC(int poc); |
- |
- // Unassign a surface from |poc| and return a pointer to it, or NULL if there |
- // is no surface associated with given |poc|. Note that this does not make |
- // the surface available for reuse - as this can only happen after client |
- // returns the surface via ReusePictureBuffer() - but only removes its |
- // association with given |poc|. |
- DecodeSurface* UnassignSurfaceFromPoC(int poc); |
- |
- // The id of current input buffer, which will be associated with an |
- // output picture if a frame is decoded successfully. |
- int32 curr_input_id_; |
- |
- // X/GLX handles. |
- Display* x_display_; |
- GLXContext parent_glx_context_; |
- GLXFBConfig fb_config_; |
- |
- // VA handles. |
- VADisplay va_display_; |
- VAConfigID va_config_id_; |
- VAContextID va_context_id_; |
- VAProfile profile_; |
- |
- // Allocated VASurfaces. |
- VASurfaceID va_surface_ids_[kNumReqPictures]; |
- |
- // Called by decoder when a picture should be outputted. |
- OutputPicCB output_pic_cb_; |
- |
- DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder); |
-}; |
- |
-} // namespace content |
- |
-#endif // CONTENT_COMMON_GPU_MEDIA_VAAPI_H264_DECODER_H_ |
- |