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