| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef MEDIA_GPU_SVC_LAYERS_H_ |
| #define MEDIA_GPU_SVC_LAYERS_H_ |
| |
| #include <stdint.h> |
| |
| #include <variant> |
| #include <vector> |
| |
| #include "media/base/svc_scalability_mode.h" |
| #include "media/gpu/media_gpu_export.h" |
| #include "media/parsers/vp9_parser.h" |
| #include "media/video/video_encode_accelerator.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace media { |
| |
| class MEDIA_GPU_EXPORT SVCLayers { |
| public: |
| constexpr static size_t kMaxTemporalLayers = 3u; |
| constexpr static size_t kMaxSpatialLayers = 3u; |
| |
| // Config is the SVC configuration used in SVCLayers. It cannot be changed |
| // after creation. In other words, if active spatial layers or the number of |
| // temporal layers are changed, a client needs to recreate SVCLayers with |
| // the new Config. |
| struct MEDIA_GPU_EXPORT Config { |
| Config(const std::vector<gfx::Size>& spatial_layer_resolutions, |
| size_t begin_active_layer, |
| size_t end_active_layer, |
| size_t num_temporal_layers, |
| SVCInterLayerPredMode inter_layer_pred); |
| ~Config(); |
| Config(const Config& config); |
| |
| // The resolutions in spatial layers. This includes resolutions in inactive |
| // resolutions. |
| std::vector<gfx::Size> spatial_layer_resolutions; |
| // The active spatial layer resolutions index. |
| // [begin_active_layer, end_active_layer - 1]. |
| size_t begin_active_layer = 0; |
| size_t end_active_layer = 0; |
| size_t num_temporal_layers = 0; |
| // The active spatial layer resolutions, i.e., resolutions from |
| // spatial_layer_resolutions[begin_active_layer] to |
| // spatial_layer_resolutions[end_active_layer - 1]. |
| std::vector<gfx::Size> active_spatial_layer_resolutions; |
| SVCInterLayerPredMode inter_layer_pred = SVCInterLayerPredMode::kOnKeyPic; |
| }; |
| |
| // The parameters used for encoding the current frame. |
| struct MEDIA_GPU_EXPORT PictureParam { |
| PictureParam(); |
| ~PictureParam(); |
| PictureParam(const PictureParam&); |
| |
| bool key_frame = false; |
| gfx::Size frame_size; |
| uint8_t refresh_frame_flags = 0; |
| std::vector<uint8_t> reference_frame_indices; |
| }; |
| |
| explicit SVCLayers(const Config& config); |
| |
| std::pair<bool, std::optional<std::unique_ptr<SVCLayers>>> |
| RecreateSVCLayersIfNeeded(VideoBitrateAllocation& bitrate_allocation); |
| |
| // These functions are constant functions. Unless Reset() or PostEncode() is |
| // called, these functions returns the same result as the previous result. |
| // Returns whether the current frame shall encoded as key frame. |
| bool IsKeyFrame() const; |
| // Gets PictureParam and fill the metadata for the current frame. |
| void GetPictureParamAndMetadata( |
| PictureParam& picture_param, |
| std::variant<Vp9Metadata*, SVCGenericMetadata*> metadata) const; |
| |
| // Resets the current spatial layer stream. |
| // This can be called before encoding the SVC frame. |
| void Reset(); |
| // Moves to the next frame by changing |spatial_index_| and |frame_num_| and |
| // updates |frame_num_ref_frames_| by |refresh_frame_flags|. |
| void PostEncode(uint8_t refresh_frame_flags); |
| |
| // Returns the currently used configuration and the spatial index and the |
| // frame number for the current frame. |
| const Config& config() const { return config_; } |
| size_t spatial_idx() const { return spatial_idx_; } |
| size_t frame_num() const { return frame_num_; } |
| |
| private: |
| // Fill metadata for the first frame, i.e. frame_num=0. |
| void FillMetadataForFirstFrame( |
| std::variant<Vp9Metadata*, SVCGenericMetadata*> metadata, |
| bool& key_frame, |
| uint8_t& refresh_frame_flags, |
| std::vector<uint8_t>& reference_frame_indices) const; |
| // Fill metadata for the second and later frames, i.e. frame_num != 0. |
| void FillMetadataForNonFirstFrame( |
| std::variant<Vp9Metadata*, SVCGenericMetadata*> metadata, |
| uint8_t& refresh_frame_flags, |
| std::vector<uint8_t>& reference_frame_indices) const; |
| |
| const Config config_; |
| |
| size_t spatial_idx_ = 0; |
| // The frame number since the last frame containing keyframe. |
| // It is incremented after PostEncode() on the top spatial index. |
| size_t frame_num_ = 0; |
| // The |frame_num| of reference frames. This is used to compute |p_diff|. |
| std::array<size_t, kVp9NumRefFrames> frame_num_ref_frames_; |
| }; |
| } // namespace media |
| #endif // MEDIA_GPU_SVC_LAYERS_H_ |