Ai
1 Star 9 Fork 9

John Yet/rtsp_proxy_server

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
rtsp_proxy_client.cpp 6.38 KB
一键复制 编辑 原始数据 按行查看 历史
learnhow 提交于 2020-07-21 11:31 +08:00 . 初始化第一次提交
#include "rtsp_proxy_client.h"
#include <cstring>
#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include "event2/event.h"
#include "event2/bufferevent.h"
#include "config.h"
#include "thread_pool.h"
using namespace std;
using namespace rtsp;
RTSPProxyClient::RTSPProxyClient(struct event_base* eb, const char* camera_host, int camera_port, const char* player_host)
: connect_port_(camera_port),
eb_(eb),
current_method_(RM_NONE)
{
memcpy(camera_host_, camera_host, strlen(camera_host));
memcpy(player_host_, player_host, strlen(player_host));
stream_task_ = new StreamTask();
}
void RTSPProxyClient::Connect(connect_cb cb, void *cbarg)
{
// 使用自定义的socket创建读写事件
this->conn_cb_ = cb;
this->conn_cbarg_ = cbarg;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(this->camera_host_);
sin.sin_port = htons(this->connect_port_);
evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0);
this->bev_ = bufferevent_socket_new(eb_, fd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev_, OnRead, OnWrite, OnEvent, this);
bufferevent_enable(bev_, EV_READ | EV_WRITE);
bufferevent_socket_connect(bev_, (struct sockaddr*)&sin, sizeof(sin));
}
int RTSPProxyClient::ExecuteMethod(const char *msg, method_cb cb, void *cbarg)
{
current_method_ = GetRtspMethodName(msg);
switch (current_method_) {
case RM_OPTIONS:
OptionsMethod(msg, cb, cbarg);
break;
case RM_DESCRIBE:
DescribeMethod(msg, cb, cbarg);
break;
case RM_SETUP:
SetupMethod(msg, cb, cbarg);
break;
case RM_PLAY:
PlayMethod(msg, cb, cbarg);
break;
case RM_GET_PARAMETER:
GetParameterMethod(msg, cb, cbarg);
break;
case RM_TEARDOWN:
break;
default:
qCritical("当前方法未被定义");
break;
}
}
int RTSPProxyClient::OptionsMethod(const char* msg, method_cb cb, void *cbarg)
{
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
return this->SendTo(msg);
}
int RTSPProxyClient::DescribeMethod(const char *msg, method_cb cb, void *cbarg)
{
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
return this->SendTo(msg);
}
int RTSPProxyClient::SetupMethod(const char *msg, method_cb cb, void *cbarg)
{
// 获取4个代理端口号
pair<RTSPPort, RTSPPort> pipe_ports = Config::Get()->NextDoublePipePort();
camera_proxy_ports_ = pipe_ports.first;
player_proxy_ports_ = pipe_ports.second;
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
player_ports_ = parser_.GetClientPort(msg);
char out[1024] ={0};
// 替换报文中的客户端端口
parser_.ReplaceClientPort(msg, out, player_proxy_ports_);
qInfo("播放器rtp端口: %d, rtcp端口: %d, 代理rtp端口: %d, 代理rtcp端口: %d",
player_ports_.rtp_port,
player_ports_.rtcp_port,
player_proxy_ports_.rtp_port,
player_proxy_ports_.rtcp_port);
return this->SendTo(out);
}
int RTSPProxyClient::PlayMethod(const char *msg, method_cb cb, void *cbarg)
{
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
return this->SendTo(msg);
}
int RTSPProxyClient::TeardownMethod(const char *msg, method_cb cb, void *cbarg)
{
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
return this->SendTo(msg);
}
int RTSPProxyClient::GetParameterMethod(const char *msg, method_cb cb, void *cbarg)
{
this->event_cb_ = cb;
this->event_cbarg_ = cbarg;
return this->SendTo(msg);
}
RTSPProxyClient::~RTSPProxyClient()
{
if(bev_)
{
bufferevent_free(bev_);
bev_ = NULL;
}
if(stream_task_)
{
// 从线程池中释放管线
ThreadPool::Get()->RemoveTask(stream_task_);
delete stream_task_;
stream_task_ = NULL;
}
}
void RTSPProxyClient::OnRead(bufferevent *bev, void *ctx)
{
char buf[1024] = {0};
int len = bufferevent_read(bev, buf, 1024);
if(len > 0)
{
qInfo("摄像机消息: \r\n%s\r\n", buf);
RTSPProxyClient *c = (RTSPProxyClient*)ctx;
// 如果当前方法为SETUP,则创建一对UDP管线并提交给线程池
if(RM_SETUP == c->current_method_)
{
c->camera_ports_ = c->parser_.GetServerPort(buf);
qInfo("摄像机rtp端口: %d, rtcp端口: %d, 代理rtp端口: %d, 代理rtcp端口: %d\r\n",
c->camera_ports_.rtp_port,
c->camera_ports_.rtcp_port,
c->camera_proxy_ports_.rtp_port,
c->camera_proxy_ports_.rtcp_port);
char out[1024] = {0};
c->parser_.ReplaceServerPort(buf, out, c->camera_proxy_ports_);
memcpy(buf, out, sizeof(out));
c->parser_.ReplaceClientPort(buf, out, c->player_ports_);
memcpy(buf, out, sizeof(out));
// 初始化管线参数
c->stream_task_->PlayerHost(c->player_host_)->CameraHost(c->camera_host_)->PlayerPorts(c->player_ports_, c->player_proxy_ports_)
->CameraPorts(c->camera_ports_, c->camera_proxy_ports_);
ThreadPool::Get()->AddTask(c->stream_task_);
}
c->event_cb_(c->current_method_, buf, c->event_cbarg_);
}
}
void RTSPProxyClient::OnWrite(bufferevent *bev, void *ctx)
{
}
void RTSPProxyClient::OnEvent(bufferevent *bev, short what, void *ctx)
{
RTSPProxyClient *c = (RTSPProxyClient*)ctx;
if(what & BEV_EVENT_CONNECTED)
{
c->conn_cb_(CONNECTION, c->conn_cbarg_);
return;
}
if(what & BEV_EVENT_ERROR)
{
c->conn_cb_(DISCONNECTION, c->conn_cbarg_);
return;
}
}
RtspMethodEnum RTSPProxyClient::GetRtspMethodName(const char *in)
{
if(memcmp(in, "OPTIONS", 7) == 0)
{
return RM_OPTIONS;
}
if(memcmp(in, "DESCRIBE", 8) == 0)
{
return RM_DESCRIBE;
}
if(memcmp(in, "SETUP", 5) == 0)
{
return RM_SETUP;
}
if(memcmp(in, "PLAY", 4) == 0)
{
return RM_PLAY;
}
if(memcmp(in, "GET_PARAMETER", 13) == 0)
{
return RM_GET_PARAMETER;
}
if(memcmp(in, "TEARDOWN", 8) == 0)
{
return RM_TEARDOWN;
}
return RM_NONE;
}
int RTSPProxyClient::SendTo(const char *msg)
{
return bufferevent_write(bev_, msg, strlen(msg));
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/learnhow/rtsp_proxy_server.git
git@gitee.com:learnhow/rtsp_proxy_server.git
learnhow
rtsp_proxy_server
rtsp_proxy_server
master

搜索帮助