Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {$ifndef NO_SMART_LINK}
- {$smartlink on}
- {$endif}
- unit lrtmp;
- interface
- {$PACKRECORDS C}
- uses
- ctypes,
- sockets;
- Const
- {$ifdef windows}
- LibRtmp = 'librtmp'; // Library name
- { matching lib version for librtmp.dll, needed for initialization }
- RTMP_LIBRTMP_VER_STRING='2.3';
- {$else windows}
- LibRtmp = 'rtmp'; // Library name
- { matching lib version for librtmp, needed for initialization }
- RTMP_LIBRTMP_VER_STRING='2.3';
- {$endif windows}
- {$I inttypes}
- {AMF Constants}
- Const
- AMF_NUMBER = 0;
- AMF_BOOLEAN = 1;
- AMF_STRING = 2;
- AMF_OBJECT = 3;
- AMF_MOVIECLIP = 4;
- AMF_NULL = 5;
- AMF_UNDEFINED = 6;
- AMF_REFERENCE = 7;
- AMF_ECMA_ARRAY = 8;
- AMF_OBJECT_END = 9;
- AMF_STRICT_ARRAY = 10;
- AMF_DATE = 11;
- AMF_LONG_STRING = 12;
- AMF_UNSUPPORTED = 13;
- AMF_RECORDSET = 14;
- AMF_XML_DOC = 15;
- AMF_TYPED_OBJECT = 16;
- AMF_AVMPLUS = 17;
- AMF_INVALID = $ff;
- AMF3_UNDEFINED = 0;
- AMF3_NULL = 1;
- AMF3_FALSE = 2;
- AMF3_TRUE = 3;
- AMF3_INTEGER = 4;
- AMF3_DOUBLE = 5;
- AMF3_STRING = 6;
- AMF3_XML_DOC = 7;
- AMF3_DATE = 8;
- AMF3_ARRAY = 9;
- AMF3_OBJECT = 10;
- AMF3_XML = 11;
- AMF3_BYTE_ARRAY = 12;
- {RTMP Constants}
- const
- RTMP_LIB_VERSION = $020300;
- RTMP_FEATURE_HTTP = $01;
- RTMP_FEATURE_ENC = $02;
- RTMP_FEATURE_SSL = $04;
- RTMP_FEATURE_MFP = $08;
- RTMP_FEATURE_WRITE = $10;
- RTMP_FEATURE_HTTP2 = $20;
- RTMP_PROTOCOL_UNDEFINED = -(1);
- RTMP_PROTOCOL_RTMP = 0;
- RTMP_PROTOCOL_RTMPE = RTMP_FEATURE_ENC;
- RTMP_PROTOCOL_RTMPT = RTMP_FEATURE_HTTP;
- RTMP_PROTOCOL_RTMPS = RTMP_FEATURE_SSL;
- RTMP_PROTOCOL_RTMPTE = RTMP_FEATURE_HTTP or RTMP_FEATURE_ENC;
- RTMP_PROTOCOL_RTMPTS = RTMP_FEATURE_HTTP or RTMP_FEATURE_SSL;
- RTMP_PROTOCOL_RTMFP = RTMP_FEATURE_MFP;
- RTMP_DEFAULT_CHUNKSIZE = 128;
- RTMP_BUFFER_CACHE_SIZE = 16*1024;
- RTMP_CHANNELS = 65600;
- RTMP_PACKET_TYPE_AUDIO = $08;
- RTMP_PACKET_TYPE_VIDEO = $09;
- RTMP_PACKET_TYPE_INFO = $12;
- RTMP_MAX_HEADER_SIZE = 18;
- RTMP_PACKET_SIZE_LARGE = 0;
- RTMP_PACKET_SIZE_MEDIUM = 1;
- RTMP_PACKET_SIZE_SMALL = 2;
- RTMP_PACKET_SIZE_MINIMUM = 3;
- RTMP_LF_AUTH = $0001;
- RTMP_LF_LIVE = $0002;
- RTMP_LF_SWFV = $0004;
- RTMP_LF_PLST = $0008;
- RTMP_LF_BUFX = $0010;
- RTMP_LF_FTCU = $0020;
- RTMP_SWF_HASHLEN = 32;
- RTMP_READ_HEADER = $01;
- RTMP_READ_RESUME = $02;
- RTMP_READ_NO_IGNORE = $04;
- RTMP_READ_GOTKF = $08;
- RTMP_READ_GOTFLVK = $10;
- RTMP_READ_SEEKING = $20;
- RTMP_READ_COMPLETE = -(3);
- RTMP_READ_ERROR = -(2);
- RTMP_READ_EOF = -(1);
- RTMP_READ_IGNORE = 0;
- {AMF Types}
- Type
- AVal = record
- av_val : pcchar;
- av_len : cint;
- end;
- PAVal = ^AVal;
- AMF3ClassDef = record
- cd_name : AVal;
- cd_externalizable : cchar;
- cd_dynamic : cchar;
- cd_num : cint;
- cd_props : PAVal;
- end;
- PAMF3ClassDef = ^AMF3ClassDef;
- AMF3DataType = Longint;
- PAMF3DataType = ^AMF3DataType;
- AMFDataType = Longint;
- PAMFDataType = ^AMFDataType;
- AMFObjectProperty = record
- {undefined structure}
- end;
- PAMFObjectProperty = ^AMFObjectProperty;
- AMFObject = record
- o_num : cint;
- o_props : PAMFObjectProperty;
- end;
- PAMFObject = ^AMFObject;
- {RTMP Types}
- Type
- TArray0toRTMP_SWF_HASHLEN1OfUint8_t = array[0..(RTMP_SWF_HASHLEN)-1] of uint8_t;
- TArray0toRTMP_SWF_HASHLEN101OfCchar = array[0..(RTMP_SWF_HASHLEN+10)-1] of cchar;
- TArray0toRTMP_MAX_HEADER_SIZE1OfCchar = array[0..(RTMP_MAX_HEADER_SIZE)-1] of cchar;
- TArray0toRTMP_CHANNELS1OfCint = array[0..(RTMP_CHANNELS)-1] of cint;
- TArray0toRTMP_BUFFER_CACHE_SIZE1OfCchar = array[0..(RTMP_BUFFER_CACHE_SIZE)-1] of cchar;
- TArray0to6OfPcchar = array[0..6] of pcchar;
- RTMPChunk = record
- c_headerSize : cint;
- c_chunkSize : cint;
- c_chunk : pcchar;
- c_header : TArray0toRTMP_MAX_HEADER_SIZE1OfCchar;
- end;
- PRTMPChunk = ^RTMPChunk;
- RTMPPacket = record
- m_headerType : uint8_t;
- m_packetType : uint8_t;
- m_hasAbsTimestamp : uint8_t;
- m_nChannel : cint;
- m_nTimeStamp : uint32_t;
- m_nInfoField2 : int32_t;
- m_nBodySize : uint32_t;
- m_nBytesRead : uint32_t;
- m_chunk : PRTMPChunk;
- m_body : pcchar;
- end;
- PRTMPPacket = ^RTMPPacket;
- TArray0toRTMP_CHANNELS1OfPRTMPPacket = array[0..(RTMP_CHANNELS)-1] of PRTMPPacket;
- RTMPSockBuf = record
- sb_socket : cint;
- sb_size : cint;
- sb_start : pcchar;
- sb_buf : TArray0toRTMP_BUFFER_CACHE_SIZE1OfCchar;
- sb_timedout : cint;
- sb_ssl : pointer;
- end;
- RTMP_LNK = record
- hostname : AVal;
- sockshost : AVal;
- playpath0 : AVal;
- playpath : AVal;
- tcUrl : AVal;
- swfUrl : AVal;
- pageUrl : AVal;
- app : AVal;
- auth : AVal;
- flashVer : AVal;
- subscribepath : AVal;
- token : AVal;
- extras : AMFObject;
- edepth : cint;
- seekTime : cint;
- stopTime : cint;
- lFlags : cint;
- swfAge : cint;
- protocol : cint;
- timeout : cint;
- socksport : cushort;
- port : cushort;
- dh : pointer;
- rc4keyIn : pointer;
- rc4keyOut : pointer;
- SWFSize : uint32_t;
- SWFHash : TArray0toRTMP_SWF_HASHLEN1OfUint8_t;
- SWFVerificationResponse : TArray0toRTMP_SWF_HASHLEN101OfCchar;
- end;
- RTMP_READ = record
- buf : pcchar;
- bufpos : pcchar;
- buflen : cuint;
- timestamp : uint32_t;
- dataType : uint8_t;
- flags : uint8_t;
- status : int8_t;
- initialFrameType : uint8_t;
- nResumeTS : uint32_t;
- metaHeader : pcchar;
- initialFrame : pcchar;
- nMetaHeaderSize : uint32_t;
- nInitialFrameSize : uint32_t;
- nIgnoredFrameCounter : uint32_t;
- nIgnoredFlvFrameCounter : uint32_t;
- end;
- RTMP_METHOD = record
- name : AVal;
- num : cint;
- end;
- PRTMP_METHOD = ^RTMP_METHOD;
- RTMP = record
- m_inChunkSize : cint;
- m_outChunkSize : cint;
- m_nBWCheckCounter : cint;
- m_nBytesIn : cint;
- m_nBytesInSent : cint;
- m_nBufferMS : cint;
- m_stream_id : cint;
- m_mediaChannel : cint;
- m_mediaStamp : uint32_t;
- m_pauseStamp : uint32_t;
- m_pausing : cint;
- m_nServerBW : cint;
- m_nClientBW : cint;
- m_nClientBW2 : uint8_t;
- m_bPlaying : uint8_t;
- m_bSendEncoding : uint8_t;
- m_bSendCounter : uint8_t;
- m_numInvokes : cint;
- m_numCalls : cint;
- m_methodCalls : PRTMP_METHOD;
- m_vecChannelsIn : TArray0toRTMP_CHANNELS1OfPRTMPPacket;
- m_vecChannelsOut : TArray0toRTMP_CHANNELS1OfPRTMPPacket;
- m_channelTimestamp : TArray0toRTMP_CHANNELS1OfCint;
- m_fAudioCodecs : double;
- m_fVideoCodecs : double;
- m_fEncoding : double;
- m_fDuration : double;
- m_msgCounter : cint;
- m_polling : cint;
- m_resplen : cint;
- m_unackd : cint;
- m_clientID : AVal;
- m_read : RTMP_READ;
- m_write : RTMPPacket;
- m_sb : RTMPSockBuf;
- Link : RTMP_LNK;
- end;
- PRTMP = ^RTMP;
- PRTMP_LNK = ^RTMP_LNK;
- PRTMP_READ = ^RTMP_READ;
- PRTMPSockBuf = ^RTMPSockBuf;
- {RTMP Variables}
- var
- RTMPProtocolStringsLower : TArray0to6OfPcchar;cvar;external;
- RTMP_DefaultFlashVer : AVal;cvar;external;
- RTMP_ctrlC : cint;cvar;external;
- {AMF Functions}
- function AMF_EncodeString(output:pcchar; outend:pcchar; var str:AVal):pcchar;cdecl;external External_library name 'AMF_EncodeString';
- function AMF_EncodeNumber(output:pcchar; outend:pcchar; dVal:double):pcchar;cdecl;external External_library name 'AMF_EncodeNumber';
- function AMF_EncodeInt16(output:pcchar; outend:pcchar; nVal:cshort):pcchar;cdecl;external External_library name 'AMF_EncodeInt16';
- function AMF_EncodeInt24(output:pcchar; outend:pcchar; nVal:cint):pcchar;cdecl;external External_library name 'AMF_EncodeInt24';
- function AMF_EncodeInt32(output:pcchar; outend:pcchar; nVal:cint):pcchar;cdecl;external External_library name 'AMF_EncodeInt32';
- function AMF_EncodeBoolean(output:pcchar; outend:pcchar; bVal:cint):pcchar;cdecl;external External_library name 'AMF_EncodeBoolean';
- function AMF_EncodeNamedString(output:pcchar; outend:pcchar; var name:AVal; var value:AVal):pcchar;cdecl;external External_library name 'AMF_EncodeNamedString';
- function AMF_EncodeNamedNumber(output:pcchar; outend:pcchar; var name:AVal; dVal:double):pcchar;cdecl;external External_library name 'AMF_EncodeNamedNumber';
- function AMF_EncodeNamedBoolean(output:pcchar; outend:pcchar; var name:AVal; bVal:cint):pcchar;cdecl;external External_library name 'AMF_EncodeNamedBoolean';
- function AMF_DecodeInt16(data:pcchar):cushort;cdecl;external External_library name 'AMF_DecodeInt16';
- function AMF_DecodeInt24(data:pcchar):cuint;cdecl;external External_library name 'AMF_DecodeInt24';
- function AMF_DecodeInt32(data:pcchar):cuint;cdecl;external External_library name 'AMF_DecodeInt32';
- procedure AMF_DecodeString(data:pcchar; var str:AVal);cdecl;external External_library name 'AMF_DecodeString';
- procedure AMF_DecodeLongString(data:pcchar; var str:AVal);cdecl;external External_library name 'AMF_DecodeLongString';
- function AMF_DecodeBoolean(data:pcchar):cint;cdecl;external External_library name 'AMF_DecodeBoolean';
- function AMF_DecodeNumber(data:pcchar):double;cdecl;external External_library name 'AMF_DecodeNumber';
- function AMF_Encode(var obj:AMFObject; pBuffer:pcchar; pBufEnd:pcchar):pcchar;cdecl;external External_library name 'AMF_Encode';
- function AMF_Decode(var obj:AMFObject; pBuffer:pcchar; nSize:cint; bDecodeName:cint):cint;cdecl;external External_library name 'AMF_Decode';
- function AMF_DecodeArray(var obj:AMFObject; pBuffer:pcchar; nSize:cint; nArrayLen:cint; bDecodeName:cint):cint;cdecl;external External_library name 'AMF_DecodeArray';
- function AMF3_Decode(var obj:AMFObject; pBuffer:pcchar; nSize:cint; bDecodeName:cint):cint;cdecl;external External_library name 'AMF3_Decode';
- procedure AMF_Dump(var obj:AMFObject);cdecl;external External_library name 'AMF_Dump';
- procedure AMF_Reset(var obj:AMFObject);cdecl;external External_library name 'AMF_Reset';
- procedure AMF_AddProp(var obj:AMFObject; var prop:AMFObjectProperty);cdecl;external External_library name 'AMF_AddProp';
- function AMF_CountProp(var obj:AMFObject):cint;cdecl;external External_library name 'AMF_CountProp';
- function AMF_GetProp(var obj:AMFObject; var name:AVal; nIndex:cint):PAMFObjectProperty;cdecl;external External_library name 'AMF_GetProp';
- function AMFProp_GetType(var prop:AMFObjectProperty):AMFDataType;cdecl;external External_library name 'AMFProp_GetType';
- procedure AMFProp_SetNumber(var prop:AMFObjectProperty; dval:double);cdecl;external External_library name 'AMFProp_SetNumber';
- procedure AMFProp_SetBoolean(var prop:AMFObjectProperty; bflag:cint);cdecl;external External_library name 'AMFProp_SetBoolean';
- procedure AMFProp_SetString(var prop:AMFObjectProperty; var str:AVal);cdecl;external External_library name 'AMFProp_SetString';
- procedure AMFProp_SetObject(var prop:AMFObjectProperty; var obj:AMFObject);cdecl;external External_library name 'AMFProp_SetObject';
- procedure AMFProp_GetName(var prop:AMFObjectProperty; var name:AVal);cdecl;external External_library name 'AMFProp_GetName';
- procedure AMFProp_SetName(var prop:AMFObjectProperty; var name:AVal);cdecl;external External_library name 'AMFProp_SetName';
- function AMFProp_GetNumber(var prop:AMFObjectProperty):double;cdecl;external External_library name 'AMFProp_GetNumber';
- function AMFProp_GetBoolean(var prop:AMFObjectProperty):cint;cdecl;external External_library name 'AMFProp_GetBoolean';
- procedure AMFProp_GetString(var prop:AMFObjectProperty; var str:AVal);cdecl;external External_library name 'AMFProp_GetString';
- procedure AMFProp_GetObject(var prop:AMFObjectProperty; var obj:AMFObject);cdecl;external External_library name 'AMFProp_GetObject';
- function AMFProp_IsValid(var prop:AMFObjectProperty):cint;cdecl;external External_library name 'AMFProp_IsValid';
- function AMFProp_Encode(var prop:AMFObjectProperty; pBuffer:pcchar; pBufEnd:pcchar):pcchar;cdecl;external External_library name 'AMFProp_Encode';
- function AMF3Prop_Decode(var prop:AMFObjectProperty; pBuffer:pcchar; nSize:cint; bDecodeName:cint):cint;cdecl;external External_library name 'AMF3Prop_Decode';
- function AMFProp_Decode(var prop:AMFObjectProperty; pBuffer:pcchar; nSize:cint; bDecodeName:cint):cint;cdecl;external External_library name 'AMFProp_Decode';
- procedure AMFProp_Dump(var prop:AMFObjectProperty);cdecl;external External_library name 'AMFProp_Dump';
- procedure AMFProp_Reset(var prop:AMFObjectProperty);cdecl;external External_library name 'AMFProp_Reset';
- procedure AMF3CD_AddProp(var cd:AMF3ClassDef; var prop:AVal);cdecl;external External_library name 'AMF3CD_AddProp';
- function AMF3CD_GetProp(var cd:AMF3ClassDef; idx:cint):PAVal;cdecl;external External_library name 'AMF3CD_GetProp';
- {RTMP Functions}
- procedure RTMPPacket_Reset(var p:RTMPPacket);cdecl;external External_library name 'RTMPPacket_Reset';
- procedure RTMPPacket_Dump(var p:RTMPPacket);cdecl;external External_library name 'RTMPPacket_Dump';
- function RTMPPacket_Alloc(var p:RTMPPacket; nSize:cint):cint;cdecl;external External_library name 'RTMPPacket_Alloc';
- procedure RTMPPacket_Free(var p:RTMPPacket);cdecl;external External_library name 'RTMPPacket_Free';
- function RTMP_GetTime:uint32_t;cdecl;external External_library name 'RTMP_GetTime';
- function RTMP_ParseURL(url:pcchar; var protocol:cint; var host:AVal; var port:cuint; var playpath:AVal;
- var app:AVal):cint;cdecl;external External_library name 'RTMP_ParseURL';
- procedure RTMP_ParsePlaypath(var input:AVal; var output:AVal);cdecl;external External_library name 'RTMP_ParsePlaypath';
- procedure RTMP_SetBufferMS(var r:RTMP; size:cint);cdecl;external External_library name 'RTMP_SetBufferMS';
- procedure RTMP_UpdateBufferMS(var r:RTMP);cdecl;external External_library name 'RTMP_UpdateBufferMS';
- function RTMP_SetOpt(var r:RTMP; var opt:AVal; var arg:AVal):cint;cdecl;external External_library name 'RTMP_SetOpt';
- function RTMP_SetupURL(var r:RTMP; url:pcchar):cint;cdecl;external External_library name 'RTMP_SetupURL';
- procedure RTMP_SetupStream(var r:RTMP; protocol:cint; var hostname:AVal; port:cuint; var sockshost:AVal;
- var playpath:AVal; var tcUrl:AVal; var swfUrl:AVal; var pageUrl:AVal; var app:AVal;
- var auth:AVal; var swfSHA256Hash:AVal; swfSize:uint32_t; var flashVer:AVal; var subscribepath:AVal;
- dStart:cint; dStop:cint; bLiveStream:cint; timeout:clong);cdecl;external External_library name 'RTMP_SetupStream';
- function RTMP_Connect(var r:RTMP; var cp:RTMPPacket):cint;cdecl;external External_library name 'RTMP_Connect';
- function RTMP_Connect0(var r:RTMP; var svc:sockaddr):cint;cdecl;external External_library name 'RTMP_Connect0';
- function RTMP_Connect1(var r:RTMP; var cp:RTMPPacket):cint;cdecl;external External_library name 'RTMP_Connect1';
- function RTMP_Serve(var r:RTMP):cint;cdecl;external External_library name 'RTMP_Serve';
- function RTMP_ReadPacket(var r:RTMP; var packet:RTMPPacket):cint;cdecl;external External_library name 'RTMP_ReadPacket';
- function RTMP_SendPacket(var r:RTMP; var packet:RTMPPacket; queue:cint):cint;cdecl;external External_library name 'RTMP_SendPacket';
- function RTMP_SendChunk(var r:RTMP; var chunk:RTMPChunk):cint;cdecl;external External_library name 'RTMP_SendChunk';
- function RTMP_IsConnected(var r:RTMP):cint;cdecl;external External_library name 'RTMP_IsConnected';
- function RTMP_Socket(var r:RTMP):cint;cdecl;external External_library name 'RTMP_Socket';
- function RTMP_IsTimedout(var r:RTMP):cint;cdecl;external External_library name 'RTMP_IsTimedout';
- function RTMP_GetDuration(var r:RTMP):double;cdecl;external External_library name 'RTMP_GetDuration';
- function RTMP_ToggleStream(var r:RTMP):cint;cdecl;external External_library name 'RTMP_ToggleStream';
- function RTMP_ConnectStream(var r:RTMP; seekTime:cint):cint;cdecl;external External_library name 'RTMP_ConnectStream';
- function RTMP_ReconnectStream(var r:RTMP; seekTime:cint):cint;cdecl;external External_library name 'RTMP_ReconnectStream';
- procedure RTMP_DeleteStream(var r:RTMP);cdecl;external External_library name 'RTMP_DeleteStream';
- function RTMP_GetNextMediaPacket(var r:RTMP; var packet:RTMPPacket):cint;cdecl;external External_library name 'RTMP_GetNextMediaPacket';
- function RTMP_ClientPacket(var r:RTMP; var packet:RTMPPacket):cint;cdecl;external External_library name 'RTMP_ClientPacket';
- procedure RTMP_Init(var r:RTMP);cdecl;external External_library name 'RTMP_Init';
- procedure RTMP_Close(var r:RTMP);cdecl;external External_library name 'RTMP_Close';
- function RTMP_Alloc:PRTMP;cdecl;external External_library name 'RTMP_Alloc';
- procedure RTMP_Free(var r:RTMP);cdecl;external External_library name 'RTMP_Free';
- procedure RTMP_EnableWrite(var r:RTMP);cdecl;external External_library name 'RTMP_EnableWrite';
- function RTMP_LibVersion:cint;cdecl;external External_library name 'RTMP_LibVersion';
- procedure RTMP_UserInterrupt;cdecl;external External_library name 'RTMP_UserInterrupt';
- function RTMP_SendCtrl(var r:RTMP; nType:cshort; nObject:cuint; nTime:cuint):cint;cdecl;external External_library name 'RTMP_SendCtrl';
- function RTMP_SendPause(var r:RTMP; DoPause:cint; dTime:cint):cint;cdecl;external External_library name 'RTMP_SendPause';
- function RTMP_Pause(var r:RTMP; DoPause:cint):cint;cdecl;external External_library name 'RTMP_Pause';
- function RTMP_FindFirstMatchingProperty(var obj:AMFObject; var name:AVal; var p:AMFObjectProperty):cint;cdecl;external External_library name 'RTMP_FindFirstMatchingProperty';
- function RTMPSockBuf_Fill(var sb:RTMPSockBuf):cint;cdecl;external External_library name 'RTMPSockBuf_Fill';
- function RTMPSockBuf_Send(var sb:RTMPSockBuf; buf:pcchar; len:cint):cint;cdecl;external External_library name 'RTMPSockBuf_Send';
- function RTMPSockBuf_Close(var sb:RTMPSockBuf):cint;cdecl;external External_library name 'RTMPSockBuf_Close';
- function RTMP_SendCreateStream(var r:RTMP):cint;cdecl;external External_library name 'RTMP_SendCreateStream';
- function RTMP_SendSeek(var r:RTMP; dTime:cint):cint;cdecl;external External_library name 'RTMP_SendSeek';
- function RTMP_SendServerBW(var r:RTMP):cint;cdecl;external External_library name 'RTMP_SendServerBW';
- function RTMP_SendClientBW(var r:RTMP):cint;cdecl;external External_library name 'RTMP_SendClientBW';
- procedure RTMP_DropRequest(var r:RTMP; i:cint; freeit:cint);cdecl;external External_library name 'RTMP_DropRequest';
- function RTMP_ReadData(var r:RTMP; buf:pcchar; size:cint):cint;cdecl;external External_library name 'RTMP_ReadData';
- function RTMP_WriteData(var r:RTMP; buf:pcchar; size:cint):cint;cdecl;external External_library name 'RTMP_WriteData';
- function RTMP_HashSWF(url:pcchar; var size:cuint; hash:pcuchar; age:cint):cint;cdecl;external External_library name 'RTMP_HashSWF';
- implementation
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement