/**
* @file SipStreamHandler.cpp
* @brief 流媒体处理者类实现文件.
* @see SipStreamHandler.h
*
* Change History : \n
* -linxuan 创建 0000/0/0
*/
#include "SipStreamHandler.h"
#include "TNLog.h"
namespace SIP
{
//! RTP负载类型定义
static std::string RTPMAP_PS = "96 PS/90000";
static std::string RTPMAP_H264 = "98 H264/90000";
static std::string RTPMAP_MPEG4 = "97 MPEG4/90000";
//! RTP范围定义[19000,19199]
static const int START_RTP_PORT = 19000;
static const int END_RTP_PORT = 19199;
//! 因rtp、rtcp端口连续,故此处步长置为2
static int STEP_RTP_PORT = 2;
//! 当前rtp端口
static std::atomic_int CUR_RTP_PORT(START_RTP_PORT);
//! 流处理对象统计,也用来做gbt28181协议中y字段值组成部分
static std::atomic<int> g_streamCount(0);
CSipStreamHandler::CSipStreamHandler(pjsip_endpoint *endpoint, PISipStreamNotify notifyObj, pjmedia_endpt *meidaEndpit, bool tcp/*=false*/)
: CSipSendBaseHandler(endpoint, tcp)
, m_stop(true)
, m_meidaEndpit(meidaEndpit)
, m_streamNotifyObj(notifyObj)
{
g_streamCount++;
}
CSipStreamHandler::~CSipStreamHandler()
{
m_stop = true;
if (m_mediaStreamSdpInfo.isPlay)
{
pjsip_tx_data *tdata;
pj_status_t status = pjsip_inv_end_session(m_mediaStreamSdpInfo.inv, PJSIP_SC_DECLINE, NULL, &tdata);
if (status == PJ_SUCCESS && tdata != NULL)
pjsip_inv_send_msg(m_mediaStreamSdpInfo.inv, tdata);
else
LOG_WARN_FMT("stream handler[%d] end session failed. code[%d]", m_handlerId, status);
WaitMsg(SIP_COM_TIMEOUT);
// 传输断开
pjmedia_transport_detach(m_mediaStreamSdpInfo.transport, this);
pjmedia_transport_close(m_mediaStreamSdpInfo.transport);
}
}
bool CSipStreamHandler::OnMessage(pjsip_rx_data *rdata)
{
if (NULL == rdata || NULL == rdata->msg_info.msg)
{
LOG_WARN("parameter error");
return false;
}
std::string srcIP = rdata->pkt_info.src_name;
if (srcIP != m_sipProFillInfo.targetIP)
{
//LOG_WARN_FMT("stream handler[%d] parameter src ip error. srcIP[%s] targetIP[%s]", m_handlerId, srcIP.c_str(), m_sipProFillInfo.targetIP.c_str());
return false;
}
bool res = false;
pjsip_method_e methodID = rdata->msg_info.msg->line.req.method.id;
LOG_INFO_FMT("stream handler[%d] receive method[%d].", m_handlerId, methodID);
switch (methodID)
{
case PJSIP_INVITE_METHOD:
case PJSIP_CANCEL_METHOD:
case PJSIP_ACK_METHOD:
case PJSIP_BYE_METHOD:
// 如上消息,接收到即认为处理完成
res = true;
break;
default:
break;
}
return res;
}
// rtp流传输预留端口 [19000,19199]
static int GetRtpPort()
{
int res = CUR_RTP_PORT;
CUR_RTP_PORT += STEP_RTP_PORT;
if (END_RTP_PORT <= CUR_RTP_PORT)
CUR_RTP_PORT = START_RTP_PORT;
return res;
}
bool CSipStreamHandler::StartStream(MediaStreamType type /*= SMST_PLAY*/ , time_t start /*= 0 */ , time_t end /*= 0 */ )
{
// 启动后,不在操作
if (!m_stop)
{
LOG_INFO_FMT("stream handler[%d] stream started.", m_handlerId);
return true;
}
m_stop = false;
LOG_INFO_FMT("stream handler[%d] starting stream. type[%d]", m_handlerId, type);
// sdp字段信息收集
int format = 0;
switch (type)
{
case SMST_PLAY:
format = 0;
break;
case SMST_PLAYBACK:
case SMST_DOWNLOAD:
format = 1;
m_mediaStreamSdpInfo.u = "u="+ m_sipProFillInfo.targetID +":3";
break;
default:
LOG_ERROR_FMT("stream handler[%d] start stream failed. meidia stream type error. type[%d]", m_handlerId, type);
return false;
}
m_mediaStreamSdpInfo.type = type;
char temp[32] = { 0 };
char from[128] = { 0 };
char to[128] = { 0 };
char target[128] = { 0 };
char contact[128] = { 0 };
sprintf(temp, "y=%1d%s%04d", format, m_sipProFillInfo.srcID.substr(3, 5).c_str(), g_streamCount % 10000);
m_mediaStreamSdpInfo.y = temp;
m_mediaStreamSdpInfo.port = GetRtpPort();
LOG_INFO_FMT("stream handler[%d] rtp port[%d]", m_handlerId, m_mediaStreamSdpInfo.port);
sprintf(from, "sip:%s@%s", m_sipProFillInfo.srcID.c_str(), m_sipProFillInfo.srcRealm.c_str());
sprintf(to, "sip:%s@%s", m_sipProFillInfo.targetID.c_str(), m_sipProFillInfo.srcRealm.c_str());
if (m_tcpFlg)
sprintf(target, "sip:%s@%s:%d;transport=tcp", m_sipProFillInfo.targetID.c_str(), m_sipProFillInfo.targetIP.c_str(), m_sipProFillInfo.targetPort);
else
sprintf(target, "sip:%s@%s:%d", m_sipProFillInfo.targetID.c_str(), m_sipProFillInfo.targetIP.c_str(), m_sipProFillInfo.targetPort);
if (m_tcpFlg)
sprintf(contact, "sip:%s@%s:%d;transport=tcp", m_sipProFillInfo.srcID.c_str(), m_sipProFillInfo.srcIP.c_str(), m_sipProFillInfo.srcPort);
else
sprintf(contact, "sip:%s@%s:%d", m_sipProFillInfo.srcID.c_str(), m_sipProFillInfo.srcIP.c_str(), m_sipProFillInfo.srcPort);
// 创建会话
pj_str_t tmpFrom = pj_str(from);
pj_str_t tmpContact = pj_str(contact);
pj_str_t tmpTo = pj_str(to);
pj_str_t tmpTarget = pj_str(target);
pj_status_t status = pjsip_dlg_create_uac(pjsip_ua_instance(), &tmpFrom, &tmpContact, &tmpTo, &tmpTarget, &m_mediaStreamSdpInfo.dlg);
if (status != PJ_SUCCESS)
{
LOG_ERROR_FMT("stream handler[%d] start stream failed. pjsip_dlg_create_uac failed. code[%d]", m_handlerId, status);
return false;
}
//创建SDP
m_mediaStreamSdpInfo.start = start;
m_mediaStreamSdpInfo.end = end;
pjmedia_sdp_session *sdp;
CreateSDP(&sdp, start, end);
// INVITE 会话建立
status = pjsip_inv_create_uac(m_mediaStreamSdpInfo.dlg, sdp, 0, &m_mediaStreamSdpInfo.inv);
if (status != PJ_SUCCESS)
{
pjsip_dlg_terminate(m_mediaStreamSdpInfo.dlg);
LOG_ERROR_FMT("stream handler[%d] start stream failed. pjsip_inv_create_uac failed. code[%d]", m_handlerId, status);
return false;
}
m_mediaStreamSdpInfo.inv->mod_data[0] = this;
// invite请求信息填充
pjsip_tx_data *tdata;
status = pjsip_inv_invite(m_mediaStreamSdpInfo.inv, &tdata);
if (status != PJ_SUCCESS)
{
LOG_ERROR_FMT("stream handler[%d] start stream failed. pjsip_inv_invite failed. code[%d]", m_handlerId, status);
return false;
}
//Subject填充
pj_str_t subjectName = pj_str("Subject");
char subjectBuf[128] = { 0 };
sprintf(subjectBuf, "%s:01,%s:01", m_sipProFillInfo.targetID.c_str(), m_sipProFillInfo.srcID.c_str());
pj_str_t subjectValue = pj_str(subjectBuf);
pjsip_generic_string_hdr* hdr=pjsip_generic_string_hdr_create(m_pPool, &subjectName, &subjectValue);
pjsip_msg_add_hdr(tdata->msg,(pjsip_hdr *)hdr);
status = pjsip_inv_send_msg(m_mediaStreamSdpInfo.inv, tdata);
if (status != PJ_SUCCESS)
{
LOG_ERROR_FMT("stream handler[%d] start stream failed. pjsip_inv_send_msg failed. code[%d]", m_handlerId, status);
return false;
}
if (!WaitMsg(SIP_COM_TIMEOUT))
{
LOG_ERROR_FMT("stream handler[%d] start stream failed. start stream r
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
基于pjsip实现GBT28181协议 (462个子文件)
libpjsua2.so.2 4.11MB
libpjmedia.so.2 406KB
libpjsip.so.2 350KB
libyuv.so.2 323KB
libpjsua.so.2 306KB
libpj.so.2 231KB
libpjnath.so.2 193KB
libpjlib-util.so.2 184KB
libspeex.so.2 184KB
libwebrtc.so.2 176KB
libpjsip-ua.so.2 131KB
libpjsip-simple.so.2 106KB
libsrtp.so.2 97KB
libpjmedia-codec.so.2 94KB
libg7221codec.so.2 74KB
libilbccodec.so.2 68KB
libresample.so.2 52KB
libgsmcodec.so.2 47KB
libpjmedia-audiodev.so.2 34KB
libpjmedia-videodev.so.2 8KB
libpjsua2-x86_64-unknown-linux-gnu.a 10.28MB
libpjmedia-x86_64-unknown-linux-gnu.a 653KB
libpjsip-x86_64-unknown-linux-gnu.a 544KB
libpjsua-x86_64-unknown-linux-gnu.a 424KB
libyuv-x86_64-unknown-linux-gnu.a 422KB
libpj-x86_64-unknown-linux-gnu.a 341KB
libspeex-x86_64-unknown-linux-gnu.a 290KB
libpjnath-x86_64-unknown-linux-gnu.a 281KB
libpjlib-util-x86_64-unknown-linux-gnu.a 271KB
libwebrtc-x86_64-unknown-linux-gnu.a 247KB
libpjsip-ua-x86_64-unknown-linux-gnu.a 177KB
libpjsip-simple-x86_64-unknown-linux-gnu.a 146KB
libpjmedia-codec-x86_64-unknown-linux-gnu.a 142KB
libsrtp-x86_64-unknown-linux-gnu.a 135KB
libilbccodec-x86_64-unknown-linux-gnu.a 101KB
libg7221codec-x86_64-unknown-linux-gnu.a 79KB
libgsmcodec-x86_64-unknown-linux-gnu.a 63KB
libresample-x86_64-unknown-linux-gnu.a 46KB
libpjmedia-audiodev-x86_64-unknown-linux-gnu.a 41KB
libpjmedia-videodev-x86_64-unknown-linux-gnu.a 9KB
libpjproject-i386-Win32-vc14-Debug-Dynamic.bsc 19KB
applicationhost.config 83KB
applicationhost.config 83KB
SipStreamHandler.cpp 16KB
SipDevMgr.cpp 16KB
SipStreamCB.cpp 15KB
SipCore.cpp 10KB
SipDevInfoHandler.cpp 9KB
SipMsgAnalyze.cpp 7KB
main.cpp 7KB
SipBaseHandler.cpp 2KB
SipSendBaseHandler.cpp 1KB
SipDataDefine.cpp 445B
Browse.VC.db 39.55MB
Browse.VC.db 35.74MB
log4cplusD.dll 772KB
pjsipDemo.exe 1.35MB
pjsipDemo.vcxproj.filters 2KB
opencore-amr.tar.gz 448KB
pjsua.h 240KB
sip_msg.h 67KB
stun_msg.h 58KB
sip_transport.h 52KB
sock.h 49KB
ssl_sock.h 43KB
amr_helper.h 43KB
os.h 42KB
config.h 41KB
sip_inv.h 40KB
codec.h 39KB
sip_config.h 38KB
ioqueue.h 37KB
config.h 35KB
doxygen.h 35KB
transport.h 34KB
sip_util.h 33KB
ice_session.h 33KB
stun_session.h 32KB
sdp_neg.h 32KB
ice_strans.h 31KB
sip_dialog.h 31KB
pool.h 31KB
pjsua_internal.h 30KB
vid_codec.h 28KB
turn_session.h 26KB
videodev.h 26KB
format.h 26KB
sip_endpoint.h 24KB
string.h 23KB
audiodev.h 23KB
sdp.h 22KB
activesock.h 22KB
sip_auth.h 20KB
errno.h 19KB
errno.h 19KB
resolver.h 19KB
conference.h 18KB
sip_transaction.h 17KB
scanner.h 17KB
sip_parser.h 17KB
共 462 条
- 1
- 2
- 3
- 4
- 5
hfxy5200704031010
- 粉丝: 3
- 资源: 21
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于CarNet实现裂缝检测python源码+文档说明+数据+图片(课程设计)
- 课程设计-基于耐火材料裂缝剥落检测python源码+课件
- 基于OpenCV的视频道路车道检测python源码+文档说明+实验演示+图片+使用方法(高分毕业设计)
- 基于OpenCV的案例:图像边缘、角点和轮廓检测,图像分割,图像增强;图片拼接;运动目标检测,颜色直方图比较,三帧帧差法,抠图
- SmartPlug-html大一笔记
- SmartPlug-proteusdemo
- Preliminary Findings on Handmade Rattan Baby Crib andBassinet Designs Regarding.zip
- aveebfq_v1.2.83_downyi.com.apk
- 基于有机发光二极管(OLED)的建模优化算法的matlab仿真源码+数据+文档说明+项目说明(高分课程设计)
- hash01-test.c 本人哈希表(一)的示例代码,仅供参考!
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
前往页