/*
* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/lgpl.html
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "rtmp_sys.h"
#include "log.h"
#ifdef CRYPTO
#ifdef USE_GNUTLS
#include <gnutls/gnutls.h>
#else
#include <openssl/ssl.h>
#include <openssl/rc4.h>
#endif
#endif
#define RTMP_SIG_SIZE 1536
#define RTMP_LARGE_HEADER_SIZE 12
TLS_CTX RTMP_TLS_ctx;
static const int packetSize[] = { 12, 8, 4, 1 };
bool RTMP_ctrlC;
const char RTMPProtocolStrings[][7] = {
"RTMP",
"RTMPT",
"RTMPE",
"RTMPTE",
"",
"RTMPS",
"",
"",
"RTMFP"
};
const char RTMPProtocolStringsLower[][7] = {
"rtmp",
"rtmpt",
"rtmpe",
"rtmpte",
"",
"rtmps",
"",
"",
"rtmfp"
};
static const char *RTMPT_cmds[] = {
"open",
"send",
"idle",
"close"
};
typedef enum {
RTMPT_OPEN=0, RTMPT_SEND, RTMPT_IDLE, RTMPT_CLOSE
} RTMPTCmd;
static bool DumpMetaData(AMFObject *obj);
static bool HandShake(RTMP *r, bool FP9HandShake);
static bool SocksNegotiate(RTMP *r);
static bool SendConnectPacket(RTMP *r, RTMPPacket *cp);
static bool SendCheckBW(RTMP *r);
static bool SendCheckBWResult(RTMP *r, double txn);
static bool SendDeleteStream(RTMP *r, double dStreamId);
static bool SendFCSubscribe(RTMP *r, AVal *subscribepath);
static bool SendPlay(RTMP *r);
static bool SendBytesReceived(RTMP *r);
#if 0 /* unused */
static bool SendBGHasStream(RTMP *r, double dId, AVal *playpath);
#endif
static int HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize);
static bool HandleMetadata(RTMP *r, char *body, unsigned int len);
static void HandleChangeChunkSize(RTMP *r, const RTMPPacket *packet);
static void HandleAudio(RTMP *r, const RTMPPacket *packet);
static void HandleVideo(RTMP *r, const RTMPPacket *packet);
static void HandleCtrl(RTMP *r, const RTMPPacket *packet);
static void HandleServerBW(RTMP *r, const RTMPPacket *packet);
static void HandleClientBW(RTMP *r, const RTMPPacket *packet);
static int ReadN(RTMP *r, char *buffer, int n);
static bool WriteN(RTMP *r, const char *buffer, int n);
static void DecodeTEA(AVal *key, AVal *text);
static int HTTP_Post(RTMP *r, RTMPTCmd cmd, const char *buf, int len);
static int HTTP_read(RTMP *r, int fill);
#ifndef WIN32
static int clk_tck;
#endif
#ifdef CRYPTO
#include "handshake.h"
#endif
uint32_t
RTMP_GetTime()
{
#ifdef _DEBUG
return 0;
#elif defined(WIN32)
return timeGetTime();
#else
struct tms t;
if (!clk_tck) clk_tck = sysconf(_SC_CLK_TCK);
return times(&t) * 1000 / clk_tck;
#endif
}
void
RTMP_UserInterrupt()
{
RTMP_ctrlC = true;
}
void
RTMPPacket_Reset(RTMPPacket *p)
{
p->m_headerType = 0;
p->m_packetType = 0;
p->m_nChannel = 0;
p->m_nInfoField1 = 0;
p->m_nInfoField2 = 0;
p->m_hasAbsTimestamp = false;
p->m_nBodySize = 0;
p->m_nBytesRead = 0;
}
bool
RTMPPacket_Alloc(RTMPPacket *p, int nSize)
{
char *ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE);
if (!ptr)
return false;
p->m_body = ptr + RTMP_MAX_HEADER_SIZE;
p->m_nBytesRead = 0;
return true;
}
void
RTMPPacket_Free(RTMPPacket *p)
{
if (p->m_body)
{
free(p->m_body - RTMP_MAX_HEADER_SIZE);
p->m_body = NULL;
}
}
void
RTMPPacket_Dump(RTMPPacket *p)
{
RTMP_Log(RTMP_LOGDEBUG,
"RTMP PACKET: packet type: 0x%02x. channel: 0x%02x. info 1: %d info 2: %d. Body size: %lu. body: 0x%02x",
p->m_packetType, p->m_nChannel, p->m_nInfoField1, p->m_nInfoField2,
p->m_nBodySize, p->m_body ? (unsigned char)p->m_body[0] : 0);
}
int
RTMP_LibVersion()
{
return RTMP_LIB_VERSION;
}
void
RTMP_TLS_Init()
{
#ifdef USE_GNUTLS
gnutls_global_init();
RTMP_TLS_ctx = malloc(sizeof(struct tls_ctx));
gnutls_certificate_allocate_credentials(&RTMP_TLS_ctx->cred);
gnutls_priority_init(&RTMP_TLS_ctx->prios, "NORMAL", NULL);
gnutls_certificate_set_x509_trust_file(RTMP_TLS_ctx->cred,
"ca.pem", GNUTLS_X509_FMT_PEM);
#else
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_digests();
RTMP_TLS_ctx = SSL_CTX_new(SSLv23_method());
SSL_CTX_set_options(RTMP_TLS_ctx, SSL_OP_ALL);
SSL_CTX_set_default_verify_paths(RTMP_TLS_ctx);
#endif
}
void
RTMP_Init(RTMP *r)
{
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
memset(r, 0, sizeof(RTMP));
r->m_sb.sb_socket = -1;
r->m_inChunkSize = RTMP_DEFAULT_CHUNKSIZE;
r->m_outChunkSize = RTMP_DEFAULT_CHUNKSIZE;
r->m_nBufferMS = 300;
r->m_nClientBW = 2500000;
r->m_nClientBW2 = 2;
r->m_nServerBW = 2500000;
r->m_fAudioCodecs = 3191.0;
r->m_fVideoCodecs = 252.0;
}
double
RTMP_GetDuration(RTMP *r)
{
return r->m_fDuration;
}
bool
RTMP_IsConnected(RTMP *r)
{
return r->m_sb.sb_socket != -1;
}
bool
RTMP_IsTimedout(RTMP *r)
{
return r->m_sb.sb_timedout;
}
void
RTMP_SetBufferMS(RTMP *r, int size)
{
r->m_nBufferMS = size;
}
void
RTMP_UpdateBufferMS(RTMP *r)
{
RTMP_SendCtrl(r, 3, r->m_stream_id, r->m_nBufferMS);
}
#undef OSS
#ifdef WIN32
#define OSS "WIN"
#elif defined(__sun__)
#define OSS "SOL"
#elif defined(__APPLE__)
#define OSS "MAC"
#elif defined(__linux__)
#define OSS "LNX"
#else
#define OSS "GNU"
#endif
static const char DEFAULT_FLASH_VER[] = OSS " 10,0,32,18";
const AVal RTMP_DefaultFlashVer =
{ (char *)DEFAULT_FLASH_VER, sizeof(DEFAULT_FLASH_VER) - 1 };
void
RTMP_SetupStream(RTMP *r,
int protocol,
const char *hostname,
unsigned int port,
const char *sockshost,
AVal *playpath,
AVal *tcUrl,
AVal *swfUrl,
AVal *pageUrl,
AVal *app,
AVal *auth,
AVal *swfSHA256Hash,
uint32_t swfSize,
AVal *flashVer,
AVal *subscribepath,
double dTime,
uint32_t dLength, bool bLiveStream, long int timeout)
{
RTMP_Log(RTMP_LOGDEBUG, "Protocol : %s", RTMPProtocolStrings[protocol&7]);
RTMP_Log(RTMP_LOGDEBUG, "Hostname : %s", hostname);
RTMP_Log(RTMP_LOGDEBUG, "Port : %d", port);
RTMP_Log(RTMP_LOGDEBUG, "Playpath : %s", playpath->av_val);
if (tcUrl && tcUrl->av_val)
RTMP_Log(RTMP_LOGDEBUG, "tcUrl : %s", tcUrl->av_val);
if (swfUrl && swfUrl->av_val)
RTMP_Log(RTMP_LOGDEBUG, "swfUrl : %s", swfUrl->av_val);
if (pageUrl && pageUrl->av_val)
RTMP_Log(RTMP_LOGDEBUG, "pageUrl : %s", pageUrl->av_val);
if (app && app->av_val)
RTMP_Log(RTMP_LOGDEBUG, "app : %.*s", app->av_len, app->av_val);
if (auth && auth->av_val)
RTMP_Log(RTMP_LOGDEBUG, "auth : %s", auth->av_val);
if (subscribepath && subscribepath->av_val)
RTMP_Log(RTMP_LOGDEBUG, "subscribepath : %s", subscribepath->av_val);
if (flashVer && flashVer->av_val)
RTMP_Log(RTMP_LOGDEBUG, "flashVer : %s", flashVer->av_val);
if (dTime > 0)
RTMP_Log(RTMP_LOGDEBUG, "SeekTime : %.3f sec", (double)dTime / 1000.0);
if (dLength > 0)
RTMP_Log(RTMP_LOGDEBUG, "playLength : %.3f sec", (double)dLength / 1000.0);
RTMP_Log(RTMP_LOGDEBUG, "live : %s", bLiveStream ? "yes" : "no");
RTMP_Log(RTMP_LOGDEBUG, "timeout : %d sec", timeout);
#ifdef CRYPTO
if (swfSHA256Hash != NULL && swfSize > 0)
{
r->Link.SWFHash = *swfSHA256Hash;
r->Link.SWFSize = swfSize;
RTMP_Log(RTMP_LOGDEBUG, "SWFSHA256:");
RTMP_LogHex(RTMP_LOGDEBUG, r->Link.SWFHa
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
rtmpdump-2.2b.tar.gz (31个子文件)
rtmpdump-2.2b
rtmpdump.1.html 10KB
rtmpgw.8 7KB
rtmpdump.1 7KB
rtmpsrv.c 26KB
thread.h 1KB
README 8KB
rtmpdump.c 38KB
rtmpgw.c 28KB
librtmp
hashswf.c 14KB
handshake.h 30KB
rtmp_sys.h 3KB
librtmp.pc.in 289B
amf.c 24KB
amf.h 5KB
dh.h 7KB
bytes.h 2KB
rtmp.c 93KB
dhgroups.h 9KB
rtmp.h 9KB
log.c 4KB
Makefile 1KB
log.h 2KB
http.h 2KB
COPYING 26KB
parseurl.c 6KB
Makefile 2KB
ChangeLog 8KB
COPYING 18KB
thread.c 1KB
rtmpsuck.c 32KB
rtmpgw.8.html 10KB
共 31 条
- 1
资源评论
JaniceLu
- 粉丝: 98
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功