| // 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_ |