Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(898)

Unified Diff: media/remoting/proto/remoting_rpc_message.proto

Issue 2261503002: Define remote playback proto buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove all change in src/BUILD.gn and media_options.gni Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/remoting/README ('k') | media/remoting/rpc/proto_enum_utils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/remoting/proto/remoting_rpc_message.proto
diff --git a/media/remoting/proto/remoting_rpc_message.proto b/media/remoting/proto/remoting_rpc_message.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e9b9e7eb9d2a3d54e1229d2966b0d11a451de3cf
--- /dev/null
+++ b/media/remoting/proto/remoting_rpc_message.proto
@@ -0,0 +1,563 @@
+// Copyright 2016 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.
+//
+// Protocol buffer for Media Remoting.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package media.remoting.pb;
+
+// DecoderBuffer information which will be sent using RTP packets. The actual
+// decoder buffer is not included in this proto data structure.
+message DecoderBuffer {
+ optional int64 timestamp_usec = 1;
+ optional int64 duration_usec = 2;
+ optional bool is_key_frame = 3;
+ optional DecryptConfig decrypt_config = 4;
+ optional int64 front_discard_usec = 5;
+ optional int64 back_discard_usec = 6;
+ optional int64 splice_timestamp_usec = 7;
+ optional bytes side_data = 8;
+ // To distinguish from valid 0-length buffers
+ optional bool is_eos = 9;
+}
+
+// Utility proto data structure
+message Size {
+ optional int32 width = 1;
+ optional int32 height = 2;
+}
+
+message EncryptionScheme {
+ // Align with EncryptionScheme::CipherMode
+ enum CipherMode {
+ CIPHER_MODE_UNENCRYPTED = 0;
+ CIPHER_MODE_AES_CTR = 1;
+ CIPHER_MODE_AES_CBC = 2;
+ }
+
+ optional CipherMode mode = 1;
+ optional uint32 encrypt_blocks = 2;
+ optional uint32 skip_blocks = 3;
+}
+
+message AudioDecoderConfig {
+ // Should align with ::media::Codec
+ enum Codec {
+ kUnknownAudioCodec = 0;
+ kCodecAAC = 1;
+ kCodecMP3 = 2;
+ kCodecPCM = 3;
+ kCodecVorbis = 4;
+ kCodecFLAC = 5;
+ kCodecAMR_NB = 6;
+ kCodecAMR_WB = 7;
+ kCodecPCM_MULAW = 8;
+ kCodecGSM_MS = 9;
+ kCodecPCM_S16BE = 10;
+ kCodecPCM_S24BE = 11;
+ kCodecOpus = 12;
+ kCodecEAC3 = 13;
+ kCodecPCM_ALAW = 14;
+ kCodecALAC = 15;
+ kCodecAC3 = 16;
+ }
+
+ // Should align with ::media::SampleFormat
+ enum SampleFormat {
+ kUnknownSampleFormat = 0;
+ kSampleFormatU8 = 1;
+ kSampleFormatS16 = 2;
+ kSampleFormatS32 = 3;
+ kSampleFormatF32 = 4;
+ kSampleFormatPlanarS16 = 5;
+ kSampleFormatPlanarF32 = 6;
+ kSampleFormatPlanarS32 = 7;
+ kSampleFormatS24 = 8;
+ };
+
+ // Should align with ::media::ChannelLayout
+ enum ChannelLayout {
+ CHANNEL_LAYOUT_NONE = 0;
+ CHANNEL_LAYOUT_UNSUPPORTED = 1;
+ CHANNEL_LAYOUT_MONO = 2;
+ CHANNEL_LAYOUT_STEREO = 3;
+ CHANNEL_LAYOUT_2_1 = 4;
+ CHANNEL_LAYOUT_SURROUND = 5;
+ CHANNEL_LAYOUT_4_0 = 6;
+ CHANNEL_LAYOUT_2_2 = 7;
+ CHANNEL_LAYOUT_QUAD = 8;
+ CHANNEL_LAYOUT_5_0 = 9;
+ CHANNEL_LAYOUT_5_1 = 10;
+ CHANNEL_LAYOUT_5_0_BACK = 11;
+ CHANNEL_LAYOUT_5_1_BACK = 12;
+ CHANNEL_LAYOUT_7_0 = 13;
+ CHANNEL_LAYOUT_7_1 = 14;
+ CHANNEL_LAYOUT_7_1_WIDE = 15;
+ CHANNEL_LAYOUT_STEREO_DOWNMIX = 16;
+ CHANNEL_LAYOUT_2POINT1 = 17;
+ CHANNEL_LAYOUT_3_1 = 18;
+ CHANNEL_LAYOUT_4_1 = 19;
+ CHANNEL_LAYOUT_6_0 = 20;
+ CHANNEL_LAYOUT_6_0_FRONT = 21;
+ CHANNEL_LAYOUT_HEXAGONAL = 22;
+ CHANNEL_LAYOUT_6_1 = 23;
+ CHANNEL_LAYOUT_6_1_BACK = 24;
+ CHANNEL_LAYOUT_6_1_FRONT = 25;
+ CHANNEL_LAYOUT_7_0_FRONT = 26;
+ CHANNEL_LAYOUT_7_1_WIDE_BACK = 27;
+ CHANNEL_LAYOUT_OCTAGONAL = 28;
+ CHANNEL_LAYOUT_DISCRETE = 29;
+ CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC = 30;
+ CHANNEL_LAYOUT_4_1_QUAD_SIDE = 31;
+ };
+
+ optional Codec codec = 1;
+ optional EncryptionScheme encryption_scheme = 2;
+ optional SampleFormat sample_format = 3;
+ optional ChannelLayout channel_layout = 4;
+ optional int32 samples_per_second = 5;
+ optional int64 seek_preroll_usec = 6;
+ optional int32 codec_delay = 7;
+ optional bytes extra_data = 8;
+}
+
+message Rect {
+ optional int32 x = 1;
+ optional int32 y = 2;
+ optional int32 width = 3;
+ optional int32 height = 4;
+}
+
+message VideoDecoderConfig {
+ // Should align with ::media::VideoCodec
+ enum Codec {
+ kUnknownVideoCodec = 0;
+ kCodecH264 = 1;
+ kCodecVC1 = 2;
+ kCodecMPEG2 = 3;
+ kCodecMPEG4 = 4;
+ kCodecTheora = 5;
+ kCodecVP8 = 6;
+ kCodecVP9 = 7;
+ kCodecHEVC = 8;
+ }
+
+ // Should align with ::media::VideoCodecProfile
+ enum Profile {
+ VIDEO_CODEC_PROFILE_UNKNOWN = -1;
+ H264PROFILE_BASELINE = 0;
+ H264PROFILE_MAIN = 1;
+ H264PROFILE_EXTENDED = 2;
+ H264PROFILE_HIGH = 3;
+ H264PROFILE_HIGH10PROFILE = 4;
+ H264PROFILE_HIGH422PROFILE = 5;
+ H264PROFILE_HIGH444PREDICTIVEPROFILE = 6;
+ H264PROFILE_SCALABLEBASELINE = 7;
+ H264PROFILE_SCALABLEHIGH = 8;
+ H264PROFILE_STEREOHIGH = 9;
+ H264PROFILE_MULTIVIEWHIGH = 10;
+ VP8PROFILE_ANY = 11;
+ VP9PROFILE_PROFILE0 = 12;
+ VP9PROFILE_PROFILE1 = 13;
+ VP9PROFILE_PROFILE2 = 14;
+ VP9PROFILE_PROFILE3 = 15;
+ HEVCPROFILE_MAIN = 16;
+ HEVCPROFILE_MAIN10 = 17;
+ HEVCPROFILE_MAIN_STILL_PICTURE = 18;
+ };
+
+ // Should align with ::media::VideoPixelFormat
+ enum Format {
+ PIXEL_FORMAT_UNKNOWN = 0;
+ PIXEL_FORMAT_I420 = 1;
+ PIXEL_FORMAT_YV12 = 2;
+ PIXEL_FORMAT_YV16 = 3;
+ PIXEL_FORMAT_YV12A = 4;
+ PIXEL_FORMAT_YV24 = 5;
+ PIXEL_FORMAT_NV12 = 6;
+ PIXEL_FORMAT_NV21 = 7;
+ PIXEL_FORMAT_UYVY = 8;
+ PIXEL_FORMAT_YUY2 = 9;
+ PIXEL_FORMAT_ARGB = 10;
+ PIXEL_FORMAT_XRGB = 11;
+ PIXEL_FORMAT_RGB24 = 12;
+ PIXEL_FORMAT_RGB32 = 13;
+ PIXEL_FORMAT_MJPEG = 14;
+ PIXEL_FORMAT_MT21 = 15;
+ PIXEL_FORMAT_YUV420P9 = 16;
+ PIXEL_FORMAT_YUV420P10 = 17;
+ PIXEL_FORMAT_YUV422P9 = 18;
+ PIXEL_FORMAT_YUV422P10 = 19;
+ PIXEL_FORMAT_YUV444P9 = 20;
+ PIXEL_FORMAT_YUV444P10 = 21;
+ };
+
+ // Should align with ::media::ColorSpace
+ enum ColorSpace {
+ COLOR_SPACE_UNSPECIFIED = 0;
+ COLOR_SPACE_JPEG = 1;
+ COLOR_SPACE_HD_REC709 = 2;
+ COLOR_SPACE_SD_REC601 = 3;
+ };
+
+ optional Codec codec = 1;
+ optional EncryptionScheme encryption_scheme = 2;
+ optional Profile profile = 3;
+ optional Format format = 4;
+ optional ColorSpace color_space = 5;
+ optional Size coded_size = 6;
+ optional Rect visible_rect = 7;
+ optional Size natural_size = 8;
+ optional bytes extra_data = 9;
+}
+
+message DecryptConfig {
+ message SubSample {
+ optional uint32 clear_bytes = 1;
+ optional uint32 cypher_bytes = 2;
+ }
+
+ optional bytes key_id = 1;
+ optional bytes iv = 2;
+ repeated SubSample sub_samples = 3;
+}
+
+message PipelineStatistics {
+ optional uint64 audio_bytes_decoded = 1;
+ optional uint64 video_bytes_decoded = 2;
+ optional uint32 video_frames_decoded = 3;
+ optional uint32 video_frames_dropped = 4;
+ optional int64 audio_memory_usage = 5;
+ optional int64 video_memory_usage = 6;
+};
+
+message CdmKeyInformation {
+ // Align with ::media::CdmKeyInformation::KeyStatus
+ enum KeyStatus {
+ USABLE = 0;
+ INTERNAL_ERROR = 1;
+ EXPIRED = 2;
+ OUTPUT_RESTRICTED = 3;
+ OUTPUT_DOWNSCALED = 4;
+ KEY_STATUS_PENDING = 5;
+ RELEASED = 6;
+ }
+
+ optional bytes key_id = 1;
+ optional KeyStatus status = 2;
+ optional uint32 system_code = 3;
+}
+
+// Should align with ::media::MediaKeys::Exception
+enum MediaKeysException {
+ NOT_SUPPORTED_ERROR = 0;
+ INVALID_STATE_ERROR = 1;
+ INVALID_ACCESS_ERROR = 2;
+ QUOTA_EXCEEDED_ERROR = 3;
+ UNKNOWN_ERROR = 4;
+ CLIENT_ERROR = 5;
+ OUTPUT_ERROR = 6;
+}
+
+// Should align with ::media::MediaKeys::MessageType
+enum MediaKeysMessageType {
+ LICENSE_REQUEST = 0;
+ LICENSE_RENEWAL = 1;
+ LICENSE_RELEASE = 2;
+}
+
+// Should align with ::media::MediaKeys::SessionType
+enum MediaKeysSessionType {
+ TEMPORARY_SESSION = 0;
+ PERSISTENT_LICENSE_SESSION = 1;
+ PERSISTENT_RELEASE_MESSAGE_SESSION = 2;
+};
+
+// Custom proto data structure
+message RendererInitialize {
+ optional int32 client_handle = 1;
+ optional int32 audio_demuxer_handle = 2;
+ optional int32 video_demuxer_handle = 3;
+ optional int32 callback_handle = 4;
+}
+
+message RendererFlushUntil {
+ optional uint32 audio_count = 1;
+ optional uint32 video_count = 2;
+ optional int32 callback_handle = 3;
+}
+
+message RendererSetCdm {
+ optional int32 cdm_id = 1;
+ optional int32 callback_handle = 2;
+}
+
+message RendererClientOnTimeUpdate {
+ optional int64 time_usec = 1;
+ optional int64 max_time_usec = 2;
+}
+
+message DemuxerStreamReadUntil {
+ optional int32 callback_handle = 1;
+ optional uint32 count = 2;
+}
+
+message DemuxerStreamInitializeCallback {
+ optional int32 type = 1;
+ optional AudioDecoderConfig audio_decoder_config = 2;
+ optional VideoDecoderConfig video_decoder_config = 3;
+}
+
+message DemuxerStreamReadUntilCallback {
+ // Should align with ::media::DemuxerStream::Status
+ enum Status {
+ kOk = 0;
+ kAborted = 1;
+ kConfigChanged = 2;
+ };
+
+ optional Status status = 1;
+ optional uint32 count = 2;
+ optional AudioDecoderConfig audio_decoder_config = 3;
+ optional VideoDecoderConfig video_decoder_config = 4;
+}
+
+message CdmInitialize {
+ optional string key_system = 1;
+ optional string security_origin = 2;
+ optional bool allow_distinctive_identifier = 3;
+ optional bool allow_persistent_state = 4;
+ optional bool use_hw_secure_codecs = 5;
+ optional int32 callback_handle = 6;
+}
+
+message CdmSetServerCertificate {
+ optional int32 callback_handle = 1;
+ optional bytes certificate_data = 2;
+}
+
+message CdmCreateSessionAndGenerateRequest {
+ enum EmeInitDataType {
+ UNKNOWN = 0;
+ WEBM = 1;
+ CENC = 2;
+ KEYIDS = 3;
+ };
+
+ optional MediaKeysSessionType session_type = 1;
+ optional EmeInitDataType init_data_type = 2;
+ optional int32 callback_handle = 3;
+ optional bytes init_data = 4;
+}
+
+message CdmLoadSession {
+ optional MediaKeysSessionType session_type = 1;
+ optional string session_id = 2;
+ optional int32 callback_handle = 3;
+}
+
+message CdmUpdateSession {
+ optional string session_id = 1;
+ optional int32 callback_handle = 2;
+ optional bytes response = 3;
+}
+
+message CdmCloseSession {
+ optional string session_id = 1;
+ optional int32 callback_handle = 2;
+}
+
+message CdmRemoveSession {
+ optional string session_id = 1;
+ optional int32 callback_handle = 2;
+}
+
+message CdmPromise {
+ // These two fields are used only for RPC_CDM_INITIALIZE_CALLBACK
+ optional int32 cdm_id = 1;
+ optional int32 decryptor_handle = 2;
+
+ optional string session_id = 3;
+ optional bool success = 4;
+ optional MediaKeysException exception = 5;
+ optional uint32 system_code = 6;
+ optional string error_message = 7;
+}
+
+message CdmClientOnSessionMessage {
+ optional string session_id = 1;
+ optional MediaKeysMessageType message_type = 2;
+ optional bytes message = 3;
+}
+
+message CdmClientOnSessionKeysChange {
+ optional string session_id = 1;
+ optional bool has_additional_usable_key = 2;
+ repeated CdmKeyInformation key_information = 3;
+}
+
+message CdmClientOnSessionExpirationUpdate {
+ optional string session_id = 1;
+ optional double new_expiry_time_sec = 2;
+}
+
+message RpcMessage {
+ enum RpcProc {
+ // Remoting setup
+ RPC_INTERNAL = 0;
+ RPC_ACQUIRE_RENDERER = 1;
+ RPC_ACQUIRE_RENDERER_DONE = 2;
+ RPC_ACQUIRE_CDM = 3;
+ RPC_ACQUIRE_CDM_DONE = 4;
+ // Renderer message
+ RPC_R_INITIALIZE = 1000;
+ RPC_R_FLUSHUNTIL = 1001;
+ RPC_R_STARTPLAYINGFROM = 1002;
+ RPC_R_SETPLAYBACKRATE = 1003;
+ RPC_R_SETVOLUME = 1004;
+ RPC_R_SETCDM = 1005;
+ // Renderer callbacks
+ RPC_R_INITIALIZE_CALLBACK = 1100;
+ RPC_R_FLUSHUNTIL_CALLBACK = 1101;
+ RPC_R_SETCDM_CALLBACK = 1102;
+ // Renderer client message
+ RPC_RC_ONTIMEUPDATE = 2000;
+ RPC_RC_ONBUFFERINGSTATECHANGE = 2001;
+ RPC_RC_ONENDED = 2002;
+ RPC_RC_ONERROR = 2003;
+ RPC_RC_ONVIDEONATURALSIZECHANGE = 2004;
+ RPC_RC_ONVIDEOOPACITYCHANGE = 2005;
+ RPC_RC_ONSTATISTICSUPDATE = 2006;
+ RPC_RC_ONWAITINGFORDECRYPTIONKEY = 2007;
+ RPC_RC_ONDURATIONCHANGE = 2008;
+ // DemuxerStream message
+ RPC_DS_INITIALIZE = 3000;
+ RPC_DS_READUNTIL = 3001;
+ RPC_DS_ENABLEBITSTREAMCONVERTER = 3002;
+ // DemuxerStream callbacks
+ RPC_DS_INITIALIZE_CALLBACK = 3100;
+ RPC_DS_READUNTIL_CALLBACK = 3101;
+ // ContentDecryptionModule
+ RPC_CDM_SETCLIENT = 4000;
+ RPC_CDM_INITIALIZE = 4001;
+ RPC_CDM_SETSERVERCERTIFICATE = 4002;
+ RPC_CDM_CREATESESSIONANDGENERATEREQUEST = 4003;
+ RPC_CDM_LOADSESSION = 4004;
+ RPC_CDM_UPDATESESSION = 4005;
+ RPC_CDM_CLOSESESSION = 4006;
+ RPC_CDM_REMOVESESSION = 4007;
+ // ContentDecryptionModule callbacks
+ RPC_CDM_INITIALIZE_CALLBACK = 4100;
+ RPC_CDM_SETSERVERCERTIFICATE_CALLBACK = 4101;
+ RPC_CDM_CREATESESSIONANDGENERATEREQUEST_CALLBACK = 4102;
+ RPC_CDM_LOADSESSION_CALLBACK = 4103;
+ RPC_CDM_UPDATESESSION_CALLBACK = 4104;
+ RPC_CDM_CLOSESESSION_CALLBACK = 4105;
+ RPC_CDM_REMOVESESSION_CALLBACK = 4106;
+ // ContentDecryptionModule client
+ RPC_CDMC_ONSESSIONMESSAGE = 5000;
+ RPC_CDMC_ONSESSIONCLOSED = 5001;
+ RPC_CDMC_ONSESSIONKEYSCHANGE = 5002;
+ RPC_CDMC_ONSESSIONEXPIRATIONUPDATE = 5003;
+ };
+
+ // Component base of RPC message handle. This allows both sender and receiver
+ // to send or handle message in desired individual components.
+ optional int32 handle = 1;
+
+ // RpcProc of this RPC message
+ optional RpcProc proc = 2;
+
+ oneof rpc_oneof {
+ // For simple RPC which only passes one parameters can use the following
+ // various data type variables without using specific proto data structure.
+ // RPC_ACQUIRE_RENDERER
+ // RPC_ACQUIRE_RENDERER_DONE
+ // RPC_ACQUIRE_CDM
+ // RPC_ACQUIRE_CDM_DONE
+ // RPC_RC_ONBUFFERINGSTATECHANGE
+ // RPC_DS_INITIALIZE_CALLBACK
+ // RPC_DS_READ
+ // RPC_CDM_SETCLIENT
+ int32 integer_value = 3;
+
+ // RPC_R_STARTPLAYINGFROM
+ // RPC_RC_ONDURATIONCHANGE
+ int64 integer64_value = 4;
+
+ // RPC_R_SETPLAYBACKRATE
+ // RPC_R_SETVOLUME
+ double double_value = 5;
+
+ // RPC_R_INITIALIZE_CALLBACK
+ // RPC_R_SETCDM_CALLBACK
+ // RPC_RC_ONVIDEOOPACITYCHANGE
+ bool boolean_value = 6;
+
+ // string only:
+ // RPC_CDMC_ONSESSIONCLOSED
+ string string_value = 7;
+
+ // RPC_R_INITIALIZE
+ RendererInitialize renderer_initialize_rpc = 100;
+
+ // RPC_R_FLUSHUNTIL
+ RendererFlushUntil renderer_flushuntil_rpc = 101;
+
+ // RPC_R_SETCDM
+ RendererSetCdm renderer_set_cdm_rpc = 102;
+
+ // RPC_RC_ONTIMEUPDATE
+ RendererClientOnTimeUpdate rendererclient_ontimeupdate_rpc = 200;
+ // RPC_RC_ONVIDEONATURALSIZECHANGE
+ Size rendererclient_onvideonatualsizechange_rpc = 201;
+ // RPC_RC_ONSTATISTICSUPDATE
+ PipelineStatistics rendererclient_onstatisticsupdate_rpc = 202;
+
+ // RPC_DS_READUNTIL
+ DemuxerStreamReadUntil demuxerstream_readuntil_rpc = 300;
+
+ // RPC_DS_INITIALIZE_CALLBACK
+ DemuxerStreamInitializeCallback demuxerstream_initializecb_rpc = 400;
+ // RPC_DS_READUNTIL_CALLBACK
+ DemuxerStreamReadUntilCallback demuxerstream_readuntilcb_rpc = 401;
+
+ // RPC_CDM_INITIALIZE
+ CdmInitialize cdm_initialize_rpc = 500;
+ // RPC_CDM_SETSERVERCERTIFICATE
+ CdmSetServerCertificate cdm_setservercertificate_rpc = 501;
+ // RPC_CDM_CREATESESSIONANDGENERATEREQUEST
+ CdmCreateSessionAndGenerateRequest cdm_createsessionandgeneraterequest_rpc =
+ 502;
+ // RPC_CDM_LOADSESSION
+ CdmLoadSession cdm_loadsession_rpc = 503;
+ // RPC_CDM_UPDATESESSION
+ CdmUpdateSession cdm_updatesession_rpc = 504;
+ // RPC_CDM_CLOSESESSION
+ CdmCloseSession cdm_closesession_rpc = 505;
+ // RPC_CDM_REMOVESESSION
+ CdmRemoveSession cdm_removesession_rpc = 506;
+
+ // CdmPromise message type used for the following procedure
+ // RPC_CDM_INITIALIZE_CALLBACK
+ // RPC_CDM_SETSERVERCERTIFICATE_CALLBACK
+ // RPC_CDM_CREATESESSIONANDGENERATEREQUEST_CALLBACK
+ // RPC_CDM_LOADSESSION_CALLBACK
+ // RPC_CDM_UPDATESESSION_CALLBACK
+ // RPC_CDM_CLOSESESSION_CALLBACK
+ // RPC_CDM_REMOVESESSION_CALLBACK
+ CdmPromise cdm_promise_rpc = 600;
+
+ // RPC_CDMC_ONSESSIONMESSAGE
+ CdmClientOnSessionMessage cdmclient_onsessionmessage_rpc = 601;
+ // RPC_CDMC_ONSESSIONKEYSCHANGE
+ CdmClientOnSessionKeysChange cdmclient_onsessionkeychange_rpc = 602;
+ // RPC_CDMC_ONSESSIONEXPIRATIONUPDATE
+ CdmClientOnSessionExpirationUpdate cdmclient_onsessionexpirationupdate_rpc =
+ 603;
+ };
+}
« no previous file with comments | « media/remoting/README ('k') | media/remoting/rpc/proto_enum_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698