// 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 #include #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/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/converters/geometry/geometry_type_converters.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::interfaces::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::interfaces::mojo_enum_value), \ "Mismatched enum: " #media_enum_value " != " #mojo_enum_value) // BufferingState. ASSERT_ENUM_EQ(BufferingState, BUFFERING_, , HAVE_NOTHING); ASSERT_ENUM_EQ(BufferingState, BUFFERING_, , HAVE_ENOUGH); // 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( static_cast( media::interfaces::DemuxerStream::Type::LAST_TYPE) + 2), "Mismatched enum: media::DemuxerStream::NUM_TYPES != " "media::interfaces::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_ANY); ASSERT_ENUM_EQ(VideoCodecProfile, , , VP9PROFILE_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::interfaces::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::interfaces::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::interfaces::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::interfaces::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); // CDM Message Type #define ASSERT_CDM_MESSAGE_TYPE(value) \ static_assert(media::MediaKeys::value == \ static_cast( \ media::interfaces::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 { static media::interfaces::PatternPtr Convert( const media::EncryptionScheme::Pattern& input); }; template <> struct TypeConverter { static media::EncryptionScheme::Pattern Convert( const media::interfaces::PatternPtr& input); }; // static media::interfaces::PatternPtr TypeConverter:: Convert(const media::EncryptionScheme::Pattern& input) { media::interfaces::PatternPtr mojo_pattern(media::interfaces::Pattern::New()); mojo_pattern->encrypt_blocks = input.encrypt_blocks(); mojo_pattern->skip_blocks = input.skip_blocks(); return mojo_pattern; } // static media::EncryptionScheme::Pattern TypeConverter:: Convert(const media::interfaces::PatternPtr& input) { return media::EncryptionScheme::Pattern(input->encrypt_blocks, input->skip_blocks); } // static media::interfaces::EncryptionSchemePtr TypeConverter< media::interfaces::EncryptionSchemePtr, media::EncryptionScheme>::Convert(const media::EncryptionScheme& input) { media::interfaces::EncryptionSchemePtr mojo_encryption_scheme( media::interfaces::EncryptionScheme::New()); mojo_encryption_scheme->mode = static_cast(input.mode()); mojo_encryption_scheme->pattern = media::interfaces::Pattern::From(input.pattern()); return mojo_encryption_scheme; } // static media::EncryptionScheme TypeConverter:: Convert(const media::interfaces::EncryptionSchemePtr& input) { return media::EncryptionScheme( static_cast(input->mode), input->pattern.To()); } // static media::interfaces::SubsampleEntryPtr TypeConverter< media::interfaces::SubsampleEntryPtr, media::SubsampleEntry>::Convert(const media::SubsampleEntry& input) { media::interfaces::SubsampleEntryPtr mojo_subsample_entry( media::interfaces::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:: Convert(const media::interfaces::SubsampleEntryPtr& input) { return media::SubsampleEntry(input->clear_bytes, input->cypher_bytes); } // static media::interfaces::DecryptConfigPtr TypeConverter< media::interfaces::DecryptConfigPtr, media::DecryptConfig>::Convert(const media::DecryptConfig& input) { media::interfaces::DecryptConfigPtr mojo_decrypt_config( media::interfaces::DecryptConfig::New()); mojo_decrypt_config->key_id = input.key_id(); mojo_decrypt_config->iv = input.iv(); mojo_decrypt_config->subsamples = Array::From(input.subsamples()); return mojo_decrypt_config; } // static scoped_ptr TypeConverter, media::interfaces::DecryptConfigPtr>:: Convert(const media::interfaces::DecryptConfigPtr& input) { return make_scoped_ptr(new media::DecryptConfig( input->key_id, input->iv, input->subsamples.To>())); } // static media::interfaces::DecoderBufferPtr TypeConverter>:: Convert(const scoped_refptr& input) { DCHECK(input); media::interfaces::DecoderBufferPtr mojo_buffer( media::interfaces::DecoderBuffer::New()); if (input->end_of_stream()) return mojo_buffer; mojo_buffer->timestamp_usec = input->timestamp().InMicroseconds(); mojo_buffer->duration_usec = input->duration().InMicroseconds(); mojo_buffer->is_key_frame = input->is_key_frame(); mojo_buffer->data_size = base::checked_cast(input->data_size()); mojo_buffer->side_data_size = base::checked_cast(input->side_data_size()); mojo_buffer->front_discard_usec = input->discard_padding().first.InMicroseconds(); mojo_buffer->back_discard_usec = input->discard_padding().second.InMicroseconds(); mojo_buffer->splice_timestamp_usec = input->splice_timestamp().InMicroseconds(); // Note: The side data is always small, so this copy is okay. std::vector 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::interfaces::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 TypeConverter, media::interfaces::DecoderBufferPtr>:: Convert(const media::interfaces::DecoderBufferPtr& input) { if (!input->data_size) return media::DecoderBuffer::CreateEOSBuffer(); scoped_refptr buffer( new media::DecoderBuffer(input->data_size)); if (input->side_data_size) buffer->CopySideDataFrom(&input->side_data.front(), input->side_data_size); buffer->set_timestamp( base::TimeDelta::FromMicroseconds(input->timestamp_usec)); buffer->set_duration(base::TimeDelta::FromMicroseconds(input->duration_usec)); if (input->is_key_frame) buffer->set_is_key_frame(true); if (input->decrypt_config) { buffer->set_decrypt_config( input->decrypt_config.To>()); } media::DecoderBuffer::DiscardPadding discard_padding( base::TimeDelta::FromMicroseconds(input->front_discard_usec), base::TimeDelta::FromMicroseconds(input->back_discard_usec)); buffer->set_discard_padding(discard_padding); buffer->set_splice_timestamp( base::TimeDelta::FromMicroseconds(input->splice_timestamp_usec)); // 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::interfaces::AudioDecoderConfigPtr TypeConverter< media::interfaces::AudioDecoderConfigPtr, media::AudioDecoderConfig>::Convert(const media::AudioDecoderConfig& input) { media::interfaces::AudioDecoderConfigPtr config( media::interfaces::AudioDecoderConfig::New()); config->codec = static_cast(input.codec()); config->sample_format = static_cast(input.sample_format()); config->channel_layout = static_cast(input.channel_layout()); config->samples_per_second = input.samples_per_second(); if (!input.extra_data().empty()) { config->extra_data = mojo::Array::From(input.extra_data()); } config->seek_preroll_usec = input.seek_preroll().InMicroseconds(); config->codec_delay = input.codec_delay(); config->encryption_scheme = media::interfaces::EncryptionScheme::From(input.encryption_scheme()); return config; } // static media::AudioDecoderConfig TypeConverter:: Convert(const media::interfaces::AudioDecoderConfigPtr& input) { media::AudioDecoderConfig config; config.Initialize(static_cast(input->codec), static_cast(input->sample_format), static_cast(input->channel_layout), input->samples_per_second, input->extra_data.storage(), input->encryption_scheme.To(), base::TimeDelta::FromMicroseconds(input->seek_preroll_usec), input->codec_delay); return config; } // static media::interfaces::VideoDecoderConfigPtr TypeConverter< media::interfaces::VideoDecoderConfigPtr, media::VideoDecoderConfig>::Convert(const media::VideoDecoderConfig& input) { media::interfaces::VideoDecoderConfigPtr config( media::interfaces::VideoDecoderConfig::New()); config->codec = static_cast(input.codec()); config->profile = static_cast(input.profile()); config->format = static_cast(input.format()); config->color_space = static_cast(input.color_space()); config->coded_size = Size::From(input.coded_size()); config->visible_rect = Rect::From(input.visible_rect()); config->natural_size = Size::From(input.natural_size()); if (!input.extra_data().empty()) { config->extra_data = mojo::Array::From(input.extra_data()); } config->encryption_scheme = media::interfaces::EncryptionScheme::From(input.encryption_scheme()); return config; } // static media::VideoDecoderConfig TypeConverter:: Convert(const media::interfaces::VideoDecoderConfigPtr& input) { media::VideoDecoderConfig config; config.Initialize( static_cast(input->codec), static_cast(input->profile), static_cast(input->format), static_cast(input->color_space), input->coded_size.To(), input->visible_rect.To(), input->natural_size.To(), input->extra_data.storage(), input->encryption_scheme.To()); return config; } // static media::interfaces::CdmKeyInformationPtr TypeConverter< media::interfaces::CdmKeyInformationPtr, media::CdmKeyInformation>::Convert(const media::CdmKeyInformation& input) { media::interfaces::CdmKeyInformationPtr info( media::interfaces::CdmKeyInformation::New()); std::vector key_id_copy(input.key_id); info->key_id.Swap(&key_id_copy); info->status = static_cast(input.status); info->system_code = input.system_code; return info; } // static scoped_ptr TypeConverter, media::interfaces::CdmKeyInformationPtr>:: Convert(const media::interfaces::CdmKeyInformationPtr& input) { return make_scoped_ptr(new media::CdmKeyInformation( input->key_id.storage(), static_cast(input->status), input->system_code)); } // static media::interfaces::CdmConfigPtr TypeConverter::Convert( const media::CdmConfig& input) { media::interfaces::CdmConfigPtr config(media::interfaces::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::Convert( const media::interfaces::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::interfaces::AudioBufferPtr TypeConverter>:: Convert(const scoped_refptr& input) { media::interfaces::AudioBufferPtr buffer( media::interfaces::AudioBuffer::New()); buffer->sample_format = static_cast(input->sample_format_); buffer->channel_layout = static_cast(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_usec = input->timestamp().InMicroseconds(); if (!input->end_of_stream()) { std::vector input_data(input->data_.get(), input->data_.get() + input->data_size_); buffer->data.Swap(&input_data); } return buffer; } // static scoped_refptr TypeConverter, media::interfaces::AudioBufferPtr>:: Convert(const media::interfaces::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 channel_ptrs(input->channel_count, nullptr); std::vector 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(input->sample_format), static_cast(input->channel_layout), input->channel_count, input->sample_rate, input->frame_count, &channel_ptrs[0], base::TimeDelta::FromMicroseconds(input->timestamp_usec)); } // static media::interfaces::VideoFramePtr TypeConverter>:: Convert(const scoped_refptr& input) { media::interfaces::VideoFramePtr frame(media::interfaces::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(input.get()); mojo::ScopedSharedBufferHandle duplicated_handle; const MojoResult result = DuplicateBuffer(input_frame->Handle(), nullptr, &duplicated_handle); CHECK_EQ(MOJO_RESULT_OK, result); CHECK(duplicated_handle.is_valid()); frame->format = static_cast(input->format()); frame->coded_size = Size::From(input->coded_size()); frame->visible_rect = Rect::From(input->visible_rect()); frame->natural_size = Size::From(input->natural_size()); frame->timestamp_usec = input->timestamp().InMicroseconds(); 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 TypeConverter, media::interfaces::VideoFramePtr>:: Convert(const media::interfaces::VideoFramePtr& input) { if (input->end_of_stream) return media::VideoFrame::CreateEOSFrame(); return media::MojoSharedBufferVideoFrame::Create( static_cast(input->format), input->coded_size.To(), input->visible_rect.To(), input->natural_size.To(), std::move(input->frame_data), base::saturated_cast(input->frame_data_size), base::saturated_cast(input->y_offset), base::saturated_cast(input->u_offset), base::saturated_cast(input->v_offset), input->y_stride, input->u_stride, input->v_stride, base::TimeDelta::FromMicroseconds(input->timestamp_usec)); } } // namespace mojo