blob: 9db0f854eab8863c17f9d77f5ee8b7d8b832fa13 [file] [log] [blame]
// Copyright 2014 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/mojo/common/media_type_converters.h"
#include <stddef.h>
#include <stdint.h>
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/buffering_state.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_key_information.h"
#include "media/base/decode_status.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/decryptor.h"
#include "media/base/demuxer_stream.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_keys.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
#include "media/mojo/interfaces/demuxer_stream.mojom.h"
#include "mojo/public/cpp/system/buffer.h"
namespace mojo {
#define ASSERT_ENUM_EQ(media_enum, media_prefix, mojo_prefix, value) \
static_assert(media::media_prefix##value == \
static_cast<media::media_enum>( \
media::mojom::media_enum::mojo_prefix##value), \
"Mismatched enum: " #media_prefix #value " != " #media_enum \
"::" #mojo_prefix #value)
#define ASSERT_ENUM_EQ_RAW(media_enum, media_enum_value, mojo_enum_value) \
static_assert(media::media_enum_value == static_cast<media::media_enum>( \
media::mojom::mojo_enum_value), \
"Mismatched enum: " #media_enum_value " != " #mojo_enum_value)
#define ASSERT_ENUM_CLASS_EQ(media_enum, value) \
static_assert( \
media::media_enum::value == \
static_cast<media::media_enum>(media::mojom::media_enum::value), \
"Mismatched enum: " #media_enum #value)
// BufferingState.
ASSERT_ENUM_EQ(BufferingState, BUFFERING_, , HAVE_NOTHING);
ASSERT_ENUM_EQ(BufferingState, BUFFERING_, , HAVE_ENOUGH);
// DecodeStatus.
ASSERT_ENUM_CLASS_EQ(DecodeStatus, OK);
ASSERT_ENUM_CLASS_EQ(DecodeStatus, ABORTED);
ASSERT_ENUM_CLASS_EQ(DecodeStatus, DECODE_ERROR);
// AudioCodec.
ASSERT_ENUM_EQ_RAW(AudioCodec, kUnknownAudioCodec, AudioCodec::UNKNOWN);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , AAC);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , MP3);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , PCM);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , Vorbis);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , FLAC);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , AMR_NB);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , PCM_MULAW);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , GSM_MS);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , PCM_S16BE);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , PCM_S24BE);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , Opus);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , EAC3);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , PCM_ALAW);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , ALAC);
ASSERT_ENUM_EQ(AudioCodec, kCodec, , AC3);
ASSERT_ENUM_EQ_RAW(AudioCodec, kAudioCodecMax, AudioCodec::MAX);
// ChannelLayout.
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _NONE);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _UNSUPPORTED);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _MONO);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _STEREO);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _2_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _SURROUND);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _4_0);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _2_2);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _QUAD);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _5_0);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _5_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _5_0_BACK);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _5_1_BACK);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _7_0);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _7_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _7_1_WIDE);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _STEREO_DOWNMIX);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _2POINT1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _3_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _4_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _6_0);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _6_0_FRONT);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _HEXAGONAL);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _6_1);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _6_1_BACK);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _6_1_FRONT);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _7_0_FRONT);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _7_1_WIDE_BACK);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _OCTAGONAL);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _DISCRETE);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _STEREO_AND_KEYBOARD_MIC);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _4_1_QUAD_SIDE);
ASSERT_ENUM_EQ(ChannelLayout, CHANNEL_LAYOUT, k, _MAX);
// SampleFormat.
ASSERT_ENUM_EQ_RAW(SampleFormat, kUnknownSampleFormat, SampleFormat::UNKNOWN);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , U8);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , S16);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , S32);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , F32);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , PlanarS16);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , PlanarF32);
ASSERT_ENUM_EQ(SampleFormat, kSampleFormat, , Max);
// DemuxerStream Type. Note: Mojo DemuxerStream's don't have the TEXT type.
ASSERT_ENUM_EQ_RAW(DemuxerStream::Type,
DemuxerStream::UNKNOWN,
DemuxerStream::Type::UNKNOWN);
ASSERT_ENUM_EQ_RAW(DemuxerStream::Type,
DemuxerStream::AUDIO,
DemuxerStream::Type::AUDIO);
ASSERT_ENUM_EQ_RAW(DemuxerStream::Type,
DemuxerStream::VIDEO,
DemuxerStream::Type::VIDEO);
static_assert(
media::DemuxerStream::NUM_TYPES ==
static_cast<media::DemuxerStream::Type>(
static_cast<int>(media::mojom::DemuxerStream::Type::LAST_TYPE) + 2),
"Mismatched enum: media::DemuxerStream::NUM_TYPES != "
"media::mojom::DemuxerStream::Type::LAST_TYPE + 2");
// DemuxerStream Status.
ASSERT_ENUM_EQ_RAW(DemuxerStream::Status,
DemuxerStream::kOk,
DemuxerStream::Status::OK);
ASSERT_ENUM_EQ_RAW(DemuxerStream::Status,
DemuxerStream::kAborted,
DemuxerStream::Status::ABORTED);
ASSERT_ENUM_EQ_RAW(DemuxerStream::Status,
DemuxerStream::kConfigChanged,
DemuxerStream::Status::CONFIG_CHANGED);
// VideoFormat.
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_UNKNOWN,
VideoFormat::UNKNOWN);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_I420, VideoFormat::I420);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_YV12, VideoFormat::YV12);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_YV16, VideoFormat::YV16);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_YV12A, VideoFormat::YV12A);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_YV24, VideoFormat::YV24);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_NV12, VideoFormat::NV12);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_NV21, VideoFormat::NV21);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_UYVY, VideoFormat::UYVY);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_YUY2, VideoFormat::YUY2);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_ARGB, VideoFormat::ARGB);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_XRGB, VideoFormat::XRGB);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_RGB24, VideoFormat::RGB24);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_RGB32, VideoFormat::RGB32);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_MJPEG, VideoFormat::MJPEG);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_MT21, VideoFormat::MT21);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV420P9,
VideoFormat::YUV420P9);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV422P9,
VideoFormat::YUV422P9);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV444P9,
VideoFormat::YUV444P9);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV420P10,
VideoFormat::YUV420P10);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV422P10,
VideoFormat::YUV422P10);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat,
PIXEL_FORMAT_YUV444P10,
VideoFormat::YUV444P10);
ASSERT_ENUM_EQ_RAW(VideoPixelFormat, PIXEL_FORMAT_MAX, VideoFormat::FORMAT_MAX);
// ColorSpace.
ASSERT_ENUM_EQ_RAW(ColorSpace,
COLOR_SPACE_UNSPECIFIED,
ColorSpace::UNSPECIFIED);
ASSERT_ENUM_EQ_RAW(ColorSpace, COLOR_SPACE_JPEG, ColorSpace::JPEG);
ASSERT_ENUM_EQ_RAW(ColorSpace, COLOR_SPACE_HD_REC709, ColorSpace::HD_REC709);
ASSERT_ENUM_EQ_RAW(ColorSpace, COLOR_SPACE_SD_REC601, ColorSpace::SD_REC601);
ASSERT_ENUM_EQ_RAW(ColorSpace, COLOR_SPACE_MAX, ColorSpace::MAX);
// VideoCodec
ASSERT_ENUM_EQ_RAW(VideoCodec, kUnknownVideoCodec, VideoCodec::UNKNOWN);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , H264);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , HEVC);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , VC1);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , MPEG2);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , MPEG4);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , Theora);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , VP8);
ASSERT_ENUM_EQ(VideoCodec, kCodec, , VP9);
ASSERT_ENUM_EQ_RAW(VideoCodec, kVideoCodecMax, VideoCodec::Max);
// VideoCodecProfile
ASSERT_ENUM_EQ(VideoCodecProfile, , , VIDEO_CODEC_PROFILE_UNKNOWN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VIDEO_CODEC_PROFILE_MIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_MIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_BASELINE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_MAIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_EXTENDED);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_HIGH);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_HIGH10PROFILE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_HIGH422PROFILE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_HIGH444PREDICTIVEPROFILE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_SCALABLEBASELINE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_SCALABLEHIGH);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_STEREOHIGH);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_MULTIVIEWHIGH);
ASSERT_ENUM_EQ(VideoCodecProfile, , , H264PROFILE_MAX);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP8PROFILE_MIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP8PROFILE_ANY);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP8PROFILE_MAX);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_MIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_PROFILE0);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_PROFILE1);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_PROFILE2);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_PROFILE3);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_MAX);
ASSERT_ENUM_EQ(VideoCodecProfile, , , HEVCPROFILE_MIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , HEVCPROFILE_MAIN);
ASSERT_ENUM_EQ(VideoCodecProfile, , , HEVCPROFILE_MAIN10);
ASSERT_ENUM_EQ(VideoCodecProfile, , , HEVCPROFILE_MAIN_STILL_PICTURE);
ASSERT_ENUM_EQ(VideoCodecProfile, , , HEVCPROFILE_MAX);
ASSERT_ENUM_EQ(VideoCodecProfile, , , VIDEO_CODEC_PROFILE_MAX);
// CipherMode
ASSERT_ENUM_EQ_RAW(EncryptionScheme::CipherMode,
EncryptionScheme::CipherMode::CIPHER_MODE_UNENCRYPTED,
CipherMode::UNENCRYPTED);
ASSERT_ENUM_EQ_RAW(EncryptionScheme::CipherMode,
EncryptionScheme::CipherMode::CIPHER_MODE_AES_CTR,
CipherMode::AES_CTR);
ASSERT_ENUM_EQ_RAW(EncryptionScheme::CipherMode,
EncryptionScheme::CipherMode::CIPHER_MODE_AES_CBC,
CipherMode::AES_CBC);
ASSERT_ENUM_EQ_RAW(EncryptionScheme::CipherMode,
EncryptionScheme::CipherMode::CIPHER_MODE_MAX,
CipherMode::MAX);
// Decryptor Status
ASSERT_ENUM_EQ_RAW(Decryptor::Status,
Decryptor::kSuccess,
Decryptor::Status::SUCCESS);
ASSERT_ENUM_EQ_RAW(Decryptor::Status,
Decryptor::kNoKey,
Decryptor::Status::NO_KEY);
ASSERT_ENUM_EQ_RAW(Decryptor::Status,
Decryptor::kNeedMoreData,
Decryptor::Status::NEED_MORE_DATA);
ASSERT_ENUM_EQ_RAW(Decryptor::Status,
Decryptor::kError,
Decryptor::Status::DECRYPTION_ERROR);
// CdmException
#define ASSERT_CDM_EXCEPTION(value) \
static_assert( \
media::MediaKeys::value == static_cast<media::MediaKeys::Exception>( \
media::mojom::CdmException::value), \
"Mismatched CDM Exception")
ASSERT_CDM_EXCEPTION(NOT_SUPPORTED_ERROR);
ASSERT_CDM_EXCEPTION(INVALID_STATE_ERROR);
ASSERT_CDM_EXCEPTION(INVALID_ACCESS_ERROR);
ASSERT_CDM_EXCEPTION(QUOTA_EXCEEDED_ERROR);
ASSERT_CDM_EXCEPTION(UNKNOWN_ERROR);
ASSERT_CDM_EXCEPTION(CLIENT_ERROR);
ASSERT_CDM_EXCEPTION(OUTPUT_ERROR);
// CDM Session Type
#define ASSERT_CDM_SESSION_TYPE(value) \
static_assert( \
media::MediaKeys::value == \
static_cast<media::MediaKeys::SessionType>( \
media::mojom::ContentDecryptionModule::SessionType::value), \
"Mismatched CDM Session Type")
ASSERT_CDM_SESSION_TYPE(TEMPORARY_SESSION);
ASSERT_CDM_SESSION_TYPE(PERSISTENT_LICENSE_SESSION);
ASSERT_CDM_SESSION_TYPE(PERSISTENT_RELEASE_MESSAGE_SESSION);
// CDM InitDataType
#define ASSERT_CDM_INIT_DATA_TYPE(value) \
static_assert( \
media::EmeInitDataType::value == \
static_cast<media::EmeInitDataType>( \
media::mojom::ContentDecryptionModule::InitDataType::value), \
"Mismatched CDM Init Data Type")
ASSERT_CDM_INIT_DATA_TYPE(UNKNOWN);
ASSERT_CDM_INIT_DATA_TYPE(WEBM);
ASSERT_CDM_INIT_DATA_TYPE(CENC);
ASSERT_CDM_INIT_DATA_TYPE(KEYIDS);
// CDM Key Status
#define ASSERT_CDM_KEY_STATUS(value) \
static_assert(media::CdmKeyInformation::value == \
static_cast<media::CdmKeyInformation::KeyStatus>( \
media::mojom::CdmKeyStatus::value), \
"Mismatched CDM Key Status")
ASSERT_CDM_KEY_STATUS(USABLE);
ASSERT_CDM_KEY_STATUS(INTERNAL_ERROR);
ASSERT_CDM_KEY_STATUS(EXPIRED);
ASSERT_CDM_KEY_STATUS(OUTPUT_RESTRICTED);
ASSERT_CDM_KEY_STATUS(OUTPUT_DOWNSCALED);
ASSERT_CDM_KEY_STATUS(KEY_STATUS_PENDING);
ASSERT_CDM_KEY_STATUS(RELEASED);
// CDM Message Type
#define ASSERT_CDM_MESSAGE_TYPE(value) \
static_assert( \
media::MediaKeys::value == static_cast<media::MediaKeys::MessageType>( \
media::mojom::CdmMessageType::value), \
"Mismatched CDM Message Type")
ASSERT_CDM_MESSAGE_TYPE(LICENSE_REQUEST);
ASSERT_CDM_MESSAGE_TYPE(LICENSE_RENEWAL);
ASSERT_CDM_MESSAGE_TYPE(LICENSE_RELEASE);
template <>
struct TypeConverter<media::mojom::PatternPtr,
media::EncryptionScheme::Pattern> {
static media::mojom::PatternPtr Convert(
const media::EncryptionScheme::Pattern& input);
};
template <>
struct TypeConverter<media::EncryptionScheme::Pattern,
media::mojom::PatternPtr> {
static media::EncryptionScheme::Pattern Convert(
const media::mojom::PatternPtr& input);
};
// static
media::mojom::PatternPtr
TypeConverter<media::mojom::PatternPtr, media::EncryptionScheme::Pattern>::
Convert(const media::EncryptionScheme::Pattern& input) {
media::mojom::PatternPtr mojo_pattern(media::mojom::Pattern::New());
mojo_pattern->encrypt_blocks = input.encrypt_blocks();
mojo_pattern->skip_blocks = input.skip_blocks();
return mojo_pattern;
}
// static
media::EncryptionScheme::Pattern TypeConverter<
media::EncryptionScheme::Pattern,
media::mojom::PatternPtr>::Convert(const media::mojom::PatternPtr& input) {
return media::EncryptionScheme::Pattern(input->encrypt_blocks,
input->skip_blocks);
}
// static
media::mojom::EncryptionSchemePtr TypeConverter<
media::mojom::EncryptionSchemePtr,
media::EncryptionScheme>::Convert(const media::EncryptionScheme& input) {
media::mojom::EncryptionSchemePtr mojo_encryption_scheme(
media::mojom::EncryptionScheme::New());
mojo_encryption_scheme->mode =
static_cast<media::mojom::CipherMode>(input.mode());
mojo_encryption_scheme->pattern =
media::mojom::Pattern::From(input.pattern());
return mojo_encryption_scheme;
}
// static
media::EncryptionScheme
TypeConverter<media::EncryptionScheme, media::mojom::EncryptionSchemePtr>::
Convert(const media::mojom::EncryptionSchemePtr& input) {
return media::EncryptionScheme(
static_cast<media::EncryptionScheme::CipherMode>(input->mode),
input->pattern.To<media::EncryptionScheme::Pattern>());
}
// static
media::mojom::SubsampleEntryPtr
TypeConverter<media::mojom::SubsampleEntryPtr, media::SubsampleEntry>::Convert(
const media::SubsampleEntry& input) {
media::mojom::SubsampleEntryPtr mojo_subsample_entry(
media::mojom::SubsampleEntry::New());
mojo_subsample_entry->clear_bytes = input.clear_bytes;
mojo_subsample_entry->cypher_bytes = input.cypher_bytes;
return mojo_subsample_entry;
}
// static
media::SubsampleEntry
TypeConverter<media::SubsampleEntry, media::mojom::SubsampleEntryPtr>::Convert(
const media::mojom::SubsampleEntryPtr& input) {
return media::SubsampleEntry(input->clear_bytes, input->cypher_bytes);
}
// static
media::mojom::DecryptConfigPtr
TypeConverter<media::mojom::DecryptConfigPtr, media::DecryptConfig>::Convert(
const media::DecryptConfig& input) {
media::mojom::DecryptConfigPtr mojo_decrypt_config(
media::mojom::DecryptConfig::New());
mojo_decrypt_config->key_id = input.key_id();
mojo_decrypt_config->iv = input.iv();
mojo_decrypt_config->subsamples =
Array<media::mojom::SubsampleEntryPtr>::From(input.subsamples());
return mojo_decrypt_config;
}
// static
std::unique_ptr<media::DecryptConfig>
TypeConverter<std::unique_ptr<media::DecryptConfig>,
media::mojom::DecryptConfigPtr>::
Convert(const media::mojom::DecryptConfigPtr& input) {
return base::MakeUnique<media::DecryptConfig>(
input->key_id, input->iv,
input->subsamples.To<std::vector<media::SubsampleEntry>>());
}
// static
media::mojom::DecoderBufferPtr
TypeConverter<media::mojom::DecoderBufferPtr,
scoped_refptr<media::DecoderBuffer>>::
Convert(const scoped_refptr<media::DecoderBuffer>& input) {
DCHECK(input);
media::mojom::DecoderBufferPtr mojo_buffer(
media::mojom::DecoderBuffer::New());
if (input->end_of_stream())
return mojo_buffer;
mojo_buffer->timestamp = input->timestamp();
mojo_buffer->duration = input->duration();
mojo_buffer->is_key_frame = input->is_key_frame();
mojo_buffer->data_size = base::checked_cast<uint32_t>(input->data_size());
mojo_buffer->front_discard = input->discard_padding().first;
mojo_buffer->back_discard = input->discard_padding().second;
mojo_buffer->splice_timestamp = input->splice_timestamp();
// Note: The side data is always small, so this copy is okay.
std::vector<uint8_t> side_data(input->side_data(),
input->side_data() + input->side_data_size());
mojo_buffer->side_data.Swap(&side_data);
if (input->decrypt_config()) {
mojo_buffer->decrypt_config =
media::mojom::DecryptConfig::From(*input->decrypt_config());
}
// TODO(dalecurtis): We intentionally do not serialize the data section of
// the DecoderBuffer here; this must instead be done by clients via their
// own DataPipe. See http://crbug.com/432960
return mojo_buffer;
}
// static
scoped_refptr<media::DecoderBuffer>
TypeConverter<scoped_refptr<media::DecoderBuffer>,
media::mojom::DecoderBufferPtr>::
Convert(const media::mojom::DecoderBufferPtr& input) {
if (!input->data_size)
return media::DecoderBuffer::CreateEOSBuffer();
scoped_refptr<media::DecoderBuffer> buffer(
new media::DecoderBuffer(input->data_size));
if (!input->side_data.empty()) {
buffer->CopySideDataFrom(&input->side_data.front(),
input->side_data.size());
}
buffer->set_timestamp(input->timestamp);
buffer->set_duration(input->duration);
if (input->is_key_frame)
buffer->set_is_key_frame(true);
if (input->decrypt_config) {
buffer->set_decrypt_config(
input->decrypt_config.To<std::unique_ptr<media::DecryptConfig>>());
}
media::DecoderBuffer::DiscardPadding discard_padding(input->front_discard,
input->back_discard);
buffer->set_discard_padding(discard_padding);
buffer->set_splice_timestamp(input->splice_timestamp);
// TODO(dalecurtis): We intentionally do not deserialize the data section of
// the DecoderBuffer here; this must instead be done by clients via their
// own DataPipe. See http://crbug.com/432960
return buffer;
}
// static
media::mojom::AudioDecoderConfigPtr
TypeConverter<media::mojom::AudioDecoderConfigPtr, media::AudioDecoderConfig>::
Convert(const media::AudioDecoderConfig& input) {
media::mojom::AudioDecoderConfigPtr config(
media::mojom::AudioDecoderConfig::New());
config->codec = static_cast<media::mojom::AudioCodec>(input.codec());
config->sample_format =
static_cast<media::mojom::SampleFormat>(input.sample_format());
config->channel_layout =
static_cast<media::mojom::ChannelLayout>(input.channel_layout());
config->samples_per_second = input.samples_per_second();
if (!input.extra_data().empty()) {
config->extra_data = mojo::Array<uint8_t>::From(input.extra_data());
}
config->seek_preroll = input.seek_preroll();
config->codec_delay = input.codec_delay();
config->encryption_scheme =
media::mojom::EncryptionScheme::From(input.encryption_scheme());
return config;
}
// static
media::AudioDecoderConfig
TypeConverter<media::AudioDecoderConfig, media::mojom::AudioDecoderConfigPtr>::
Convert(const media::mojom::AudioDecoderConfigPtr& input) {
media::AudioDecoderConfig config;
config.Initialize(static_cast<media::AudioCodec>(input->codec),
static_cast<media::SampleFormat>(input->sample_format),
static_cast<media::ChannelLayout>(input->channel_layout),
input->samples_per_second, input->extra_data.storage(),
input->encryption_scheme.To<media::EncryptionScheme>(),
input->seek_preroll, input->codec_delay);
return config;
}
// static
media::mojom::VideoDecoderConfigPtr
TypeConverter<media::mojom::VideoDecoderConfigPtr, media::VideoDecoderConfig>::
Convert(const media::VideoDecoderConfig& input) {
media::mojom::VideoDecoderConfigPtr config(
media::mojom::VideoDecoderConfig::New());
config->codec = static_cast<media::mojom::VideoCodec>(input.codec());
config->profile =
static_cast<media::mojom::VideoCodecProfile>(input.profile());
config->format = static_cast<media::mojom::VideoFormat>(input.format());
config->color_space =
static_cast<media::mojom::ColorSpace>(input.color_space());
config->coded_size = input.coded_size();
config->visible_rect = input.visible_rect();
config->natural_size = input.natural_size();
if (!input.extra_data().empty()) {
config->extra_data = mojo::Array<uint8_t>::From(input.extra_data());
}
config->encryption_scheme =
media::mojom::EncryptionScheme::From(input.encryption_scheme());
return config;
}
// static
media::VideoDecoderConfig
TypeConverter<media::VideoDecoderConfig, media::mojom::VideoDecoderConfigPtr>::
Convert(const media::mojom::VideoDecoderConfigPtr& input) {
media::VideoDecoderConfig config;
config.Initialize(static_cast<media::VideoCodec>(input->codec),
static_cast<media::VideoCodecProfile>(input->profile),
static_cast<media::VideoPixelFormat>(input->format),
static_cast<media::ColorSpace>(input->color_space),
input->coded_size, input->visible_rect, input->natural_size,
input->extra_data.storage(),
input->encryption_scheme.To<media::EncryptionScheme>());
return config;
}
// static
media::mojom::CdmKeyInformationPtr TypeConverter<
media::mojom::CdmKeyInformationPtr,
media::CdmKeyInformation>::Convert(const media::CdmKeyInformation& input) {
media::mojom::CdmKeyInformationPtr info(
media::mojom::CdmKeyInformation::New());
std::vector<uint8_t> key_id_copy(input.key_id);
info->key_id.Swap(&key_id_copy);
info->status = static_cast<media::mojom::CdmKeyStatus>(input.status);
info->system_code = input.system_code;
return info;
}
// static
std::unique_ptr<media::CdmKeyInformation>
TypeConverter<std::unique_ptr<media::CdmKeyInformation>,
media::mojom::CdmKeyInformationPtr>::
Convert(const media::mojom::CdmKeyInformationPtr& input) {
return base::MakeUnique<media::CdmKeyInformation>(
input->key_id.storage(),
static_cast<media::CdmKeyInformation::KeyStatus>(input->status),
input->system_code);
}
// static
media::mojom::CdmConfigPtr
TypeConverter<media::mojom::CdmConfigPtr, media::CdmConfig>::Convert(
const media::CdmConfig& input) {
media::mojom::CdmConfigPtr config(media::mojom::CdmConfig::New());
config->allow_distinctive_identifier = input.allow_distinctive_identifier;
config->allow_persistent_state = input.allow_persistent_state;
config->use_hw_secure_codecs = input.use_hw_secure_codecs;
return config;
}
// static
media::CdmConfig
TypeConverter<media::CdmConfig, media::mojom::CdmConfigPtr>::Convert(
const media::mojom::CdmConfigPtr& input) {
media::CdmConfig config;
config.allow_distinctive_identifier = input->allow_distinctive_identifier;
config.allow_persistent_state = input->allow_persistent_state;
config.use_hw_secure_codecs = input->use_hw_secure_codecs;
return config;
}
// static
media::mojom::AudioBufferPtr
TypeConverter<media::mojom::AudioBufferPtr, scoped_refptr<media::AudioBuffer>>::
Convert(const scoped_refptr<media::AudioBuffer>& input) {
media::mojom::AudioBufferPtr buffer(media::mojom::AudioBuffer::New());
buffer->sample_format =
static_cast<media::mojom::SampleFormat>(input->sample_format_);
buffer->channel_layout =
static_cast<media::mojom::ChannelLayout>(input->channel_layout());
buffer->channel_count = input->channel_count();
buffer->sample_rate = input->sample_rate();
buffer->frame_count = input->frame_count();
buffer->end_of_stream = input->end_of_stream();
buffer->timestamp = input->timestamp();
if (!input->end_of_stream()) {
std::vector<uint8_t> input_data(input->data_.get(),
input->data_.get() + input->data_size_);
buffer->data.Swap(&input_data);
}
return buffer;
}
// static
scoped_refptr<media::AudioBuffer>
TypeConverter<scoped_refptr<media::AudioBuffer>, media::mojom::AudioBufferPtr>::
Convert(const media::mojom::AudioBufferPtr& input) {
if (input->end_of_stream)
return media::AudioBuffer::CreateEOSBuffer();
// Setup channel pointers. AudioBuffer::CopyFrom() will only use the first
// one in the case of interleaved data.
std::vector<const uint8_t*> channel_ptrs(input->channel_count, nullptr);
std::vector<uint8_t> storage = input->data.storage();
const size_t size_per_channel = storage.size() / input->channel_count;
DCHECK_EQ(0u, storage.size() % input->channel_count);
for (int i = 0; i < input->channel_count; ++i)
channel_ptrs[i] = storage.data() + i * size_per_channel;
return media::AudioBuffer::CopyFrom(
static_cast<media::SampleFormat>(input->sample_format),
static_cast<media::ChannelLayout>(input->channel_layout),
input->channel_count, input->sample_rate, input->frame_count,
&channel_ptrs[0], input->timestamp);
}
// static
media::mojom::VideoFramePtr
TypeConverter<media::mojom::VideoFramePtr, scoped_refptr<media::VideoFrame>>::
Convert(const scoped_refptr<media::VideoFrame>& input) {
media::mojom::VideoFramePtr frame(media::mojom::VideoFrame::New());
frame->end_of_stream =
input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM);
if (frame->end_of_stream)
return frame;
// Handle non EOS frame. It must be a MojoSharedBufferVideoFrame.
// TODO(jrummell): Support other types of VideoFrame.
CHECK_EQ(media::VideoFrame::STORAGE_MOJO_SHARED_BUFFER,
input->storage_type());
media::MojoSharedBufferVideoFrame* input_frame =
static_cast<media::MojoSharedBufferVideoFrame*>(input.get());
mojo::ScopedSharedBufferHandle duplicated_handle =
input_frame->Handle().Clone();
CHECK(duplicated_handle.is_valid());
frame->format = static_cast<media::mojom::VideoFormat>(input->format());
frame->coded_size = input->coded_size();
frame->visible_rect = input->visible_rect();
frame->natural_size = input->natural_size();
frame->timestamp = input->timestamp();
frame->frame_data = std::move(duplicated_handle);
frame->frame_data_size = input_frame->MappedSize();
frame->y_stride = input_frame->stride(media::VideoFrame::kYPlane);
frame->u_stride = input_frame->stride(media::VideoFrame::kUPlane);
frame->v_stride = input_frame->stride(media::VideoFrame::kVPlane);
frame->y_offset = input_frame->PlaneOffset(media::VideoFrame::kYPlane);
frame->u_offset = input_frame->PlaneOffset(media::VideoFrame::kUPlane);
frame->v_offset = input_frame->PlaneOffset(media::VideoFrame::kVPlane);
return frame;
}
// static
scoped_refptr<media::VideoFrame>
TypeConverter<scoped_refptr<media::VideoFrame>, media::mojom::VideoFramePtr>::
Convert(const media::mojom::VideoFramePtr& input) {
if (input->end_of_stream)
return media::VideoFrame::CreateEOSFrame();
return media::MojoSharedBufferVideoFrame::Create(
static_cast<media::VideoPixelFormat>(input->format), input->coded_size,
input->visible_rect, input->natural_size, std::move(input->frame_data),
base::saturated_cast<size_t>(input->frame_data_size),
base::saturated_cast<size_t>(input->y_offset),
base::saturated_cast<size_t>(input->u_offset),
base::saturated_cast<size_t>(input->v_offset), input->y_stride,
input->u_stride, input->v_stride, input->timestamp);
}
} // namespace mojo