1 // Copyright 2015 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 // Note: ported from Chromium commit head: 77118c9 5 6 #ifndef VP9_DECODER_H_ 7 #define VP9_DECODER_H_ 8 9 #include <stddef.h> 10 #include <stdint.h> 11 12 #include <memory> 13 #include <vector> 14 15 #include "base/callback_forward.h" 16 #include "base/macros.h" 17 #include "base/memory/ref_counted.h" 18 #include "accelerated_video_decoder.h" 19 #include "vp9_parser.h" 20 #include "vp9_picture.h" 21 22 namespace media { 23 24 // This class implements an AcceleratedVideoDecoder for VP9 decoding. 25 // Clients of this class are expected to pass raw VP9 stream and are expected 26 // to provide an implementation of VP9Accelerator for offloading final steps 27 // of the decoding process. 28 // 29 // This class must be created, called and destroyed on a single thread, and 30 // does nothing internally on any other thread. 31 class VP9Decoder : public AcceleratedVideoDecoder { 32 public: 33 class VP9Accelerator { 34 public: 35 VP9Accelerator(); 36 virtual ~VP9Accelerator(); 37 38 // Create a new VP9Picture that the decoder client can use for initial 39 // stages of the decoding process and pass back to this accelerator for 40 // final, accelerated stages of it, or for reference when decoding other 41 // pictures. 42 // 43 // When a picture is no longer needed by the decoder, it will just drop 44 // its reference to it, and it may do so at any time. 45 // 46 // Note that this may return nullptr if the accelerator is not able to 47 // provide any new pictures at the given time. The decoder must handle this 48 // case and treat it as normal, returning kRanOutOfSurfaces from Decode(). 49 virtual scoped_refptr<VP9Picture> CreateVP9Picture() = 0; 50 51 // Submit decode for |pic| to be run in accelerator, taking as arguments 52 // information contained in it, as well as current segmentation and loop 53 // filter state in |segm_params| and |lf_params|, respectively, and using 54 // pictures in |ref_pictures| for reference. 55 // If done_cb_ is not null, it will be run once decode is done in hardware. 56 // 57 // Note that returning from this method does not mean that the decode 58 // process is finished, but the caller may drop its references to |pic| 59 // and |ref_pictures| immediately, and the data in |segm_params| and 60 // |lf_params| does not need to remain valid after this method returns. 61 // 62 // Return true when successful, false otherwise. 63 virtual bool SubmitDecode( 64 const scoped_refptr<VP9Picture>& pic, 65 const Vp9SegmentationParams& segm_params, 66 const Vp9LoopFilterParams& lf_params, 67 const std::vector<scoped_refptr<VP9Picture>>& ref_pictures, 68 const base::Closure& done_cb) = 0; 69 70 // Schedule output (display) of |pic|. 71 // 72 // Note that returning from this method does not mean that |pic| has already 73 // been outputted (displayed), but guarantees that all pictures will be 74 // outputted in the same order as this method was called for them, and that 75 // they are decoded before outputting (assuming SubmitDecode() has been 76 // called for them beforehand). Decoder may drop its references to |pic| 77 // immediately after calling this method. 78 // 79 // Return true when successful, false otherwise. 80 virtual bool OutputPicture(const scoped_refptr<VP9Picture>& pic) = 0; 81 82 // Return true if the accelerator requires the client to provide frame 83 // context in order to decode. If so, the Vp9FrameHeader provided by the 84 // client must contain a valid compressed header and frame context data. 85 virtual bool IsFrameContextRequired() const = 0; 86 87 // Set |frame_ctx| to the state after decoding |pic|, returning true on 88 // success, false otherwise. 89 virtual bool GetFrameContext(const scoped_refptr<VP9Picture>& pic, 90 Vp9FrameContext* frame_ctx) = 0; 91 92 private: 93 DISALLOW_COPY_AND_ASSIGN(VP9Accelerator); 94 }; 95 96 explicit VP9Decoder(VP9Accelerator* accelerator); 97 ~VP9Decoder() override; 98 99 // AcceleratedVideoDecoder implementation. 100 void SetStream(const uint8_t* ptr, size_t size) override; 101 bool Flush() override WARN_UNUSED_RESULT; 102 void Reset() override; 103 DecodeResult Decode() override WARN_UNUSED_RESULT; 104 Size GetPicSize() const override; 105 size_t GetRequiredNumOfPictures() const override; 106 107 private: 108 // Update ref_frames_ based on the information in current frame header. 109 void RefreshReferenceFrames(const scoped_refptr<VP9Picture>& pic); 110 111 // Decode and possibly output |pic| (if the picture is to be shown). 112 // Return true on success, false otherwise. 113 bool DecodeAndOutputPicture(scoped_refptr<VP9Picture> pic); 114 115 // Get frame context state after decoding |pic| from the accelerator, and call 116 // |context_refresh_cb| with the acquired state. 117 void UpdateFrameContext( 118 const scoped_refptr<VP9Picture>& pic, 119 const base::Callback<void(const Vp9FrameContext&)>& context_refresh_cb); 120 121 // Called on error, when decoding cannot continue. Sets state_ to kError and 122 // releases current state. 123 void SetError(); 124 125 enum State { 126 kNeedStreamMetadata, // After initialization, need a keyframe. 127 kDecoding, // Ready to decode from any point. 128 kAfterReset, // After Reset(), need a resume point. 129 kError, // Error in decode, can't continue. 130 }; 131 132 // Current decoder state. 133 State state_; 134 135 // Current frame header to be used in decoding the next picture. 136 std::unique_ptr<Vp9FrameHeader> curr_frame_hdr_; 137 138 // Reference frames currently in use. 139 std::vector<scoped_refptr<VP9Picture>> ref_frames_; 140 141 // Current coded resolution. 142 Size pic_size_; 143 144 // VP9Accelerator instance owned by the client. 145 VP9Accelerator* accelerator_; 146 147 Vp9Parser parser_; 148 149 DISALLOW_COPY_AND_ASSIGN(VP9Decoder); 150 }; 151 152 } // namespace media 153 154 #endif // VP9_DECODER_H_ 155