[go: nahoru, domu]

blob: 94bafbe34381085c8adbd7baddfc825164092a10 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/mojo/mojom/video_encode_accelerator_mojom_traits.h"
#include <optional>
#include "base/notreached.h"
#include "media/base/video_bitrate_allocation.h"
#include "media/mojo/mojom/video_encode_accelerator.mojom.h"
#include "media/video/video_encode_accelerator.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
namespace mojo {
// static
media::mojom::VideoEncodeAcceleratorSupportedRateControlMode
EnumTraits<media::mojom::VideoEncodeAcceleratorSupportedRateControlMode,
media::VideoEncodeAccelerator::SupportedRateControlMode>::
ToMojom(media::VideoEncodeAccelerator::SupportedRateControlMode mode) {
switch (mode) {
case media::VideoEncodeAccelerator::kNoMode:
return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kNoMode;
case media::VideoEncodeAccelerator::kConstantMode:
return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kConstantMode;
case media::VideoEncodeAccelerator::kVariableMode:
return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kVariableMode;
case media::VideoEncodeAccelerator::kExternalMode:
return media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kExternalMode;
}
NOTREACHED_NORETURN();
}
// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorSupportedRateControlMode,
media::VideoEncodeAccelerator::SupportedRateControlMode>::
FromMojom(media::mojom::VideoEncodeAcceleratorSupportedRateControlMode mode,
media::VideoEncodeAccelerator::SupportedRateControlMode* out) {
switch (mode) {
case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::kNoMode:
*out = media::VideoEncodeAccelerator::kNoMode;
return true;
case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kConstantMode:
*out = media::VideoEncodeAccelerator::kConstantMode;
return true;
case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kVariableMode:
*out = media::VideoEncodeAccelerator::kVariableMode;
return true;
case media::mojom::VideoEncodeAcceleratorSupportedRateControlMode::
kExternalMode:
*out = media::VideoEncodeAccelerator::kExternalMode;
return true;
}
NOTREACHED_NORETURN();
}
// static
bool StructTraits<media::mojom::VideoEncodeAcceleratorSupportedProfileDataView,
media::VideoEncodeAccelerator::SupportedProfile>::
Read(media::mojom::VideoEncodeAcceleratorSupportedProfileDataView data,
media::VideoEncodeAccelerator::SupportedProfile* out) {
if (!data.ReadMinResolution(&out->min_resolution) ||
!data.ReadMaxResolution(&out->max_resolution) ||
!data.ReadProfile(&out->profile)) {
return false;
}
out->max_framerate_numerator = data.max_framerate_numerator();
out->max_framerate_denominator = data.max_framerate_denominator();
out->rate_control_modes = media::VideoEncodeAccelerator::kNoMode;
std::vector<media::VideoEncodeAccelerator::SupportedRateControlMode> modes;
if (!data.ReadRateControlModes(&modes))
return false;
for (const auto& mode : modes) {
out->rate_control_modes |= mode;
}
std::vector<media::SVCScalabilityMode> scalability_modes;
if (!data.ReadScalabilityModes(&scalability_modes))
return false;
out->scalability_modes = std::move(scalability_modes);
out->is_software_codec = data.is_software_codec();
return true;
}
// static
bool StructTraits<media::mojom::VariableBitratePeakDataView, uint32_t>::Read(
media::mojom::VariableBitratePeakDataView data,
uint32_t* out_peak_bps) {
uint32_t peak_bps = data.bps();
if (peak_bps == 0)
return false;
*out_peak_bps = peak_bps;
return true;
}
// static
std::vector<uint32_t> StructTraits<media::mojom::VideoBitrateAllocationDataView,
media::VideoBitrateAllocation>::
bitrates(const media::VideoBitrateAllocation& bitrate_allocation) {
std::vector<uint32_t> bitrates;
uint32_t sum_bps = 0;
for (size_t si = 0; si < media::VideoBitrateAllocation::kMaxSpatialLayers;
++si) {
for (size_t ti = 0; ti < media::VideoBitrateAllocation::kMaxTemporalLayers;
++ti) {
if (sum_bps == bitrate_allocation.GetSumBps()) {
// The rest is all zeros, no need to iterate further.
return bitrates;
}
const uint32_t layer_bitrate = bitrate_allocation.GetBitrateBps(si, ti);
bitrates.emplace_back(layer_bitrate);
sum_bps += layer_bitrate;
}
}
return bitrates;
}
// static
bool StructTraits<media::mojom::VideoBitrateAllocationDataView,
media::VideoBitrateAllocation>::
Read(media::mojom::VideoBitrateAllocationDataView data,
media::VideoBitrateAllocation* out_bitrate_allocation) {
std::optional<uint32_t> peak_bps;
if (!data.ReadVariableBitratePeak(&peak_bps))
return false;
if (peak_bps.has_value()) {
*out_bitrate_allocation =
media::VideoBitrateAllocation(media::Bitrate::Mode::kVariable);
} else {
*out_bitrate_allocation =
media::VideoBitrateAllocation(media::Bitrate::Mode::kConstant);
}
ArrayDataView<uint32_t> bitrates;
data.GetBitratesDataView(&bitrates);
size_t size = bitrates.size();
if (size > media::VideoBitrateAllocation::kMaxSpatialLayers *
media::VideoBitrateAllocation::kMaxTemporalLayers) {
return false;
}
for (size_t i = 0; i < size; ++i) {
const uint32_t bitrate = bitrates[i];
const size_t si = i / media::VideoBitrateAllocation::kMaxTemporalLayers;
const size_t ti = i % media::VideoBitrateAllocation::kMaxTemporalLayers;
if (!out_bitrate_allocation->SetBitrate(si, ti, bitrate)) {
return false;
}
}
if (peak_bps.has_value()) {
if (!out_bitrate_allocation->SetPeakBps(*peak_bps)) {
// Invalid (too low) peak for the sum of the bitrates.
return false;
}
}
return true;
}
// static
bool StructTraits<media::mojom::VideoEncodeOptionsDataView,
media::VideoEncoder::EncodeOptions>::
Read(media::mojom::VideoEncodeOptionsDataView data,
media::VideoEncoder::EncodeOptions* out_options) {
out_options->key_frame = data.force_keyframe();
int32_t quantizer = data.quantizer();
if (quantizer < 0) {
out_options->quantizer.reset();
} else {
out_options->quantizer = data.quantizer();
}
return true;
}
// static
bool UnionTraits<media::mojom::CodecMetadataDataView,
media::BitstreamBufferMetadata>::
Read(media::mojom::CodecMetadataDataView data,
media::BitstreamBufferMetadata* out) {
switch (data.tag()) {
case media::mojom::CodecMetadataDataView::Tag::kH264: {
return data.ReadH264(&out->h264);
}
case media::mojom::CodecMetadataDataView::Tag::kVp8: {
return data.ReadVp8(&out->vp8);
}
case media::mojom::CodecMetadataDataView::Tag::kVp9: {
return data.ReadVp9(&out->vp9);
}
case media::mojom::CodecMetadataDataView::Tag::kAv1: {
return data.ReadAv1(&out->av1);
}
case media::mojom::CodecMetadataDataView::Tag::kH265: {
return data.ReadH265(&out->h265);
}
}
NOTREACHED_NORETURN();
}
// static
bool StructTraits<media::mojom::BitstreamBufferMetadataDataView,
media::BitstreamBufferMetadata>::
Read(media::mojom::BitstreamBufferMetadataDataView data,
media::BitstreamBufferMetadata* metadata) {
metadata->payload_size_bytes = data.payload_size_bytes();
metadata->key_frame = data.key_frame();
if (!data.ReadTimestamp(&metadata->timestamp)) {
return false;
}
metadata->end_of_picture = data.end_of_picture();
metadata->qp = data.qp();
if (!data.ReadEncodedSize(&metadata->encoded_size)) {
return false;
}
if (!data.ReadEncodedColorSpace(&metadata->encoded_color_space)) {
return false;
}
return data.ReadCodecMetadata(metadata);
}
// static
bool StructTraits<media::mojom::H264MetadataDataView, media::H264Metadata>::
Read(media::mojom::H264MetadataDataView data,
media::H264Metadata* out_metadata) {
out_metadata->temporal_idx = data.temporal_idx();
out_metadata->layer_sync = data.layer_sync();
return true;
}
// static
bool StructTraits<media::mojom::H265MetadataDataView, media::H265Metadata>::
Read(media::mojom::H265MetadataDataView data,
media::H265Metadata* out_metadata) {
out_metadata->temporal_idx = data.temporal_idx();
return true;
}
// static
bool StructTraits<media::mojom::Vp8MetadataDataView, media::Vp8Metadata>::Read(
media::mojom::Vp8MetadataDataView data,
media::Vp8Metadata* out_metadata) {
out_metadata->non_reference = data.non_reference();
out_metadata->temporal_idx = data.temporal_idx();
out_metadata->layer_sync = data.layer_sync();
return true;
}
// static
bool StructTraits<media::mojom::Vp9MetadataDataView, media::Vp9Metadata>::Read(
media::mojom::Vp9MetadataDataView data,
media::Vp9Metadata* out_metadata) {
out_metadata->inter_pic_predicted = data.inter_pic_predicted();
out_metadata->temporal_up_switch = data.temporal_up_switch();
out_metadata->referenced_by_upper_spatial_layers =
data.referenced_by_upper_spatial_layers();
out_metadata->reference_lower_spatial_layers =
data.reference_lower_spatial_layers();
out_metadata->temporal_idx = data.temporal_idx();
out_metadata->spatial_idx = data.spatial_idx();
out_metadata->begin_active_spatial_layer_index =
data.begin_active_spatial_layer_index();
out_metadata->end_active_spatial_layer_index =
data.end_active_spatial_layer_index();
return data.ReadSpatialLayerResolutions(
&out_metadata->spatial_layer_resolutions) &&
data.ReadPDiffs(&out_metadata->p_diffs);
}
// static
bool StructTraits<media::mojom::Av1MetadataDataView, media::Av1Metadata>::Read(
media::mojom::Av1MetadataDataView data,
media::Av1Metadata* out_metadata) {
out_metadata->temporal_idx = data.temporal_idx();
return true;
}
// static
media::mojom::VideoEncodeAcceleratorConfig_StorageType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_StorageType,
media::VideoEncodeAccelerator::Config::StorageType>::
ToMojom(media::VideoEncodeAccelerator::Config::StorageType input) {
switch (input) {
case media::VideoEncodeAccelerator::Config::StorageType::kGpuMemoryBuffer:
return media::mojom::VideoEncodeAcceleratorConfig_StorageType::
kGpuMemoryBuffer;
case media::VideoEncodeAccelerator::Config::StorageType::kShmem:
return media::mojom::VideoEncodeAcceleratorConfig_StorageType::kShmem;
}
NOTREACHED_NORETURN();
}
// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_StorageType,
media::VideoEncodeAccelerator::Config::StorageType>::
FromMojom(media::mojom::VideoEncodeAcceleratorConfig_StorageType input,
media::VideoEncodeAccelerator::Config::StorageType* output) {
switch (input) {
case media::mojom::VideoEncodeAcceleratorConfig_StorageType::kShmem:
*output = media::VideoEncodeAccelerator::Config::StorageType::kShmem;
return true;
case media::mojom::VideoEncodeAcceleratorConfig_StorageType::
kGpuMemoryBuffer:
*output =
media::VideoEncodeAccelerator::Config::StorageType::kGpuMemoryBuffer;
return true;
}
NOTREACHED_NORETURN();
}
// static
media::mojom::VideoEncodeAcceleratorConfig_EncoderType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_EncoderType,
media::VideoEncodeAccelerator::Config::EncoderType>::
ToMojom(media::VideoEncodeAccelerator::Config::EncoderType input) {
switch (input) {
case media::VideoEncodeAccelerator::Config::EncoderType::kHardware:
return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kHardware;
case media::VideoEncodeAccelerator::Config::EncoderType::kSoftware:
return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kSoftware;
case media::VideoEncodeAccelerator::Config::EncoderType::kNoPreference:
return media::mojom::VideoEncodeAcceleratorConfig_EncoderType::
kNoPreference;
}
NOTREACHED_NORETURN();
}
// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_EncoderType,
media::VideoEncodeAccelerator::Config::EncoderType>::
FromMojom(media::mojom::VideoEncodeAcceleratorConfig_EncoderType input,
media::VideoEncodeAccelerator::Config::EncoderType* output) {
switch (input) {
case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kHardware:
*output = media::VideoEncodeAccelerator::Config::EncoderType::kHardware;
return true;
case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kSoftware:
*output = media::VideoEncodeAccelerator::Config::EncoderType::kSoftware;
return true;
case media::mojom::VideoEncodeAcceleratorConfig_EncoderType::kNoPreference:
*output =
media::VideoEncodeAccelerator::Config::EncoderType::kNoPreference;
return true;
}
NOTREACHED_NORETURN();
}
// static
media::mojom::VideoEncodeAcceleratorConfig_ContentType
EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_ContentType,
media::VideoEncodeAccelerator::Config::ContentType>::
ToMojom(media::VideoEncodeAccelerator::Config::ContentType input) {
switch (input) {
case media::VideoEncodeAccelerator::Config::ContentType::kDisplay:
return media::mojom::VideoEncodeAcceleratorConfig_ContentType::kDisplay;
case media::VideoEncodeAccelerator::Config::ContentType::kCamera:
return media::mojom::VideoEncodeAcceleratorConfig_ContentType::kCamera;
}
NOTREACHED_NORETURN();
}
// static
bool EnumTraits<media::mojom::VideoEncodeAcceleratorConfig_ContentType,
media::VideoEncodeAccelerator::Config::ContentType>::
FromMojom(media::mojom::VideoEncodeAcceleratorConfig_ContentType input,
media::VideoEncodeAccelerator::Config::ContentType* output) {
switch (input) {
case media::mojom::VideoEncodeAcceleratorConfig_ContentType::kCamera:
*output = media::VideoEncodeAccelerator::Config::ContentType::kCamera;
return true;
case media::mojom::VideoEncodeAcceleratorConfig_ContentType::kDisplay:
*output = media::VideoEncodeAccelerator::Config::ContentType::kDisplay;
return true;
}
NOTREACHED_NORETURN();
}
// static
bool StructTraits<media::mojom::SpatialLayerDataView,
media::VideoEncodeAccelerator::Config::SpatialLayer>::
Read(media::mojom::SpatialLayerDataView input,
media::VideoEncodeAccelerator::Config::SpatialLayer* output) {
output->width = input.width();
output->height = input.height();
output->bitrate_bps = input.bitrate_bps();
output->framerate = input.framerate();
output->max_qp = input.max_qp();
output->num_of_temporal_layers = input.num_of_temporal_layers();
return true;
}
// static
bool StructTraits<media::mojom::ConstantBitrateDataView, media::Bitrate>::Read(
media::mojom::ConstantBitrateDataView input,
media::Bitrate* output) {
*output = media::Bitrate::ConstantBitrate(input.target_bps());
return true;
}
// static
bool StructTraits<media::mojom::VariableBitrateDataView, media::Bitrate>::Read(
media::mojom::VariableBitrateDataView input,
media::Bitrate* output) {
if (input.target_bps() > input.peak_bps())
return false;
if (input.peak_bps() == 0u)
return false;
*output =
media::Bitrate::VariableBitrate(input.target_bps(), input.peak_bps());
return true;
}
// static
bool StructTraits<media::mojom::ExternalBitrateDataView, media::Bitrate>::Read(
media::mojom::ExternalBitrateDataView input,
media::Bitrate* output) {
*output = media::Bitrate::ExternalRateControl();
return true;
}
// static
media::mojom::BitrateDataView::Tag
UnionTraits<media::mojom::BitrateDataView, media::Bitrate>::GetTag(
const media::Bitrate& input) {
switch (input.mode()) {
case media::Bitrate::Mode::kConstant:
return media::mojom::BitrateDataView::Tag::kConstant;
case media::Bitrate::Mode::kVariable:
return media::mojom::BitrateDataView::Tag::kVariable;
case media::Bitrate::Mode::kExternal:
return media::mojom::BitrateDataView::Tag::kExternal;
}
NOTREACHED_NORETURN();
}
// static
bool UnionTraits<media::mojom::BitrateDataView, media::Bitrate>::Read(
media::mojom::BitrateDataView input,
media::Bitrate* output) {
switch (input.tag()) {
case media::mojom::BitrateDataView::Tag::kConstant:
return input.ReadConstant(output);
case media::mojom::BitrateDataView::Tag::kVariable:
return input.ReadVariable(output);
case media::mojom::BitrateDataView::Tag::kExternal:
return input.ReadExternal(output);
}
NOTREACHED_NORETURN();
}
// static
bool StructTraits<media::mojom::VideoEncodeAcceleratorConfigDataView,
media::VideoEncodeAccelerator::Config>::
Read(media::mojom::VideoEncodeAcceleratorConfigDataView input,
media::VideoEncodeAccelerator::Config* output) {
media::VideoPixelFormat input_format;
if (!input.ReadInputFormat(&input_format))
return false;
gfx::Size input_visible_size;
if (!input.ReadInputVisibleSize(&input_visible_size))
return false;
media::VideoCodecProfile output_profile;
if (!input.ReadOutputProfile(&output_profile))
return false;
media::Bitrate bitrate;
if (!input.ReadBitrate(&bitrate))
return false;
std::optional<uint32_t> initial_framerate;
if (input.has_initial_framerate())
initial_framerate = input.initial_framerate();
std::optional<uint32_t> gop_length;
if (input.has_gop_length())
gop_length = input.gop_length();
std::optional<uint8_t> h264_output_level;
if (input.has_h264_output_level())
h264_output_level = input.h264_output_level();
bool is_constrained_h264 = input.is_constrained_h264();
std::optional<media::VideoEncodeAccelerator::Config::StorageType>
storage_type;
if (input.has_storage_type()) {
if (!input.ReadStorageType(&storage_type))
return false;
}
media::VideoEncodeAccelerator::Config::ContentType content_type;
if (!input.ReadContentType(&content_type))
return false;
uint8_t drop_frame_thresh_percentage = input.drop_frame_thresh_percentage();
if (drop_frame_thresh_percentage > 100) {
return false;
}
std::vector<media::VideoEncodeAccelerator::Config::SpatialLayer>
spatial_layers;
if (!input.ReadSpatialLayers(&spatial_layers))
return false;
media::SVCInterLayerPredMode inter_layer_pred;
if (!input.ReadInterLayerPred(&inter_layer_pred))
return false;
media::VideoEncodeAccelerator::Config::EncoderType required_encoder_type;
if (!input.ReadRequiredEncoderType(&required_encoder_type))
return false;
struct CheckVEAConfig {
// The variable declaration order must be the same as
// VideoEncodeAccelerator::Config.
media::VideoPixelFormat input_format;
gfx::Size input_visible_size;
media::VideoCodecProfile output_profile;
media::Bitrate bitrate;
std::optional<uint32_t> initial_framerate;
std::optional<uint32_t> gop_length;
std::optional<uint8_t> h264_output_level;
bool is_constrained_h264;
std::optional<media::VideoEncodeAccelerator::Config::StorageType>
storage_type;
media::VideoEncodeAccelerator::Config::ContentType content_type;
uint8_t drop_frame_thresh_percentage;
std::vector<media::VideoEncodeAccelerator::Config::SpatialLayer>
spatial_layers;
media::SVCInterLayerPredMode inter_layer_pred;
bool require_low_delay = true;
media::VideoEncodeAccelerator::Config::EncoderType required_encoder_type;
};
static_assert(
sizeof(CheckVEAConfig) == sizeof(media::VideoEncodeAccelerator::Config),
"Please apply removed/added values in VideoEncodeAccelerator::Config "
"to the following copy and then remove/add the values in CheckVEAConfig");
*output = media::VideoEncodeAccelerator::Config(
input_format, input_visible_size, output_profile, bitrate);
output->initial_framerate = initial_framerate;
output->gop_length = gop_length;
output->h264_output_level = h264_output_level;
output->is_constrained_h264 = is_constrained_h264;
output->storage_type = storage_type;
output->content_type = content_type;
output->drop_frame_thresh_percentage = drop_frame_thresh_percentage;
output->spatial_layers = spatial_layers;
output->inter_layer_pred = inter_layer_pred;
output->require_low_delay = input.require_low_delay();
output->required_encoder_type = required_encoder_type;
return true;
}
} // namespace mojo