Commit 9e40822e authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media: Introduce VideoEncoderInfo

libwebrtc can know the information about encoders that are not
contained in the library, by webrtc::EncoderInfo. In the current
chrome implementation, the structure stops in RtcVideoEncoder and
thus the filled information doesn't respect the hw encoders.

This Cl introduces VideoEncoderInfo. It is similar to
webrtc::EncoderInfo. The information is filled in and dealt with
the structure in chrome code.

Bug: 1031965
Test: webrtc.DecoderPerf.h264_hw
Test: webrtc.PeerConnection*
Change-Id: I5305d69be7ff8b7406be6493125f535cd5473ab6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1972742Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726644}
parent 4e6993f0
...@@ -39,6 +39,8 @@ source_set("video") { ...@@ -39,6 +39,8 @@ source_set("video") {
"video_decode_accelerator.h", "video_decode_accelerator.h",
"video_encode_accelerator.cc", "video_encode_accelerator.cc",
"video_encode_accelerator.h", "video_encode_accelerator.h",
"video_encoder_info.cc",
"video_encoder_info.h",
] ]
if (proprietary_codecs && enable_platform_hevc) { if (proprietary_codecs && enable_platform_hevc) {
......
...@@ -80,6 +80,11 @@ std::string VideoEncodeAccelerator::Config::AsHumanReadableString() const { ...@@ -80,6 +80,11 @@ std::string VideoEncodeAccelerator::Config::AsHumanReadableString() const {
return str; return str;
} }
void VideoEncodeAccelerator::Client::NotifyEncoderInfoChange(
const VideoEncoderInfo& info) {
// Do nothing if a client doesn't use the info.
}
VideoEncodeAccelerator::~VideoEncodeAccelerator() = default; VideoEncodeAccelerator::~VideoEncodeAccelerator() = default;
VideoEncodeAccelerator::SupportedProfile::SupportedProfile() VideoEncodeAccelerator::SupportedProfile::SupportedProfile()
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/video/h264_parser.h" #include "media/video/h264_parser.h"
#include "media/video/video_encoder_info.h"
namespace media { namespace media {
...@@ -209,6 +210,9 @@ class MEDIA_EXPORT VideoEncodeAccelerator { ...@@ -209,6 +210,9 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
// there. // there.
virtual void NotifyError(Error error) = 0; virtual void NotifyError(Error error) = 0;
// Call VideoEncoderInfo of the VEA is changed.
virtual void NotifyEncoderInfoChange(const VideoEncoderInfo& info);
protected: protected:
// Clients are not owned by VEA instances and should not be deleted through // Clients are not owned by VEA instances and should not be deleted through
// these pointers. // these pointers.
......
// Copyright 2013 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 "media/video/video_encoder_info.h"
namespace media {
ScalingSettings::ScalingSettings() = default;
ScalingSettings::ScalingSettings(int min_qp, int max_qp)
: min_qp(min_qp), max_qp(max_qp) {}
ScalingSettings::~ScalingSettings() = default;
ResolutionBitrateLimit::ResolutionBitrateLimit() = default;
ResolutionBitrateLimit::ResolutionBitrateLimit(const ResolutionBitrateLimit&) =
default;
ResolutionBitrateLimit::ResolutionBitrateLimit(const gfx::Size& frame_size,
int min_start_bitrate_bps,
int min_bitrate_bps,
int max_bitrate_bps)
: frame_size(frame_size),
min_start_bitrate_bps(min_start_bitrate_bps),
min_bitrate_bps(min_bitrate_bps),
max_bitrate_bps(max_bitrate_bps) {}
ResolutionBitrateLimit::~ResolutionBitrateLimit() = default;
VideoEncoderInfo::VideoEncoderInfo() = default;
VideoEncoderInfo::VideoEncoderInfo(const VideoEncoderInfo&) = default;
VideoEncoderInfo::~VideoEncoderInfo() = default;
} // namespace media
// Copyright 2019 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_VIDEO_VIDEO_ENCODER_INFO_H_
#define MEDIA_VIDEO_VIDEO_ENCODER_INFO_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "media/base/media_export.h"
#include "ui/gfx/geometry/size.h"
namespace media {
// These chromium classes are the corresponding classes in webrtc project.
// See third_party/webrtc/api/video_codecs/video_encoder.h for the detail.
struct MEDIA_EXPORT ScalingSettings {
ScalingSettings();
ScalingSettings(int min_qp, int max_qp);
~ScalingSettings();
int min_qp = 4;
int max_qp = 157;
};
struct MEDIA_EXPORT ResolutionBitrateLimit {
ResolutionBitrateLimit();
ResolutionBitrateLimit(const ResolutionBitrateLimit&);
ResolutionBitrateLimit(const gfx::Size& frame_size,
int min_start_bitrate_bps,
int min_bitrate_bps,
int max_bitrate_bps);
~ResolutionBitrateLimit();
gfx::Size frame_size;
int min_start_bitrate_bps = 0;
int min_bitrate_bps = 0;
int max_bitrate_bps = 0;
};
struct MEDIA_EXPORT VideoEncoderInfo {
static constexpr size_t kMaxSpatialLayers = 5;
VideoEncoderInfo();
VideoEncoderInfo(const VideoEncoderInfo&);
~VideoEncoderInfo();
std::string implementation_name;
bool supports_native_handle = true;
bool has_trusted_rate_controller = false;
bool is_hardware_accelerated = true;
bool supports_simulcast = false;
ScalingSettings scaling_settings;
std::vector<uint8_t> fps_allocation[kMaxSpatialLayers];
std::vector<ResolutionBitrateLimit> resolution_bitrate_limits;
};
} // namespace media
#endif // MEDIA_VIDEO_VIDEO_ENCODER_INFO_H_
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -61,6 +62,38 @@ namespace blink { ...@@ -61,6 +62,38 @@ namespace blink {
namespace { namespace {
webrtc::VideoEncoder::EncoderInfo CopyToWebrtcEncoderInfo(
const media::VideoEncoderInfo& enc_info) {
webrtc::VideoEncoder::EncoderInfo info;
info.implementation_name = enc_info.implementation_name;
info.supports_native_handle = enc_info.supports_native_handle;
info.has_trusted_rate_controller = enc_info.has_trusted_rate_controller;
info.is_hardware_accelerated = enc_info.is_hardware_accelerated;
info.supports_simulcast = enc_info.supports_simulcast;
// TODO(crbug.com/1034686): Copy ScalingSettings once getStats() hang issue
// is resolved.
// info.scaling_settings = webrtc::VideoEncoder::ScalingSettings(
// enc_info.scaling_settings.min_qp, enc_info.scaling_settings.max_qp);
static_assert(
webrtc::kMaxSpatialLayers >= media::VideoEncoderInfo::kMaxSpatialLayers,
"webrtc::kMaxSpatiallayers is less than "
"media::VideoEncoderInfo::kMaxSpatialLayers");
for (size_t i = 0; i < base::size(enc_info.fps_allocation); ++i) {
if (enc_info.fps_allocation[i].empty())
continue;
info.fps_allocation[i] =
absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>(
enc_info.fps_allocation[i].begin(),
enc_info.fps_allocation[i].end());
}
for (const auto& limit : enc_info.resolution_bitrate_limits) {
info.resolution_bitrate_limits.emplace_back(
limit.frame_size.GetArea(), limit.min_start_bitrate_bps,
limit.min_bitrate_bps, limit.max_bitrate_bps);
}
return info;
}
struct RTCTimestamps { struct RTCTimestamps {
RTCTimestamps(const base::TimeDelta& media_timestamp, RTCTimestamps(const base::TimeDelta& media_timestamp,
int32_t rtp_timestamp, int32_t rtp_timestamp,
...@@ -156,6 +189,9 @@ class RTCVideoEncoder::Impl ...@@ -156,6 +189,9 @@ class RTCVideoEncoder::Impl
media::VideoCodecProfile profile, media::VideoCodecProfile profile,
base::WaitableEvent* async_waiter, base::WaitableEvent* async_waiter,
int32_t* async_retval); int32_t* async_retval);
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const;
// Enqueue a frame from WebRTC for encoding. // Enqueue a frame from WebRTC for encoding.
// RTCVideoEncoder expects to be able to call this function synchronously from // RTCVideoEncoder expects to be able to call this function synchronously from
// its own thread, hence the |async_waiter| and |async_retval| arguments. // its own thread, hence the |async_waiter| and |async_retval| arguments.
...@@ -196,6 +232,7 @@ class RTCVideoEncoder::Impl ...@@ -196,6 +232,7 @@ class RTCVideoEncoder::Impl
int32_t bitstream_buffer_id, int32_t bitstream_buffer_id,
const media::BitstreamBufferMetadata& metadata) override; const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override; void NotifyError(media::VideoEncodeAccelerator::Error error) override;
void NotifyEncoderInfoChange(const media::VideoEncoderInfo& info) override;
private: private:
friend class base::RefCountedThreadSafe<Impl>; friend class base::RefCountedThreadSafe<Impl>;
...@@ -319,15 +356,18 @@ class RTCVideoEncoder::Impl ...@@ -319,15 +356,18 @@ class RTCVideoEncoder::Impl
// The content type, as reported to WebRTC (screenshare vs realtime video). // The content type, as reported to WebRTC (screenshare vs realtime video).
const webrtc::VideoContentType video_content_type_; const webrtc::VideoContentType video_content_type_;
// Protect |status_|. |status_| is read or written on |gpu_task_runner_| in webrtc::VideoEncoder::EncoderInfo encoder_info_ GUARDED_BY(lock_);
// Impl. It can be read in RTCVideoEncoder on other threads.
mutable base::Lock status_lock_; // Protect |status_| and |encoder_info_|. |status_| is read or written on
// |gpu_task_runner_| in Impl. It can be read in RTCVideoEncoder on other
// threads.
mutable base::Lock lock_;
// We cannot immediately return error conditions to the WebRTC user of this // We cannot immediately return error conditions to the WebRTC user of this
// class, as there is no error callback in the webrtc::VideoEncoder interface. // class, as there is no error callback in the webrtc::VideoEncoder interface.
// Instead, we cache an error status here and return it the next time an // Instead, we cache an error status here and return it the next time an
// interface entry point is called. This is protected by |status_lock_|. // interface entry point is called. This is protected by |lock_|.
int32_t status_; int32_t status_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(Impl); DISALLOW_COPY_AND_ASSIGN(Impl);
}; };
...@@ -348,6 +388,13 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories, ...@@ -348,6 +388,13 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
video_content_type_(video_content_type), video_content_type_(video_content_type),
status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) { status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
DETACH_FROM_THREAD(thread_checker_); DETACH_FROM_THREAD(thread_checker_);
// The default values of EncoderInfo.
encoder_info_.implementation_name =
RTCVideoEncoder::Impl::ImplementationName();
encoder_info_.supports_native_handle = true;
encoder_info_.is_hardware_accelerated = true;
encoder_info_.has_internal_source = false;
} }
void RTCVideoEncoder::Impl::CreateAndInitializeVEA( void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
...@@ -424,6 +471,18 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA( ...@@ -424,6 +471,18 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
// be signaled. // be signaled.
} }
webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::Impl::GetEncoderInfo()
const {
base::AutoLock lock(lock_);
return encoder_info_;
}
void RTCVideoEncoder::Impl::NotifyEncoderInfoChange(
const media::VideoEncoderInfo& info) {
base::AutoLock lock(lock_);
encoder_info_ = CopyToWebrtcEncoderInfo(info);
}
void RTCVideoEncoder::Impl::Enqueue(const webrtc::VideoFrame* input_frame, void RTCVideoEncoder::Impl::Enqueue(const webrtc::VideoFrame* input_frame,
bool force_keyframe, bool force_keyframe,
base::WaitableEvent* async_waiter, base::WaitableEvent* async_waiter,
...@@ -542,12 +601,12 @@ void RTCVideoEncoder::Impl::Destroy(base::WaitableEvent* async_waiter) { ...@@ -542,12 +601,12 @@ void RTCVideoEncoder::Impl::Destroy(base::WaitableEvent* async_waiter) {
} }
int32_t RTCVideoEncoder::Impl::GetStatus() const { int32_t RTCVideoEncoder::Impl::GetStatus() const {
base::AutoLock lock(status_lock_); base::AutoLock lock(lock_);
return status_; return status_;
} }
void RTCVideoEncoder::Impl::SetStatus(int32_t status) { void RTCVideoEncoder::Impl::SetStatus(int32_t status) {
base::AutoLock lock(status_lock_); base::AutoLock lock(lock_);
status_ = status; status_ = status;
} }
...@@ -1223,11 +1282,10 @@ void RTCVideoEncoder::SetRates( ...@@ -1223,11 +1282,10 @@ void RTCVideoEncoder::SetRates(
} }
webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::GetEncoderInfo() const { webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::GetEncoderInfo() const {
EncoderInfo info; webrtc::VideoEncoder::EncoderInfo info;
info.implementation_name = RTCVideoEncoder::Impl::ImplementationName(); if (impl_)
info.supports_native_handle = true; info = impl_->GetEncoderInfo();
info.is_hardware_accelerated = true;
info.has_internal_source = false;
return info; return info;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment