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
22namespace 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.
31class 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