16858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// Copyright 2015 The Chromium Authors. All rights reserved.
26858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// Use of this source code is governed by a BSD-style license that can be
36858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// found in the LICENSE file.
4a21d5d577bdc284457867409e2a9c3b4a665d152Johny Lin// Note: ported from Chromium commit head: 60f9667
56858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
66858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#ifndef VP8_DECODER_H_
76858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#define VP8_DECODER_H_
86858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
96858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include <stddef.h>
106858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include <stdint.h>
116858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
126858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include <memory>
136858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
146858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "base/macros.h"
156858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "base/memory/ref_counted.h"
166858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "accelerated_video_decoder.h"
176858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "size.h"
186858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "vp8_parser.h"
196858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#include "vp8_picture.h"
206858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
216858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Linnamespace media {
226858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
236858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// Clients of this class are expected to pass raw VP8 stream and are expected
246858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// to provide an implementation of VP8Accelerator for offloading final steps
256858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// of the decoding process.
266858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin//
276858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// This class must be created, called and destroyed on a single thread, and
286858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin// does nothing internally on any other thread.
296858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Linclass VP8Decoder : public AcceleratedVideoDecoder {
306858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin public:
316858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  class VP8Accelerator {
326858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin   public:
336858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    VP8Accelerator();
346858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    virtual ~VP8Accelerator();
356858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
366858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Create a new VP8Picture that the decoder client can use for decoding
376858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // and pass back to this accelerator for decoding or reference.
386858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // When the picture is no longer needed by decoder, it will just drop
396858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // its reference to it, and it may do so at any time.
406858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Note that this may return nullptr if accelerator is not able to provide
416858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // any new pictures at given time. The decoder is expected to handle
426858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // this situation as normal and return from Decode() with kRanOutOfSurfaces.
436858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    virtual scoped_refptr<VP8Picture> CreateVP8Picture() = 0;
446858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
456858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Submit decode for |pic|, taking as arguments |frame_hdr| with parsed
466858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // VP8 frame header information for current frame, and using |last_frame|,
476858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // |golden_frame| and |alt_frame| as references, as per VP8 specification.
486858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Note that this runs the decode in hardware.
496858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Return true if successful.
506858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    virtual bool SubmitDecode(const scoped_refptr<VP8Picture>& pic,
516858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin                              const Vp8FrameHeader* frame_hdr,
526858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin                              const scoped_refptr<VP8Picture>& last_frame,
536858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin                              const scoped_refptr<VP8Picture>& golden_frame,
546858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin                              const scoped_refptr<VP8Picture>& alt_frame) = 0;
556858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
566858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Schedule output (display) of |pic|. Note that returning from this
576858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // method does not mean that |pic| has already been outputted (displayed),
586858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // but guarantees that all pictures will be outputted in the same order
596858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // as this method was called for them. Decoder may drop its reference
606858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // to |pic| after calling this method.
616858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    // Return true if successful.
626858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    virtual bool OutputPicture(const scoped_refptr<VP8Picture>& pic) = 0;
636858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
646858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin   private:
656858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    DISALLOW_COPY_AND_ASSIGN(VP8Accelerator);
666858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  };
676858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
686858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  VP8Decoder(VP8Accelerator* accelerator);
696858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  ~VP8Decoder() override;
706858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
716858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  // AcceleratedVideoDecoder implementation.
726858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  bool Flush() override WARN_UNUSED_RESULT;
736858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  void Reset() override;
746858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  void SetStream(const uint8_t* ptr, size_t size) override;
756858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  DecodeResult Decode() override WARN_UNUSED_RESULT;
766858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  Size GetPicSize() const override;
776858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  size_t GetRequiredNumOfPictures() const override;
786858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
796858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin private:
806858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  bool DecodeAndOutputCurrentFrame();
816858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  void RefreshReferenceFrames();
826858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
836858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  enum State {
846858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    kNeedStreamMetadata,  // After initialization, need a keyframe.
856858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    kDecoding,            // Ready to decode from any point.
866858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    kAfterReset,          // After Reset(), need a resume point.
876858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin    kError,               // Error in decode, can't continue.
886858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  };
896858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
906858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  State state_;
916858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
926858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  Vp8Parser parser_;
936858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
946858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  std::unique_ptr<Vp8FrameHeader> curr_frame_hdr_;
956858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  scoped_refptr<VP8Picture> curr_pic_;
966858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  scoped_refptr<VP8Picture> last_frame_;
976858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  scoped_refptr<VP8Picture> golden_frame_;
986858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  scoped_refptr<VP8Picture> alt_frame_;
996858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1006858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  const uint8_t* curr_frame_start_;
1016858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  size_t frame_size_;
1026858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1036858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  Size pic_size_;
1046858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  int horizontal_scale_;
1056858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  int vertical_scale_;
1066858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1076858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  VP8Accelerator* accelerator_;
1086858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1096858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin  DISALLOW_COPY_AND_ASSIGN(VP8Decoder);
1106858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin};
1116858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1126858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin}  // namespace media
1136858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin
1146858be529aa0995c49fb61e0400b8aeec5f65063Pin-chih Lin#endif  // VP8_DECODER_H_
115