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: 60f9667
5
6#ifndef VP8_DECODER_H_
7#define VP8_DECODER_H_
8
9#include <stddef.h>
10#include <stdint.h>
11
12#include <memory>
13
14#include "base/macros.h"
15#include "base/memory/ref_counted.h"
16#include "accelerated_video_decoder.h"
17#include "size.h"
18#include "vp8_parser.h"
19#include "vp8_picture.h"
20
21namespace media {
22
23// Clients of this class are expected to pass raw VP8 stream and are expected
24// to provide an implementation of VP8Accelerator for offloading final steps
25// of the decoding process.
26//
27// This class must be created, called and destroyed on a single thread, and
28// does nothing internally on any other thread.
29class VP8Decoder : public AcceleratedVideoDecoder {
30 public:
31  class VP8Accelerator {
32   public:
33    VP8Accelerator();
34    virtual ~VP8Accelerator();
35
36    // Create a new VP8Picture that the decoder client can use for decoding
37    // and pass back to this accelerator for decoding or reference.
38    // When the picture is no longer needed by decoder, it will just drop
39    // its reference to it, and it may do so at any time.
40    // Note that this may return nullptr if accelerator is not able to provide
41    // any new pictures at given time. The decoder is expected to handle
42    // this situation as normal and return from Decode() with kRanOutOfSurfaces.
43    virtual scoped_refptr<VP8Picture> CreateVP8Picture() = 0;
44
45    // Submit decode for |pic|, taking as arguments |frame_hdr| with parsed
46    // VP8 frame header information for current frame, and using |last_frame|,
47    // |golden_frame| and |alt_frame| as references, as per VP8 specification.
48    // Note that this runs the decode in hardware.
49    // Return true if successful.
50    virtual bool SubmitDecode(const scoped_refptr<VP8Picture>& pic,
51                              const Vp8FrameHeader* frame_hdr,
52                              const scoped_refptr<VP8Picture>& last_frame,
53                              const scoped_refptr<VP8Picture>& golden_frame,
54                              const scoped_refptr<VP8Picture>& alt_frame) = 0;
55
56    // Schedule output (display) of |pic|. Note that returning from this
57    // method does not mean that |pic| has already been outputted (displayed),
58    // but guarantees that all pictures will be outputted in the same order
59    // as this method was called for them. Decoder may drop its reference
60    // to |pic| after calling this method.
61    // Return true if successful.
62    virtual bool OutputPicture(const scoped_refptr<VP8Picture>& pic) = 0;
63
64   private:
65    DISALLOW_COPY_AND_ASSIGN(VP8Accelerator);
66  };
67
68  VP8Decoder(VP8Accelerator* accelerator);
69  ~VP8Decoder() override;
70
71  // AcceleratedVideoDecoder implementation.
72  bool Flush() override WARN_UNUSED_RESULT;
73  void Reset() override;
74  void SetStream(const uint8_t* ptr, size_t size) override;
75  DecodeResult Decode() override WARN_UNUSED_RESULT;
76  Size GetPicSize() const override;
77  size_t GetRequiredNumOfPictures() const override;
78
79 private:
80  bool DecodeAndOutputCurrentFrame();
81  void RefreshReferenceFrames();
82
83  enum State {
84    kNeedStreamMetadata,  // After initialization, need a keyframe.
85    kDecoding,            // Ready to decode from any point.
86    kAfterReset,          // After Reset(), need a resume point.
87    kError,               // Error in decode, can't continue.
88  };
89
90  State state_;
91
92  Vp8Parser parser_;
93
94  std::unique_ptr<Vp8FrameHeader> curr_frame_hdr_;
95  scoped_refptr<VP8Picture> curr_pic_;
96  scoped_refptr<VP8Picture> last_frame_;
97  scoped_refptr<VP8Picture> golden_frame_;
98  scoped_refptr<VP8Picture> alt_frame_;
99
100  const uint8_t* curr_frame_start_;
101  size_t frame_size_;
102
103  Size pic_size_;
104  int horizontal_scale_;
105  int vertical_scale_;
106
107  VP8Accelerator* accelerator_;
108
109  DISALLOW_COPY_AND_ASSIGN(VP8Decoder);
110};
111
112}  // namespace media
113
114#endif  // VP8_DECODER_H_
115