425 lines
13 KiB
C
425 lines
13 KiB
C
#ifndef __RTMP_H__
|
|
#define __RTMP_H__
|
|
/*
|
|
* Copyright (C) 2005-2008 Team XBMC
|
|
* http://www.xbmc.org
|
|
* Copyright (C) 2008-2009 Andrej Stepanchuk
|
|
* Copyright (C) 2009-2010 Howard Chu
|
|
*
|
|
* This file is part of librtmp.
|
|
*
|
|
* librtmp is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1,
|
|
* or (at your option) any later version.
|
|
*
|
|
* librtmp is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with librtmp see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/lgpl.html
|
|
*/
|
|
|
|
#if !defined(NO_CRYPTO) && !defined(CRYPTO)
|
|
#define CRYPTO
|
|
#else
|
|
#include <sys/types.h> //for off_t
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef _WIN32
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable:4996) //depricated warnings
|
|
#pragma warning(disable:4244) //64bit defensive mechanism, fixed the ones that mattered
|
|
#endif
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#else
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#define SOCKET int
|
|
#endif
|
|
|
|
#include "amf.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#define RTMP_LIB_VERSION 0x020300 /* 2.3 */
|
|
|
|
#define RTMP_FEATURE_HTTP 0x01
|
|
#define RTMP_FEATURE_ENC 0x02
|
|
#define RTMP_FEATURE_SSL 0x04
|
|
#define RTMP_FEATURE_MFP 0x08 /* not yet supported */
|
|
#define RTMP_FEATURE_WRITE 0x10 /* publish, not play */
|
|
#define RTMP_FEATURE_HTTP2 0x20 /* server-side rtmpt */
|
|
|
|
#define RTMP_PROTOCOL_UNDEFINED -1
|
|
#define RTMP_PROTOCOL_RTMP 0
|
|
#define RTMP_PROTOCOL_RTMPE RTMP_FEATURE_ENC
|
|
#define RTMP_PROTOCOL_RTMPT RTMP_FEATURE_HTTP
|
|
#define RTMP_PROTOCOL_RTMPS RTMP_FEATURE_SSL
|
|
#define RTMP_PROTOCOL_RTMPTE (RTMP_FEATURE_HTTP|RTMP_FEATURE_ENC)
|
|
#define RTMP_PROTOCOL_RTMPTS (RTMP_FEATURE_HTTP|RTMP_FEATURE_SSL)
|
|
#define RTMP_PROTOCOL_RTMFP RTMP_FEATURE_MFP
|
|
|
|
#define RTMP_DEFAULT_CHUNKSIZE 128
|
|
|
|
/* needs to fit largest number of bytes recv() may return */
|
|
#define RTMP_BUFFER_CACHE_SIZE (16*1024)
|
|
|
|
#define RTMP_CHANNELS 65600
|
|
|
|
extern const char RTMPProtocolStringsLower[][7];
|
|
extern const AVal RTMP_DefaultFlashVer;
|
|
extern int RTMP_ctrlC;
|
|
|
|
uint32_t RTMP_GetTime(void);
|
|
|
|
/* RTMP_PACKET_TYPE_... 0x00 */
|
|
#define RTMP_PACKET_TYPE_CHUNK_SIZE 0x01
|
|
/* RTMP_PACKET_TYPE_... 0x02 */
|
|
#define RTMP_PACKET_TYPE_BYTES_READ_REPORT 0x03
|
|
#define RTMP_PACKET_TYPE_CONTROL 0x04
|
|
#define RTMP_PACKET_TYPE_SERVER_BW 0x05
|
|
#define RTMP_PACKET_TYPE_CLIENT_BW 0x06
|
|
/* RTMP_PACKET_TYPE_... 0x07 */
|
|
#define RTMP_PACKET_TYPE_AUDIO 0x08
|
|
#define RTMP_PACKET_TYPE_VIDEO 0x09
|
|
/* RTMP_PACKET_TYPE_... 0x0A */
|
|
/* RTMP_PACKET_TYPE_... 0x0B */
|
|
/* RTMP_PACKET_TYPE_... 0x0C */
|
|
/* RTMP_PACKET_TYPE_... 0x0D */
|
|
/* RTMP_PACKET_TYPE_... 0x0E */
|
|
#define RTMP_PACKET_TYPE_FLEX_STREAM_SEND 0x0F
|
|
#define RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT 0x10
|
|
#define RTMP_PACKET_TYPE_FLEX_MESSAGE 0x11
|
|
#define RTMP_PACKET_TYPE_INFO 0x12
|
|
#define RTMP_PACKET_TYPE_SHARED_OBJECT 0x13
|
|
#define RTMP_PACKET_TYPE_INVOKE 0x14
|
|
/* RTMP_PACKET_TYPE_... 0x15 */
|
|
#define RTMP_PACKET_TYPE_FLASH_VIDEO 0x16
|
|
|
|
#define RTMP_MAX_HEADER_SIZE 18
|
|
|
|
#define RTMP_PACKET_SIZE_LARGE 0
|
|
#define RTMP_PACKET_SIZE_MEDIUM 1
|
|
#define RTMP_PACKET_SIZE_SMALL 2
|
|
#define RTMP_PACKET_SIZE_MINIMUM 3
|
|
|
|
typedef struct RTMPChunk
|
|
{
|
|
int c_headerSize;
|
|
int c_chunkSize;
|
|
char *c_chunk;
|
|
char c_header[RTMP_MAX_HEADER_SIZE];
|
|
} RTMPChunk;
|
|
|
|
typedef struct RTMPPacket
|
|
{
|
|
uint8_t m_headerType;
|
|
uint8_t m_packetType;
|
|
uint8_t m_hasAbsTimestamp; /* timestamp absolute or relative? */
|
|
int m_nChannel;
|
|
uint32_t m_nTimeStamp; /* timestamp */
|
|
int32_t m_nInfoField2; /* last 4 bytes in a long header */
|
|
uint32_t m_nBodySize;
|
|
uint32_t m_nBytesRead;
|
|
RTMPChunk *m_chunk;
|
|
char *m_body;
|
|
} RTMPPacket;
|
|
|
|
typedef struct RTMPSockBuf
|
|
{
|
|
SOCKET sb_socket;
|
|
int sb_size; /* number of unprocessed bytes in buffer */
|
|
char *sb_start; /* pointer into sb_pBuffer of next byte to process */
|
|
char sb_buf[RTMP_BUFFER_CACHE_SIZE]; /* data read from socket */
|
|
int sb_timedout;
|
|
void *sb_ssl;
|
|
} RTMPSockBuf;
|
|
|
|
void RTMPPacket_Reset(RTMPPacket *p);
|
|
void RTMPPacket_Dump(RTMPPacket *p);
|
|
int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize);
|
|
void RTMPPacket_Free(RTMPPacket *p);
|
|
|
|
#define RTMPPacket_IsReady(a) ((a)->m_nBytesRead == (a)->m_nBodySize)
|
|
|
|
typedef struct RTMP_Stream {
|
|
int id;
|
|
AVal playpath;
|
|
} RTMP_Stream;
|
|
|
|
typedef struct RTMP_LNK
|
|
{
|
|
#define RTMP_MAX_STREAMS 8
|
|
RTMP_Stream streams[RTMP_MAX_STREAMS];
|
|
int nStreams;
|
|
int curStreamIdx;
|
|
int playingStreams;
|
|
|
|
AVal hostname;
|
|
AVal sockshost;
|
|
|
|
AVal tcUrl;
|
|
AVal swfUrl;
|
|
AVal pageUrl;
|
|
AVal app;
|
|
AVal auth;
|
|
AVal flashVer;
|
|
AVal subscribepath;
|
|
AVal usherToken;
|
|
AVal token;
|
|
AVal pubUser;
|
|
AVal pubPasswd;
|
|
AMFObject extras;
|
|
int edepth;
|
|
|
|
int seekTime;
|
|
int stopTime;
|
|
|
|
#define RTMP_LF_AUTH 0x0001 /* using auth param */
|
|
#define RTMP_LF_LIVE 0x0002 /* stream is live */
|
|
#define RTMP_LF_SWFV 0x0004 /* do SWF verification */
|
|
#define RTMP_LF_PLST 0x0008 /* send playlist before play */
|
|
#define RTMP_LF_BUFX 0x0010 /* toggle stream on BufferEmpty msg */
|
|
#define RTMP_LF_FTCU 0x0020 /* free tcUrl on close */
|
|
int lFlags;
|
|
|
|
int swfAge;
|
|
|
|
int protocol;
|
|
int timeout; /* connection timeout in seconds */
|
|
|
|
#define RTMP_PUB_NAME 0x0001 /* send login to server */
|
|
#define RTMP_PUB_RESP 0x0002 /* send salted password hash */
|
|
#define RTMP_PUB_ALLOC 0x0004 /* allocated data for new tcUrl & app */
|
|
#define RTMP_PUB_CLEAN 0x0008 /* need to free allocated data for newer tcUrl & app at exit */
|
|
#define RTMP_PUB_CLATE 0x0010 /* late clean tcUrl & app at exit */
|
|
int pFlags;
|
|
|
|
unsigned short socksport;
|
|
unsigned short port;
|
|
|
|
#ifdef CRYPTO
|
|
#define RTMP_SWF_HASHLEN 32
|
|
void *dh; /* for encryption */
|
|
void *rc4keyIn;
|
|
void *rc4keyOut;
|
|
|
|
uint32_t SWFSize;
|
|
uint8_t SWFHash[RTMP_SWF_HASHLEN];
|
|
char SWFVerificationResponse[RTMP_SWF_HASHLEN+10];
|
|
#endif
|
|
} RTMP_LNK;
|
|
|
|
/* state for read() wrapper */
|
|
typedef struct RTMP_READ
|
|
{
|
|
char *buf;
|
|
char *bufpos;
|
|
unsigned int buflen;
|
|
uint32_t timestamp;
|
|
uint8_t dataType;
|
|
uint8_t flags;
|
|
#define RTMP_READ_HEADER 0x01
|
|
#define RTMP_READ_RESUME 0x02
|
|
#define RTMP_READ_NO_IGNORE 0x04
|
|
#define RTMP_READ_GOTKF 0x08
|
|
#define RTMP_READ_GOTFLVK 0x10
|
|
#define RTMP_READ_SEEKING 0x20
|
|
int8_t status;
|
|
#define RTMP_READ_COMPLETE -3
|
|
#define RTMP_READ_ERROR -2
|
|
#define RTMP_READ_EOF -1
|
|
#define RTMP_READ_IGNORE 0
|
|
|
|
/* if bResume == TRUE */
|
|
uint8_t initialFrameType;
|
|
uint32_t nResumeTS;
|
|
char *metaHeader;
|
|
char *initialFrame;
|
|
uint32_t nMetaHeaderSize;
|
|
uint32_t nInitialFrameSize;
|
|
uint32_t nIgnoredFrameCounter;
|
|
uint32_t nIgnoredFlvFrameCounter;
|
|
} RTMP_READ;
|
|
|
|
typedef struct RTMP_METHOD
|
|
{
|
|
AVal name;
|
|
int num;
|
|
} RTMP_METHOD;
|
|
|
|
typedef struct RTMP_BINDINFO
|
|
{
|
|
struct sockaddr_storage addr;
|
|
int addrLen;
|
|
} RTMP_BINDINFO;
|
|
|
|
typedef int (*CUSTOMSEND)(RTMPSockBuf*, const char *, int, void*);
|
|
|
|
typedef struct RTMP
|
|
{
|
|
int m_inChunkSize;
|
|
int m_outChunkSize;
|
|
int m_nBWCheckCounter;
|
|
int m_nBytesIn;
|
|
int m_nBytesInSent;
|
|
int m_nBufferMS;
|
|
int m_stream_id; /* returned in _result from createStream */
|
|
int m_mediaChannel;
|
|
uint32_t m_mediaStamp;
|
|
uint32_t m_pauseStamp;
|
|
int m_pausing;
|
|
int m_nServerBW;
|
|
int m_nClientBW;
|
|
uint8_t m_nClientBW2;
|
|
uint8_t m_bPlaying;
|
|
uint8_t m_bSendEncoding;
|
|
uint8_t m_bSendCounter;
|
|
|
|
uint8_t m_bUseNagle;
|
|
uint8_t m_bCustomSend;
|
|
void* m_customSendParam;
|
|
CUSTOMSEND m_customSendFunc;
|
|
|
|
RTMP_BINDINFO m_bindIP;
|
|
|
|
uint8_t m_bSendChunkSizeInfo;
|
|
|
|
int m_numInvokes;
|
|
int m_numCalls;
|
|
RTMP_METHOD *m_methodCalls; /* remote method calls queue */
|
|
|
|
int m_channelsAllocatedIn;
|
|
int m_channelsAllocatedOut;
|
|
RTMPPacket **m_vecChannelsIn;
|
|
RTMPPacket **m_vecChannelsOut;
|
|
int *m_channelTimestamp; /* abs timestamp of last packet */
|
|
|
|
double m_fAudioCodecs; /* audioCodecs for the connect packet */
|
|
double m_fVideoCodecs; /* videoCodecs for the connect packet */
|
|
double m_fEncoding; /* AMF0 or AMF3 */
|
|
|
|
double m_fDuration; /* duration of stream in seconds */
|
|
|
|
int m_msgCounter; /* RTMPT stuff */
|
|
int m_polling;
|
|
int m_resplen;
|
|
int m_unackd;
|
|
AVal m_clientID;
|
|
|
|
RTMP_READ m_read;
|
|
RTMPPacket m_write;
|
|
RTMPSockBuf m_sb;
|
|
RTMP_LNK Link;
|
|
int connect_time_ms;
|
|
int last_error_code;
|
|
} RTMP;
|
|
|
|
int RTMP_ParseURL(const char *url, int *protocol, AVal *host,
|
|
unsigned int *port, AVal *app);
|
|
|
|
void RTMP_ParsePlaypath(AVal *in, AVal *out);
|
|
void RTMP_SetBufferMS(RTMP *r, int size);
|
|
void RTMP_UpdateBufferMS(RTMP *r);
|
|
|
|
int RTMP_SetOpt(RTMP *r, const AVal *opt, AVal *arg);
|
|
int RTMP_SetupURL(RTMP *r, char *url);
|
|
int RTMP_AddStream(RTMP *r, const char *playpath);
|
|
void RTMP_SetupStream(RTMP *r, int protocol,
|
|
AVal *hostname,
|
|
unsigned int port,
|
|
AVal *sockshost,
|
|
AVal *playpath,
|
|
AVal *tcUrl,
|
|
AVal *swfUrl,
|
|
AVal *pageUrl,
|
|
AVal *app,
|
|
AVal *auth,
|
|
AVal *swfSHA256Hash,
|
|
uint32_t swfSize,
|
|
AVal *flashVer,
|
|
AVal *subscribepath,
|
|
AVal *usherToken,
|
|
int dStart,
|
|
int dStop, int bLiveStream, long int timeout);
|
|
|
|
int RTMP_Connect(RTMP *r, RTMPPacket *cp);
|
|
struct sockaddr;
|
|
int RTMP_Connect0(RTMP *r, struct sockaddr *svc, socklen_t addrlen);
|
|
int RTMP_Connect1(RTMP *r, RTMPPacket *cp);
|
|
int RTMP_Serve(RTMP *r);
|
|
int RTMP_TLS_Accept(RTMP *r, void *ctx);
|
|
|
|
int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet);
|
|
int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue);
|
|
int RTMP_SendChunk(RTMP *r, RTMPChunk *chunk);
|
|
int RTMP_IsConnected(RTMP *r);
|
|
SOCKET RTMP_Socket(RTMP *r);
|
|
int RTMP_IsTimedout(RTMP *r);
|
|
double RTMP_GetDuration(RTMP *r);
|
|
int RTMP_ToggleStream(RTMP *r);
|
|
|
|
int RTMP_ConnectStream(RTMP *r, int seekTime);
|
|
int RTMP_ReconnectStream(RTMP *r, int seekTime, int streamIdx);
|
|
void RTMP_DeleteStream(RTMP *r, int streamIdx);
|
|
int RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet);
|
|
int RTMP_ClientPacket(RTMP *r, RTMPPacket *packet);
|
|
|
|
void RTMP_Init(RTMP *r);
|
|
void RTMP_Close(RTMP *r);
|
|
RTMP *RTMP_Alloc(void);
|
|
void RTMP_Free(RTMP *r);
|
|
void RTMP_EnableWrite(RTMP *r);
|
|
|
|
void *RTMP_TLS_AllocServerContext(const char* cert, const char* key);
|
|
void RTMP_TLS_FreeServerContext(void *ctx);
|
|
|
|
int RTMP_LibVersion(void);
|
|
void RTMP_UserInterrupt(void); /* user typed Ctrl-C */
|
|
|
|
int RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject,
|
|
unsigned int nTime);
|
|
|
|
/* caller probably doesn't know current timestamp, should
|
|
* just use RTMP_Pause instead
|
|
*/
|
|
int RTMP_SendPause(RTMP *r, int DoPause, int dTime);
|
|
int RTMP_Pause(RTMP *r, int DoPause);
|
|
|
|
int RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name,
|
|
AMFObjectProperty * p);
|
|
|
|
int RTMPSockBuf_Fill(RTMPSockBuf *sb);
|
|
int RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len);
|
|
int RTMPSockBuf_Close(RTMPSockBuf *sb);
|
|
|
|
int RTMP_SendCreateStream(RTMP *r);
|
|
int RTMP_SendSeek(RTMP *r, int dTime);
|
|
int RTMP_SendServerBW(RTMP *r);
|
|
int RTMP_SendClientBW(RTMP *r);
|
|
void RTMP_DropRequest(RTMP *r, int i, int freeit);
|
|
int RTMP_Read(RTMP *r, char *buf, int size);
|
|
int RTMP_Write(RTMP *r, const char *buf, int size, int streamIdx);
|
|
|
|
/* hashswf.c */
|
|
int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
|
|
int age);
|
|
|
|
#ifdef __cplusplus
|
|
};
|
|
#endif
|
|
|
|
#endif
|