OBS源码分析之rtmp

rtmp推流过程如下:

1)启动connect线程   

static void *connect_thread(void *data)
{
struct rtmp_stream *stream = data;//流信息赋值
int ret;


os_set_thread_name("rtmp-stream: connect_thread");


if (!init_connect(stream)) {//初始化流信息
obs_output_signal_stop(stream->output, OBS_OUTPUT_BAD_PATH);
return NULL;
}


ret = try_connect(stream);//尝试连接


if (ret != OBS_OUTPUT_SUCCESS) {
obs_output_signal_stop(stream->output, ret);//发送停止推流信号
info("Connection to %s failed: %d", stream->path.array, ret);
}


if (!stopping(stream))
pthread_detach(stream->connect_thread);


os_atomic_set_bool(&stream->connecting, false);
return NULL;
}

2)尝试connect   

static int try_connect(struct rtmp_stream *stream)
{
if (dstr_is_empty(&stream->path)) {//推流地址不能为空
warn("URL is empty");
return OBS_OUTPUT_BAD_PATH;
}


info("Connecting to RTMP URL %s...", stream->path.array);


memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
return OBS_OUTPUT_BAD_PATH;


RTMP_EnableWrite(&stream->rtmp);//写权限


dstr_copy(&stream->encoder_name, "FMLE/3.0 (compatible; obs-studio/");


#ifdef HAVE_OBSCONFIG_H
dstr_cat(&stream->encoder_name, OBS_VERSION);
#else
dstr_catf(&stream->encoder_name, "%d.%d.%d",
LIBOBS_API_MAJOR_VER,
LIBOBS_API_MINOR_VER,
LIBOBS_API_PATCH_VER);
#endif


dstr_cat(&stream->encoder_name, "; FMSc/1.0)");


set_rtmp_dstr(&stream->rtmp.Link.pubUser,   &stream->username);
set_rtmp_dstr(&stream->rtmp.Link.pubPasswd, &stream->password);
set_rtmp_dstr(&stream->rtmp.Link.flashVer,  &stream->encoder_name);
stream->rtmp.Link.swfUrl = stream->rtmp.Link.tcUrl;


RTMP_AddStream(&stream->rtmp, stream->key.array);//key连接


for (size_t idx = 1;; idx++) {
obs_encoder_t *encoder = obs_output_get_audio_encoder(
stream->output, idx);
const char *encoder_name;


if (!encoder)
break;


encoder_name = obs_encoder_get_name(encoder);
RTMP_AddStream(&stream->rtmp, encoder_name);//编码器
}


stream->rtmp.m_outChunkSize       = 4096;
stream->rtmp.m_bSendChunkSizeInfo = true;
stream->rtmp.m_bUseNagle          = true;


#ifdef _WIN32
win32_log_interface_type(stream);
#endif


if (!RTMP_Connect(&stream->rtmp, NULL))//推流服务器连接
return OBS_OUTPUT_CONNECT_FAILED;
if (!RTMP_ConnectStream(&stream->rtmp, 0))//流连接
return OBS_OUTPUT_INVALID_STREAM;


info("Connection to %s successful", stream->path.array);


return init_send(stream);//推流线程
}

3) connect过程 
int
RTMP_Connect(RTMP *r, RTMPPacket *cp)
{
#ifdef _WIN32
    HOSTENT *h;
#endif
    struct sockaddr_storage service;
    socklen_t addrlen = 0;
    if (!r->Link.hostname.av_len)
        return FALSE;


#ifdef _WIN32
    //COMODO security software sandbox blocks all DNS by returning "host not found"
    h = gethostbyname("localhost");
    if (!h && GetLastError() == WSAHOST_NOT_FOUND)
    {
        RTMP_Log(RTMP_LOGERROR, "RTMP_Connect: Connection test failed. This error is likely caused by Comodo Internet Security running OBS in sandbox mode. Please add OBS to the Comodo automatic sandbox exclusion list, restart OBS and try again (11001).");
        return FALSE;
    }
#endif


    memset(&service, 0, sizeof(service));


    if (r->Link.socksport)
    {
        /* Connect via SOCKS */
        if (!add_addr_info(&service, &addrlen, &r->Link.sockshost, r->Link.socksport))
            return FALSE;
    }
    else
    {
        /* Connect directly */
        if (!add_addr_info(&service, &addrlen, &r->Link.hostname, r->Link.port))
            return FALSE;
    }


    if (!RTMP_Connect0(r, (struct sockaddr *)&service, addrlen))
        return FALSE;


    r->m_bSendCounter = TRUE;


    return RTMP_Connect1(r, cp);
}

RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen)

RTMP_Connect1(RTMP *r, RTMPPacket *cp)

4)三次握手

static int
HandShake(RTMP *r, int FP9HandShake)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值