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