aboutsummaryrefslogtreecommitdiff
path: root/vda/vp9_decoder.h
blob: 77a8d8829e598c59d02298434e2ca9a9283c53a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// 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.

#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_