diff --git a/api/test/mock_video_decoder.h b/api/test/mock_video_decoder.h index faadabc4d7..03c93b8619 100644 --- a/api/test/mock_video_decoder.h +++ b/api/test/mock_video_decoder.h @@ -37,6 +37,7 @@ class MockDecodedImageCallback : public DecodedImageCallback { class MockVideoDecoder : public VideoDecoder { public: + MOCK_METHOD(bool, Configure, (const Settings& settings), (override)); MOCK_METHOD(int32_t, InitDecode, (const VideoCodec* codec_settings, int32_t number_of_cores), diff --git a/api/transport/rtp/BUILD.gn b/api/transport/rtp/BUILD.gn index 7b01169360..26036c7f32 100644 --- a/api/transport/rtp/BUILD.gn +++ b/api/transport/rtp/BUILD.gn @@ -24,7 +24,10 @@ rtc_source_set("dependency_descriptor") { "dependency_descriptor.cc", "dependency_descriptor.h", ] - deps = [ "../../../rtc_base:checks" ] + deps = [ + "../../../rtc_base:checks", + "../../video:render_resolution", + ] absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/strings", diff --git a/api/transport/rtp/dependency_descriptor.h b/api/transport/rtp/dependency_descriptor.h index 6967c83517..0db600918e 100644 --- a/api/transport/rtp/dependency_descriptor.h +++ b/api/transport/rtp/dependency_descriptor.h @@ -20,30 +20,11 @@ #include "absl/container/inlined_vector.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/video/render_resolution.h" namespace webrtc { // Structures to build and parse dependency descriptor as described in // https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension -class RenderResolution { - public: - constexpr RenderResolution() = default; - constexpr RenderResolution(int width, int height) - : width_(width), height_(height) {} - RenderResolution(const RenderResolution&) = default; - RenderResolution& operator=(const RenderResolution&) = default; - - friend bool operator==(const RenderResolution& lhs, - const RenderResolution& rhs) { - return lhs.width_ == rhs.width_ && lhs.height_ == rhs.height_; - } - - constexpr int Width() const { return width_; } - constexpr int Height() const { return height_; } - - private: - int width_ = 0; - int height_ = 0; -}; // Relationship of a frame to a Decode target. enum class DecodeTargetIndication { diff --git a/api/video/BUILD.gn b/api/video/BUILD.gn index eaa7715f75..e358b1f41e 100644 --- a/api/video/BUILD.gn +++ b/api/video/BUILD.gn @@ -112,6 +112,11 @@ rtc_source_set("video_frame_type") { sources = [ "video_frame_type.h" ] } +rtc_source_set("render_resolution") { + visibility = [ "*" ] + public = [ "render_resolution.h" ] +} + rtc_library("encoded_image") { visibility = [ "*" ] sources = [ diff --git a/api/video/render_resolution.h b/api/video/render_resolution.h new file mode 100644 index 0000000000..edcf8f8ee5 --- /dev/null +++ b/api/video/render_resolution.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VIDEO_RENDER_RESOLUTION_H_ +#define API_VIDEO_RENDER_RESOLUTION_H_ + +namespace webrtc { + +class RenderResolution { + public: + constexpr RenderResolution() = default; + constexpr RenderResolution(int width, int height) + : width_(width), height_(height) {} + RenderResolution(const RenderResolution&) = default; + RenderResolution& operator=(const RenderResolution&) = default; + + friend bool operator==(const RenderResolution& lhs, + const RenderResolution& rhs) { + return lhs.width_ == rhs.width_ && lhs.height_ == rhs.height_; + } + friend bool operator!=(const RenderResolution& lhs, + const RenderResolution& rhs) { + return !(lhs == rhs); + } + + constexpr bool Valid() const { return width_ > 0 && height_ > 0; } + + constexpr int Width() const { return width_; } + constexpr int Height() const { return height_; } + + private: + int width_ = 0; + int height_ = 0; +}; + +} // namespace webrtc + +#endif // API_VIDEO_RENDER_RESOLUTION_H_ diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index 83d67fcac4..cab0f7a049 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -50,6 +50,7 @@ rtc_library("video_codecs_api") { "../../rtc_base/system:rtc_export", "../units:data_rate", "../video:encoded_image", + "../video:render_resolution", "../video:video_bitrate_allocation", "../video:video_codec_constants", "../video:video_frame", diff --git a/api/video_codecs/video_decoder.cc b/api/video_codecs/video_decoder.cc index 04673e6c31..544b8ce444 100644 --- a/api/video_codecs/video_decoder.cc +++ b/api/video_codecs/video_decoder.cc @@ -10,6 +10,9 @@ #include "api/video_codecs/video_decoder.h" +#include "absl/types/optional.h" +#include "api/video/render_resolution.h" +#include "api/video/video_codec_type.h" #include "rtc_base/strings/string_builder.h" namespace webrtc { @@ -53,4 +56,29 @@ bool VideoDecoder::DecoderInfo::operator==(const DecoderInfo& rhs) const { implementation_name == rhs.implementation_name; } +bool VideoDecoder::Configure(const Settings& settings) { + VideoCodec codec_settings = {}; + codec_settings.buffer_pool_size = settings.buffer_pool_size(); + RenderResolution max_resolution = settings.max_render_resolution(); + if (max_resolution.Valid()) { + codec_settings.width = max_resolution.Width(); + codec_settings.height = max_resolution.Height(); + } + codec_settings.codecType = settings.codec_type(); + return InitDecode(&codec_settings, settings.number_of_cores()) >= 0; +} + +int32_t VideoDecoder::InitDecode(const VideoCodec* codec_settings, + int32_t number_of_cores) { + Settings settings; + if (codec_settings != nullptr) { + settings.set_buffer_pool_size(codec_settings->buffer_pool_size); + settings.set_max_render_resolution( + {codec_settings->width, codec_settings->height}); + settings.set_codec_type(codec_settings->codecType); + } + settings.set_number_of_cores(number_of_cores); + return Configure(settings) ? 0 : -1; +} + } // namespace webrtc diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h index 04052de08b..e26488e40a 100644 --- a/api/video_codecs/video_decoder.h +++ b/api/video_codecs/video_decoder.h @@ -15,7 +15,10 @@ #include #include +#include "absl/types/optional.h" #include "api/video/encoded_image.h" +#include "api/video/render_resolution.h" +#include "api/video/video_codec_type.h" #include "api/video/video_frame.h" #include "api/video_codecs/video_codec.h" #include "rtc_base/system/rtc_export.h" @@ -54,10 +57,53 @@ class RTC_EXPORT VideoDecoder { bool operator!=(const DecoderInfo& rhs) const { return !(*this == rhs); } }; - virtual ~VideoDecoder() {} + class Settings { + public: + Settings() = default; + Settings(const Settings&) = default; + Settings& operator=(const Settings&) = default; + ~Settings() = default; + // The size of pool which is used to store video frame buffers inside + // decoder. If value isn't present some codec-default value will be used. If + // value is present and decoder doesn't have buffer pool the value will be + // ignored. + absl::optional buffer_pool_size() const; + void set_buffer_pool_size(absl::optional value); + + // When valid, user of the VideoDecoder interface shouldn't `Decode` + // encoded images with render resolution larger than width and height + // specified here. + RenderResolution max_render_resolution() const; + void set_max_render_resolution(RenderResolution value); + + // Maximum number of cpu cores the decoder is allowed to use in parallel. + int number_of_cores() const { return number_of_cores_; } + void set_number_of_cores(int value) { number_of_cores_ = value; } + + // Codec of encoded images user of the VideoDecoder interface will `Decode`. + VideoCodecType codec_type() const { return codec_type_; } + void set_codec_type(VideoCodecType value) { codec_type_ = value; } + + private: + absl::optional buffer_pool_size_; + RenderResolution max_resolution_; + int number_of_cores_ = 1; + VideoCodecType codec_type_ = kVideoCodecGeneric; + }; + + virtual ~VideoDecoder() = default; + + // Prepares decoder to handle incoming encoded frames. Can be called multiple + // times, in such case only latest `settings` are in effect. + // TODO(bugs.webrtc.org/13045): Make pure virtual when implemented by all + // derived classes. + virtual bool Configure(const Settings& settings); + + // TODO(bugs.webrtc.org/13045): Delete in favor of the Configure function + // above. virtual int32_t InitDecode(const VideoCodec* codec_settings, - int32_t number_of_cores) = 0; + int32_t number_of_cores); virtual int32_t Decode(const EncodedImage& input_image, bool missing_frames, @@ -74,6 +120,24 @@ class RTC_EXPORT VideoDecoder { virtual const char* ImplementationName() const; }; +inline absl::optional VideoDecoder::Settings::buffer_pool_size() const { + return buffer_pool_size_; +} + +inline void VideoDecoder::Settings::set_buffer_pool_size( + absl::optional value) { + buffer_pool_size_ = value; +} + +inline RenderResolution VideoDecoder::Settings::max_render_resolution() const { + return max_resolution_; +} + +inline void VideoDecoder::Settings::set_max_render_resolution( + RenderResolution value) { + max_resolution_ = value; +} + } // namespace webrtc #endif // API_VIDEO_CODECS_VIDEO_DECODER_H_