// 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.
|
// Note: ported from Chromium commit head: 77118c9
|
|
#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_
|