blob: 6c1c2264baac41f64e324be23b87925770e13912 [file] [log] [blame]
// Copyright 2020 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.
#ifndef MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_
#define MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_
#include <stdint.h>
#include <vector>
#include "media/filters/vp9_parser.h"
#include "media/video/video_encode_accelerator.h"
namespace media {
class VideoBitrateAllocation;
class VP9Picture;
struct Vp9Metadata;
// This class manages a state of K-SVC encoding up to three spatial and temporal
// layers. This supports activating/deactivating spatial layers while the
// temporal layer sizes must be unchanged. The temporal layer sizes among
// spatial layers must be identical. Temporal layers and spatial layers are
// described in https://tools.ietf.org/html/draft-ietf-payload-vp9-10#section-3.
class VP9SVCLayers {
public:
struct FrameConfig;
constexpr static size_t kMaxSupportedTemporalLayers = 3u;
constexpr static size_t kMaxSpatialLayers = 3u;
constexpr static size_t kMaxNumUsedRefFramesEachSpatialLayer =
kVp9NumRefFrames / kMaxSpatialLayers;
static_assert(
kMaxNumUsedRefFramesEachSpatialLayer == 2u,
"VP9SVCLayers uses two reference frames for each spatial layer");
constexpr static size_t kMaxNumUsedReferenceFrames =
kMaxNumUsedRefFramesEachSpatialLayer * kMaxSpatialLayers;
static_assert(kMaxNumUsedReferenceFrames == 6u,
"VP9SVCLayers uses six reference frames");
using SpatialLayer = VideoEncodeAccelerator::Config::SpatialLayer;
explicit VP9SVCLayers(const std::vector<SpatialLayer>& spatial_layers);
~VP9SVCLayers();
static std::vector<uint8_t> GetFpsAllocation(size_t num_temporal_layers);
// Returns true if EncodeJob needs to produce key frame.
bool UpdateEncodeJob(bool is_key_frame_requested, size_t kf_period_frames);
// Activate/Deactivate spatial layers via |bitrate_allocation|.
// Returns whether (de)updating is successful.
bool MaybeUpdateActiveLayer(VideoBitrateAllocation* bitrate_allocation);
// Sets |picture|'s used reference frames and |ref_frames_used| so that they
// structure valid temporal layers. This also fills |picture|'s
// |metadata_for_encoding|.
void FillUsedRefFramesAndMetadata(
VP9Picture* picture,
std::array<bool, kVp9NumRefsPerFrame>* ref_frames_used);
size_t num_temporal_layers() const { return num_temporal_layers_; }
const std::vector<gfx::Size>& active_spatial_layer_resolutions() const {
return active_spatial_layer_resolutions_;
}
private:
// Useful functions to construct refresh flag and detect reference frames
// from the flag.
void FillVp9MetadataForEncoding(
Vp9Metadata* metadata,
const std::vector<uint8_t>& reference_frame_indices) const;
void UpdateRefFramesPatternIndex(
const std::vector<uint8_t>& refresh_frame_indices);
// Following variables are configured upon construction, containing the amount
// of temporal layers/spatial layers, the associated temporal layers indices
// and the nature (reference, update, both, none) of each frame in the
// temporal group, respectively.
const size_t num_temporal_layers_;
const std::vector<FrameConfig> temporal_layers_reference_pattern_;
// The current index into the |temporal_layers_reference_pattern_|.
uint8_t pattern_index_;
const size_t temporal_pattern_size_;
size_t spatial_idx_ = 0;
size_t frame_num_ = 0;
bool force_key_frame_ = false;
// Resolutions for all spatial layers and active spatial layers.
std::vector<gfx::Size> spatial_layer_resolutions_;
std::vector<gfx::Size> active_spatial_layer_resolutions_;
// Stores the active layer range, only used to judge whether active range has
// changed in |MaybeUpdateActiveLayer|, then
// |active_spatial_layer_resolutions_| needs update.
size_t begin_active_layer_;
size_t end_active_layer_;
// The pattern index used for reference frames slots.
uint8_t pattern_index_of_ref_frames_slots_[kMaxNumUsedReferenceFrames] = {};
};
} // namespace media
#endif // MEDIA_GPU_VAAPI_VP9_SVC_LAYERS_H_