blob: b28a2239029abd2343593cd145d7ac25c6aace49 [file] [log] [blame]
// Copyright (c) 2012 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/base/video_decoder_config.h"
#include <iomanip>
#include <vector>
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/limits.h"
#include "media/base/media_util.h"
#include "media/base/video_types.h"
#include "media/base/video_util.h"
namespace media {
static bool IsValidSize(const gfx::Size& size) {
const int area = size.GetCheckedArea().ValueOrDefault(INT_MAX);
return area && area <= limits::kMaxCanvas &&
size.width() <= limits::kMaxDimension &&
size.height() <= limits::kMaxDimension;
}
VideoDecoderConfig::VideoDecoderConfig() = default;
VideoDecoderConfig::VideoDecoderConfig(VideoCodec codec,
VideoCodecProfile profile,
AlphaMode alpha_mode,
const VideoColorSpace& color_space,
VideoTransformation rotation,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
const std::vector<uint8_t>& extra_data,
EncryptionScheme encryption_scheme) {
Initialize(codec, profile, alpha_mode, color_space, rotation, coded_size,
visible_rect, natural_size, extra_data, encryption_scheme);
}
VideoDecoderConfig::VideoDecoderConfig(const VideoDecoderConfig& other) =
default;
VideoDecoderConfig::~VideoDecoderConfig() = default;
void VideoDecoderConfig::Initialize(VideoCodec codec,
VideoCodecProfile profile,
AlphaMode alpha_mode,
const VideoColorSpace& color_space,
VideoTransformation transformation,
const gfx::Size& coded_size,
const gfx::Rect& visible_rect,
const gfx::Size& natural_size,
const std::vector<uint8_t>& extra_data,
EncryptionScheme encryption_scheme) {
codec_ = codec;
profile_ = profile;
alpha_mode_ = alpha_mode;
transformation_ = transformation;
coded_size_ = coded_size;
visible_rect_ = visible_rect;
natural_size_ = natural_size;
aspect_ratio_ = VideoAspectRatio(visible_rect, natural_size);
extra_data_ = extra_data;
encryption_scheme_ = encryption_scheme;
color_space_info_ = color_space;
}
bool VideoDecoderConfig::IsValidConfig() const {
return codec_ != VideoCodec::kUnknown && IsValidSize(coded_size_) &&
IsValidSize(natural_size_) &&
gfx::Rect(coded_size_).Contains(visible_rect_);
}
bool VideoDecoderConfig::Matches(const VideoDecoderConfig& config) const {
return codec() == config.codec() && profile() == config.profile() &&
alpha_mode() == config.alpha_mode() &&
video_transformation() == config.video_transformation() &&
coded_size() == config.coded_size() &&
visible_rect() == config.visible_rect() &&
natural_size() == config.natural_size() &&
extra_data() == config.extra_data() &&
encryption_scheme() == config.encryption_scheme() &&
color_space_info() == config.color_space_info() &&
hdr_metadata() == config.hdr_metadata() && level() == config.level();
}
std::string VideoDecoderConfig::AsHumanReadableString() const {
std::ostringstream s;
s << "codec: " << GetCodecName(codec())
<< ", profile: " << GetProfileName(profile()) << ", level: "
<< (level() > kNoVideoCodecLevel ? base::NumberToString(level())
: "not available")
<< ", alpha_mode: "
<< (alpha_mode() == AlphaMode::kHasAlpha ? "has_alpha" : "is_opaque")
<< ", coded size: [" << coded_size().width() << "," << coded_size().height()
<< "]"
<< ", visible rect: [" << visible_rect().x() << "," << visible_rect().y()
<< "," << visible_rect().width() << "," << visible_rect().height() << "]"
<< ", natural size: [" << natural_size().width() << ","
<< natural_size().height() << "]"
<< ", has extra data: " << (extra_data().empty() ? "false" : "true")
<< ", encryption scheme: " << encryption_scheme()
<< ", rotation: " << VideoRotationToString(video_transformation().rotation)
<< ", flipped: " << video_transformation().mirrored
<< ", color space: " << color_space_info().ToGfxColorSpace().ToString();
if (hdr_metadata().has_value()) {
s << std::setprecision(4) << ", luminance range: "
<< hdr_metadata()->color_volume_metadata.luminance_min << "-"
<< hdr_metadata()->color_volume_metadata.luminance_max
<< ", primaries: r("
<< hdr_metadata()->color_volume_metadata.primary_r.x() << ","
<< hdr_metadata()->color_volume_metadata.primary_r.y() << ") g("
<< hdr_metadata()->color_volume_metadata.primary_g.x() << ","
<< hdr_metadata()->color_volume_metadata.primary_g.y() << ") b("
<< hdr_metadata()->color_volume_metadata.primary_b.x() << ","
<< hdr_metadata()->color_volume_metadata.primary_b.y() << ") wp("
<< hdr_metadata()->color_volume_metadata.white_point.x() << ","
<< hdr_metadata()->color_volume_metadata.white_point.y()
<< "), max_content_light_level="
<< hdr_metadata()->max_content_light_level
<< ", max_frame_average_light_level="
<< hdr_metadata()->max_frame_average_light_level;
}
return s.str();
}
std::string VideoDecoderConfig::GetHumanReadableCodecName() const {
return GetCodecName(codec());
}
void VideoDecoderConfig::SetExtraData(const std::vector<uint8_t>& extra_data) {
extra_data_ = extra_data;
}
void VideoDecoderConfig::SetIsEncrypted(bool is_encrypted) {
if (!is_encrypted) {
DCHECK_NE(encryption_scheme_, EncryptionScheme::kUnencrypted)
<< "Config is already clear.";
encryption_scheme_ = EncryptionScheme::kUnencrypted;
} else {
DCHECK_EQ(encryption_scheme_, EncryptionScheme::kUnencrypted)
<< "Config is already encrypted.";
// TODO(xhwang): This is only used to guide decoder selection, so set
// a common encryption scheme that should be supported by all decrypting
// decoders. We should be able to remove this when we support switching
// decoders at run time. See http://crbug.com/695595
encryption_scheme_ = EncryptionScheme::kCenc;
}
}
} // namespace media