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") {
"video_decode_accelerator.h",
"video_encode_accelerator.cc",
"video_encode_accelerator.h",
"video_encoder_info.cc",
"video_encoder_info.h",
]
if (proprietary_codecs && enable_platform_hevc) {
......
......@@ -80,6 +80,11 @@ std::string VideoEncodeAccelerator::Config::AsHumanReadableString() const {
return str;
}
void VideoEncodeAccelerator::Client::NotifyEncoderInfoChange(
const VideoEncoderInfo& info) {
// Do nothing if a client doesn't use the info.
}
VideoEncodeAccelerator::~VideoEncodeAccelerator() = default;
VideoEncodeAccelerator::SupportedProfile::SupportedProfile()
......
......@@ -22,6 +22,7 @@
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/video/h264_parser.h"
#include "media/video/video_encoder_info.h"
namespace media {
......@@ -209,6 +210,9 @@ class MEDIA_EXPORT VideoEncodeAccelerator {
// there.
virtual void NotifyError(Error error) = 0;
// Call VideoEncoderInfo of the VEA is changed.
virtual void NotifyEncoderInfoChange(const VideoEncoderInfo& info);
protected:
// Clients are not owned by VEA instances and should not be deleted through
// 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 @@
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
......@@ -61,6 +62,38 @@ namespace blink {
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 {
RTCTimestamps(const base::TimeDelta& media_timestamp,
int32_t rtp_timestamp,
......@@ -156,6 +189,9 @@ class RTCVideoEncoder::Impl
media::VideoCodecProfile profile,
base::WaitableEvent* async_waiter,
int32_t* async_retval);
webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const;
// Enqueue a frame from WebRTC for encoding.
// RTCVideoEncoder expects to be able to call this function synchronously from
// its own thread, hence the |async_waiter| and |async_retval| arguments.
......@@ -196,6 +232,7 @@ class RTCVideoEncoder::Impl
int32_t bitstream_buffer_id,
const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
void NotifyEncoderInfoChange(const media::VideoEncoderInfo& info) override;
private:
friend class base::RefCountedThreadSafe<Impl>;
......@@ -319,15 +356,18 @@ class RTCVideoEncoder::Impl
// The content type, as reported to WebRTC (screenshare vs realtime video).
const webrtc::VideoContentType video_content_type_;
// Protect |status_|. |status_| is read or written on |gpu_task_runner_| in
// Impl. It can be read in RTCVideoEncoder on other threads.
mutable base::Lock status_lock_;
webrtc::VideoEncoder::EncoderInfo encoder_info_ GUARDED_BY(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
// 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
// interface entry point is called. This is protected by |status_lock_|.
int32_t status_;
// interface entry point is called. This is protected by |lock_|.
int32_t status_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(Impl);
};
......@@ -348,6 +388,13 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
video_content_type_(video_content_type),
status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
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(
......@@ -424,6 +471,18 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
// 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,
bool force_keyframe,
base::WaitableEvent* async_waiter,
......@@ -542,12 +601,12 @@ void RTCVideoEncoder::Impl::Destroy(base::WaitableEvent* async_waiter) {
}
int32_t RTCVideoEncoder::Impl::GetStatus() const {
base::AutoLock lock(status_lock_);
base::AutoLock lock(lock_);
return status_;
}
void RTCVideoEncoder::Impl::SetStatus(int32_t status) {
base::AutoLock lock(status_lock_);
base::AutoLock lock(lock_);
status_ = status;
}
......@@ -1223,11 +1282,10 @@ void RTCVideoEncoder::SetRates(
}
webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::GetEncoderInfo() const {
EncoderInfo info;
info.implementation_name = RTCVideoEncoder::Impl::ImplementationName();
info.supports_native_handle = true;
info.is_hardware_accelerated = true;
info.has_internal_source = false;
webrtc::VideoEncoder::EncoderInfo info;
if (impl_)
info = impl_->GetEncoderInfo();
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