// Copyright 2015 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. // Note: ported from Chromium commit head: 77118c9 #ifndef VP9_DECODER_H_ #define VP9_DECODER_H_ #include <stddef.h> #include <stdint.h> #include <memory> #include <vector> #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "accelerated_video_decoder.h" #include "vp9_parser.h" #include "vp9_picture.h" namespace media { // This class implements an AcceleratedVideoDecoder for VP9 decoding. // Clients of this class are expected to pass raw VP9 stream and are expected // to provide an implementation of VP9Accelerator for offloading final steps // of the decoding process. // // This class must be created, called and destroyed on a single thread, and // does nothing internally on any other thread. class VP9Decoder : public AcceleratedVideoDecoder { public: class VP9Accelerator { public: VP9Accelerator(); virtual ~VP9Accelerator(); // Create a new VP9Picture that the decoder client can use for initial // stages of the decoding process and pass back to this accelerator for // final, accelerated stages of it, or for reference when decoding other // pictures. // // When a picture is no longer needed by the decoder, it will just drop // its reference to it, and it may do so at any time. // // Note that this may return nullptr if the accelerator is not able to // provide any new pictures at the given time. The decoder must handle this // case and treat it as normal, returning kRanOutOfSurfaces from Decode(). virtual scoped_refptr<VP9Picture> CreateVP9Picture() = 0; // Submit decode for |pic| to be run in accelerator, taking as arguments // information contained in it, as well as current segmentation and loop // filter state in |segm_params| and |lf_params|, respectively, and using // pictures in |ref_pictures| for reference. // If done_cb_ is not null, it will be run once decode is done in hardware. // // Note that returning from this method does not mean that the decode // process is finished, but the caller may drop its references to |pic| // and |ref_pictures| immediately, and the data in |segm_params| and // |lf_params| does not need to remain valid after this method returns. // // Return true when successful, false otherwise. virtual bool SubmitDecode( const scoped_refptr<VP9Picture>& pic, const Vp9SegmentationParams& segm_params, const Vp9LoopFilterParams& lf_params, const std::vector<scoped_refptr<VP9Picture>>& ref_pictures, const base::Closure& done_cb) = 0; // Schedule output (display) of |pic|. // // Note that returning from this method does not mean that |pic| has already // been outputted (displayed), but guarantees that all pictures will be // outputted in the same order as this method was called for them, and that // they are decoded before outputting (assuming SubmitDecode() has been // called for them beforehand). Decoder may drop its references to |pic| // immediately after calling this method. // // Return true when successful, false otherwise. virtual bool OutputPicture(const scoped_refptr<VP9Picture>& pic) = 0; // Return true if the accelerator requires the client to provide frame // context in order to decode. If so, the Vp9FrameHeader provided by the // client must contain a valid compressed header and frame context data. virtual bool IsFrameContextRequired() const = 0; // Set |frame_ctx| to the state after decoding |pic|, returning true on // success, false otherwise. virtual bool GetFrameContext(const scoped_refptr<VP9Picture>& pic, Vp9FrameContext* frame_ctx) = 0; private: DISALLOW_COPY_AND_ASSIGN(VP9Accelerator); }; explicit VP9Decoder(VP9Accelerator* accelerator); ~VP9Decoder() override; // AcceleratedVideoDecoder implementation. void SetStream(const uint8_t* ptr, size_t size) override; bool Flush() override WARN_UNUSED_RESULT; void Reset() override; DecodeResult Decode() override WARN_UNUSED_RESULT; Size GetPicSize() const override; size_t GetRequiredNumOfPictures() const override; private: // Update ref_frames_ based on the information in current frame header. void RefreshReferenceFrames(const scoped_refptr<VP9Picture>& pic); // Decode and possibly output |pic| (if the picture is to be shown). // Return true on success, false otherwise. bool DecodeAndOutputPicture(scoped_refptr<VP9Picture> pic); // Get frame context state after decoding |pic| from the accelerator, and call // |context_refresh_cb| with the acquired state. void UpdateFrameContext( const scoped_refptr<VP9Picture>& pic, const base::Callback<void(const Vp9FrameContext&)>& context_refresh_cb); // Called on error, when decoding cannot continue. Sets state_ to kError and // releases current state. void SetError(); enum State { kNeedStreamMetadata, // After initialization, need a keyframe. kDecoding, // Ready to decode from any point. kAfterReset, // After Reset(), need a resume point. kError, // Error in decode, can't continue. }; // Current decoder state. State state_; // Current frame header to be used in decoding the next picture. std::unique_ptr<Vp9FrameHeader> curr_frame_hdr_; // Reference frames currently in use. std::vector<scoped_refptr<VP9Picture>> ref_frames_; // Current coded resolution. Size pic_size_; // VP9Accelerator instance owned by the client. VP9Accelerator* accelerator_; Vp9Parser parser_; DISALLOW_COPY_AND_ASSIGN(VP9Decoder); }; } // namespace media #endif // VP9_DECODER_H_