blob: 95b6e07df353ece052cf1a7cc870b97334ddec16 [file] [log] [blame]
// Copyright 2018 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.
#include <vector>
#include "base/callback.h"
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "media/base/video_bitrate_allocation.h"
#include "media/base/video_codecs.h"
#include "media/gpu/codec_picture.h"
#include "media/video/video_encode_accelerator.h"
#include "ui/gfx/geometry/size.h"
namespace media {
struct BitstreamBufferMetadata;
class VaapiEncodeJob;
class VideoFrame;
// An AcceleratedVideoEncoder (AVE) performs high-level, platform-independent
// encoding process tasks, such as managing codec state, reference frames, etc.,
// but may require support from an external accelerator (typically a hardware
// accelerator) to offload some stages of the actual encoding process, using
// the parameters that AVE prepares beforehand.
// For each frame to be encoded, clients provide an EncodeJob object to be set
// up by an AVE with job parameters, and execute the job afterwards. Any
// resources required for the job are also provided by the clients, and
// associated with the EncodeJob object.
class AcceleratedVideoEncoder {
AcceleratedVideoEncoder() = default;
virtual ~AcceleratedVideoEncoder() = default;
// An abstraction of an encode job for one frame. Parameters required for an
// EncodeJob to be executed are prepared by an AcceleratedVideoEncoder, while
// the accelerator-specific callbacks required to set up and execute it are
// provided by the accelerator itself, based on these parameters.
// Accelerators are also responsible for providing any resources (such as
// memory for output and reference pictures, etc.) as needed.
class EncodeJob : public base::RefCounted<EncodeJob> {
// Creates an EncodeJob to encode |input_frame|, which will be executed
// by calling |execute_cb|. If |keyframe| is true, requests this job
// to produce a keyframe.
EncodeJob(scoped_refptr<VideoFrame> input_frame,
bool keyframe,
base::OnceClosure execute_cb);
// Schedules a callback to be run immediately before this job is executed.
// Can be called multiple times to schedule multiple callbacks, and all
// of them will be run, in order added.
// Callbacks can be used to e.g. set up hardware parameters before the job
// is executed.
void AddSetupCallback(base::OnceClosure cb);
// Adds |ref_pic| to the list of pictures to be used as reference pictures
// for this frame, to ensure they remain valid until the job is executed
// (or discarded).
void AddReferencePicture(scoped_refptr<CodecPicture> ref_pic);
// Runs all setup callbacks previously scheduled, if any, in order added,
// and executes the job by calling the execute callback. Note that the
// actual job execution may be asynchronous, and returning from this method
// does not have to indicate that the job has been finished. The execute
// callback is responsible for retaining references to any resources that
// may be in use after this method returns however, so it is safe to release
// the EncodeJob object itself immediately after this method returns.
void Execute();
// Requests this job to produce a keyframe; requesting a keyframe may not
// always result in one being produced by the encoder (e.g. if it would
// not fit in the bitrate budget).
void ProduceKeyframe() { keyframe_ = true; }
// Returns true if this job has been requested to produce a keyframe.
bool IsKeyframeRequested() const { return keyframe_; }
// Returns the timestamp associated with this job.
base::TimeDelta timestamp() const { return timestamp_; }
virtual BitstreamBufferMetadata Metadata(size_t payload_size) const;
virtual VaapiEncodeJob* AsVaapiEncodeJob();
friend class base::RefCounted<EncodeJob>;
virtual ~EncodeJob();
// Input VideoFrame to be encoded.
const scoped_refptr<VideoFrame> input_frame_;
// Source timestamp for |input_frame_|.
const base::TimeDelta timestamp_;
// True if this job is to produce a keyframe.
bool keyframe_;
// Callbacks to be run (in the same order as the order of AddSetupCallback()
// calls) to set up the job.
base::queue<base::OnceClosure> setup_callbacks_;
// Callback to be run to execute this job.
base::OnceClosure execute_callback_;
// Reference pictures required for this job.
std::vector<scoped_refptr<CodecPicture>> reference_pictures_;
// Initializes the encoder with requested parameter set |config|.
// Returns false if the requested set of parameters is not supported,
// true on success.
virtual bool Initialize(const VideoEncodeAccelerator::Config& config) = 0;
// Updates current framerate and/or bitrate to |framerate| in FPS
// and the specified video bitrate allocation.
virtual bool UpdateRates(const VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) = 0;
// Returns coded size for the input buffers required to encode, in pixels;
// typically visible size adjusted to match codec alignment requirements.
virtual gfx::Size GetCodedSize() const = 0;
// Returns minimum size in bytes for bitstream buffers required to fit output
// stream buffers produced.
virtual size_t GetBitstreamBufferSize() const;
// Returns maximum number of reference frames that may be used by the
// encoder to encode one frame. The client should be able to provide up to
// at least this many frames simultaneously for encode to make progress.
virtual size_t GetMaxNumOfRefFrames() const = 0;
// Prepares a new |encode_job| to be executed in Accelerator and returns true
// on success. The caller may then call Execute() on the job to run it.
virtual bool PrepareEncodeJob(EncodeJob* encode_job) = 0;
} // namespace media