Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
39baaebc
Commit
39baaebc
authored
Oct 24, 2018
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
统一成员变量命名风格
parent
97567ec3
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
74 个修改的文件
包含
1246 行增加
和
1245 行删除
+1246
-1245
src/Codec/AACEncoder.cpp
+26
-26
src/Codec/AACEncoder.h
+7
-7
src/Codec/H264Encoder.cpp
+31
-31
src/Codec/H264Encoder.h
+4
-4
src/Common/MediaSource.cpp
+27
-27
src/Common/MediaSource.h
+27
-27
src/Device/Device.cpp
+0
-0
src/Device/Device.h
+15
-15
src/Device/PlayerProxy.cpp
+26
-26
src/Device/PlayerProxy.h
+9
-9
src/H264/H264Parser.cpp
+22
-22
src/H264/H264Parser.h
+13
-13
src/Http/HttpSession.cpp
+0
-0
src/Http/HttpSession.h
+7
-7
src/Http/HttpsSession.h
+6
-6
src/MediaFile/HLSMaker.cpp
+35
-35
src/MediaFile/HLSMaker.h
+10
-10
src/MediaFile/MediaReader.cpp
+0
-0
src/MediaFile/MediaReader.h
+28
-28
src/MediaFile/MediaRecorder.cpp
+10
-10
src/MediaFile/MediaRecorder.h
+4
-4
src/MediaFile/Mp4Maker.cpp
+65
-65
src/MediaFile/Mp4Maker.h
+15
-15
src/Player/MediaPlayer.cpp
+14
-14
src/Player/MediaPlayer.h
+1
-1
src/Player/PlayerBase.h
+28
-28
src/RTP/AACRtpCodec.cpp
+38
-38
src/RTP/AACRtpCodec.h
+3
-3
src/RTP/H264RtpCodec.cpp
+43
-42
src/RTP/H264RtpCodec.h
+2
-2
src/RTP/RtpCodec.h
+19
-19
src/RTP/RtpMaker.h
+21
-21
src/RTP/RtpMakerAAC.cpp
+27
-27
src/RTP/RtpMakerAAC.h
+1
-1
src/RTP/RtpMakerH264.cpp
+13
-13
src/Rtmp/FlvMuxer.cpp
+8
-8
src/Rtmp/FlvMuxer.h
+2
-2
src/Rtmp/RtmpMediaSource.h
+28
-28
src/Rtmp/RtmpParser.cpp
+53
-53
src/Rtmp/RtmpParser.h
+21
-21
src/Rtmp/RtmpPlayer.cpp
+47
-47
src/Rtmp/RtmpPlayer.h
+29
-29
src/Rtmp/RtmpPlayerImp.h
+12
-12
src/Rtmp/RtmpProtocol.cpp
+0
-0
src/Rtmp/RtmpProtocol.h
+17
-17
src/Rtmp/RtmpPusher.cpp
+34
-34
src/Rtmp/RtmpPusher.h
+25
-25
src/Rtmp/RtmpSession.cpp
+0
-0
src/Rtmp/RtmpSession.h
+15
-15
src/Rtmp/RtmpToRtspMediaSource.cpp
+33
-33
src/Rtmp/RtmpToRtspMediaSource.h
+14
-14
src/Rtmp/amf.cpp
+34
-34
src/Rtmp/amf.h
+35
-35
src/RtmpCodec/AACRtmpCodec.cpp
+3
-3
src/RtmpCodec/AACRtmpCodec.h
+1
-1
src/RtmpCodec/H264RtmpCodec.cpp
+26
-26
src/RtmpCodec/H264RtmpCodec.h
+3
-3
src/Rtsp/RtpBroadCaster.cpp
+34
-34
src/Rtsp/RtpBroadCaster.h
+9
-9
src/Rtsp/RtpParser.cpp
+1
-1
src/Rtsp/RtpParser.h
+2
-2
src/Rtsp/Rtsp.h
+36
-36
src/Rtsp/RtspMediaSource.h
+12
-12
src/Rtsp/RtspPlayer.cpp
+0
-0
src/Rtsp/RtspPlayer.h
+28
-28
src/Rtsp/RtspPlayerImp.h
+12
-12
src/Rtsp/RtspSession.cpp
+0
-0
src/Rtsp/RtspSession.h
+36
-36
src/Rtsp/RtspToRtmpMediaSource.cpp
+39
-39
src/Rtsp/RtspToRtmpMediaSource.h
+0
-0
src/Rtsp/UDPServer.cpp
+0
-0
src/Rtsp/UDPServer.h
+0
-0
src/Shell/ShellSession.cpp
+0
-0
src/Shell/ShellSession.h
+0
-0
没有找到文件。
src/Codec/AACEncoder.cpp
查看文件 @
39baaebc
...
...
@@ -48,17 +48,17 @@ AACEncoder::AACEncoder() {
}
AACEncoder
::~
AACEncoder
()
{
if
(
m
_hEncoder
!=
nullptr
)
{
faacEncClose
(
m
_hEncoder
);
m
_hEncoder
=
nullptr
;
if
(
_hEncoder
!=
nullptr
)
{
faacEncClose
(
_hEncoder
);
_hEncoder
=
nullptr
;
}
if
(
m
_pucAacBuf
!=
nullptr
)
{
delete
[]
m
_pucAacBuf
;
m
_pucAacBuf
=
nullptr
;
if
(
_pucAacBuf
!=
nullptr
)
{
delete
[]
_pucAacBuf
;
_pucAacBuf
=
nullptr
;
}
if
(
m
_pucPcmBuf
!=
nullptr
)
{
delete
[]
m
_pucPcmBuf
;
m
_pucPcmBuf
=
nullptr
;
if
(
_pucPcmBuf
!=
nullptr
)
{
delete
[]
_pucPcmBuf
;
_pucPcmBuf
=
nullptr
;
}
}
...
...
@@ -67,19 +67,19 @@ bool AACEncoder::init(int iSampleRate, int iChannels, int iSampleBit) {
return
false
;
}
// (1) Open FAAC engine
m_hEncoder
=
faacEncOpen
(
iSampleRate
,
iChannels
,
&
m
_ulInputSamples
,
&
m
_ulMaxOutputBytes
);
if
(
m
_hEncoder
==
NULL
)
{
_hEncoder
=
faacEncOpen
(
iSampleRate
,
iChannels
,
&
_ulInputSamples
,
&
_ulMaxOutputBytes
);
if
(
_hEncoder
==
NULL
)
{
return
false
;
}
m_pucAacBuf
=
new
unsigned
char
[
m
_ulMaxOutputBytes
];
m_ulMaxInputBytes
=
m
_ulInputSamples
*
iSampleBit
/
8
;
m_pucPcmBuf
=
new
unsigned
char
[
m
_ulMaxInputBytes
*
4
];
_pucAacBuf
=
new
unsigned
char
[
_ulMaxOutputBytes
];
_ulMaxInputBytes
=
_ulInputSamples
*
iSampleBit
/
8
;
_pucPcmBuf
=
new
unsigned
char
[
_ulMaxInputBytes
*
4
];
// (2.1) Get current encoding configuration
faacEncConfigurationPtr
pConfiguration
=
faacEncGetCurrentConfiguration
(
m
_hEncoder
);
faacEncConfigurationPtr
pConfiguration
=
faacEncGetCurrentConfiguration
(
_hEncoder
);
if
(
pConfiguration
==
NULL
)
{
faacEncClose
(
m
_hEncoder
);
faacEncClose
(
_hEncoder
);
return
false
;
}
pConfiguration
->
aacObjectType
=
LOW
;
...
...
@@ -95,25 +95,25 @@ bool AACEncoder::init(int iSampleRate, int iChannels, int iSampleBit) {
pConfiguration
->
inputFormat
=
FAAC_INPUT_16BIT
;
// (2.2) Set encoding configuration
if
(
!
faacEncSetConfiguration
(
m
_hEncoder
,
pConfiguration
)){
if
(
!
faacEncSetConfiguration
(
_hEncoder
,
pConfiguration
)){
ErrorL
<<
"faacEncSetConfiguration failed"
;
faacEncClose
(
m
_hEncoder
);
faacEncClose
(
_hEncoder
);
return
false
;
}
return
true
;
}
int
AACEncoder
::
inputData
(
char
*
pcPcmBufr
,
int
iLen
,
unsigned
char
**
ppucOutBuffer
)
{
memcpy
(
m_pucPcmBuf
+
m
_uiPcmLen
,
pcPcmBufr
,
iLen
);
m
_uiPcmLen
+=
iLen
;
if
(
m_uiPcmLen
<
m
_ulMaxInputBytes
)
{
memcpy
(
_pucPcmBuf
+
_uiPcmLen
,
pcPcmBufr
,
iLen
);
_uiPcmLen
+=
iLen
;
if
(
_uiPcmLen
<
_ulMaxInputBytes
)
{
return
0
;
}
int
nRet
=
faacEncEncode
(
m_hEncoder
,
(
int32_t
*
)
(
m_pucPcmBuf
),
m_ulInputSamples
,
m_pucAacBuf
,
m
_ulMaxOutputBytes
);
m_uiPcmLen
-=
m
_ulMaxInputBytes
;
memmove
(
m_pucPcmBuf
,
m_pucPcmBuf
+
m_ulMaxInputBytes
,
m
_uiPcmLen
);
*
ppucOutBuffer
=
m
_pucAacBuf
;
int
nRet
=
faacEncEncode
(
_hEncoder
,
(
int32_t
*
)
(
_pucPcmBuf
),
_ulInputSamples
,
_pucAacBuf
,
_ulMaxOutputBytes
);
_uiPcmLen
-=
_ulMaxInputBytes
;
memmove
(
_pucPcmBuf
,
_pucPcmBuf
+
_ulMaxInputBytes
,
_uiPcmLen
);
*
ppucOutBuffer
=
_pucAacBuf
;
return
nRet
;
}
...
...
src/Codec/AACEncoder.h
查看文件 @
39baaebc
...
...
@@ -39,15 +39,15 @@ public:
int
inputData
(
char
*
pcData
,
int
iLen
,
unsigned
char
**
ppucOutBuffer
);
private
:
unsigned
char
*
m
_pucPcmBuf
=
nullptr
;
unsigned
int
m
_uiPcmLen
=
0
;
unsigned
char
*
_pucPcmBuf
=
nullptr
;
unsigned
int
_uiPcmLen
=
0
;
unsigned
char
*
m
_pucAacBuf
=
nullptr
;
void
*
m
_hEncoder
=
nullptr
;
unsigned
char
*
_pucAacBuf
=
nullptr
;
void
*
_hEncoder
=
nullptr
;
unsigned
long
m
_ulInputSamples
=
0
;
unsigned
long
m
_ulMaxInputBytes
=
0
;
unsigned
long
m
_ulMaxOutputBytes
=
0
;
unsigned
long
_ulInputSamples
=
0
;
unsigned
long
_ulMaxInputBytes
=
0
;
unsigned
long
_ulMaxOutputBytes
=
0
;
};
...
...
src/Codec/H264Encoder.cpp
查看文件 @
39baaebc
...
...
@@ -39,19 +39,19 @@ H264Encoder::H264Encoder() {
H264Encoder
::~
H264Encoder
()
{
//* 清除图像区域
if
(
m
_pPicIn
)
{
delete
m
_pPicIn
;
m
_pPicIn
=
nullptr
;
if
(
_pPicIn
)
{
delete
_pPicIn
;
_pPicIn
=
nullptr
;
}
if
(
m
_pPicOut
)
{
delete
m
_pPicOut
;
m
_pPicOut
=
nullptr
;
if
(
_pPicOut
)
{
delete
_pPicOut
;
_pPicOut
=
nullptr
;
}
//* 关闭编码器句柄
if
(
m
_pX264Handle
)
{
x264_encoder_close
(
m
_pX264Handle
);
m
_pX264Handle
=
nullptr
;
if
(
_pX264Handle
)
{
x264_encoder_close
(
_pX264Handle
);
_pX264Handle
=
nullptr
;
}
}
...
...
@@ -229,7 +229,7 @@ Value的值就是fps。
} x264_param_t;*/
bool
H264Encoder
::
init
(
int
iWidth
,
int
iHeight
,
int
iFps
)
{
if
(
m
_pX264Handle
)
{
if
(
_pX264Handle
)
{
return
true
;
}
x264_param_t
X264Param
,
*
pX264Param
=
&
X264Param
;
...
...
@@ -307,43 +307,43 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps) {
//* 打开编码器句柄,通过x264_encoder_parameters得到设置给X264
//* 的参数.通过x264_encoder_reconfig更新X264的参数
m
_pX264Handle
=
x264_encoder_open
(
pX264Param
);
if
(
!
m
_pX264Handle
)
{
_pX264Handle
=
x264_encoder_open
(
pX264Param
);
if
(
!
_pX264Handle
)
{
return
false
;
}
m
_pPicIn
=
new
x264_picture_t
;
m
_pPicOut
=
new
x264_picture_t
;
x264_picture_init
(
m
_pPicIn
);
x264_picture_init
(
m
_pPicOut
);
m
_pPicIn
->
img
.
i_csp
=
X264_CSP_I420
;
m
_pPicIn
->
img
.
i_plane
=
3
;
_pPicIn
=
new
x264_picture_t
;
_pPicOut
=
new
x264_picture_t
;
x264_picture_init
(
_pPicIn
);
x264_picture_init
(
_pPicOut
);
_pPicIn
->
img
.
i_csp
=
X264_CSP_I420
;
_pPicIn
->
img
.
i_plane
=
3
;
return
true
;
}
int
H264Encoder
::
inputData
(
char
*
apcYuv
[
3
],
int
aiYuvLen
[
3
],
int64_t
i64Pts
,
H264Frame
**
ppFrame
)
{
//TimeTicker1(5);
m
_pPicIn
->
img
.
i_stride
[
0
]
=
aiYuvLen
[
0
];
m
_pPicIn
->
img
.
i_stride
[
1
]
=
aiYuvLen
[
1
];
m
_pPicIn
->
img
.
i_stride
[
2
]
=
aiYuvLen
[
2
];
m
_pPicIn
->
img
.
plane
[
0
]
=
(
uint8_t
*
)
apcYuv
[
0
];
m
_pPicIn
->
img
.
plane
[
1
]
=
(
uint8_t
*
)
apcYuv
[
1
];
m
_pPicIn
->
img
.
plane
[
2
]
=
(
uint8_t
*
)
apcYuv
[
2
];
m
_pPicIn
->
i_pts
=
i64Pts
;
_pPicIn
->
img
.
i_stride
[
0
]
=
aiYuvLen
[
0
];
_pPicIn
->
img
.
i_stride
[
1
]
=
aiYuvLen
[
1
];
_pPicIn
->
img
.
i_stride
[
2
]
=
aiYuvLen
[
2
];
_pPicIn
->
img
.
plane
[
0
]
=
(
uint8_t
*
)
apcYuv
[
0
];
_pPicIn
->
img
.
plane
[
1
]
=
(
uint8_t
*
)
apcYuv
[
1
];
_pPicIn
->
img
.
plane
[
2
]
=
(
uint8_t
*
)
apcYuv
[
2
];
_pPicIn
->
i_pts
=
i64Pts
;
int
iNal
;
x264_nal_t
*
pNals
;
int
iResult
=
x264_encoder_encode
(
m_pX264Handle
,
&
pNals
,
&
iNal
,
m
_pPicIn
,
m
_pPicOut
);
int
iResult
=
x264_encoder_encode
(
_pX264Handle
,
&
pNals
,
&
iNal
,
_pPicIn
,
_pPicOut
);
if
(
iResult
<=
0
)
{
return
0
;
}
for
(
int
i
=
0
;
i
<
iNal
;
i
++
)
{
x264_nal_t
pNal
=
pNals
[
i
];
m
_aFrames
[
i
].
iType
=
pNal
.
i_type
;
m
_aFrames
[
i
].
iLength
=
pNal
.
i_payload
;
m
_aFrames
[
i
].
pucData
=
pNal
.
p_payload
;
_aFrames
[
i
].
iType
=
pNal
.
i_type
;
_aFrames
[
i
].
iLength
=
pNal
.
i_payload
;
_aFrames
[
i
].
pucData
=
pNal
.
p_payload
;
}
*
ppFrame
=
m
_aFrames
;
*
ppFrame
=
_aFrames
;
return
iNal
;
}
...
...
src/Codec/H264Encoder.h
查看文件 @
39baaebc
...
...
@@ -54,10 +54,10 @@ public:
bool
init
(
int
iWidth
,
int
iHeight
,
int
iFps
);
int
inputData
(
char
*
apcYuv
[
3
],
int
aiYuvLen
[
3
],
int64_t
i64Pts
,
H264Frame
**
ppFrame
);
private
:
x264_t
*
m
_pX264Handle
=
nullptr
;
x264_picture_t
*
m
_pPicIn
=
nullptr
;
x264_picture_t
*
m
_pPicOut
=
nullptr
;
H264Frame
m
_aFrames
[
10
];
x264_t
*
_pX264Handle
=
nullptr
;
x264_picture_t
*
_pPicIn
=
nullptr
;
x264_picture_t
*
_pPicOut
=
nullptr
;
H264Frame
_aFrames
[
10
];
};
}
/* namespace Codec */
...
...
src/Common/MediaSource.cpp
查看文件 @
39baaebc
...
...
@@ -77,16 +77,16 @@ MediaSource::Ptr MediaSource::find(
bool
MediaSource
::
regist
()
{
//注册该源,注册后服务器才能找到该源
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
auto
pr
=
g_mapMediaSrc
[
m_strSchema
][
m_strVhost
][
m_strApp
].
emplace
(
m
_strId
,
shared_from_this
());
auto
pr
=
g_mapMediaSrc
[
_strSchema
][
_strVhost
][
_strApp
].
emplace
(
_strId
,
shared_from_this
());
auto
success
=
pr
.
second
;
if
(
success
){
InfoL
<<
m_strSchema
<<
" "
<<
m_strVhost
<<
" "
<<
m_strApp
<<
" "
<<
m
_strId
;
InfoL
<<
_strSchema
<<
" "
<<
_strVhost
<<
" "
<<
_strApp
<<
" "
<<
_strId
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaChanged
,
true
,
m
_strSchema
,
m
_strVhost
,
m
_strApp
,
m
_strId
,
_strSchema
,
_strVhost
,
_strApp
,
_strId
,
*
this
);
}
return
success
;
...
...
@@ -94,7 +94,7 @@ bool MediaSource::regist() {
bool
MediaSource
::
unregist
()
{
//反注册该源
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
return
searchMedia
(
m_strSchema
,
m_strVhost
,
m_strApp
,
m
_strId
,
[
&
](
SchemaVhostAppStreamMap
::
iterator
&
it0
,
return
searchMedia
(
_strSchema
,
_strVhost
,
_strApp
,
_strId
,
[
&
](
SchemaVhostAppStreamMap
::
iterator
&
it0
,
VhostAppStreamMap
::
iterator
&
it1
,
AppStreamMap
::
iterator
&
it2
,
StreamMap
::
iterator
&
it3
){
...
...
@@ -110,13 +110,13 @@ bool MediaSource::unregist() {
});
}
void
MediaSource
::
unregisted
(){
InfoL
<<
""
<<
m_strSchema
<<
" "
<<
m_strVhost
<<
" "
<<
m_strApp
<<
" "
<<
m
_strId
;
InfoL
<<
""
<<
_strSchema
<<
" "
<<
_strVhost
<<
" "
<<
_strApp
<<
" "
<<
_strId
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaChanged
,
false
,
m
_strSchema
,
m
_strVhost
,
m
_strApp
,
m
_strId
,
_strSchema
,
_strVhost
,
_strApp
,
_strId
,
*
this
);
}
...
...
@@ -124,7 +124,7 @@ void MediaInfo::parse(const string &url){
//string url = "rtsp://127.0.0.1:8554/live/id?key=val&a=1&&b=2&vhost=vhost.com";
auto
schema_pos
=
url
.
find
(
"://"
);
if
(
schema_pos
!=
string
::
npos
){
m
_schema
=
url
.
substr
(
0
,
schema_pos
);
_schema
=
url
.
substr
(
0
,
schema_pos
);
}
else
{
schema_pos
=
-
3
;
}
...
...
@@ -133,14 +133,14 @@ void MediaInfo::parse(const string &url){
auto
vhost
=
split_vec
[
0
];
auto
pos
=
vhost
.
find
(
":"
);
if
(
pos
!=
string
::
npos
){
m_host
=
m
_vhost
=
vhost
.
substr
(
0
,
pos
);
m
_port
=
vhost
.
substr
(
pos
+
1
);
_host
=
_vhost
=
vhost
.
substr
(
0
,
pos
);
_port
=
vhost
.
substr
(
pos
+
1
);
}
else
{
m_host
=
m
_vhost
=
vhost
;
_host
=
_vhost
=
vhost
;
}
}
if
(
split_vec
.
size
()
>
1
){
m
_app
=
split_vec
[
1
];
_app
=
split_vec
[
1
];
}
if
(
split_vec
.
size
()
>
2
){
string
steamid
;
...
...
@@ -152,23 +152,23 @@ void MediaInfo::parse(const string &url){
}
auto
pos
=
steamid
.
find
(
"?"
);
if
(
pos
!=
string
::
npos
){
m
_streamid
=
steamid
.
substr
(
0
,
pos
);
m_param
_strs
=
steamid
.
substr
(
pos
+
1
);
m_params
=
Parser
::
parseArgs
(
m_param
_strs
);
if
(
m_params
.
find
(
VHOST_KEY
)
!=
m
_params
.
end
()){
m_vhost
=
m
_params
[
VHOST_KEY
];
_streamid
=
steamid
.
substr
(
0
,
pos
);
_para
_strs
=
steamid
.
substr
(
pos
+
1
);
_params
=
Parser
::
parseArgs
(
_para
_strs
);
if
(
_params
.
find
(
VHOST_KEY
)
!=
_params
.
end
()){
_vhost
=
_params
[
VHOST_KEY
];
}
}
else
{
m
_streamid
=
steamid
;
_streamid
=
steamid
;
}
}
if
(
m
_vhost
.
empty
()){
if
(
_vhost
.
empty
()){
//无效vhost
m
_vhost
=
DEFAULT_VHOST
;
_vhost
=
DEFAULT_VHOST
;
}
else
{
if
(
INADDR_NONE
!=
inet_addr
(
m
_vhost
.
data
())){
if
(
INADDR_NONE
!=
inet_addr
(
_vhost
.
data
())){
//这是ip,未指定vhost;使用默认vhost
m
_vhost
=
DEFAULT_VHOST
;
_vhost
=
DEFAULT_VHOST
;
}
}
}
...
...
src/Common/MediaSource.h
查看文件 @
39baaebc
...
...
@@ -77,17 +77,17 @@ public:
void
parse
(
const
string
&
url
);
string
&
operator
[](
const
string
&
key
){
return
m
_params
[
key
];
return
_params
[
key
];
}
public
:
string
m
_schema
;
string
m
_host
;
string
m
_port
;
string
m
_vhost
;
string
m
_app
;
string
m
_streamid
;
StrCaseMap
m
_params
;
string
m_param
_strs
;
string
_schema
;
string
_host
;
string
_port
;
string
_vhost
;
string
_app
;
string
_streamid
;
StrCaseMap
_params
;
string
_para
_strs
;
};
...
...
@@ -104,13 +104,13 @@ public:
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
)
:
m
_strSchema
(
strSchema
),
m
_strApp
(
strApp
),
m
_strId
(
strId
)
{
_strSchema
(
strSchema
),
_strApp
(
strApp
),
_strId
(
strId
)
{
if
(
strVhost
.
empty
()){
m
_strVhost
=
DEFAULT_VHOST
;
_strVhost
=
DEFAULT_VHOST
;
}
else
{
m
_strVhost
=
strVhost
;
_strVhost
=
strVhost
;
}
}
virtual
~
MediaSource
()
{
...
...
@@ -124,21 +124,21 @@ public:
bool
bMake
=
true
)
;
const
string
&
getSchema
()
const
{
return
m
_strSchema
;
return
_strSchema
;
}
const
string
&
getVhost
()
const
{
return
m
_strVhost
;
return
_strVhost
;
}
const
string
&
getApp
()
const
{
//获取该源的id
return
m
_strApp
;
return
_strApp
;
}
const
string
&
getId
()
const
{
return
m
_strId
;
return
_strId
;
}
bool
seekTo
(
uint32_t
ui32Stamp
)
{
auto
listener
=
m
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
false
;
}
...
...
@@ -146,21 +146,21 @@ public:
}
uint32_t
getStamp
()
{
auto
listener
=
m
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
0
;
}
return
listener
->
getStamp
();
}
bool
shutDown
()
{
auto
listener
=
m
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
false
;
}
return
listener
->
shutDown
();
}
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
){
m
_listener
=
listener
;
_listener
=
listener
;
}
template
<
typename
FUN
>
...
...
@@ -224,12 +224,12 @@ private:
void
unregisted
();
protected
:
std
::
weak_ptr
<
MediaSourceEvent
>
m
_listener
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
private
:
string
m
_strSchema
;
//协议类型
string
m
_strVhost
;
//vhost
string
m
_strApp
;
//媒体app
string
m
_strId
;
//媒体id
string
_strSchema
;
//协议类型
string
_strVhost
;
//vhost
string
_strApp
;
//媒体app
string
_strId
;
//媒体id
static
SchemaVhostAppStreamMap
g_mapMediaSrc
;
//静态的媒体源表
static
recursive_mutex
g_mtxMediaSrc
;
//访问静态的媒体源表的互斥锁
};
...
...
src/Device/Device.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Device/Device.h
查看文件 @
39baaebc
...
...
@@ -102,25 +102,25 @@ private:
inline
void
makeSDP_AAC
(
unsigned
char
*
pucData
);
inline
void
makeSDP
(
const
string
&
strSdp
);
#ifdef ENABLE_X264
std
::
shared_ptr
<
H264Encoder
>
m
_pH264Enc
;
std
::
shared_ptr
<
H264Encoder
>
_pH264Enc
;
#endif //ENABLE_X264
#ifdef ENABLE_FAAC
std
::
shared_ptr
<
AACEncoder
>
m
_pAacEnc
;
std
::
shared_ptr
<
AACEncoder
>
_pAacEnc
;
#endif //ENABLE_FAAC
RtpMaker_AAC
::
Ptr
m
_pRtpMaker_aac
;
RtpMaker_H264
::
Ptr
m
_pRtpMaker_h264
;
bool
m
_bSdp_gotH264
=
false
;
bool
m
_bSdp_gotAAC
=
false
;
unsigned
char
m
_aucSPS
[
256
];
unsigned
int
m
_uiSPSLen
=
0
;
unsigned
char
m
_aucPPS
[
256
];
unsigned
int
m
_uiPPSLen
=
0
;
std
::
shared_ptr
<
VideoInfo
>
m
_video
;
std
::
shared_ptr
<
AudioInfo
>
m
_audio
;
SmoothTicker
m
_aTicker
[
2
];
std
::
shared_ptr
<
AACFrame
>
m
_pAdtsHeader
;
RtpMaker_AAC
::
Ptr
_pRtpMaker_aac
;
RtpMaker_H264
::
Ptr
_pRtpMaker_h264
;
bool
_bSdp_gotH264
=
false
;
bool
_bSdp_gotAAC
=
false
;
unsigned
char
_aucSPS
[
256
];
unsigned
int
_uiSPSLen
=
0
;
unsigned
char
_aucPPS
[
256
];
unsigned
int
_uiPPSLen
=
0
;
std
::
shared_ptr
<
VideoInfo
>
_video
;
std
::
shared_ptr
<
AudioInfo
>
_audio
;
SmoothTicker
_aTicker
[
2
];
std
::
shared_ptr
<
AACFrame
>
_pAdtsHeader
;
};
...
...
src/Device/PlayerProxy.cpp
查看文件 @
39baaebc
...
...
@@ -74,12 +74,12 @@ PlayerProxy::PlayerProxy(const char *strVhost,
bool
bEnableHls
,
bool
bEnableMp4
,
int
iRetryCount
){
m
_strVhost
=
strVhost
;
m
_strApp
=
strApp
;
m
_strSrc
=
strSrc
;
m
_bEnableHls
=
bEnableHls
;
m
_bEnableMp4
=
bEnableMp4
;
m
_iRetryCount
=
iRetryCount
;
_strVhost
=
strVhost
;
_strApp
=
strApp
;
_strSrc
=
strSrc
;
_bEnableHls
=
bEnableHls
;
_bEnableMp4
=
bEnableMp4
;
_iRetryCount
=
iRetryCount
;
}
void
PlayerProxy
::
play
(
const
char
*
strUrl
)
{
weak_ptr
<
PlayerProxy
>
weakSelf
=
shared_from_this
();
...
...
@@ -90,9 +90,9 @@ void PlayerProxy::play(const char* strUrl) {
// if(!strongSelf){
// return;
// }
// if(strongSelf->
m
_pChn){
// strongSelf->
m
_pChn->inputH264((char *)data.data(), data.size(), data.timeStamp);
// if(!strongSelf->
m
_haveAudio){
// if(strongSelf->_pChn){
// strongSelf->_pChn->inputH264((char *)data.data(), data.size(), data.timeStamp);
// if(!strongSelf->_haveAudio){
// strongSelf->makeMuteAudio(data.timeStamp);
// }
// }else{
...
...
@@ -104,8 +104,8 @@ void PlayerProxy::play(const char* strUrl) {
// if(!strongSelf){
// return;
// }
// if(strongSelf->
m
_pChn){
// strongSelf->
m
_pChn->inputAAC((char *)data.data(), data.size(), data.timeStamp);
// if(strongSelf->_pChn){
// strongSelf->_pChn->inputAAC((char *)data.data(), data.size(), data.timeStamp);
// }else{
// strongSelf->initMedia();
// }
...
...
@@ -121,7 +121,7 @@ void PlayerProxy::play(const char* strUrl) {
if
(
!
err
)
{
// 播放成功
*
piFailedCnt
=
0
;
//连续播放失败次数清0
}
else
if
(
*
piFailedCnt
<
strongSelf
->
m_iRetryCount
||
strongSelf
->
m
_iRetryCount
<
0
)
{
}
else
if
(
*
piFailedCnt
<
strongSelf
->
_iRetryCount
||
strongSelf
->
_iRetryCount
<
0
)
{
// 播放失败,延时重试播放
strongSelf
->
rePlay
(
strUrlTmp
,(
*
piFailedCnt
)
++
);
}
...
...
@@ -131,11 +131,11 @@ void PlayerProxy::play(const char* strUrl) {
if
(
!
strongSelf
)
{
return
;
}
if
(
strongSelf
->
m
_pChn
)
{
strongSelf
->
m
_pChn
.
reset
();
if
(
strongSelf
->
_pChn
)
{
strongSelf
->
_pChn
.
reset
();
}
//播放异常中断,延时重试播放
if
(
*
piFailedCnt
<
strongSelf
->
m_iRetryCount
||
strongSelf
->
m
_iRetryCount
<
0
)
{
if
(
*
piFailedCnt
<
strongSelf
->
_iRetryCount
||
strongSelf
->
_iRetryCount
<
0
)
{
strongSelf
->
rePlay
(
strUrlTmp
,(
*
piFailedCnt
)
++
);
}
});
...
...
@@ -166,8 +166,8 @@ void PlayerProxy::initMedia() {
if
(
!
isInited
())
{
return
;
}
m_pChn
.
reset
(
new
DevChannel
(
m_strVhost
.
data
(),
m_strApp
.
data
(),
m_strSrc
.
data
(),
getDuration
(),
m_bEnableHls
,
m
_bEnableMp4
));
m
_pChn
->
setListener
(
shared_from_this
());
_pChn
.
reset
(
new
DevChannel
(
_strVhost
.
data
(),
_strApp
.
data
(),
_strSrc
.
data
(),
getDuration
(),
_bEnableHls
,
_bEnableMp4
));
_pChn
->
setListener
(
shared_from_this
());
//todo(xzl) 修复此处
...
...
@@ -176,22 +176,22 @@ void PlayerProxy::initMedia() {
// info.iFrameRate = getVideoFps();
// info.iWidth = getVideoWidth();
// info.iHeight = getVideoHeight();
//
m
_pChn->initVideo(info);
// _pChn->initVideo(info);
// }
//
//
m
_haveAudio = containAudio();
// _haveAudio = containAudio();
// if (containAudio()) {
// AudioInfo info;
// info.iSampleRate = getAudioSampleRate();
// info.iChannel = getAudioChannel();
// info.iSampleBit = getAudioSampleBit();
//
m
_pChn->initAudio(info);
// _pChn->initAudio(info);
// }else{
// AudioInfo info;
// info.iSampleRate = MUTE_ADTS_SAMPLE_RATE;
// info.iChannel = MUTE_ADTS_CHN_CNT;
// info.iSampleBit = MUTE_ADTS_SAMPLE_BIT;
//
m
_pChn->initAudio(info);
// _pChn->initAudio(info);
// }
}
bool
PlayerProxy
::
shutDown
()
{
...
...
@@ -202,7 +202,7 @@ bool PlayerProxy::shutDown() {
executor
->
async_first
([
weakSlef
]()
{
auto
stronSelf
=
weakSlef
.
lock
();
if
(
stronSelf
)
{
stronSelf
->
m
_pChn
.
reset
();
stronSelf
->
_pChn
.
reset
();
stronSelf
->
teardown
();
}
});
...
...
@@ -212,10 +212,10 @@ bool PlayerProxy::shutDown() {
void
PlayerProxy
::
makeMuteAudio
(
uint32_t
stamp
)
{
auto
iAudioIndex
=
stamp
/
MUTE_ADTS_DATA_MS
;
if
(
m
_iAudioIndex
!=
iAudioIndex
){
m
_iAudioIndex
=
iAudioIndex
;
m_pChn
->
inputAAC
((
char
*
)
MUTE_ADTS_DATA
,
MUTE_ADTS_DATA_LEN
,
m
_iAudioIndex
*
MUTE_ADTS_DATA_MS
);
//DebugL <<
m
_iAudioIndex * MUTE_ADTS_DATA_MS << " " << stamp;
if
(
_iAudioIndex
!=
iAudioIndex
){
_iAudioIndex
=
iAudioIndex
;
_pChn
->
inputAAC
((
char
*
)
MUTE_ADTS_DATA
,
MUTE_ADTS_DATA_LEN
,
_iAudioIndex
*
MUTE_ADTS_DATA_MS
);
//DebugL << _iAudioIndex * MUTE_ADTS_DATA_MS << " " << stamp;
}
}
...
...
src/Device/PlayerProxy.h
查看文件 @
39baaebc
...
...
@@ -60,15 +60,15 @@ private:
void
rePlay
(
const
string
&
strUrl
,
int
iFailedCnt
);
void
makeMuteAudio
(
uint32_t
stamp
);
private
:
bool
m
_bEnableHls
;
bool
m
_bEnableMp4
;
int
m
_iRetryCount
;
DevChannel
::
Ptr
m
_pChn
;
string
m
_strVhost
;
string
m
_strApp
;
string
m
_strSrc
;
bool
m
_haveAudio
=
false
;
int
m
_iAudioIndex
=
0
;
bool
_bEnableHls
;
bool
_bEnableMp4
;
int
_iRetryCount
;
DevChannel
::
Ptr
_pChn
;
string
_strVhost
;
string
_strApp
;
string
_strSrc
;
bool
_haveAudio
=
false
;
int
_iAudioIndex
=
0
;
};
}
/* namespace Player */
...
...
src/H264/H264Parser.cpp
查看文件 @
39baaebc
...
...
@@ -37,19 +37,19 @@ H264Parser::~H264Parser(){
}
void
H264Parser
::
inputH264
(
const
string
&
h264
,
uint32_t
dts
){
m
_parser
.
SetStream
((
const
uint8_t
*
)
h264
.
data
(),
h264
.
size
());
_parser
.
SetStream
((
const
uint8_t
*
)
h264
.
data
(),
h264
.
size
());
while
(
true
)
{
if
(
media
::
H264Parser
::
kOk
!=
m_parser
.
AdvanceToNextNALU
(
&
m
_nalu
)){
if
(
media
::
H264Parser
::
kOk
!=
_parser
.
AdvanceToNextNALU
(
&
_nalu
)){
break
;
}
switch
(
m
_nalu
.
nal_unit_type
)
{
switch
(
_nalu
.
nal_unit_type
)
{
case
media
:
:
H264NALU
::
kNonIDRSlice
:
case
media
:
:
H264NALU
::
kIDRSlice
:
{
if
(
media
::
H264Parser
::
kOk
==
m_parser
.
ParseSliceHeader
(
m_nalu
,
&
m
_shdr
)){
const
media
::
H264SPS
*
pPps
=
m_parser
.
GetSPS
(
m
_shdr
.
pic_parameter_set_id
);
if
(
media
::
H264Parser
::
kOk
==
_parser
.
ParseSliceHeader
(
_nalu
,
&
_shdr
)){
const
media
::
H264SPS
*
pPps
=
_parser
.
GetSPS
(
_shdr
.
pic_parameter_set_id
);
if
(
pPps
)
{
m_poc
.
ComputePicOrderCnt
(
pPps
,
m_shdr
,
&
m
_iNowPOC
);
_poc
.
ComputePicOrderCnt
(
pPps
,
_shdr
,
&
_iNowPOC
);
computePts
(
dts
);
}
}
...
...
@@ -57,12 +57,12 @@ void H264Parser::inputH264(const string &h264,uint32_t dts){
break
;
case
media
:
:
H264NALU
::
kSPS
:
{
int
sps_id
;
m
_parser
.
ParseSPS
(
&
sps_id
);
_parser
.
ParseSPS
(
&
sps_id
);
}
break
;
case
media
:
:
H264NALU
::
kPPS
:
{
int
pps_id
;
m
_parser
.
ParsePPS
(
&
pps_id
);
_parser
.
ParsePPS
(
&
pps_id
);
}
break
;
default
:
...
...
@@ -72,33 +72,33 @@ void H264Parser::inputH264(const string &h264,uint32_t dts){
}
void
H264Parser
::
computePts
(
uint32_t
iNowDTS
)
{
auto
iPOCInc
=
m_iNowPOC
-
m
_iLastPOC
;
if
(
m
_shdr
.
slice_type
%
5
==
1
)
{
auto
iPOCInc
=
_iNowPOC
-
_iLastPOC
;
if
(
_shdr
.
slice_type
%
5
==
1
)
{
//这是B帧
m_iNowPTS
=
m_iLastPTS
+
m
_iMsPerPOC
*
(
iPOCInc
);
_iNowPTS
=
_iLastPTS
+
_iMsPerPOC
*
(
iPOCInc
);
}
else
{
//这是I帧或者P帧
m
_iNowPTS
=
iNowDTS
;
_iNowPTS
=
iNowDTS
;
//计算每一POC的时间
if
(
iPOCInc
==
0
){
WarnL
<<
"iPOCInc = 0,"
<<
m_iNowPOC
<<
" "
<<
m
_iLastPOC
;
WarnL
<<
"iPOCInc = 0,"
<<
_iNowPOC
<<
" "
<<
_iLastPOC
;
}
else
{
m_iMsPerPOC
=
(
m_iNowPTS
-
m
_iLastPTS
)
/
iPOCInc
;
_iMsPerPOC
=
(
_iNowPTS
-
_iLastPTS
)
/
iPOCInc
;
}
m_iLastPTS
=
m
_iNowPTS
;
m_iLastPOC
=
m
_iNowPOC
;
_iLastPTS
=
_iNowPTS
;
_iLastPOC
=
_iNowPOC
;
}
// DebugL <<
m
_shdr.slice_type
// DebugL << _shdr.slice_type
// <<"\r\nNOW:"
// <<
m
_iNowPOC << " "
// <<
m
_iNowPTS << " "
// << _iNowPOC << " "
// << _iNowPTS << " "
// << iNowDTS << " "
// << "\r\nLST:"
// <<
m
_iLastPOC << " "
// <<
m
_iLastPTS << " "
// <<
m
_iMsPerPOC << endl;
// << _iLastPOC << " "
// << _iLastPTS << " "
// << _iMsPerPOC << endl;
}
...
...
src/H264/H264Parser.h
查看文件 @
39baaebc
...
...
@@ -44,29 +44,29 @@ public:
void
inputH264
(
const
string
&
h264
,
uint32_t
dts
);
int32_t
getPOC
()
const
{
return
m
_iNowPOC
;
return
_iNowPOC
;
}
int
getSliceType
()
const
{
return
m
_shdr
.
slice_type
;
return
_shdr
.
slice_type
;
}
int
getNaluType
()
const
{
return
m
_nalu
.
nal_unit_type
;
return
_nalu
.
nal_unit_type
;
}
uint32_t
getPts
()
const
{
return
m
_iNowPTS
;
return
_iNowPTS
;
}
private
:
media
::
H264Parser
m
_parser
;
media
::
H264POC
m
_poc
;
media
::
H264NALU
m
_nalu
;
media
::
H264SliceHeader
m
_shdr
;
media
::
H264Parser
_parser
;
media
::
H264POC
_poc
;
media
::
H264NALU
_nalu
;
media
::
H264SliceHeader
_shdr
;
int32_t
m
_iNowPOC
=
INT32_MAX
;
int32_t
m
_iLastPOC
=
INT32_MAX
;
int32_t
_iNowPOC
=
INT32_MAX
;
int32_t
_iLastPOC
=
INT32_MAX
;
uint32_t
m
_iNowPTS
=
INT32_MAX
;
uint32_t
m
_iLastPTS
=
INT32_MAX
;
int32_t
m
_iMsPerPOC
=
30
;
uint32_t
_iNowPTS
=
INT32_MAX
;
uint32_t
_iLastPTS
=
INT32_MAX
;
int32_t
_iMsPerPOC
=
30
;
void
computePts
(
uint32_t
dts
);
...
...
src/Http/HttpSession.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Http/HttpSession.h
查看文件 @
39baaebc
...
...
@@ -101,16 +101,16 @@ protected:
WebSocketSplitter
::
decode
((
uint8_t
*
)
data
,
len
);
}
private
:
Parser
m
_parser
;
string
m
_strPath
;
Ticker
m
_ticker
;
uint32_t
m
_iReqCnt
=
0
;
Parser
_parser
;
string
_strPath
;
Ticker
_ticker
;
uint32_t
_iReqCnt
=
0
;
//消耗的总流量
uint64_t
m
_ui64TotalBytes
=
0
;
uint64_t
_ui64TotalBytes
=
0
;
//flv over http
MediaInfo
m
_mediaInfo
;
MediaInfo
_mediaInfo
;
//处理content数据的callback
function
<
bool
(
const
char
*
data
,
uint64_t
len
)
>
m
_contentCallBack
;
function
<
bool
(
const
char
*
data
,
uint64_t
len
)
>
_contentCallBack
;
private
:
inline
bool
Handle_Req_GET
(
int64_t
&
content_len
);
inline
bool
Handle_Req_POST
(
int64_t
&
content_len
);
...
...
src/Http/HttpsSession.h
查看文件 @
39baaebc
...
...
@@ -40,14 +40,14 @@ class HttpsSession: public HttpSession {
public
:
HttpsSession
(
const
std
::
shared_ptr
<
ThreadPool
>
&
pTh
,
const
Socket
::
Ptr
&
pSock
)
:
HttpSession
(
pTh
,
pSock
){
m
_sslBox
.
setOnEncData
([
&
](
const
char
*
data
,
uint32_t
len
){
_sslBox
.
setOnEncData
([
&
](
const
char
*
data
,
uint32_t
len
){
#if defined(__GNUC__) && (__GNUC__ < 5)
public_send
(
data
,
len
);
#else//defined(__GNUC__) && (__GNUC__ < 5)
HttpSession
::
send
(
obtainBuffer
(
data
,
len
));
#endif//defined(__GNUC__) && (__GNUC__ < 5)
});
m
_sslBox
.
setOnDecData
([
&
](
const
char
*
data
,
uint32_t
len
){
_sslBox
.
setOnDecData
([
&
](
const
char
*
data
,
uint32_t
len
){
#if defined(__GNUC__) && (__GNUC__ < 5)
public_onRecv
(
data
,
len
);
#else//defined(__GNUC__) && (__GNUC__ < 5)
...
...
@@ -56,11 +56,11 @@ public:
});
}
virtual
~
HttpsSession
(){
//
m
_sslBox.shutdown();
//_sslBox.shutdown();
}
void
onRecv
(
const
Buffer
::
Ptr
&
pBuf
)
override
{
TimeTicker
();
m
_sslBox
.
onRecv
(
pBuf
->
data
(),
pBuf
->
size
());
_sslBox
.
onRecv
(
pBuf
->
data
(),
pBuf
->
size
());
}
#if defined(__GNUC__) && (__GNUC__ < 5)
int
public_send
(
const
char
*
data
,
uint32_t
len
){
...
...
@@ -73,10 +73,10 @@ public:
protected
:
virtual
int
send
(
const
Buffer
::
Ptr
&
buf
)
override
{
TimeTicker
();
m
_sslBox
.
onSend
(
buf
->
data
(),
buf
->
size
());
_sslBox
.
onSend
(
buf
->
data
(),
buf
->
size
());
return
buf
->
size
();
}
SSL_Box
m
_sslBox
;
SSL_Box
_sslBox
;
};
...
...
src/MediaFile/HLSMaker.cpp
查看文件 @
39baaebc
...
...
@@ -43,35 +43,35 @@ HLSMaker::HLSMaker(const string& strM3u8File,
if
(
ui32Num
<
1
){
ui32Num
=
1
;
}
m
_ui32BufSize
=
ui32BufSize
;
m
_ui64TsCnt
=
0
;
m
_strM3u8File
=
strM3u8File
;
m
_ui32NumSegments
=
ui32Num
;
m
_ui32SegmentDuration
=
ui32Duration
;
m
_ui32LastStamp
=
0
;
m
_strOutputPrefix
=
strM3u8File
.
substr
(
0
,
strM3u8File
.
rfind
(
'.'
));
m_strFileName
=
m_strOutputPrefix
.
substr
(
m
_strOutputPrefix
.
rfind
(
'/'
)
+
1
);
m_ts
.
init
(
m_strOutputPrefix
+
"-0.ts"
,
m
_ui32BufSize
);
_ui32BufSize
=
ui32BufSize
;
_ui64TsCnt
=
0
;
_strM3u8File
=
strM3u8File
;
_ui32NumSegments
=
ui32Num
;
_ui32SegmentDuration
=
ui32Duration
;
_ui32LastStamp
=
0
;
_strOutputPrefix
=
strM3u8File
.
substr
(
0
,
strM3u8File
.
rfind
(
'.'
));
_strFileName
=
_strOutputPrefix
.
substr
(
_strOutputPrefix
.
rfind
(
'/'
)
+
1
);
_ts
.
init
(
_strOutputPrefix
+
"-0.ts"
,
_ui32BufSize
);
}
HLSMaker
::~
HLSMaker
()
{
m
_ts
.
clear
();
string
strDir
=
m_strOutputPrefix
.
substr
(
0
,
m
_strOutputPrefix
.
rfind
(
'/'
));
_ts
.
clear
();
string
strDir
=
_strOutputPrefix
.
substr
(
0
,
_strOutputPrefix
.
rfind
(
'/'
));
File
::
delete_file
(
strDir
.
data
());
}
bool
HLSMaker
::
write_index_file
(
int
iFirstSegment
,
unsigned
int
uiLastSegment
,
int
iEnd
)
{
char
acWriteBuf
[
1024
];
std
::
shared_ptr
<
FILE
>
pM3u8File
(
File
::
createfile_file
(
m
_strM3u8File
.
data
(),
"w"
),[](
FILE
*
fp
){
std
::
shared_ptr
<
FILE
>
pM3u8File
(
File
::
createfile_file
(
_strM3u8File
.
data
(),
"w"
),[](
FILE
*
fp
){
if
(
fp
){
fflush
(
fp
);
fclose
(
fp
);
}
});
if
(
!
pM3u8File
)
{
WarnL
<<
"Could not open temporary m3u8 index file ("
<<
m
_strM3u8File
<<
"), no index file will be created"
;
WarnL
<<
"Could not open temporary m3u8 index file ("
<<
_strM3u8File
<<
"), no index file will be created"
;
return
false
;
}
if
(
iFirstSegment
<
0
)
{
...
...
@@ -80,13 +80,13 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i
//最少1秒
int
maxSegmentDuration
=
0
;
for
(
auto
dur
:
m
_iDurations
)
{
for
(
auto
dur
:
_iDurations
)
{
dur
/=
1000
;
if
(
dur
>
maxSegmentDuration
){
maxSegmentDuration
=
dur
;
}
}
if
(
m
_ui32NumSegments
)
{
if
(
_ui32NumSegments
)
{
snprintf
(
acWriteBuf
,
sizeof
(
acWriteBuf
),
"#EXTM3U
\r\n
"
...
...
@@ -114,8 +114,8 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i
snprintf
(
acWriteBuf
,
sizeof
(
acWriteBuf
),
"#EXTINF:%.3f,
\r\n
%s-%u.ts
\r\n
"
,
m
_iDurations
[
i
-
iFirstSegment
]
/
1000.0
,
m
_strFileName
.
c_str
(),
_iDurations
[
i
-
iFirstSegment
]
/
1000.0
,
_strFileName
.
c_str
(),
i
);
if
(
fwrite
(
acWriteBuf
,
strlen
(
acWriteBuf
),
1
,
pM3u8File
.
get
())
!=
1
)
{
WarnL
<<
"Could not write to m3u8 index file, will not continue writing to index file"
;
...
...
@@ -134,36 +134,36 @@ bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, i
}
void
HLSMaker
::
inputH264
(
void
*
data
,
uint32_t
length
,
uint32_t
timeStamp
,
int
type
)
{
if
(
m
_ui32LastStamp
==
0
){
m
_ui32LastStamp
=
timeStamp
;
if
(
_ui32LastStamp
==
0
){
_ui32LastStamp
=
timeStamp
;
}
int
stampInc
=
timeStamp
-
m
_ui32LastStamp
;
int
stampInc
=
timeStamp
-
_ui32LastStamp
;
switch
(
type
)
{
case
7
:
//SPS
if
(
stampInc
>=
m
_ui32SegmentDuration
*
1000
)
{
m
_ui32LastStamp
=
timeStamp
;
if
(
stampInc
>=
_ui32SegmentDuration
*
1000
)
{
_ui32LastStamp
=
timeStamp
;
//关闭文件
m
_ts
.
clear
();
auto
strTmpFileName
=
StrPrinter
<<
m_strOutputPrefix
<<
'-'
<<
(
++
m
_ui64TsCnt
)
<<
".ts"
<<
endl
;
if
(
!
m_ts
.
init
(
strTmpFileName
,
m
_ui32BufSize
))
{
_ts
.
clear
();
auto
strTmpFileName
=
StrPrinter
<<
_strOutputPrefix
<<
'-'
<<
(
++
_ui64TsCnt
)
<<
".ts"
<<
endl
;
if
(
!
_ts
.
init
(
strTmpFileName
,
_ui32BufSize
))
{
//创建文件失败
return
;
}
//记录切片时间
m
_iDurations
.
push_back
(
stampInc
);
_iDurations
.
push_back
(
stampInc
);
if
(
removets
()){
//删除老的时间戳
m
_iDurations
.
pop_front
();
_iDurations
.
pop_front
();
}
write_index_file
(
m_ui64TsCnt
-
m_ui32NumSegments
,
m
_ui64TsCnt
,
0
);
write_index_file
(
_ui64TsCnt
-
_ui32NumSegments
,
_ui64TsCnt
,
0
);
}
case
1
:
//P
//insert aud frame before p and SPS frame
m
_ts
.
inputH264
(
"\x0\x0\x0\x1\x9
\xf0
"
,
6
,
timeStamp
*
90
);
_ts
.
inputH264
(
"\x0\x0\x0\x1\x9
\xf0
"
,
6
,
timeStamp
*
90
);
case
5
:
//IDR
case
8
:
//PPS
m
_ts
.
inputH264
((
char
*
)
data
,
length
,
timeStamp
*
90
);
_ts
.
inputH264
((
char
*
)
data
,
length
,
timeStamp
*
90
);
break
;
default
:
break
;
...
...
@@ -171,15 +171,15 @@ void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp, int ty
}
void
HLSMaker
::
inputAAC
(
void
*
data
,
uint32_t
length
,
uint32_t
timeStamp
)
{
m
_ts
.
inputAAC
((
char
*
)
data
,
length
,
timeStamp
*
90
);
_ts
.
inputAAC
((
char
*
)
data
,
length
,
timeStamp
*
90
);
}
bool
HLSMaker
::
removets
()
{
if
(
m_ui64TsCnt
<
m
_ui32NumSegments
+
2
)
{
if
(
_ui64TsCnt
<
_ui32NumSegments
+
2
)
{
return
false
;
}
File
::
delete_file
((
StrPrinter
<<
m
_strOutputPrefix
<<
"-"
<<
m_ui64TsCnt
-
m
_ui32NumSegments
-
2
File
::
delete_file
((
StrPrinter
<<
_strOutputPrefix
<<
"-"
<<
_ui64TsCnt
-
_ui32NumSegments
-
2
<<
".ts"
<<
endl
).
data
());
return
true
;
}
...
...
src/MediaFile/HLSMaker.h
查看文件 @
39baaebc
...
...
@@ -60,16 +60,16 @@ public:
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
private
:
TSMaker
m
_ts
;
string
m
_strM3u8File
;
string
m
_strFileName
;
string
m
_strOutputPrefix
;
uint32_t
m
_ui32SegmentDuration
;
uint32_t
m
_ui32NumSegments
;
uint64_t
m
_ui64TsCnt
;
uint32_t
m
_ui32BufSize
;
uint32_t
m
_ui32LastStamp
;
std
::
deque
<
int
>
m
_iDurations
;
TSMaker
_ts
;
string
_strM3u8File
;
string
_strFileName
;
string
_strOutputPrefix
;
uint32_t
_ui32SegmentDuration
;
uint32_t
_ui32NumSegments
;
uint64_t
_ui64TsCnt
;
uint32_t
_ui32BufSize
;
uint32_t
_ui32LastStamp
;
std
::
deque
<
int
>
_iDurations
;
bool
write_index_file
(
int
iFirstSegment
,
unsigned
int
uiLastSegment
,
int
iEnd
);
bool
removets
();
...
...
src/MediaFile/MediaReader.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/MediaFile/MediaReader.h
查看文件 @
39baaebc
...
...
@@ -55,37 +55,37 @@ public:
private
:
#ifdef ENABLE_MP4V2
MP4FileHandle
m
_hMP4File
=
MP4_INVALID_FILE_HANDLE
;
MP4TrackId
m
_video_trId
=
MP4_INVALID_TRACK_ID
;
uint32_t
m
_video_ms
=
0
;
uint32_t
m
_video_num_samples
=
0
;
uint32_t
m
_video_sample_max_size
=
0
;
uint32_t
m
_video_width
=
0
;
uint32_t
m
_video_height
=
0
;
uint32_t
m
_video_framerate
=
0
;
string
m
_strPps
;
string
m
_strSps
;
bool
m
_bSyncSample
=
false
;
MP4FileHandle
_hMP4File
=
MP4_INVALID_FILE_HANDLE
;
MP4TrackId
_video_trId
=
MP4_INVALID_TRACK_ID
;
uint32_t
_video_ms
=
0
;
uint32_t
_video_num_samples
=
0
;
uint32_t
_video_sample_max_size
=
0
;
uint32_t
_video_width
=
0
;
uint32_t
_video_height
=
0
;
uint32_t
_video_framerate
=
0
;
string
_strPps
;
string
_strSps
;
bool
_bSyncSample
=
false
;
MP4TrackId
m
_audio_trId
=
MP4_INVALID_TRACK_ID
;
uint32_t
m
_audio_ms
=
0
;
uint32_t
m
_audio_num_samples
=
0
;
uint32_t
m
_audio_sample_max_size
=
0
;
uint32_t
m
_audio_sample_rate
=
0
;
uint32_t
m
_audio_num_channels
=
0
;
string
m
_strAacCfg
;
AACFrame
m
_adts
;
MP4TrackId
_audio_trId
=
MP4_INVALID_TRACK_ID
;
uint32_t
_audio_ms
=
0
;
uint32_t
_audio_num_samples
=
0
;
uint32_t
_audio_sample_max_size
=
0
;
uint32_t
_audio_sample_rate
=
0
;
uint32_t
_audio_num_channels
=
0
;
string
_strAacCfg
;
AACFrame
_adts
;
int
m
_iDuration
=
0
;
DevChannel
::
Ptr
m
_pChn
;
MP4SampleId
m
_video_current
=
0
;
MP4SampleId
m
_audio_current
=
0
;
std
::
shared_ptr
<
uint8_t
>
m
_pcVideoSample
;
int
_iDuration
=
0
;
DevChannel
::
Ptr
_pChn
;
MP4SampleId
_video_current
=
0
;
MP4SampleId
_audio_current
=
0
;
std
::
shared_ptr
<
uint8_t
>
_pcVideoSample
;
int
m
_iSeekTime
=
0
;
Ticker
m
_ticker
;
Ticker
m
_alive
;
recursive_mutex
m
_mtx
;
int
_iSeekTime
=
0
;
Ticker
_ticker
;
Ticker
_alive
;
recursive_mutex
_mtx
;
void
seek
(
int
iSeekTime
,
bool
bReStart
=
true
);
inline
void
setSeekTime
(
int
iSeekTime
);
...
...
src/MediaFile/MediaRecorder.cpp
查看文件 @
39baaebc
...
...
@@ -57,7 +57,7 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
if
(
enableHls
)
{
auto
m3u8FilePath
=
hlsPath
+
"/"
+
strVhost
+
"/"
+
strApp
+
"/"
+
strId
+
"/hls.m3u8"
;
m
_hlsMaker
.
reset
(
new
HLSMaker
(
m3u8FilePath
,
hlsBufSize
,
hlsDuration
,
hlsNum
));
_hlsMaker
.
reset
(
new
HLSMaker
(
m3u8FilePath
,
hlsBufSize
,
hlsDuration
,
hlsNum
));
}
#ifdef ENABLE_MP4V2
...
...
@@ -66,7 +66,7 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
if
(
enableMp4
){
auto
mp4FilePath
=
recordPath
+
"/"
+
strVhost
+
"/"
+
recordAppName
+
"/"
+
strApp
+
"/"
+
strId
+
"/"
;
m
_mp4Maker
.
reset
(
new
Mp4Maker
(
mp4FilePath
,
strVhost
,
strApp
,
strId
,
pPlayer
));
_mp4Maker
.
reset
(
new
Mp4Maker
(
mp4FilePath
,
strVhost
,
strApp
,
strId
,
pPlayer
));
}
#endif //ENABLE_MP4V2
}
...
...
@@ -75,23 +75,23 @@ MediaRecorder::~MediaRecorder() {
}
void
MediaRecorder
::
inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
,
int
iType
)
{
if
(
m
_hlsMaker
){
m
_hlsMaker
->
inputH264
(
pData
,
ui32Length
,
ui32TimeStamp
,
iType
);
if
(
_hlsMaker
){
_hlsMaker
->
inputH264
(
pData
,
ui32Length
,
ui32TimeStamp
,
iType
);
}
#ifdef ENABLE_MP4V2
if
(
m
_mp4Maker
){
m
_mp4Maker
->
inputH264
(
pData
,
ui32Length
,
ui32TimeStamp
,
iType
);
if
(
_mp4Maker
){
_mp4Maker
->
inputH264
(
pData
,
ui32Length
,
ui32TimeStamp
,
iType
);
}
#endif //ENABLE_MP4V2
}
void
MediaRecorder
::
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
)
{
if
(
m
_hlsMaker
){
m
_hlsMaker
->
inputAAC
(
pData
,
ui32Length
,
ui32TimeStamp
);
if
(
_hlsMaker
){
_hlsMaker
->
inputAAC
(
pData
,
ui32Length
,
ui32TimeStamp
);
}
#ifdef ENABLE_MP4V2
if
(
m
_mp4Maker
){
m
_mp4Maker
->
inputAAC
(
pData
,
ui32Length
,
ui32TimeStamp
);
if
(
_mp4Maker
){
_mp4Maker
->
inputAAC
(
pData
,
ui32Length
,
ui32TimeStamp
);
}
#endif //ENABLE_MP4V2
}
...
...
src/MediaFile/MediaRecorder.h
查看文件 @
39baaebc
...
...
@@ -50,8 +50,8 @@ public:
const
string
&
strApp
,
const
string
&
strId
,
const
std
::
shared_ptr
<
PlayerBase
>
&
pPlayer
,
bool
m_
enableHls
=
true
,
bool
m_
enableMp4
=
false
);
bool
enableHls
=
true
,
bool
enableMp4
=
false
);
virtual
~
MediaRecorder
();
void
inputH264
(
void
*
pData
,
...
...
@@ -63,9 +63,9 @@ public:
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
private
:
std
::
shared_ptr
<
HLSMaker
>
m
_hlsMaker
;
std
::
shared_ptr
<
HLSMaker
>
_hlsMaker
;
#ifdef ENABLE_MP4V2
std
::
shared_ptr
<
Mp4Maker
>
m
_mp4Maker
;
std
::
shared_ptr
<
Mp4Maker
>
_mp4Maker
;
#endif //ENABLE_MP4V2
};
...
...
src/MediaFile/Mp4Maker.cpp
查看文件 @
39baaebc
...
...
@@ -62,14 +62,14 @@ Mp4Maker::Mp4Maker(const string& strPath,
const
string
&
strStreamId
,
const
PlayerBase
::
Ptr
&
pPlayer
)
{
DebugL
<<
strPath
;
m
_pPlayer
=
pPlayer
;
m
_strPath
=
strPath
;
_pPlayer
=
pPlayer
;
_strPath
=
strPath
;
/////record 业务逻辑//////
m
_info
.
strAppName
=
strApp
;
m
_info
.
strStreamId
=
strStreamId
;
m
_info
.
strVhost
=
strVhost
;
m
_info
.
strFolder
=
strPath
;
_info
.
strAppName
=
strApp
;
_info
.
strStreamId
=
strStreamId
;
_info
.
strVhost
=
strVhost
;
_info
.
strFolder
=
strPath
;
//----record 业务逻辑----//
}
Mp4Maker
::~
Mp4Maker
()
{
...
...
@@ -80,22 +80,22 @@ void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStam
switch
(
iType
)
{
case
1
:
//P
case
5
:
{
//IDR
if
(
m
_strLastVideo
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
m
_ui32LastVideoTime
;
if
(
_strLastVideo
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastVideoTime
;
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
if
(
iTimeInc
==
0
||
iTimeInc
==
500
){
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
m
_ui32LastVideoTime
;
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastVideoTime
;
}
_inputH264
((
char
*
)
m_strLastVideo
.
data
(),
m_strLastVideo
.
size
(),
iTimeInc
,
m
_iLastVideoType
);
_inputH264
((
char
*
)
_strLastVideo
.
data
(),
_strLastVideo
.
size
(),
iTimeInc
,
_iLastVideoType
);
}
//
m
_strLastVideo.assign(("\x0\x0\x0\x2\x9\xf0"), 6);
//_strLastVideo.assign(("\x0\x0\x0\x2\x9\xf0"), 6);
uint32_t
*
p
=
(
uint32_t
*
)
pData
;
*
p
=
htonl
(
ui32Length
-
4
);
m
_strLastVideo
.
assign
((
char
*
)
pData
,
ui32Length
);
_strLastVideo
.
assign
((
char
*
)
pData
,
ui32Length
);
memcpy
(
pData
,
"
\x00\x00\x00\x01
"
,
4
);
m
_ui32LastVideoTime
=
ui32TimeStamp
;
m
_iLastVideoType
=
iType
;
_ui32LastVideoTime
=
ui32TimeStamp
;
_iLastVideoType
=
iType
;
}
break
;
default
:
...
...
@@ -103,28 +103,28 @@ void Mp4Maker::inputH264(void *pData, uint32_t ui32Length, uint32_t ui32TimeStam
}
}
void
Mp4Maker
::
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
if
(
m
_strLastAudio
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
m
_ui32LastAudioTime
;
if
(
_strLastAudio
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastAudioTime
;
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
if
(
iTimeInc
==
0
||
iTimeInc
==
500
){
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
m
_ui32LastAudioTime
;
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastAudioTime
;
}
_inputAAC
((
char
*
)
m_strLastAudio
.
data
(),
m
_strLastAudio
.
size
(),
iTimeInc
);
_inputAAC
((
char
*
)
_strLastAudio
.
data
(),
_strLastAudio
.
size
(),
iTimeInc
);
}
m
_strLastAudio
.
assign
((
char
*
)
pData
,
ui32Length
);
m
_ui32LastAudioTime
=
ui32TimeStamp
;
_strLastAudio
.
assign
((
char
*
)
pData
,
ui32Length
);
_ui32LastAudioTime
=
ui32TimeStamp
;
}
void
Mp4Maker
::
_inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32Duration
,
int
iType
)
{
GET_CONFIG_AND_REGISTER
(
uint32_t
,
recordSec
,
Config
::
Record
::
kFileSecond
);
if
(
iType
==
5
&&
(
m_hMp4
==
MP4_INVALID_FILE_HANDLE
||
m
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
if
(
iType
==
5
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
//在I帧率处新建MP4文件
//如果文件未创建或者文件超过10分钟则创建新文件
createFile
();
}
if
(
m
_hVideo
!=
MP4_INVALID_TRACK_ID
)
{
MP4WriteSample
(
m_hMp4
,
m
_hVideo
,
(
uint8_t
*
)
pData
,
ui32Length
,
ui32Duration
*
90
,
0
,
iType
==
5
);
if
(
_hVideo
!=
MP4_INVALID_TRACK_ID
)
{
MP4WriteSample
(
_hMp4
,
_hVideo
,
(
uint8_t
*
)
pData
,
ui32Length
,
ui32Duration
*
90
,
0
,
iType
==
5
);
}
}
...
...
@@ -134,39 +134,39 @@ void Mp4Maker::_inputAAC(void* pData, uint32_t ui32Length, uint32_t ui32Duration
//todo(xzl) 修复此处
//
// if (!
m_pPlayer->containVideo() && (m_hMp4 == MP4_INVALID_FILE_HANDLE || m
_ticker.elapsedTime() > recordSec * 1000)) {
// if (!
_pPlayer->containVideo() && (_hMp4 == MP4_INVALID_FILE_HANDLE ||
_ticker.elapsedTime() > recordSec * 1000)) {
// //在I帧率处新建MP4文件
// //如果文件未创建或者文件超过10分钟则创建新文件
// createFile();
// }
// if (
m
_hAudio != MP4_INVALID_TRACK_ID) {
// auto duration = ui32Duration *
m
_pPlayer->getAudioSampleRate() /1000.0;
// MP4WriteSample(
m_hMp4, m
_hAudio, (uint8_t*)pData + 7, ui32Length - 7,duration,0,false);
// if (_hAudio != MP4_INVALID_TRACK_ID) {
// auto duration = ui32Duration * _pPlayer->getAudioSampleRate() /1000.0;
// MP4WriteSample(
_hMp4,
_hAudio, (uint8_t*)pData + 7, ui32Length - 7,duration,0,false);
// }
}
void
Mp4Maker
::
createFile
()
{
if
(
!
m
_pPlayer
->
isInited
()){
if
(
!
_pPlayer
->
isInited
()){
return
;
}
closeFile
();
auto
strDate
=
timeStr
(
"%Y-%m-%d"
);
auto
strTime
=
timeStr
(
"%H-%M-%S"
);
auto
strFileTmp
=
m
_strPath
+
strDate
+
"/."
+
strTime
+
".mp4"
;
auto
strFile
=
m
_strPath
+
strDate
+
"/"
+
strTime
+
".mp4"
;
auto
strFileTmp
=
_strPath
+
strDate
+
"/."
+
strTime
+
".mp4"
;
auto
strFile
=
_strPath
+
strDate
+
"/"
+
strTime
+
".mp4"
;
/////record 业务逻辑//////
m
_info
.
ui64StartedTime
=
::
time
(
NULL
);
m
_info
.
strFileName
=
strTime
+
".mp4"
;
m
_info
.
strFilePath
=
strFile
;
_info
.
ui64StartedTime
=
::
time
(
NULL
);
_info
.
strFileName
=
strTime
+
".mp4"
;
_info
.
strFilePath
=
strFile
;
GET_CONFIG_AND_REGISTER
(
string
,
appName
,
Config
::
Record
::
kAppName
);
m_info
.
strUrl
=
m
_info
.
strVhost
+
"/"
_info
.
strUrl
=
_info
.
strVhost
+
"/"
+
appName
+
"/"
+
m
_info
.
strAppName
+
"/"
+
m
_info
.
strStreamId
+
"/"
+
_info
.
strAppName
+
"/"
+
_info
.
strStreamId
+
"/"
+
strDate
+
"/"
+
strTime
+
".mp4"
;
//----record 业务逻辑----//
...
...
@@ -176,36 +176,36 @@ void Mp4Maker::createFile() {
#else
File
::
createfile_path
(
strFileTmp
.
data
(),
0
);
#endif
m
_hMp4
=
MP4Create
(
strFileTmp
.
data
());
if
(
m
_hMp4
==
MP4_INVALID_FILE_HANDLE
)
{
_hMp4
=
MP4Create
(
strFileTmp
.
data
());
if
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
)
{
WarnL
<<
"创建MP4文件失败:"
<<
strFileTmp
;
return
;
}
//MP4SetTimeScale(
m
_hMp4, 90000);
m
_strFileTmp
=
strFileTmp
;
m
_strFile
=
strFile
;
m
_ticker
.
resetTime
();
//MP4SetTimeScale(_hMp4, 90000);
_strFileTmp
=
strFileTmp
;
_strFile
=
strFile
;
_ticker
.
resetTime
();
//todo(xzl) 修复此处
// if(
m
_pPlayer->containVideo()){
// auto &sps =
m
_pPlayer->getSps();
// auto &pps =
m
_pPlayer->getPps();
//
m_hVideo = MP4AddH264VideoTrack(m
_hMp4, 90000, MP4_INVALID_DURATION,
//
m_pPlayer->getVideoWidth(), m
_pPlayer->getVideoHeight(),
// if(_pPlayer->containVideo()){
// auto &sps = _pPlayer->getSps();
// auto &pps = _pPlayer->getPps();
//
_hVideo = MP4AddH264VideoTrack(
_hMp4, 90000, MP4_INVALID_DURATION,
//
_pPlayer->getVideoWidth(),
_pPlayer->getVideoHeight(),
// sps[5], sps[6], sps[7], 3);
// if(
m
_hVideo !=MP4_INVALID_TRACK_ID){
// MP4AddH264SequenceParameterSet(
m_hMp4, m
_hVideo, (uint8_t *)sps.data() + 4, sps.size() - 4);
// MP4AddH264PictureParameterSet(
m_hMp4, m
_hVideo, (uint8_t *)pps.data() + 4, pps.size() - 4);
// if(_hVideo !=MP4_INVALID_TRACK_ID){
// MP4AddH264SequenceParameterSet(
_hMp4,
_hVideo, (uint8_t *)sps.data() + 4, sps.size() - 4);
// MP4AddH264PictureParameterSet(
_hMp4,
_hVideo, (uint8_t *)pps.data() + 4, pps.size() - 4);
// }else{
// WarnL << "添加视频通道失败:" << strFileTmp;
// }
// }
// if(
m
_pPlayer->containAudio()){
//
m_hAudio = MP4AddAudioTrack(m_hMp4, m
_pPlayer->getAudioSampleRate(), MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
// if (
m
_hAudio != MP4_INVALID_TRACK_ID) {
// auto &cfg =
m
_pPlayer->getAudioCfg();
// MP4SetTrackESConfiguration(
m_hMp4, m
_hAudio,(uint8_t *)cfg.data(), cfg.size());
// if(_pPlayer->containAudio()){
//
_hAudio = MP4AddAudioTrack(_hMp4,
_pPlayer->getAudioSampleRate(), MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
// if (_hAudio != MP4_INVALID_TRACK_ID) {
// auto &cfg = _pPlayer->getAudioCfg();
// MP4SetTrackESConfiguration(
_hMp4,
_hAudio,(uint8_t *)cfg.data(), cfg.size());
// }else{
// WarnL << "添加音频通道失败:" << strFileTmp;
// }
...
...
@@ -213,24 +213,24 @@ void Mp4Maker::createFile() {
}
void
Mp4Maker
::
closeFile
()
{
if
(
m
_hMp4
!=
MP4_INVALID_FILE_HANDLE
)
{
if
(
_hMp4
!=
MP4_INVALID_FILE_HANDLE
)
{
{
TimeTicker
();
MP4Close
(
m
_hMp4
,
MP4_CLOSE_DO_NOT_COMPUTE_BITRATE
);
MP4Close
(
_hMp4
,
MP4_CLOSE_DO_NOT_COMPUTE_BITRATE
);
}
rename
(
m_strFileTmp
.
data
(),
m
_strFile
.
data
());
m
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
m
_hVideo
=
MP4_INVALID_TRACK_ID
;
m
_hAudio
=
MP4_INVALID_TRACK_ID
;
rename
(
_strFileTmp
.
data
(),
_strFile
.
data
());
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
_hVideo
=
MP4_INVALID_TRACK_ID
;
_hAudio
=
MP4_INVALID_TRACK_ID
;
/////record 业务逻辑//////
m_info
.
ui64TimeLen
=
::
time
(
NULL
)
-
m
_info
.
ui64StartedTime
;
_info
.
ui64TimeLen
=
::
time
(
NULL
)
-
_info
.
ui64StartedTime
;
//获取文件大小
struct
stat
fileData
;
stat
(
m
_strFile
.
data
(),
&
fileData
);
m
_info
.
ui64FileSize
=
fileData
.
st_size
;
stat
(
_strFile
.
data
(),
&
fileData
);
_info
.
ui64FileSize
=
fileData
.
st_size
;
//----record 业务逻辑----//
NoticeCenter
::
Instance
().
emitEvent
(
Config
::
Broadcast
::
kBroadcastRecordMP4
,
m
_info
,
*
this
);
NoticeCenter
::
Instance
().
emitEvent
(
Config
::
Broadcast
::
kBroadcastRecordMP4
,
_info
,
*
this
);
}
}
...
...
src/MediaFile/Mp4Maker.h
查看文件 @
39baaebc
...
...
@@ -73,29 +73,29 @@ public:
//时间戳:参考频率1000
void
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
private
:
MP4FileHandle
m
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
MP4TrackId
m
_hVideo
=
MP4_INVALID_TRACK_ID
;
MP4TrackId
m
_hAudio
=
MP4_INVALID_TRACK_ID
;
PlayerBase
::
Ptr
m
_pPlayer
;
string
m
_strPath
;
string
m
_strFile
;
string
m
_strFileTmp
;
Ticker
m
_ticker
;
SmoothTicker
m
_mediaTicker
[
2
];
MP4FileHandle
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
MP4TrackId
_hVideo
=
MP4_INVALID_TRACK_ID
;
MP4TrackId
_hAudio
=
MP4_INVALID_TRACK_ID
;
PlayerBase
::
Ptr
_pPlayer
;
string
_strPath
;
string
_strFile
;
string
_strFileTmp
;
Ticker
_ticker
;
SmoothTicker
_mediaTicker
[
2
];
void
createFile
();
void
closeFile
();
void
_inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui64Duration
,
int
iType
);
void
_inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui64Duration
);
string
m
_strLastVideo
;
string
m
_strLastAudio
;
string
_strLastVideo
;
string
_strLastAudio
;
uint32_t
m
_ui32LastVideoTime
=
0
;
uint32_t
m
_ui32LastAudioTime
=
0
;
int
m
_iLastVideoType
=
0
;
uint32_t
_ui32LastVideoTime
=
0
;
uint32_t
_ui32LastAudioTime
=
0
;
int
_iLastVideoType
=
0
;
Mp4Info
m
_info
;
Mp4Info
_info
;
};
}
/* namespace MediaFile */
...
...
src/Player/MediaPlayer.cpp
查看文件 @
39baaebc
...
...
@@ -43,22 +43,22 @@ MediaPlayer::~MediaPlayer() {
}
void
MediaPlayer
::
play
(
const
char
*
strUrl
)
{
string
strPrefix
=
FindField
(
strUrl
,
NULL
,
"://"
);
if
((
strcasecmp
(
m
_strPrefix
.
data
(),
strPrefix
.
data
())
!=
0
)
||
strPrefix
.
empty
())
{
if
((
strcasecmp
(
_strPrefix
.
data
(),
strPrefix
.
data
())
!=
0
)
||
strPrefix
.
empty
())
{
//协议切换
m
_strPrefix
=
strPrefix
;
m
_parser
=
PlayerBase
::
createPlayer
(
strUrl
);
m_parser
->
setOnShutdown
(
m
_shutdownCB
);
_strPrefix
=
strPrefix
;
_parser
=
PlayerBase
::
createPlayer
(
strUrl
);
_parser
->
setOnShutdown
(
_shutdownCB
);
//todo(xzl) 修复此处
//
m_parser->setOnVideoCB(m
_onGetVideoCB);
//
m_parser->setOnAudioCB(m
_onGetAudioCB);
//
_parser->setOnVideoCB(
_onGetVideoCB);
//
_parser->setOnAudioCB(
_onGetAudioCB);
}
m_parser
->
setOnPlayResult
(
m
_playResultCB
);
m
_parser
->
mINI
::
operator
=
(
*
this
);
m
_parser
->
play
(
strUrl
);
_parser
->
setOnPlayResult
(
_playResultCB
);
_parser
->
mINI
::
operator
=
(
*
this
);
_parser
->
play
(
strUrl
);
}
TaskExecutor
::
Ptr
MediaPlayer
::
getExecutor
(){
auto
parser
=
dynamic_pointer_cast
<
SocketHelper
>
(
m
_parser
);
auto
parser
=
dynamic_pointer_cast
<
SocketHelper
>
(
_parser
);
if
(
!
parser
){
return
nullptr
;
}
...
...
@@ -66,14 +66,14 @@ TaskExecutor::Ptr MediaPlayer::getExecutor(){
}
void
MediaPlayer
::
pause
(
bool
bPause
)
{
if
(
m
_parser
)
{
m
_parser
->
pause
(
bPause
);
if
(
_parser
)
{
_parser
->
pause
(
bPause
);
}
}
void
MediaPlayer
::
teardown
()
{
if
(
m
_parser
)
{
m
_parser
->
teardown
();
if
(
_parser
)
{
_parser
->
teardown
();
}
}
...
...
src/Player/MediaPlayer.h
查看文件 @
39baaebc
...
...
@@ -54,7 +54,7 @@ public:
void
teardown
()
override
;
TaskExecutor
::
Ptr
getExecutor
();
private
:
string
m
_strPrefix
;
string
_strPrefix
;
};
...
...
src/Player/PlayerBase.h
查看文件 @
39baaebc
...
...
@@ -101,73 +101,73 @@ public:
PlayerImp
(){}
virtual
~
PlayerImp
(){}
void
setOnShutdown
(
const
function
<
void
(
const
SockException
&
)
>
&
cb
)
override
{
if
(
m
_parser
)
{
m
_parser
->
setOnShutdown
(
cb
);
if
(
_parser
)
{
_parser
->
setOnShutdown
(
cb
);
}
m
_shutdownCB
=
cb
;
_shutdownCB
=
cb
;
}
void
setOnPlayResult
(
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
)
override
{
if
(
m
_parser
)
{
m
_parser
->
setOnPlayResult
(
cb
);
if
(
_parser
)
{
_parser
->
setOnPlayResult
(
cb
);
}
m
_playResultCB
=
cb
;
_playResultCB
=
cb
;
}
bool
isInited
()
const
override
{
if
(
m
_parser
)
{
return
m
_parser
->
isInited
();
if
(
_parser
)
{
return
_parser
->
isInited
();
}
return
PlayerBase
::
isInited
();
}
float
getDuration
()
const
override
{
if
(
m
_parser
)
{
return
m
_parser
->
getDuration
();
if
(
_parser
)
{
return
_parser
->
getDuration
();
}
return
PlayerBase
::
getDuration
();
}
float
getProgress
()
const
override
{
if
(
m
_parser
)
{
return
m
_parser
->
getProgress
();
if
(
_parser
)
{
return
_parser
->
getProgress
();
}
return
PlayerBase
::
getProgress
();
}
void
seekTo
(
float
fProgress
)
override
{
if
(
m
_parser
)
{
return
m
_parser
->
seekTo
(
fProgress
);
if
(
_parser
)
{
return
_parser
->
seekTo
(
fProgress
);
}
return
PlayerBase
::
seekTo
(
fProgress
);
}
void
setMediaSouce
(
const
MediaSource
::
Ptr
&
src
)
override
{
if
(
m
_parser
)
{
return
m
_parser
->
setMediaSouce
(
src
);
if
(
_parser
)
{
return
_parser
->
setMediaSouce
(
src
);
}
m
_pMediaSrc
=
src
;
_pMediaSrc
=
src
;
}
vector
<
Track
::
Ptr
>
getTracks
()
const
override
{
if
(
m
_parser
)
{
return
m
_parser
->
getTracks
();
if
(
_parser
)
{
return
_parser
->
getTracks
();
}
return
PlayerBase
::
getTracks
();
}
protected
:
void
onShutdown
(
const
SockException
&
ex
)
override
{
if
(
m
_shutdownCB
)
{
m
_shutdownCB
(
ex
);
if
(
_shutdownCB
)
{
_shutdownCB
(
ex
);
}
}
void
onPlayResult
(
const
SockException
&
ex
)
override
{
if
(
m
_playResultCB
)
{
m
_playResultCB
(
ex
);
m
_playResultCB
=
nullptr
;
if
(
_playResultCB
)
{
_playResultCB
(
ex
);
_playResultCB
=
nullptr
;
}
}
protected
:
function
<
void
(
const
SockException
&
ex
)
>
m
_shutdownCB
;
function
<
void
(
const
SockException
&
ex
)
>
m
_playResultCB
;
std
::
shared_ptr
<
Parser
>
m
_parser
;
MediaSource
::
Ptr
m
_pMediaSrc
;
function
<
void
(
const
SockException
&
ex
)
>
_shutdownCB
;
function
<
void
(
const
SockException
&
ex
)
>
_playResultCB
;
std
::
shared_ptr
<
Parser
>
_parser
;
MediaSource
::
Ptr
_pMediaSrc
;
};
}
/* namespace Player */
...
...
src/RTP/AACRtpCodec.cpp
查看文件 @
39baaebc
...
...
@@ -29,41 +29,41 @@ void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) {
char
*
ptr
=
(
char
*
)
pcData
;
int
iSize
=
iLen
;
while
(
iSize
>
0
)
{
if
(
iSize
<=
m
_ui32MtuSize
-
20
)
{
m
_aucSectionBuf
[
0
]
=
0
;
m
_aucSectionBuf
[
1
]
=
16
;
m
_aucSectionBuf
[
2
]
=
iLen
>>
5
;
m
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
m
_aucSectionBuf
+
4
,
ptr
,
iSize
);
makeAACRtp
(
m
_aucSectionBuf
,
iSize
+
4
,
true
,
uiStamp
);
if
(
iSize
<=
_ui32MtuSize
-
20
)
{
_aucSectionBuf
[
0
]
=
0
;
_aucSectionBuf
[
1
]
=
16
;
_aucSectionBuf
[
2
]
=
iLen
>>
5
;
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
_aucSectionBuf
+
4
,
ptr
,
iSize
);
makeAACRtp
(
_aucSectionBuf
,
iSize
+
4
,
true
,
uiStamp
);
break
;
}
m
_aucSectionBuf
[
0
]
=
0
;
m
_aucSectionBuf
[
1
]
=
16
;
m
_aucSectionBuf
[
2
]
=
(
iLen
)
>>
5
;
m
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
m_aucSectionBuf
+
4
,
ptr
,
m
_ui32MtuSize
-
20
);
makeAACRtp
(
m_aucSectionBuf
,
m
_ui32MtuSize
-
16
,
false
,
uiStamp
);
ptr
+=
(
m
_ui32MtuSize
-
20
);
iSize
-=
(
m
_ui32MtuSize
-
20
);
_aucSectionBuf
[
0
]
=
0
;
_aucSectionBuf
[
1
]
=
16
;
_aucSectionBuf
[
2
]
=
(
iLen
)
>>
5
;
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
_aucSectionBuf
+
4
,
ptr
,
_ui32MtuSize
-
20
);
makeAACRtp
(
_aucSectionBuf
,
_ui32MtuSize
-
16
,
false
,
uiStamp
);
ptr
+=
(
_ui32MtuSize
-
20
);
iSize
-=
(
_ui32MtuSize
-
20
);
}
}
void
AACRtpEncoder
::
makeAACRtp
(
const
void
*
pData
,
unsigned
int
uiLen
,
bool
bMark
,
uint32_t
uiStamp
)
{
uint16_t
u16RtpLen
=
uiLen
+
12
;
m_ui32TimeStamp
=
(
m
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
m
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
m
_ui16Sequence
);
uint32_t
sc
=
htonl
(
m
_ui32Ssrc
);
_ui32TimeStamp
=
(
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
_ui16Sequence
);
uint32_t
sc
=
htonl
(
_ui32Ssrc
);
auto
pRtppkt
=
ResourcePoolHelper
<
RtpPacket
>::
obtainObj
();
auto
&
rtppkt
=
*
pRtppkt
;
unsigned
char
*
pucRtp
=
rtppkt
.
payload
;
pucRtp
[
0
]
=
'$'
;
pucRtp
[
1
]
=
m
_ui8Interleaved
;
pucRtp
[
1
]
=
_ui8Interleaved
;
pucRtp
[
2
]
=
u16RtpLen
>>
8
;
pucRtp
[
3
]
=
u16RtpLen
&
0x00FF
;
pucRtp
[
4
]
=
0x80
;
pucRtp
[
5
]
=
(
bMark
<<
7
)
|
m
_ui8PlayloadType
;
pucRtp
[
5
]
=
(
bMark
<<
7
)
|
_ui8PlayloadType
;
memcpy
(
&
pucRtp
[
6
],
&
sq
,
2
);
memcpy
(
&
pucRtp
[
8
],
&
ts
,
4
);
//ssrc
...
...
@@ -71,24 +71,24 @@ void AACRtpEncoder::makeAACRtp(const void *pData, unsigned int uiLen, bool bMark
//playload
memcpy
(
&
pucRtp
[
16
],
pData
,
uiLen
);
rtppkt
.
PT
=
m
_ui8PlayloadType
;
rtppkt
.
interleaved
=
m
_ui8Interleaved
;
rtppkt
.
PT
=
_ui8PlayloadType
;
rtppkt
.
interleaved
=
_ui8Interleaved
;
rtppkt
.
mark
=
bMark
;
rtppkt
.
length
=
uiLen
+
16
;
rtppkt
.
sequence
=
m
_ui16Sequence
;
rtppkt
.
timeStamp
=
m
_ui32TimeStamp
;
rtppkt
.
ssrc
=
m
_ui32Ssrc
;
rtppkt
.
sequence
=
_ui16Sequence
;
rtppkt
.
timeStamp
=
_ui32TimeStamp
;
rtppkt
.
ssrc
=
_ui32Ssrc
;
rtppkt
.
type
=
TrackAudio
;
rtppkt
.
offset
=
16
;
RtpCodec
::
inputRtp
(
pRtppkt
,
false
);
m
_ui16Sequence
++
;
_ui16Sequence
++
;
}
/////////////////////////////////////////////////////////////////////////////////////
AACRtpDecoder
::
AACRtpDecoder
(
uint32_t
ui32SampleRate
)
{
m
_adts
=
obtainFrame
();
m
_sampleRate
=
ui32SampleRate
;
_adts
=
obtainFrame
();
_sampleRate
=
ui32SampleRate
;
}
AACFrame
::
Ptr
AACRtpDecoder
::
obtainFrame
()
{
...
...
@@ -103,18 +103,18 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
RtpCodec
::
inputRtp
(
rtppack
,
false
);
int
length
=
rtppack
->
length
-
rtppack
->
offset
;
if
(
m
_adts
->
aac_frame_length
+
length
-
4
>
sizeof
(
AACFrame
::
buffer
))
{
m
_adts
->
aac_frame_length
=
7
;
if
(
_adts
->
aac_frame_length
+
length
-
4
>
sizeof
(
AACFrame
::
buffer
))
{
_adts
->
aac_frame_length
=
7
;
WarnL
<<
"aac负载数据太长"
;
return
false
;
}
memcpy
(
m_adts
->
buffer
+
m
_adts
->
aac_frame_length
,
rtppack
->
payload
+
rtppack
->
offset
+
4
,
length
-
4
);
m
_adts
->
aac_frame_length
+=
(
length
-
4
);
memcpy
(
_adts
->
buffer
+
_adts
->
aac_frame_length
,
rtppack
->
payload
+
rtppack
->
offset
+
4
,
length
-
4
);
_adts
->
aac_frame_length
+=
(
length
-
4
);
if
(
rtppack
->
mark
==
true
)
{
m
_adts
->
sequence
=
rtppack
->
sequence
;
m_adts
->
timeStamp
=
rtppack
->
timeStamp
*
(
1000.0
/
m
_sampleRate
);
writeAdtsHeader
(
*
m_adts
,
m
_adts
->
buffer
);
onGetAAC
(
m
_adts
);
_adts
->
sequence
=
rtppack
->
sequence
;
_adts
->
timeStamp
=
rtppack
->
timeStamp
*
(
1000.0
/
_sampleRate
);
writeAdtsHeader
(
*
_adts
,
_adts
->
buffer
);
onGetAAC
(
_adts
);
}
return
false
;
}
...
...
@@ -122,7 +122,7 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
void
AACRtpDecoder
::
onGetAAC
(
const
AACFrame
::
Ptr
&
frame
)
{
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
m
_adts
=
obtainFrame
();
_adts
=
obtainFrame
();
}
...
...
src/RTP/AACRtpCodec.h
查看文件 @
39baaebc
...
...
@@ -38,8 +38,8 @@ private:
void
onGetAAC
(
const
AACFrame
::
Ptr
&
frame
);
AACFrame
::
Ptr
obtainFrame
();
private
:
AACFrame
::
Ptr
m
_adts
;
uint32_t
m
_sampleRate
;
AACFrame
::
Ptr
_adts
;
uint32_t
_sampleRate
;
};
...
...
@@ -72,7 +72,7 @@ public:
private
:
void
makeAACRtp
(
const
void
*
pData
,
unsigned
int
uiLen
,
bool
bMark
,
uint32_t
uiStamp
);
private
:
unsigned
char
m
_aucSectionBuf
[
1600
];
unsigned
char
_aucSectionBuf
[
1600
];
};
...
...
src/RTP/H264RtpCodec.cpp
查看文件 @
39baaebc
...
...
@@ -6,7 +6,7 @@
H264RtpDecoder
::
H264RtpDecoder
()
{
m
_h264frame
=
obtainFrame
();
_h264frame
=
obtainFrame
();
}
H264Frame
::
Ptr
H264RtpDecoder
::
obtainFrame
()
{
...
...
@@ -40,13 +40,13 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
nal
.
type
>=
0
&&
nal
.
type
<
24
)
{
//a full frame
m
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
m
_h264frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
m
_h264frame
->
type
=
nal
.
type
;
m
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
m
_h264frame
->
sequence
=
rtppack
->
sequence
;
auto
isIDR
=
m
_h264frame
->
type
==
5
;
onGetH264
(
m
_h264frame
);
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
type
=
nal
.
type
;
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
_h264frame
->
sequence
=
rtppack
->
sequence
;
auto
isIDR
=
_h264frame
->
type
==
5
;
onGetH264
(
_h264frame
);
return
(
isIDR
);
//i frame
}
...
...
@@ -57,31 +57,31 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
fu
.
S
==
1
)
{
//FU-A start
char
tmp
=
(
nal
.
forbidden_zero_bit
<<
7
|
nal
.
nal_ref_idc
<<
5
|
fu
.
type
);
m
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
m
_h264frame
->
buffer
.
push_back
(
tmp
);
m
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
m
_h264frame
->
type
=
fu
.
type
;
m
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
m
_h264frame
->
sequence
=
rtppack
->
sequence
;
return
(
m
_h264frame
->
type
==
5
);
//i frame
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
push_back
(
tmp
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
type
=
fu
.
type
;
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
_h264frame
->
sequence
=
rtppack
->
sequence
;
return
(
_h264frame
->
type
==
5
);
//i frame
}
if
(
rtppack
->
sequence
!=
(
uint16_t
)(
m
_h264frame
->
sequence
+
1
))
{
m
_h264frame
->
buffer
.
clear
();
WarnL
<<
"丢包,帧废弃:"
<<
rtppack
->
sequence
<<
","
<<
m
_h264frame
->
sequence
;
if
(
rtppack
->
sequence
!=
(
uint16_t
)(
_h264frame
->
sequence
+
1
))
{
_h264frame
->
buffer
.
clear
();
WarnL
<<
"丢包,帧废弃:"
<<
rtppack
->
sequence
<<
","
<<
_h264frame
->
sequence
;
return
false
;
}
m
_h264frame
->
sequence
=
rtppack
->
sequence
;
_h264frame
->
sequence
=
rtppack
->
sequence
;
if
(
fu
.
E
==
1
)
{
//FU-A end
m
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
m
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
auto
isIDR
=
m
_h264frame
->
type
==
5
;
onGetH264
(
m
_h264frame
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
/
90
;
auto
isIDR
=
_h264frame
->
type
==
5
;
onGetH264
(
_h264frame
);
return
isIDR
;
}
//FU-A mid
m
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
return
false
;
}
...
...
@@ -100,7 +100,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
m
_h264frame
=
obtainFrame
();
_h264frame
=
obtainFrame
();
}
...
...
@@ -127,7 +127,7 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
uiStamp
%=
cycleMS
;
int
iSize
=
m
_ui32MtuSize
-
2
;
int
iSize
=
_ui32MtuSize
-
2
;
if
(
iLen
>
iSize
)
{
//超过MTU
const
unsigned
char
s_e_r_Start
=
0x80
;
const
unsigned
char
s_e_r_Mid
=
0x00
;
...
...
@@ -156,11 +156,11 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
s_e_r_type
=
s_e_r_Mid
+
naluType
;
}
}
memcpy
(
m
_aucSectionBuf
,
&
f_nri_type
,
1
);
memcpy
(
m
_aucSectionBuf
+
1
,
&
s_e_r_type
,
1
);
memcpy
(
m
_aucSectionBuf
+
2
,
(
unsigned
char
*
)
pcData
+
nOffset
,
iSize
);
memcpy
(
_aucSectionBuf
,
&
f_nri_type
,
1
);
memcpy
(
_aucSectionBuf
+
1
,
&
s_e_r_type
,
1
);
memcpy
(
_aucSectionBuf
+
2
,
(
unsigned
char
*
)
pcData
+
nOffset
,
iSize
);
nOffset
+=
iSize
;
makeH264Rtp
(
m
_aucSectionBuf
,
iSize
+
2
,
mark
,
uiStamp
);
makeH264Rtp
(
_aucSectionBuf
,
iSize
+
2
,
mark
,
uiStamp
);
}
}
else
{
makeH264Rtp
(
pcData
,
iLen
,
true
,
uiStamp
);
...
...
@@ -169,19 +169,19 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
void
H264RtpEncoder
::
makeH264Rtp
(
const
void
*
data
,
unsigned
int
len
,
bool
mark
,
uint32_t
uiStamp
)
{
uint16_t
ui16RtpLen
=
len
+
12
;
m_ui32TimeStamp
=
(
m
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
m
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
m
_ui16Sequence
);
uint32_t
sc
=
htonl
(
m
_ui32Ssrc
);
_ui32TimeStamp
=
(
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
_ui16Sequence
);
uint32_t
sc
=
htonl
(
_ui32Ssrc
);
auto
rtppkt
=
ResourcePoolHelper
<
RtpPacket
>::
obtainObj
();
unsigned
char
*
pucRtp
=
rtppkt
->
payload
;
pucRtp
[
0
]
=
'$'
;
pucRtp
[
1
]
=
m
_ui8Interleaved
;
pucRtp
[
1
]
=
_ui8Interleaved
;
pucRtp
[
2
]
=
ui16RtpLen
>>
8
;
pucRtp
[
3
]
=
ui16RtpLen
&
0x00FF
;
pucRtp
[
4
]
=
0x80
;
pucRtp
[
5
]
=
(
mark
<<
7
)
|
m
_ui8PlayloadType
;
pucRtp
[
5
]
=
(
mark
<<
7
)
|
_ui8PlayloadType
;
memcpy
(
&
pucRtp
[
6
],
&
sq
,
2
);
memcpy
(
&
pucRtp
[
8
],
&
ts
,
4
);
//ssrc
...
...
@@ -189,17 +189,17 @@ void H264RtpEncoder::makeH264Rtp(const void* data, unsigned int len, bool mark,
//playload
memcpy
(
&
pucRtp
[
16
],
data
,
len
);
rtppkt
->
PT
=
m
_ui8PlayloadType
;
rtppkt
->
interleaved
=
m
_ui8Interleaved
;
rtppkt
->
PT
=
_ui8PlayloadType
;
rtppkt
->
interleaved
=
_ui8Interleaved
;
rtppkt
->
mark
=
mark
;
rtppkt
->
length
=
len
+
16
;
rtppkt
->
sequence
=
m
_ui16Sequence
;
rtppkt
->
timeStamp
=
m
_ui32TimeStamp
;
rtppkt
->
ssrc
=
m
_ui32Ssrc
;
rtppkt
->
sequence
=
_ui16Sequence
;
rtppkt
->
timeStamp
=
_ui32TimeStamp
;
rtppkt
->
ssrc
=
_ui32Ssrc
;
rtppkt
->
type
=
TrackVideo
;
rtppkt
->
offset
=
16
;
uint8_t
type
=
((
uint8_t
*
)
(
data
))[
0
]
&
0x1F
;
RtpCodec
::
inputRtp
(
rtppkt
,
type
==
5
);
m
_ui16Sequence
++
;
_ui16Sequence
++
;
}
\ No newline at end of file
src/RTP/H264RtpCodec.h
查看文件 @
39baaebc
...
...
@@ -39,7 +39,7 @@ private:
void
onGetH264
(
const
H264Frame
::
Ptr
&
frame
);
H264Frame
::
Ptr
obtainFrame
();
private
:
H264Frame
::
Ptr
m
_h264frame
;
H264Frame
::
Ptr
_h264frame
;
};
/**
...
...
@@ -71,7 +71,7 @@ public:
private
:
void
makeH264Rtp
(
const
void
*
pData
,
unsigned
int
uiLen
,
bool
bMark
,
uint32_t
uiStamp
);
private
:
unsigned
char
m
_aucSectionBuf
[
1600
];
unsigned
char
_aucSectionBuf
[
1600
];
};
...
...
src/RTP/RtpCodec.h
查看文件 @
39baaebc
...
...
@@ -105,48 +105,48 @@ public:
if
(
ui32Ssrc
==
0
){
ui32Ssrc
=
((
uint64_t
)
this
)
&
0xFFFFFFFF
;
}
m
_ui32Ssrc
=
ui32Ssrc
;
m
_ui32SampleRate
=
ui32SampleRate
;
m
_ui32MtuSize
=
ui32MtuSize
;
m
_ui8PlayloadType
=
ui8PlayloadType
;
m
_ui8Interleaved
=
ui8Interleaved
;
_ui32Ssrc
=
ui32Ssrc
;
_ui32SampleRate
=
ui32SampleRate
;
_ui32MtuSize
=
ui32MtuSize
;
_ui8PlayloadType
=
ui8PlayloadType
;
_ui8Interleaved
=
ui8Interleaved
;
}
virtual
~
RtpInfo
(){}
int
getInterleaved
()
const
{
return
m
_ui8Interleaved
;
return
_ui8Interleaved
;
}
int
getPlayloadType
()
const
{
return
m
_ui8PlayloadType
;
return
_ui8PlayloadType
;
}
int
getSampleRate
()
const
{
return
m
_ui32SampleRate
;
return
_ui32SampleRate
;
}
uint32_t
getSsrc
()
const
{
return
m
_ui32Ssrc
;
return
_ui32Ssrc
;
}
uint16_t
getSeqence
()
const
{
return
m
_ui16Sequence
;
return
_ui16Sequence
;
}
uint32_t
getTimestamp
()
const
{
return
m
_ui32TimeStamp
;
return
_ui32TimeStamp
;
}
uint32_t
getMtuSize
()
const
{
return
m
_ui32MtuSize
;
return
_ui32MtuSize
;
}
protected
:
uint32_t
m
_ui32Ssrc
;
uint32_t
m
_ui32SampleRate
;
uint32_t
m
_ui32MtuSize
;
uint8_t
m
_ui8PlayloadType
;
uint8_t
m
_ui8Interleaved
;
uint16_t
m
_ui16Sequence
=
0
;
uint32_t
m
_ui32TimeStamp
=
0
;
uint32_t
_ui32Ssrc
;
uint32_t
_ui32SampleRate
;
uint32_t
_ui32MtuSize
;
uint8_t
_ui8PlayloadType
;
uint8_t
_ui8Interleaved
;
uint16_t
_ui16Sequence
=
0
;
uint32_t
_ui32TimeStamp
=
0
;
};
class
RtpCodec
:
public
RtpRing
,
public
FrameRingInterfaceDelegate
,
public
CodecInfo
,
public
ResourcePoolHelper
<
RtpPacket
>
{
...
...
src/RTP/RtpMaker.h
查看文件 @
39baaebc
...
...
@@ -49,12 +49,12 @@ public:
RtpMaker
(
const
onGetRTP
&
cb
,
uint32_t
ui32Ssrc
,
int
iMtuSize
,
int
iSampleRate
,
uint8_t
ui8PlayloadType
,
uint8_t
ui8Interleaved
)
{
callBack
=
cb
;
m
_ui32Ssrc
=
ui32Ssrc
;
m
_ui32SampleRate
=
iSampleRate
;
m
_iMtuSize
=
iMtuSize
;
m
_ui8PlayloadType
=
ui8PlayloadType
;
m
_ui8Interleaved
=
ui8Interleaved
;
m
_pktPool
.
setSize
(
64
);
_ui32Ssrc
=
ui32Ssrc
;
_ui32SampleRate
=
iSampleRate
;
_iMtuSize
=
iMtuSize
;
_ui8PlayloadType
=
ui8PlayloadType
;
_ui8Interleaved
=
ui8Interleaved
;
_pktPool
.
setSize
(
64
);
}
virtual
~
RtpMaker
()
{
}
...
...
@@ -62,43 +62,43 @@ public:
virtual
void
makeRtp
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
uiStamp
)
=
0
;
int
getInterleaved
()
const
{
return
m
_ui8Interleaved
;
return
_ui8Interleaved
;
}
int
getPlayloadType
()
const
{
return
m
_ui8PlayloadType
;
return
_ui8PlayloadType
;
}
int
getSampleRate
()
const
{
return
m
_ui32SampleRate
;
return
_ui32SampleRate
;
}
uint32_t
getSsrc
()
const
{
return
m
_ui32Ssrc
;
return
_ui32Ssrc
;
}
uint16_t
getSeqence
()
const
{
return
m
_ui16Sequence
;
return
_ui16Sequence
;
}
uint32_t
getTimestamp
()
const
{
return
m
_ui32TimeStamp
;
return
_ui32TimeStamp
;
}
protected
:
uint32_t
m
_ui32Ssrc
;
uint32_t
m
_ui32SampleRate
;
int
m
_iMtuSize
;
uint8_t
m
_ui8PlayloadType
;
uint8_t
m
_ui8Interleaved
;
uint16_t
m
_ui16Sequence
=
0
;
uint32_t
m
_ui32TimeStamp
=
0
;
uint32_t
_ui32Ssrc
;
uint32_t
_ui32SampleRate
;
int
_iMtuSize
;
uint8_t
_ui8PlayloadType
;
uint8_t
_ui8Interleaved
;
uint16_t
_ui16Sequence
=
0
;
uint32_t
_ui32TimeStamp
=
0
;
virtual
void
onMakeRtp
(
const
RtpPacket
::
Ptr
&
pkt
,
bool
bKeyPos
=
true
)
{
callBack
(
pkt
,
bKeyPos
);
}
inline
RtpPacket
::
Ptr
obtainPkt
()
{
return
m
_pktPool
.
obtain
();
return
_pktPool
.
obtain
();
}
private
:
RtspMediaSource
::
PoolType
m
_pktPool
;
RtspMediaSource
::
PoolType
_pktPool
;
onGetRTP
callBack
;
};
...
...
src/RTP/RtpMakerAAC.cpp
查看文件 @
39baaebc
...
...
@@ -42,42 +42,42 @@ void RtpMaker_AAC::makeRtp(const char *pcData, int iLen, uint32_t uiStamp) {
char
*
ptr
=
(
char
*
)
pcData
;
int
iSize
=
iLen
;
while
(
iSize
>
0
)
{
if
(
iSize
<=
m
_iMtuSize
-
20
)
{
m
_aucSectionBuf
[
0
]
=
0
;
m
_aucSectionBuf
[
1
]
=
16
;
m
_aucSectionBuf
[
2
]
=
iLen
>>
5
;
m
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
m
_aucSectionBuf
+
4
,
ptr
,
iSize
);
makeAACRtp
(
m
_aucSectionBuf
,
iSize
+
4
,
true
,
uiStamp
);
if
(
iSize
<=
_iMtuSize
-
20
)
{
_aucSectionBuf
[
0
]
=
0
;
_aucSectionBuf
[
1
]
=
16
;
_aucSectionBuf
[
2
]
=
iLen
>>
5
;
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
_aucSectionBuf
+
4
,
ptr
,
iSize
);
makeAACRtp
(
_aucSectionBuf
,
iSize
+
4
,
true
,
uiStamp
);
break
;
}
m
_aucSectionBuf
[
0
]
=
0
;
m
_aucSectionBuf
[
1
]
=
16
;
m
_aucSectionBuf
[
2
]
=
(
iLen
)
>>
5
;
m
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
m_aucSectionBuf
+
4
,
ptr
,
m
_iMtuSize
-
20
);
makeAACRtp
(
m_aucSectionBuf
,
m
_iMtuSize
-
16
,
false
,
uiStamp
);
ptr
+=
(
m
_iMtuSize
-
20
);
iSize
-=
(
m
_iMtuSize
-
20
);
_aucSectionBuf
[
0
]
=
0
;
_aucSectionBuf
[
1
]
=
16
;
_aucSectionBuf
[
2
]
=
(
iLen
)
>>
5
;
_aucSectionBuf
[
3
]
=
(
iLen
&
0x1F
)
<<
3
;
memcpy
(
_aucSectionBuf
+
4
,
ptr
,
_iMtuSize
-
20
);
makeAACRtp
(
_aucSectionBuf
,
_iMtuSize
-
16
,
false
,
uiStamp
);
ptr
+=
(
_iMtuSize
-
20
);
iSize
-=
(
_iMtuSize
-
20
);
}
}
inline
void
RtpMaker_AAC
::
makeAACRtp
(
const
void
*
pData
,
unsigned
int
uiLen
,
bool
bMark
,
uint32_t
uiStamp
)
{
uint16_t
u16RtpLen
=
uiLen
+
12
;
m_ui32TimeStamp
=
(
m
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
m
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
m
_ui16Sequence
);
uint32_t
sc
=
htonl
(
m
_ui32Ssrc
);
_ui32TimeStamp
=
(
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
_ui16Sequence
);
uint32_t
sc
=
htonl
(
_ui32Ssrc
);
auto
pRtppkt
=
obtainPkt
();
auto
&
rtppkt
=
*
(
pRtppkt
.
get
());
unsigned
char
*
pucRtp
=
rtppkt
.
payload
;
pucRtp
[
0
]
=
'$'
;
pucRtp
[
1
]
=
m
_ui8Interleaved
;
pucRtp
[
1
]
=
_ui8Interleaved
;
pucRtp
[
2
]
=
u16RtpLen
>>
8
;
pucRtp
[
3
]
=
u16RtpLen
&
0x00FF
;
pucRtp
[
4
]
=
0x80
;
pucRtp
[
5
]
=
(
bMark
<<
7
)
|
m
_ui8PlayloadType
;
pucRtp
[
5
]
=
(
bMark
<<
7
)
|
_ui8PlayloadType
;
memcpy
(
&
pucRtp
[
6
],
&
sq
,
2
);
memcpy
(
&
pucRtp
[
8
],
&
ts
,
4
);
//ssrc
...
...
@@ -85,18 +85,18 @@ inline void RtpMaker_AAC::makeAACRtp(const void *pData, unsigned int uiLen, bool
//playload
memcpy
(
&
pucRtp
[
16
],
pData
,
uiLen
);
rtppkt
.
PT
=
m
_ui8PlayloadType
;
rtppkt
.
interleaved
=
m
_ui8Interleaved
;
rtppkt
.
PT
=
_ui8PlayloadType
;
rtppkt
.
interleaved
=
_ui8Interleaved
;
rtppkt
.
mark
=
bMark
;
rtppkt
.
length
=
uiLen
+
16
;
rtppkt
.
sequence
=
m
_ui16Sequence
;
rtppkt
.
timeStamp
=
m
_ui32TimeStamp
;
rtppkt
.
ssrc
=
m
_ui32Ssrc
;
rtppkt
.
sequence
=
_ui16Sequence
;
rtppkt
.
timeStamp
=
_ui32TimeStamp
;
rtppkt
.
ssrc
=
_ui32Ssrc
;
rtppkt
.
type
=
TrackAudio
;
rtppkt
.
offset
=
16
;
onMakeRtp
(
pRtppkt
,
false
);
m
_ui16Sequence
++
;
_ui16Sequence
++
;
}
}
/* namespace RTP */
...
...
src/RTP/RtpMakerAAC.h
查看文件 @
39baaebc
...
...
@@ -53,7 +53,7 @@ public:
void
makeRtp
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
uiStamp
)
override
;
private
:
inline
void
makeAACRtp
(
const
void
*
pData
,
unsigned
int
uiLen
,
bool
bMark
,
uint32_t
uiStamp
);
unsigned
char
m
_aucSectionBuf
[
1600
];
unsigned
char
_aucSectionBuf
[
1600
];
};
}
/* namespace RTP */
...
...
src/RTP/RtpMakerH264.cpp
查看文件 @
39baaebc
...
...
@@ -39,7 +39,7 @@ void RtpMaker_H264::makeRtp(const char* pcData, int iLen, uint32_t uiStamp) {
GET_CONFIG_AND_REGISTER
(
uint32_t
,
cycleMS
,
Config
::
Rtp
::
kCycleMS
);
uiStamp
%=
cycleMS
;
int
iSize
=
m
_iMtuSize
-
2
;
int
iSize
=
_iMtuSize
-
2
;
if
(
iLen
>
iSize
)
{
//超过MTU
const
unsigned
char
s_e_r_Start
=
0x80
;
const
unsigned
char
s_e_r_Mid
=
0x00
;
...
...
@@ -81,20 +81,20 @@ void RtpMaker_H264::makeRtp(const char* pcData, int iLen, uint32_t uiStamp) {
inline
void
RtpMaker_H264
::
makeH264Rtp
(
const
void
*
data
,
unsigned
int
len
,
bool
mark
,
uint32_t
uiStamp
)
{
uint16_t
ui16RtpLen
=
len
+
12
;
m_ui32TimeStamp
=
(
m
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
m
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
m
_ui16Sequence
);
uint32_t
sc
=
htonl
(
m
_ui32Ssrc
);
_ui32TimeStamp
=
(
_ui32SampleRate
/
1000
)
*
uiStamp
;
uint32_t
ts
=
htonl
(
_ui32TimeStamp
);
uint16_t
sq
=
htons
(
_ui16Sequence
);
uint32_t
sc
=
htonl
(
_ui32Ssrc
);
auto
pRtppkt
=
obtainPkt
();
auto
&
rtppkt
=
*
(
pRtppkt
.
get
());
unsigned
char
*
pucRtp
=
rtppkt
.
payload
;
pucRtp
[
0
]
=
'$'
;
pucRtp
[
1
]
=
m
_ui8Interleaved
;
pucRtp
[
1
]
=
_ui8Interleaved
;
pucRtp
[
2
]
=
ui16RtpLen
>>
8
;
pucRtp
[
3
]
=
ui16RtpLen
&
0x00FF
;
pucRtp
[
4
]
=
0x80
;
pucRtp
[
5
]
=
(
mark
<<
7
)
|
m
_ui8PlayloadType
;
pucRtp
[
5
]
=
(
mark
<<
7
)
|
_ui8PlayloadType
;
memcpy
(
&
pucRtp
[
6
],
&
sq
,
2
);
memcpy
(
&
pucRtp
[
8
],
&
ts
,
4
);
//ssrc
...
...
@@ -102,19 +102,19 @@ inline void RtpMaker_H264::makeH264Rtp(const void* data, unsigned int len, bool
//playload
memcpy
(
&
pucRtp
[
16
],
data
,
len
);
rtppkt
.
PT
=
m
_ui8PlayloadType
;
rtppkt
.
interleaved
=
m
_ui8Interleaved
;
rtppkt
.
PT
=
_ui8PlayloadType
;
rtppkt
.
interleaved
=
_ui8Interleaved
;
rtppkt
.
mark
=
mark
;
rtppkt
.
length
=
len
+
16
;
rtppkt
.
sequence
=
m
_ui16Sequence
;
rtppkt
.
timeStamp
=
m
_ui32TimeStamp
;
rtppkt
.
ssrc
=
m
_ui32Ssrc
;
rtppkt
.
sequence
=
_ui16Sequence
;
rtppkt
.
timeStamp
=
_ui32TimeStamp
;
rtppkt
.
ssrc
=
_ui32Ssrc
;
rtppkt
.
type
=
TrackVideo
;
rtppkt
.
offset
=
16
;
uint8_t
type
=
((
uint8_t
*
)
(
data
))[
0
]
&
0x1F
;
onMakeRtp
(
pRtppkt
,
type
==
5
);
m
_ui16Sequence
++
;
_ui16Sequence
++
;
//InfoL<<timeStamp<<" "<<time<<" "<<sampleRate;
}
...
...
src/Rtmp/FlvMuxer.cpp
查看文件 @
39baaebc
...
...
@@ -43,8 +43,8 @@ void FlvMuxer::start(const RtmpMediaSource::Ptr &media) {
}
void
FlvMuxer
::
onWriteFlvHeader
(
const
RtmpMediaSource
::
Ptr
&
mediaSrc
)
{
m
_previousTagSize
=
0
;
CLEAR_ARR
(
m
_aui32FirstStamp
);
_previousTagSize
=
0
;
CLEAR_ARR
(
_aui32FirstStamp
);
//发送flv文件头
char
flv_file_header
[]
=
"FLV\x1\x5\x0\x0\x0\x9"
;
// have audio and have video
...
...
@@ -118,7 +118,7 @@ private:
void
FlvMuxer
::
onWriteFlvTag
(
const
RtmpPacket
::
Ptr
&
pkt
,
uint32_t
ui32TimeStamp
)
{
auto
size
=
htonl
(
m
_previousTagSize
);
auto
size
=
htonl
(
_previousTagSize
);
onWrite
((
char
*
)
&
size
,
4
);
//onWrite PreviousTagSize
RtmpTagHeader
header
;
header
.
type
=
pkt
->
typeId
;
...
...
@@ -127,11 +127,11 @@ void FlvMuxer::onWriteFlvTag(const RtmpPacket::Ptr &pkt, uint32_t ui32TimeStamp)
set_be24
(
header
.
timestamp
,
ui32TimeStamp
&
0xFFFFFF
);
onWrite
((
char
*
)
&
header
,
sizeof
(
header
));
//onWrite tag header
onWrite
(
std
::
make_shared
<
BufferRtmp
>
(
pkt
));
//onWrite tag data
m
_previousTagSize
+=
(
pkt
->
strBuf
.
size
()
+
sizeof
(
header
));
_previousTagSize
+=
(
pkt
->
strBuf
.
size
()
+
sizeof
(
header
));
}
void
FlvMuxer
::
onWriteFlvTag
(
uint8_t
ui8Type
,
const
std
::
string
&
strBuf
,
uint32_t
ui32TimeStamp
)
{
auto
size
=
htonl
(
m
_previousTagSize
);
auto
size
=
htonl
(
_previousTagSize
);
onWrite
((
char
*
)
&
size
,
4
);
//onWrite PreviousTagSize
RtmpTagHeader
header
;
header
.
type
=
ui8Type
;
...
...
@@ -140,12 +140,12 @@ void FlvMuxer::onWriteFlvTag(uint8_t ui8Type, const std::string &strBuf, uint32_
set_be24
(
header
.
timestamp
,
ui32TimeStamp
&
0xFFFFFF
);
onWrite
((
char
*
)
&
header
,
sizeof
(
header
));
//onWrite tag header
onWrite
(
std
::
make_shared
<
BufferString
>
(
strBuf
));
//onWrite tag data
m
_previousTagSize
+=
(
strBuf
.
size
()
+
sizeof
(
header
));
_previousTagSize
+=
(
strBuf
.
size
()
+
sizeof
(
header
));
}
void
FlvMuxer
::
onWriteRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
auto
modifiedStamp
=
pkt
->
timeStamp
;
auto
&
firstStamp
=
m
_aui32FirstStamp
[
pkt
->
typeId
%
2
];
auto
&
firstStamp
=
_aui32FirstStamp
[
pkt
->
typeId
%
2
];
if
(
!
firstStamp
){
firstStamp
=
modifiedStamp
;
}
...
...
@@ -154,7 +154,7 @@ void FlvMuxer::onWriteRtmp(const RtmpPacket::Ptr &pkt) {
modifiedStamp
-=
firstStamp
;
}
else
{
//发生回环,重新计算时间戳增量
CLEAR_ARR
(
m
_aui32FirstStamp
);
CLEAR_ARR
(
_aui32FirstStamp
);
modifiedStamp
=
0
;
}
onWriteFlvTag
(
pkt
,
modifiedStamp
);
...
...
src/Rtmp/FlvMuxer.h
查看文件 @
39baaebc
...
...
@@ -33,8 +33,8 @@ private:
void
onWriteFlvTag
(
uint8_t
ui8Type
,
const
std
::
string
&
strBuf
,
uint32_t
ui32TimeStamp
);
private
:
RtmpMediaSource
::
RingType
::
RingReader
::
Ptr
_ring_reader
;
uint32_t
m
_aui32FirstStamp
[
2
]
=
{
0
};
uint32_t
m
_previousTagSize
=
0
;
uint32_t
_aui32FirstStamp
[
2
]
=
{
0
};
uint32_t
_previousTagSize
=
0
;
};
class
FlvRecorder
:
public
FlvMuxer
,
public
std
::
enable_shared_from_this
<
FlvRecorder
>
{
...
...
src/Rtmp/RtmpMediaSource.h
查看文件 @
39baaebc
...
...
@@ -60,66 +60,66 @@ public:
RtmpMediaSource
(
const
string
&
vhost
,
const
string
&
strApp
,
const
string
&
strId
)
:
MediaSource
(
RTMP_SCHEMA
,
vhost
,
strApp
,
strId
),
m
_pRing
(
new
RingBuffer
<
RtmpPacket
::
Ptr
>
())
{
_pRing
(
new
RingBuffer
<
RtmpPacket
::
Ptr
>
())
{
}
virtual
~
RtmpMediaSource
()
{}
const
RingType
::
Ptr
&
getRing
()
const
{
//获取媒体源的rtp环形缓冲
return
m
_pRing
;
return
_pRing
;
}
const
AMFValue
&
getMetaData
()
const
{
lock_guard
<
recursive_mutex
>
lock
(
m
_mtxMap
);
return
m
_metadata
;
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
return
_metadata
;
}
template
<
typename
FUN
>
void
getConfigFrame
(
const
FUN
&
f
)
{
lock_guard
<
recursive_mutex
>
lock
(
m
_mtxMap
);
for
(
auto
&
pr
:
m
_mapCfgFrame
)
{
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
for
(
auto
&
pr
:
_mapCfgFrame
)
{
f
(
pr
.
second
);
}
}
virtual
void
onGetMetaData
(
const
AMFValue
&
_
metadata
)
{
lock_guard
<
recursive_mutex
>
lock
(
m
_mtxMap
);
m_metadata
=
_
metadata
;
RtmpParser
parser
(
_
metadata
);
m
_iCfgFrameSize
=
parser
.
getTracks
().
size
();
virtual
void
onGetMetaData
(
const
AMFValue
&
metadata
)
{
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
_metadata
=
metadata
;
RtmpParser
parser
(
metadata
);
_iCfgFrameSize
=
parser
.
getTracks
().
size
();
if
(
ready
()){
MediaSource
::
regist
();
m
_bRegisted
=
true
;
_bRegisted
=
true
;
}
else
{
m
_bAsyncRegist
=
true
;
_bAsyncRegist
=
true
;
}
}
virtual
void
onGetMedia
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
lock_guard
<
recursive_mutex
>
lock
(
m
_mtxMap
);
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
if
(
pkt
->
isCfgFrame
())
{
m
_mapCfgFrame
.
emplace
(
pkt
->
typeId
,
pkt
);
_mapCfgFrame
.
emplace
(
pkt
->
typeId
,
pkt
);
if
(
m_bAsyncRegist
&&
!
m_bRegisted
&&
m_mapCfgFrame
.
size
()
==
m
_iCfgFrameSize
){
m
_bAsyncRegist
=
false
;
if
(
_bAsyncRegist
&&
!
_bRegisted
&&
_mapCfgFrame
.
size
()
==
_iCfgFrameSize
){
_bAsyncRegist
=
false
;
MediaSource
::
regist
();
m
_bRegisted
=
true
;
_bRegisted
=
true
;
}
}
m
_pRing
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
_pRing
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
}
private
:
bool
ready
(){
lock_guard
<
recursive_mutex
>
lock
(
m
_mtxMap
);
return
m_iCfgFrameSize
!=
-
1
&&
m_iCfgFrameSize
==
m
_mapCfgFrame
.
size
();
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
return
_iCfgFrameSize
!=
-
1
&&
_iCfgFrameSize
==
_mapCfgFrame
.
size
();
}
protected
:
AMFValue
m
_metadata
;
unordered_map
<
int
,
RtmpPacket
::
Ptr
>
m
_mapCfgFrame
;
mutable
recursive_mutex
m
_mtxMap
;
RingBuffer
<
RtmpPacket
::
Ptr
>::
Ptr
m
_pRing
;
//rtp环形缓冲
int
m
_iCfgFrameSize
=
-
1
;
bool
m
_bAsyncRegist
=
false
;
bool
m
_bRegisted
=
false
;
AMFValue
_metadata
;
unordered_map
<
int
,
RtmpPacket
::
Ptr
>
_mapCfgFrame
;
mutable
recursive_mutex
_mtxMap
;
RingBuffer
<
RtmpPacket
::
Ptr
>::
Ptr
_pRing
;
//rtp环形缓冲
int
_iCfgFrameSize
=
-
1
;
bool
_bAsyncRegist
=
false
;
bool
_bRegisted
=
false
;
};
}
/* namespace Rtmp */
...
...
src/Rtmp/RtmpParser.cpp
查看文件 @
39baaebc
...
...
@@ -36,13 +36,13 @@ RtmpParser::RtmpParser(const AMFValue &val) {
if
(
videoCodec
.
type
()
==
AMF_STRING
)
{
if
(
videoCodec
.
as_string
()
==
"avc1"
)
{
//h264
m
_iVideoCodecID
=
H264_CODEC_ID
;
_iVideoCodecID
=
H264_CODEC_ID
;
}
else
{
InfoL
<<
"不支持RTMP视频格式:"
<<
videoCodec
.
as_string
();
}
}
else
if
(
videoCodec
.
type
()
!=
AMF_NULL
){
m
_iVideoCodecID
=
videoCodec
.
as_integer
();
if
(
m
_iVideoCodecID
!=
H264_CODEC_ID
)
{
_iVideoCodecID
=
videoCodec
.
as_integer
();
if
(
_iVideoCodecID
!=
H264_CODEC_ID
)
{
InfoL
<<
"不支持RTMP视频格式:"
<<
videoCodec
.
as_integer
();
}
}
...
...
@@ -50,13 +50,13 @@ RtmpParser::RtmpParser(const AMFValue &val) {
if
(
audioCodec
.
type
()
==
AMF_STRING
)
{
if
(
audioCodec
.
as_string
()
==
"mp4a"
)
{
//aac
m
_iAudioCodecID
=
AAC_CODEC_ID
;
_iAudioCodecID
=
AAC_CODEC_ID
;
}
else
{
InfoL
<<
"不支持RTMP音频格式:"
<<
audioCodec
.
as_string
();
}
}
else
if
(
audioCodec
.
type
()
!=
AMF_NULL
)
{
m
_iAudioCodecID
=
audioCodec
.
as_integer
();
if
(
m
_iAudioCodecID
!=
AAC_CODEC_ID
)
{
_iAudioCodecID
=
audioCodec
.
as_integer
();
if
(
_iAudioCodecID
!=
AAC_CODEC_ID
)
{
InfoL
<<
"不支持RTMP音频格式:"
<<
audioCodec
.
as_integer
();
}
}
...
...
@@ -69,28 +69,28 @@ RtmpParser::~RtmpParser() {
bool
RtmpParser
::
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
switch
(
pkt
->
typeId
)
{
case
MSG_VIDEO
:{
if
(
m
_iVideoCodecID
==
0
){
if
(
_iVideoCodecID
==
0
){
//未初始化视频
m
_iVideoCodecID
=
pkt
->
getMediaType
();
if
(
m
_iVideoCodecID
!=
H264_CODEC_ID
){
InfoL
<<
"不支持RTMP视频格式:"
<<
m
_iVideoCodecID
;
_iVideoCodecID
=
pkt
->
getMediaType
();
if
(
_iVideoCodecID
!=
H264_CODEC_ID
){
InfoL
<<
"不支持RTMP视频格式:"
<<
_iVideoCodecID
;
}
}
if
(
m
_iVideoCodecID
==
H264_CODEC_ID
){
if
(
_iVideoCodecID
==
H264_CODEC_ID
){
return
inputVideo
(
pkt
);
}
return
false
;
}
case
MSG_AUDIO
:
{
if
(
m
_iAudioCodecID
==
0
){
if
(
_iAudioCodecID
==
0
){
//未初始化音频
m
_iAudioCodecID
=
pkt
->
getMediaType
();
if
(
m
_iAudioCodecID
!=
AAC_CODEC_ID
){
InfoL
<<
"不支持RTMP音频格式:"
<<
m
_iAudioCodecID
;
_iAudioCodecID
=
pkt
->
getMediaType
();
if
(
_iAudioCodecID
!=
AAC_CODEC_ID
){
InfoL
<<
"不支持RTMP音频格式:"
<<
_iAudioCodecID
;
}
}
if
(
m
_iAudioCodecID
==
AAC_CODEC_ID
)
{
if
(
_iAudioCodecID
==
AAC_CODEC_ID
)
{
return
inputAudio
(
pkt
);
}
return
false
;
...
...
@@ -104,20 +104,20 @@ bool RtmpParser::inputRtmp(const RtmpPacket::Ptr &pkt) {
inline
bool
RtmpParser
::
inputVideo
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
if
(
pkt
->
isCfgFrame
())
{
//WarnL << " got h264 cfg";
if
(
m
_strSPS
.
size
())
{
if
(
_strSPS
.
size
())
{
return
false
;
}
m
_strSPS
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
m
_strSPS
.
append
(
pkt
->
getH264SPS
());
_strSPS
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
_strSPS
.
append
(
pkt
->
getH264SPS
());
m
_strPPS
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
m
_strPPS
.
append
(
pkt
->
getH264PPS
());
_strPPS
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
_strPPS
.
append
(
pkt
->
getH264PPS
());
getAVCInfo
(
pkt
->
getH264SPS
(),
m_iVideoWidth
,
m_iVideoHeight
,
m
_fVideoFps
);
getAVCInfo
(
pkt
->
getH264SPS
(),
_iVideoWidth
,
_iVideoHeight
,
_fVideoFps
);
return
false
;
}
if
(
m
_strSPS
.
size
())
{
if
(
_strSPS
.
size
())
{
uint32_t
iTotalLen
=
pkt
->
strBuf
.
size
();
uint32_t
iOffset
=
5
;
while
(
iOffset
+
4
<
iTotalLen
){
...
...
@@ -137,8 +137,8 @@ inline bool RtmpParser::inputVideo(const RtmpPacket::Ptr &pkt) {
inline
void
RtmpParser
::
_onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
)
{
switch
(
pcData
[
0
]
&
0x1F
)
{
case
5
:
{
onGetH264
(
m_strSPS
.
data
()
+
4
,
m
_strSPS
.
length
()
-
4
,
ui32TimeStamp
);
onGetH264
(
m_strPPS
.
data
()
+
4
,
m
_strPPS
.
length
()
-
4
,
ui32TimeStamp
);
onGetH264
(
_strSPS
.
data
()
+
4
,
_strSPS
.
length
()
-
4
,
ui32TimeStamp
);
onGetH264
(
_strPPS
.
data
()
+
4
,
_strPPS
.
length
()
-
4
,
ui32TimeStamp
);
}
case
1
:
{
onGetH264
(
pcData
,
iLen
,
ui32TimeStamp
);
...
...
@@ -150,82 +150,82 @@ inline void RtmpParser::_onGetH264(const char* pcData, int iLen, uint32_t ui32Ti
}
}
inline
void
RtmpParser
::
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
)
{
m
_h264frame
.
type
=
pcData
[
0
]
&
0x1F
;
m
_h264frame
.
timeStamp
=
ui32TimeStamp
;
m
_h264frame
.
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
m
_h264frame
.
buffer
.
append
(
pcData
,
iLen
);
_h264frame
.
type
=
pcData
[
0
]
&
0x1F
;
_h264frame
.
timeStamp
=
ui32TimeStamp
;
_h264frame
.
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
.
buffer
.
append
(
pcData
,
iLen
);
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxCB
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxCB
);
if
(
onVideo
)
{
onVideo
(
m
_h264frame
);
onVideo
(
_h264frame
);
}
}
m
_h264frame
.
buffer
.
clear
();
_h264frame
.
buffer
.
clear
();
}
inline
bool
RtmpParser
::
inputAudio
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
if
(
pkt
->
isCfgFrame
())
{
if
(
m
_strAudioCfg
.
size
())
{
if
(
_strAudioCfg
.
size
())
{
return
false
;
}
m
_strAudioCfg
=
pkt
->
getAacCfg
();
m
_iSampleBit
=
pkt
->
getAudioSampleBit
();
makeAdtsHeader
(
m_strAudioCfg
,
m
_adts
);
getAACInfo
(
m_adts
,
m_iSampleRate
,
m
_iChannel
);
_strAudioCfg
=
pkt
->
getAacCfg
();
_iSampleBit
=
pkt
->
getAudioSampleBit
();
makeAdtsHeader
(
_strAudioCfg
,
_adts
);
getAACInfo
(
_adts
,
_iSampleRate
,
_iChannel
);
return
false
;
}
if
(
m
_strAudioCfg
.
size
())
{
if
(
_strAudioCfg
.
size
())
{
onGetAAC
(
pkt
->
strBuf
.
data
()
+
2
,
pkt
->
strBuf
.
size
()
-
2
,
pkt
->
timeStamp
);
}
return
false
;
}
inline
void
RtmpParser
::
onGetAAC
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
)
{
if
(
iLen
+
7
>
sizeof
(
m
_adts
.
buffer
)){
if
(
iLen
+
7
>
sizeof
(
_adts
.
buffer
)){
WarnL
<<
"Illegal adts data, exceeding the length limit."
;
return
;
}
//添加adts头
memcpy
(
m
_adts
.
buffer
+
7
,
pcData
,
iLen
);
m
_adts
.
aac_frame_length
=
7
+
iLen
;
m
_adts
.
timeStamp
=
ui32TimeStamp
;
writeAdtsHeader
(
m_adts
,
m
_adts
.
buffer
);
memcpy
(
_adts
.
buffer
+
7
,
pcData
,
iLen
);
_adts
.
aac_frame_length
=
7
+
iLen
;
_adts
.
timeStamp
=
ui32TimeStamp
;
writeAdtsHeader
(
_adts
,
_adts
.
buffer
);
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxCB
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxCB
);
if
(
onAudio
)
{
onAudio
(
m
_adts
);
onAudio
(
_adts
);
}
}
m
_adts
.
aac_frame_length
=
7
;
_adts
.
aac_frame_length
=
7
;
}
inline
void
RtmpParser
::
onCheckMedia
(
const
AMFValue
&
obj
)
{
obj
.
object_for_each
([
&
](
const
string
&
key
,
const
AMFValue
&
val
)
{
if
(
key
==
"duration"
)
{
m
_fDuration
=
val
.
as_number
();
_fDuration
=
val
.
as_number
();
return
;
}
if
(
key
==
"width"
)
{
m
_iVideoWidth
=
val
.
as_number
();
_iVideoWidth
=
val
.
as_number
();
return
;
}
if
(
key
==
"height"
)
{
m
_iVideoHeight
=
val
.
as_number
();
_iVideoHeight
=
val
.
as_number
();
return
;
}
if
(
key
==
"framerate"
)
{
m
_fVideoFps
=
val
.
as_number
();
_fVideoFps
=
val
.
as_number
();
return
;
}
if
(
key
==
"audiosamplerate"
)
{
m
_iSampleRate
=
val
.
as_number
();
_iSampleRate
=
val
.
as_number
();
return
;
}
if
(
key
==
"audiosamplesize"
)
{
m
_iSampleBit
=
val
.
as_number
();
_iSampleBit
=
val
.
as_number
();
return
;
}
if
(
key
==
"stereo"
)
{
m
_iChannel
=
val
.
as_boolean
()
?
2
:
1
;
_iChannel
=
val
.
as_boolean
()
?
2
:
1
;
return
;
}
});
...
...
src/Rtmp/RtmpParser.h
查看文件 @
39baaebc
...
...
@@ -54,19 +54,19 @@ public:
bool
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
);
bool
isInited
()
const
override
{
if
((
m_iAudioCodecID
|
m
_iVideoCodecID
)
==
0
){
if
((
_iAudioCodecID
|
_iVideoCodecID
)
==
0
){
//音视频codec_id都未获取到,说明还未初始化成功
return
false
;
}
if
((
m_iAudioCodecID
&
m_iVideoCodecID
)
==
0
&&
m
_ticker
.
elapsedTime
()
<
300
){
if
((
_iAudioCodecID
&
_iVideoCodecID
)
==
0
&&
_ticker
.
elapsedTime
()
<
300
){
//音视频codec_id有其一未获取到,且最少分析300ms才能断定没有音频或视频
return
false
;
}
if
(
m_iAudioCodecID
&&
!
m
_strAudioCfg
.
size
())
{
if
(
_iAudioCodecID
&&
!
_strAudioCfg
.
size
())
{
//如果音频是aac但是还未获取aac config ,则未初始化成功
return
false
;
}
if
(
m_iVideoCodecID
&&
!
m
_strSPS
.
size
())
{
if
(
_iVideoCodecID
&&
!
_strSPS
.
size
())
{
//如果视频是h264但是还未获取sps ,则未初始化成功
return
false
;
}
...
...
@@ -74,7 +74,7 @@ public:
return
true
;
}
float
getDuration
()
const
override
{
return
m
_fDuration
;
return
_fDuration
;
}
private
:
inline
void
onCheckMedia
(
const
AMFValue
&
obj
);
...
...
@@ -86,28 +86,28 @@ private:
inline
void
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
);
inline
void
onGetAAC
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
);
//video
H264Frame
m
_h264frame
;
H264Frame
_h264frame
;
//aduio
AACFrame
m
_adts
;
AACFrame
_adts
;
int
m
_iSampleRate
=
44100
;
int
m
_iSampleBit
=
16
;
int
m
_iChannel
=
1
;
int
_iSampleRate
=
44100
;
int
_iSampleBit
=
16
;
int
_iChannel
=
1
;
string
m
_strSPS
;
string
m
_strPPS
;
string
m
_strAudioCfg
;
int
m
_iVideoWidth
=
0
;
int
m
_iVideoHeight
=
0
;
float
m
_fVideoFps
=
0
;
string
_strSPS
;
string
_strPPS
;
string
_strAudioCfg
;
int
_iVideoWidth
=
0
;
int
_iVideoHeight
=
0
;
float
_fVideoFps
=
0
;
//音视频codec_id初始为0代表尚未获取到
int
m
_iAudioCodecID
=
0
;
int
m
_iVideoCodecID
=
0
;
float
m
_fDuration
=
0
;
mutable
Ticker
m
_ticker
;
int
_iAudioCodecID
=
0
;
int
_iVideoCodecID
=
0
;
float
_fDuration
=
0
;
mutable
Ticker
_ticker
;
function
<
void
(
const
H264Frame
&
frame
)
>
onVideo
;
function
<
void
(
const
AACFrame
&
frame
)
>
onAudio
;
recursive_mutex
m
_mtxCB
;
recursive_mutex
_mtxCB
;
};
...
...
src/Rtmp/RtmpPlayer.cpp
查看文件 @
39baaebc
...
...
@@ -53,24 +53,24 @@ RtmpPlayer::~RtmpPlayer() {
}
void
RtmpPlayer
::
teardown
()
{
if
(
alive
())
{
m
_strApp
.
clear
();
m
_strStream
.
clear
();
m
_strTcUrl
.
clear
();
_strApp
.
clear
();
_strStream
.
clear
();
_strTcUrl
.
clear
();
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
m
_mapOnResultCB
.
clear
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
_mapOnResultCB
.
clear
();
}
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
m
_dqOnStatusCB
.
clear
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
_dqOnStatusCB
.
clear
();
}
m
_pBeatTimer
.
reset
();
m
_pPlayTimer
.
reset
();
m
_pMediaTimer
.
reset
();
m
_fSeekTo
=
0
;
CLEAR_ARR
(
m
_adFistStamp
);
CLEAR_ARR
(
m
_adNowStamp
);
_pBeatTimer
.
reset
();
_pPlayTimer
.
reset
();
_pMediaTimer
.
reset
();
_fSeekTo
=
0
;
CLEAR_ARR
(
_adFistStamp
);
CLEAR_ARR
(
_adNowStamp
);
reset
();
shutdown
();
}
...
...
@@ -78,15 +78,15 @@ void RtmpPlayer::teardown() {
void
RtmpPlayer
::
play
(
const
char
*
strUrl
)
{
teardown
();
string
strHost
=
FindField
(
strUrl
,
"://"
,
"/"
);
m
_strApp
=
FindField
(
strUrl
,
(
strHost
+
"/"
).
data
(),
"/"
);
m_strStream
=
FindField
(
strUrl
,
(
strHost
+
"/"
+
m
_strApp
+
"/"
).
data
(),
NULL
);
m_strTcUrl
=
string
(
"rtmp://"
)
+
strHost
+
"/"
+
m
_strApp
;
_strApp
=
FindField
(
strUrl
,
(
strHost
+
"/"
).
data
(),
"/"
);
_strStream
=
FindField
(
strUrl
,
(
strHost
+
"/"
+
_strApp
+
"/"
).
data
(),
NULL
);
_strTcUrl
=
string
(
"rtmp://"
)
+
strHost
+
"/"
+
_strApp
;
if
(
!
m_strApp
.
size
()
||
!
m
_strStream
.
size
())
{
if
(
!
_strApp
.
size
()
||
!
_strStream
.
size
())
{
_onPlayResult
(
SockException
(
Err_other
,
"rtmp url非法"
));
return
;
}
DebugL
<<
strHost
<<
" "
<<
m_strApp
<<
" "
<<
m
_strStream
;
DebugL
<<
strHost
<<
" "
<<
_strApp
<<
" "
<<
_strStream
;
auto
iPort
=
atoi
(
FindField
(
strHost
.
c_str
(),
":"
,
NULL
).
c_str
());
if
(
iPort
<=
0
)
{
...
...
@@ -111,7 +111,7 @@ void RtmpPlayer::onConnect(const SockException &err){
}
weak_ptr
<
RtmpPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
m
_pPlayTimer
.
reset
(
new
Timer
(
10
,
[
weakSelf
]()
{
_pPlayTimer
.
reset
(
new
Timer
(
10
,
[
weakSelf
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
false
;
...
...
@@ -145,8 +145,8 @@ void RtmpPlayer::pause(bool bPause) {
inline
void
RtmpPlayer
::
send_connect
()
{
AMFValue
obj
(
AMF_OBJECT
);
obj
.
set
(
"app"
,
m
_strApp
);
obj
.
set
(
"tcUrl"
,
m
_strTcUrl
);
obj
.
set
(
"app"
,
_strApp
);
obj
.
set
(
"tcUrl"
,
_strTcUrl
);
//未使用代理
obj
.
set
(
"fpad"
,
false
);
//参考librtmp,什么作用?
...
...
@@ -177,14 +177,14 @@ inline void RtmpPlayer::send_createStream() {
addOnResultCB
([
this
](
AMFDecoder
&
dec
){
//TraceL << "createStream result";
dec
.
load
<
AMFValue
>
();
m
_ui32StreamId
=
dec
.
load
<
int
>
();
_ui32StreamId
=
dec
.
load
<
int
>
();
send_play
();
});
}
inline
void
RtmpPlayer
::
send_play
()
{
AMFEncoder
enc
;
enc
<<
"play"
<<
++
m_iReqID
<<
nullptr
<<
m_strStream
<<
(
double
)
m
_ui32StreamId
;
enc
<<
"play"
<<
++
_iReqID
<<
nullptr
<<
_strStream
<<
(
double
)
_ui32StreamId
;
sendRequest
(
MSG_CMD
,
enc
.
data
());
auto
fun
=
[
this
](
AMFValue
&
val
){
//TraceL << "play onStatus";
...
...
@@ -200,7 +200,7 @@ inline void RtmpPlayer::send_play() {
inline
void
RtmpPlayer
::
send_pause
(
bool
bPause
)
{
AMFEncoder
enc
;
enc
<<
"pause"
<<
++
m
_iReqID
<<
nullptr
<<
bPause
;
enc
<<
"pause"
<<
++
_iReqID
<<
nullptr
<<
bPause
;
sendRequest
(
MSG_CMD
,
enc
.
data
());
auto
fun
=
[
this
,
bPause
](
AMFValue
&
val
){
//TraceL << "pause onStatus";
...
...
@@ -211,21 +211,21 @@ inline void RtmpPlayer::send_pause(bool bPause) {
throw
std
::
runtime_error
(
StrPrinter
<<
"pause 恢复播放失败:"
<<
level
<<
" "
<<
code
<<
endl
);
}
}
else
{
m
_bPaused
=
bPause
;
_bPaused
=
bPause
;
if
(
!
bPause
){
_onPlayResult
(
SockException
(
Err_success
,
"rtmp resum success"
));
}
else
{
//暂停播放
m
_pMediaTimer
.
reset
();
_pMediaTimer
.
reset
();
}
}
};
addOnStatusCB
(
fun
);
m
_pBeatTimer
.
reset
();
_pBeatTimer
.
reset
();
if
(
bPause
){
weak_ptr
<
RtmpPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
m
_pBeatTimer
.
reset
(
new
Timer
(
3
,[
weakSelf
](){
_pBeatTimer
.
reset
(
new
Timer
(
3
,[
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
false
;
...
...
@@ -239,11 +239,11 @@ inline void RtmpPlayer::send_pause(bool bPause) {
void
RtmpPlayer
::
onCmd_result
(
AMFDecoder
&
dec
){
auto
iReqId
=
dec
.
load
<
int
>
();
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
auto
it
=
m
_mapOnResultCB
.
find
(
iReqId
);
if
(
it
!=
m
_mapOnResultCB
.
end
()){
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
auto
it
=
_mapOnResultCB
.
find
(
iReqId
);
if
(
it
!=
_mapOnResultCB
.
end
()){
it
->
second
(
dec
);
m
_mapOnResultCB
.
erase
(
it
);
_mapOnResultCB
.
erase
(
it
);
}
else
{
WarnL
<<
"unhandled _result"
;
}
...
...
@@ -260,10 +260,10 @@ void RtmpPlayer::onCmd_onStatus(AMFDecoder &dec) {
throw
std
::
runtime_error
(
"onStatus:the result object was not found"
);
}
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
if
(
m
_dqOnStatusCB
.
size
()){
m
_dqOnStatusCB
.
front
()(
val
);
m
_dqOnStatusCB
.
pop_front
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
if
(
_dqOnStatusCB
.
size
()){
_dqOnStatusCB
.
front
()(
val
);
_dqOnStatusCB
.
pop_front
();
}
else
{
auto
level
=
val
[
"level"
];
auto
code
=
val
[
"code"
].
as_string
();
...
...
@@ -311,8 +311,8 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
case
MSG_AUDIO
:
case
MSG_VIDEO
:
{
auto
idx
=
chunkData
.
typeId
%
2
;
if
(
m
_aNowStampTicker
[
idx
].
elapsedTime
()
>
500
)
{
m
_adNowStamp
[
idx
]
=
chunkData
.
timeStamp
;
if
(
_aNowStampTicker
[
idx
].
elapsedTime
()
>
500
)
{
_adNowStamp
[
idx
]
=
chunkData
.
timeStamp
;
}
_onMediaData
(
std
::
make_shared
<
RtmpPacket
>
(
chunkData
));
}
...
...
@@ -326,27 +326,27 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
float
RtmpPlayer
::
getProgressTime
()
const
{
double
iTime
[
2
]
=
{
0
,
0
};
for
(
auto
i
=
0
;
i
<
2
;
i
++
){
iTime
[
i
]
=
(
m_adNowStamp
[
i
]
-
m
_adFistStamp
[
i
])
/
1000.0
;
iTime
[
i
]
=
(
_adNowStamp
[
i
]
-
_adFistStamp
[
i
])
/
1000.0
;
}
return
m
_fSeekTo
+
MAX
(
iTime
[
0
],
iTime
[
1
]);
return
_fSeekTo
+
MAX
(
iTime
[
0
],
iTime
[
1
]);
}
void
RtmpPlayer
::
seekToTime
(
float
fTime
){
if
(
m
_bPaused
)
{
if
(
_bPaused
)
{
pause
(
false
);
}
AMFEncoder
enc
;
enc
<<
"seek"
<<
++
m
_iReqID
<<
nullptr
<<
fTime
*
1000.0
;
enc
<<
"seek"
<<
++
_iReqID
<<
nullptr
<<
fTime
*
1000.0
;
sendRequest
(
MSG_CMD
,
enc
.
data
());
addOnStatusCB
([
this
,
fTime
](
AMFValue
&
val
)
{
//TraceL << "seek result";
m
_aNowStampTicker
[
0
].
resetTime
();
m
_aNowStampTicker
[
1
].
resetTime
();
_aNowStampTicker
[
0
].
resetTime
();
_aNowStampTicker
[
1
].
resetTime
();
float
iTimeInc
=
fTime
-
getProgressTime
();
for
(
auto
i
=
0
;
i
<
2
;
i
++
){
m_adFistStamp
[
i
]
=
m
_adNowStamp
[
i
]
+
iTimeInc
*
1000.0
;
m_adNowStamp
[
i
]
=
m
_adFistStamp
[
i
];
_adFistStamp
[
i
]
=
_adNowStamp
[
i
]
+
iTimeInc
*
1000.0
;
_adNowStamp
[
i
]
=
_adFistStamp
[
i
];
}
m
_fSeekTo
=
fTime
;
_fSeekTo
=
fTime
;
});
}
...
...
src/Rtmp/RtmpPlayer.h
查看文件 @
39baaebc
...
...
@@ -65,28 +65,28 @@ protected:
private
:
void
_onShutdown
(
const
SockException
&
ex
)
{
WarnL
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
m
_pPlayTimer
.
reset
();
m
_pMediaTimer
.
reset
();
m
_pBeatTimer
.
reset
();
_pPlayTimer
.
reset
();
_pMediaTimer
.
reset
();
_pBeatTimer
.
reset
();
onShutdown
(
ex
);
}
void
_onMediaData
(
const
RtmpPacket
::
Ptr
&
chunkData
)
{
m
_mediaTicker
.
resetTime
();
_mediaTicker
.
resetTime
();
onMediaData
(
chunkData
);
}
void
_onPlayResult
(
const
SockException
&
ex
)
{
WarnL
<<
ex
.
getErrCode
()
<<
" "
<<
ex
.
what
();
m
_pPlayTimer
.
reset
();
m
_pMediaTimer
.
reset
();
_pPlayTimer
.
reset
();
_pMediaTimer
.
reset
();
if
(
!
ex
)
{
m
_mediaTicker
.
resetTime
();
_mediaTicker
.
resetTime
();
weak_ptr
<
RtmpPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
m
_pMediaTimer
.
reset
(
new
Timer
(
5
,
[
weakSelf
]()
{
_pMediaTimer
.
reset
(
new
Timer
(
5
,
[
weakSelf
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
false
;
}
if
(
strongSelf
->
m
_mediaTicker
.
elapsedTime
()
>
10000
)
{
if
(
strongSelf
->
_mediaTicker
.
elapsedTime
()
>
10000
)
{
//recv media timeout!
strongSelf
->
_onShutdown
(
SockException
(
Err_timeout
,
"recv rtmp timeout"
));
strongSelf
->
teardown
();
...
...
@@ -111,13 +111,13 @@ private:
template
<
typename
FUN
>
inline
void
addOnResultCB
(
const
FUN
&
fun
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
m_mapOnResultCB
.
emplace
(
m
_iReqID
,
fun
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
_mapOnResultCB
.
emplace
(
_iReqID
,
fun
);
}
template
<
typename
FUN
>
inline
void
addOnStatusCB
(
const
FUN
&
fun
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
m
_dqOnStatusCB
.
emplace_back
(
fun
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
_dqOnStatusCB
.
emplace_back
(
fun
);
}
void
onCmd_result
(
AMFDecoder
&
dec
);
...
...
@@ -129,31 +129,31 @@ private:
inline
void
send_play
();
inline
void
send_pause
(
bool
bPause
);
string
m
_strApp
;
string
m
_strStream
;
string
m
_strTcUrl
;
bool
m
_bPaused
=
false
;
string
_strApp
;
string
_strStream
;
string
_strTcUrl
;
bool
_bPaused
=
false
;
unordered_map
<
int
,
function
<
void
(
AMFDecoder
&
dec
)
>
>
m
_mapOnResultCB
;
recursive_mutex
m
_mtxOnResultCB
;
deque
<
function
<
void
(
AMFValue
&
dec
)
>
>
m
_dqOnStatusCB
;
recursive_mutex
m
_mtxOnStatusCB
;
unordered_map
<
int
,
function
<
void
(
AMFDecoder
&
dec
)
>
>
_mapOnResultCB
;
recursive_mutex
_mtxOnResultCB
;
deque
<
function
<
void
(
AMFValue
&
dec
)
>
>
_dqOnStatusCB
;
recursive_mutex
_mtxOnStatusCB
;
typedef
void
(
RtmpPlayer
::*
rtmpCMDHandle
)(
AMFDecoder
&
dec
);
static
unordered_map
<
string
,
rtmpCMDHandle
>
g_mapCmd
;
//超时功能实现
Ticker
m
_mediaTicker
;
std
::
shared_ptr
<
Timer
>
m
_pMediaTimer
;
std
::
shared_ptr
<
Timer
>
m
_pPlayTimer
;
Ticker
_mediaTicker
;
std
::
shared_ptr
<
Timer
>
_pMediaTimer
;
std
::
shared_ptr
<
Timer
>
_pPlayTimer
;
//心跳定时器
std
::
shared_ptr
<
Timer
>
m
_pBeatTimer
;
std
::
shared_ptr
<
Timer
>
_pBeatTimer
;
//播放进度控制
float
m
_fSeekTo
=
0
;
double
m
_adFistStamp
[
2
]
=
{
0
,
0
};
double
m
_adNowStamp
[
2
]
=
{
0
,
0
};
Ticker
m
_aNowStampTicker
[
2
];
float
_fSeekTo
=
0
;
double
_adFistStamp
[
2
]
=
{
0
,
0
};
double
_adNowStamp
[
2
]
=
{
0
,
0
};
Ticker
_aNowStampTicker
[
2
];
};
}
/* namespace Rtmp */
...
...
src/Rtmp/RtmpPlayerImp.h
查看文件 @
39baaebc
...
...
@@ -63,32 +63,32 @@ public:
private
:
//派生类回调函数
bool
onCheckMeta
(
AMFValue
&
val
)
override
{
m_pRtmpMediaSrc
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
m
_pMediaSrc
);
if
(
m
_pRtmpMediaSrc
){
m
_pRtmpMediaSrc
->
onGetMetaData
(
val
);
_pRtmpMediaSrc
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_pMediaSrc
);
if
(
_pRtmpMediaSrc
){
_pRtmpMediaSrc
->
onGetMetaData
(
val
);
}
try
{
m
_parser
.
reset
(
new
RtmpParser
(
val
));
_parser
.
reset
(
new
RtmpParser
(
val
));
//todo(xzl) 修复此处
//
m_parser->setOnVideoCB(m
_onGetVideoCB);
//
m_parser->setOnAudioCB(m
_onGetAudioCB);
//
_parser->setOnVideoCB(
_onGetVideoCB);
//
_parser->setOnAudioCB(
_onGetAudioCB);
return
true
;
}
catch
(
std
::
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
return
m
_pRtmpMediaSrc
?
true
:
false
;
return
_pRtmpMediaSrc
?
true
:
false
;
}
}
void
onMediaData
(
const
RtmpPacket
::
Ptr
&
chunkData
)
override
{
if
(
m
_parser
){
m
_parser
->
inputRtmp
(
chunkData
);
if
(
_parser
){
_parser
->
inputRtmp
(
chunkData
);
}
if
(
m
_pRtmpMediaSrc
){
m
_pRtmpMediaSrc
->
onGetMedia
(
chunkData
);
if
(
_pRtmpMediaSrc
){
_pRtmpMediaSrc
->
onGetMedia
(
chunkData
);
}
}
private
:
RtmpMediaSource
::
Ptr
m
_pRtmpMediaSrc
;
RtmpMediaSource
::
Ptr
_pRtmpMediaSrc
;
};
...
...
src/Rtmp/RtmpProtocol.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtmp/RtmpProtocol.h
查看文件 @
39baaebc
...
...
@@ -57,7 +57,7 @@ protected:
virtual
void
onSendRawData
(
const
Buffer
::
Ptr
&
buffer
)
=
0
;
virtual
void
onRtmpChunk
(
RtmpPacket
&
chunkData
)
=
0
;
virtual
void
onStreamBegin
(
uint32_t
ui32StreamId
){
m
_ui32StreamId
=
ui32StreamId
;
_ui32StreamId
=
ui32StreamId
;
}
virtual
void
onStreamEof
(
uint32_t
ui32StreamId
){};
virtual
void
onStreamDry
(
uint32_t
ui32StreamId
){};
...
...
@@ -77,14 +77,14 @@ protected:
void
sendResponse
(
int
iType
,
const
string
&
str
);
void
sendRtmp
(
uint8_t
ui8Type
,
uint32_t
ui32StreamId
,
const
std
::
string
&
strBuf
,
uint32_t
ui32TimeStamp
,
int
iChunkID
);
protected
:
int
m
_iReqID
=
0
;
uint32_t
m
_ui32StreamId
=
STREAM_CONTROL
;
int
m
_iNowStreamID
=
0
;
int
m
_iNowChunkID
=
0
;
bool
m
_bDataStarted
=
false
;
int
_iReqID
=
0
;
uint32_t
_ui32StreamId
=
STREAM_CONTROL
;
int
_iNowStreamID
=
0
;
int
_iNowChunkID
=
0
;
bool
_bDataStarted
=
false
;
inline
BufferRaw
::
Ptr
obtainBuffer
();
inline
BufferRaw
::
Ptr
obtainBuffer
(
const
void
*
data
,
int
len
);
//ResourcePool<BufferRaw,MAX_SEND_PKT>
m
_bufferPool;
//ResourcePool<BufferRaw,MAX_SEND_PKT> _bufferPool;
private:
void
handle_S0S1S2
(
const
function
<
void
()
>
&
cb
);
void
handle_C0C1
();
...
...
@@ -103,20 +103,20 @@ private:
private
:
////////////ChunkSize////////////
size_t
m
_iChunkLenIn
=
DEFAULT_CHUNK_LEN
;
size_t
m
_iChunkLenOut
=
DEFAULT_CHUNK_LEN
;
size_t
_iChunkLenIn
=
DEFAULT_CHUNK_LEN
;
size_t
_iChunkLenOut
=
DEFAULT_CHUNK_LEN
;
////////////Acknowledgement////////////
uint32_t
m
_ui32ByteSent
=
0
;
uint32_t
m
_ui32LastSent
=
0
;
uint32_t
m
_ui32WinSize
=
0
;
uint32_t
_ui32ByteSent
=
0
;
uint32_t
_ui32LastSent
=
0
;
uint32_t
_ui32WinSize
=
0
;
///////////PeerBandwidth///////////
uint32_t
m
_ui32Bandwidth
=
2500000
;
uint8_t
m
_ui8LimitType
=
2
;
uint32_t
_ui32Bandwidth
=
2500000
;
uint8_t
_ui8LimitType
=
2
;
////////////Chunk////////////
unordered_map
<
int
,
RtmpPacket
>
m
_mapChunkData
;
unordered_map
<
int
,
RtmpPacket
>
_mapChunkData
;
//////////Rtmp parser//////////
string
m
_strRcvBuf
;
function
<
void
()
>
m
_nextHandle
;
string
_strRcvBuf
;
function
<
void
()
>
_nextHandle
;
};
}
/* namespace Rtmp */
...
...
src/Rtmp/RtmpPusher.cpp
查看文件 @
39baaebc
...
...
@@ -56,7 +56,7 @@ void RtmpPusher::init(const RtmpMediaSource::Ptr &src){
g_mapCmd
.
emplace
(
"_result"
,
&
RtmpPusher
::
onCmd_result
);
g_mapCmd
.
emplace
(
"onStatus"
,
&
RtmpPusher
::
onCmd_onStatus
);
},
[]()
{});
m
_pMediaSrc
=
src
;
_pMediaSrc
=
src
;
}
RtmpPusher
::~
RtmpPusher
()
{
...
...
@@ -65,18 +65,18 @@ RtmpPusher::~RtmpPusher() {
}
void
RtmpPusher
::
teardown
()
{
if
(
alive
())
{
m
_strApp
.
clear
();
m
_strStream
.
clear
();
m
_strTcUrl
.
clear
();
_strApp
.
clear
();
_strStream
.
clear
();
_strTcUrl
.
clear
();
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
m
_mapOnResultCB
.
clear
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
_mapOnResultCB
.
clear
();
}
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
m
_dqOnStatusCB
.
clear
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
_dqOnStatusCB
.
clear
();
}
m
_pPublishTimer
.
reset
();
_pPublishTimer
.
reset
();
reset
();
shutdown
();
}
...
...
@@ -85,15 +85,15 @@ void RtmpPusher::teardown() {
void
RtmpPusher
::
publish
(
const
char
*
strUrl
)
{
teardown
();
string
strHost
=
FindField
(
strUrl
,
"://"
,
"/"
);
m
_strApp
=
FindField
(
strUrl
,
(
strHost
+
"/"
).
data
(),
"/"
);
m_strStream
=
FindField
(
strUrl
,
(
strHost
+
"/"
+
m
_strApp
+
"/"
).
data
(),
NULL
);
m_strTcUrl
=
string
(
"rtmp://"
)
+
strHost
+
"/"
+
m
_strApp
;
_strApp
=
FindField
(
strUrl
,
(
strHost
+
"/"
).
data
(),
"/"
);
_strStream
=
FindField
(
strUrl
,
(
strHost
+
"/"
+
_strApp
+
"/"
).
data
(),
NULL
);
_strTcUrl
=
string
(
"rtmp://"
)
+
strHost
+
"/"
+
_strApp
;
if
(
!
m_strApp
.
size
()
||
!
m
_strStream
.
size
())
{
if
(
!
_strApp
.
size
()
||
!
_strStream
.
size
())
{
onPublishResult
(
SockException
(
Err_other
,
"rtmp url非法"
));
return
;
}
DebugL
<<
strHost
<<
" "
<<
m_strApp
<<
" "
<<
m
_strStream
;
DebugL
<<
strHost
<<
" "
<<
_strApp
<<
" "
<<
_strStream
;
auto
iPort
=
atoi
(
FindField
(
strHost
.
c_str
(),
":"
,
NULL
).
c_str
());
if
(
iPort
<=
0
)
{
...
...
@@ -115,7 +115,7 @@ void RtmpPusher::onConnect(const SockException &err){
return
;
}
weak_ptr
<
RtmpPusher
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPusher
>
(
shared_from_this
());
m
_pPublishTimer
.
reset
(
new
Timer
(
10
,
[
weakSelf
]()
{
_pPublishTimer
.
reset
(
new
Timer
(
10
,
[
weakSelf
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
false
;
...
...
@@ -147,10 +147,10 @@ void RtmpPusher::onRecv(const Buffer::Ptr &pBuf){
inline
void
RtmpPusher
::
send_connect
()
{
AMFValue
obj
(
AMF_OBJECT
);
obj
.
set
(
"app"
,
m
_strApp
);
obj
.
set
(
"app"
,
_strApp
);
obj
.
set
(
"type"
,
"nonprivate"
);
obj
.
set
(
"tcUrl"
,
m
_strTcUrl
);
obj
.
set
(
"swfUrl"
,
m
_strTcUrl
);
obj
.
set
(
"tcUrl"
,
_strTcUrl
);
obj
.
set
(
"swfUrl"
,
_strTcUrl
);
sendInvoke
(
"connect"
,
obj
);
addOnResultCB
([
this
](
AMFDecoder
&
dec
){
//TraceL << "connect result";
...
...
@@ -171,13 +171,13 @@ inline void RtmpPusher::send_createStream() {
addOnResultCB
([
this
](
AMFDecoder
&
dec
){
//TraceL << "createStream result";
dec
.
load
<
AMFValue
>
();
m
_ui32StreamId
=
dec
.
load
<
int
>
();
_ui32StreamId
=
dec
.
load
<
int
>
();
send_publish
();
});
}
inline
void
RtmpPusher
::
send_publish
()
{
AMFEncoder
enc
;
enc
<<
"publish"
<<
++
m_iReqID
<<
nullptr
<<
m_strStream
<<
m
_strApp
;
enc
<<
"publish"
<<
++
_iReqID
<<
nullptr
<<
_strStream
<<
_strApp
;
sendRequest
(
MSG_CMD
,
enc
.
data
());
addOnStatusCB
([
this
](
AMFValue
&
val
)
{
...
...
@@ -192,7 +192,7 @@ inline void RtmpPusher::send_publish() {
}
inline
void
RtmpPusher
::
send_metaData
(){
auto
src
=
m
_pMediaSrc
.
lock
();
auto
src
=
_pMediaSrc
.
lock
();
if
(
!
src
)
{
throw
std
::
runtime_error
(
"the media source was released"
);
}
...
...
@@ -202,19 +202,19 @@ inline void RtmpPusher::send_metaData(){
sendRequest
(
MSG_DATA
,
enc
.
data
());
src
->
getConfigFrame
([
&
](
const
RtmpPacket
::
Ptr
&
pkt
){
sendRtmp
(
pkt
->
typeId
,
m
_ui32StreamId
,
pkt
->
strBuf
,
pkt
->
timeStamp
,
pkt
->
chunkId
);
sendRtmp
(
pkt
->
typeId
,
_ui32StreamId
,
pkt
->
strBuf
,
pkt
->
timeStamp
,
pkt
->
chunkId
);
});
m
_pRtmpReader
=
src
->
getRing
()
->
attach
();
_pRtmpReader
=
src
->
getRing
()
->
attach
();
weak_ptr
<
RtmpPusher
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPusher
>
(
shared_from_this
());
m
_pRtmpReader
->
setReadCB
([
weakSelf
](
const
RtmpPacket
::
Ptr
&
pkt
){
_pRtmpReader
->
setReadCB
([
weakSelf
](
const
RtmpPacket
::
Ptr
&
pkt
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
sendRtmp
(
pkt
->
typeId
,
strongSelf
->
m
_ui32StreamId
,
pkt
->
strBuf
,
pkt
->
timeStamp
,
pkt
->
chunkId
);
strongSelf
->
sendRtmp
(
pkt
->
typeId
,
strongSelf
->
_ui32StreamId
,
pkt
->
strBuf
,
pkt
->
timeStamp
,
pkt
->
chunkId
);
});
m
_pRtmpReader
->
setDetachCB
([
weakSelf
](){
_pRtmpReader
->
setDetachCB
([
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
strongSelf
){
strongSelf
->
onShutdown
(
SockException
(
Err_other
,
"媒体源被释放"
));
...
...
@@ -228,11 +228,11 @@ inline void RtmpPusher::send_metaData(){
}
void
RtmpPusher
::
onCmd_result
(
AMFDecoder
&
dec
){
auto
iReqId
=
dec
.
load
<
int
>
();
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
auto
it
=
m
_mapOnResultCB
.
find
(
iReqId
);
if
(
it
!=
m
_mapOnResultCB
.
end
()){
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
auto
it
=
_mapOnResultCB
.
find
(
iReqId
);
if
(
it
!=
_mapOnResultCB
.
end
()){
it
->
second
(
dec
);
m
_mapOnResultCB
.
erase
(
it
);
_mapOnResultCB
.
erase
(
it
);
}
else
{
WarnL
<<
"unhandled _result"
;
}
...
...
@@ -249,10 +249,10 @@ void RtmpPusher::onCmd_onStatus(AMFDecoder &dec) {
throw
std
::
runtime_error
(
"onStatus:the result object was not found"
);
}
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
if
(
m
_dqOnStatusCB
.
size
()){
m
_dqOnStatusCB
.
front
()(
val
);
m
_dqOnStatusCB
.
pop_front
();
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
if
(
_dqOnStatusCB
.
size
()){
_dqOnStatusCB
.
front
()(
val
);
_dqOnStatusCB
.
pop_front
();
}
else
{
auto
level
=
val
[
"level"
];
auto
code
=
val
[
"code"
].
as_string
();
...
...
src/Rtmp/RtmpPusher.h
查看文件 @
39baaebc
...
...
@@ -46,11 +46,11 @@ public:
void
teardown
();
void
setOnPublished
(
Event
onPublished
)
{
m
_onPublished
=
onPublished
;
_onPublished
=
onPublished
;
}
void
setOnShutdown
(
Event
onShutdown
)
{
m
_onShutdown
=
onShutdown
;
_onShutdown
=
onShutdown
;
}
protected
:
...
...
@@ -67,28 +67,28 @@ protected:
private
:
void
init
(
const
RtmpMediaSource
::
Ptr
&
src
);
void
onShutdown
(
const
SockException
&
ex
)
{
m
_pPublishTimer
.
reset
();
if
(
m
_onShutdown
){
m
_onShutdown
(
ex
);
_pPublishTimer
.
reset
();
if
(
_onShutdown
){
_onShutdown
(
ex
);
}
m
_pRtmpReader
.
reset
();
_pRtmpReader
.
reset
();
}
void
onPublishResult
(
const
SockException
&
ex
)
{
m
_pPublishTimer
.
reset
();
if
(
m
_onPublished
){
m
_onPublished
(
ex
);
_pPublishTimer
.
reset
();
if
(
_onPublished
){
_onPublished
(
ex
);
}
}
template
<
typename
FUN
>
inline
void
addOnResultCB
(
const
FUN
&
fun
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnResultCB
);
m_mapOnResultCB
.
emplace
(
m
_iReqID
,
fun
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnResultCB
);
_mapOnResultCB
.
emplace
(
_iReqID
,
fun
);
}
template
<
typename
FUN
>
inline
void
addOnStatusCB
(
const
FUN
&
fun
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtxOnStatusCB
);
m
_dqOnStatusCB
.
emplace_back
(
fun
);
lock_guard
<
recursive_mutex
>
lck
(
_mtxOnStatusCB
);
_dqOnStatusCB
.
emplace_back
(
fun
);
}
void
onCmd_result
(
AMFDecoder
&
dec
);
...
...
@@ -100,27 +100,27 @@ private:
inline
void
send_publish
();
inline
void
send_metaData
();
string
m
_strApp
;
string
m
_strStream
;
string
m
_strTcUrl
;
string
_strApp
;
string
_strStream
;
string
_strTcUrl
;
unordered_map
<
int
,
function
<
void
(
AMFDecoder
&
dec
)
>
>
m
_mapOnResultCB
;
recursive_mutex
m
_mtxOnResultCB
;
deque
<
function
<
void
(
AMFValue
&
dec
)
>
>
m
_dqOnStatusCB
;
recursive_mutex
m
_mtxOnStatusCB
;
unordered_map
<
int
,
function
<
void
(
AMFDecoder
&
dec
)
>
>
_mapOnResultCB
;
recursive_mutex
_mtxOnResultCB
;
deque
<
function
<
void
(
AMFValue
&
dec
)
>
>
_dqOnStatusCB
;
recursive_mutex
_mtxOnStatusCB
;
typedef
void
(
RtmpPusher
::*
rtmpCMDHandle
)(
AMFDecoder
&
dec
);
static
unordered_map
<
string
,
rtmpCMDHandle
>
g_mapCmd
;
//超时功能实现
std
::
shared_ptr
<
Timer
>
m
_pPublishTimer
;
std
::
shared_ptr
<
Timer
>
_pPublishTimer
;
//源
std
::
weak_ptr
<
RtmpMediaSource
>
m
_pMediaSrc
;
RtmpMediaSource
::
RingType
::
RingReader
::
Ptr
m
_pRtmpReader
;
std
::
weak_ptr
<
RtmpMediaSource
>
_pMediaSrc
;
RtmpMediaSource
::
RingType
::
RingReader
::
Ptr
_pRtmpReader
;
//事件监听
Event
m
_onShutdown
;
Event
m
_onPublished
;
Event
_onShutdown
;
Event
_onPublished
;
};
}
/* namespace Rtmp */
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtmp/RtmpSession.h
查看文件 @
39baaebc
...
...
@@ -70,7 +70,7 @@ private:
void
onSendMedia
(
const
RtmpPacket
::
Ptr
&
pkt
);
void
onSendRawData
(
const
Buffer
::
Ptr
&
buffer
)
override
{
m
_ui64TotalBytes
+=
buffer
->
size
();
_ui64TotalBytes
+=
buffer
->
size
();
send
(
buffer
);
}
void
onRtmpChunk
(
RtmpPacket
&
chunkData
)
override
;
...
...
@@ -78,12 +78,12 @@ private:
template
<
typename
first
,
typename
second
>
inline
void
sendReply
(
const
char
*
str
,
const
first
&
reply
,
const
second
&
status
)
{
AMFEncoder
invoke
;
invoke
<<
str
<<
m
_dNowReqID
<<
reply
<<
status
;
invoke
<<
str
<<
_dNowReqID
<<
reply
<<
status
;
sendResponse
(
MSG_CMD
,
invoke
.
data
());
}
bool
shutDown
()
override
{
InfoL
<<
"kick out:"
<<
m_mediaInfo
.
m_vhost
<<
" "
<<
m_mediaInfo
.
m_app
<<
" "
<<
m_mediaInfo
.
m
_streamid
;
InfoL
<<
"kick out:"
<<
_mediaInfo
.
_vhost
<<
" "
<<
_mediaInfo
.
_app
<<
" "
<<
_mediaInfo
.
_streamid
;
safeShutdown
();
return
true
;
}
...
...
@@ -91,19 +91,19 @@ private:
void
doDelay
(
int
delaySec
,
const
std
::
function
<
void
()
>
&
fun
);
void
cancelDelyaTask
();
private
:
std
::
string
m
_strTcUrl
;
MediaInfo
m
_mediaInfo
;
double
m
_dNowReqID
=
0
;
Ticker
m
_ticker
;
//数据接收时间
SmoothTicker
m
_stampTicker
[
2
];
//时间戳生产器
RingBuffer
<
RtmpPacket
::
Ptr
>::
RingReader
::
Ptr
m
_pRingReader
;
std
::
shared_ptr
<
RtmpMediaSource
>
m
_pPublisherSrc
;
std
::
weak_ptr
<
RtmpMediaSource
>
m
_pPlayerSrc
;
uint32_t
m
_aui32FirstStamp
[
2
]
=
{
0
};
std
::
string
_strTcUrl
;
MediaInfo
_mediaInfo
;
double
_dNowReqID
=
0
;
Ticker
_ticker
;
//数据接收时间
SmoothTicker
_stampTicker
[
2
];
//时间戳生产器
RingBuffer
<
RtmpPacket
::
Ptr
>::
RingReader
::
Ptr
_pRingReader
;
std
::
shared_ptr
<
RtmpMediaSource
>
_pPublisherSrc
;
std
::
weak_ptr
<
RtmpMediaSource
>
_pPlayerSrc
;
uint32_t
_aui32FirstStamp
[
2
]
=
{
0
};
//消耗的总流量
uint64_t
m
_ui64TotalBytes
=
0
;
std
::
function
<
void
()
>
m
_delayTask
;
uint32_t
m
_iTaskTimeLine
=
0
;
uint64_t
_ui64TotalBytes
=
0
;
std
::
function
<
void
()
>
_delayTask
;
uint32_t
_iTaskTimeLine
=
0
;
};
...
...
src/Rtmp/RtmpToRtspMediaSource.cpp
查看文件 @
39baaebc
...
...
@@ -41,27 +41,27 @@ RtmpToRtspMediaSource::RtmpToRtspMediaSource(const string &vhost,
const
string
&
id
,
bool
bEnableHls
,
bool
bEnableMp4
)
:
RtmpMediaSource
(
vhost
,
app
,
id
),
m_bEnableHls
(
bEnableHls
),
m
_bEnableMp4
(
bEnableMp4
)
{
RtmpMediaSource
(
vhost
,
app
,
id
),
_bEnableHls
(
bEnableHls
),
_bEnableMp4
(
bEnableMp4
)
{
}
RtmpToRtspMediaSource
::~
RtmpToRtspMediaSource
()
{}
void
RtmpToRtspMediaSource
::
onGetH264
(
const
H264Frame
&
frame
)
{
if
(
m
_pRecorder
){
m
_pRecorder
->
inputH264
((
char
*
)
frame
.
data
(),
frame
.
size
(),
frame
.
timeStamp
,
frame
.
type
);
if
(
_pRecorder
){
_pRecorder
->
inputH264
((
char
*
)
frame
.
data
(),
frame
.
size
(),
frame
.
timeStamp
,
frame
.
type
);
}
if
(
m
_pRtpMaker_h264
){
m
_pRtpMaker_h264
->
makeRtp
(
frame
.
data
()
+
4
,
frame
.
size
()
-
4
,
frame
.
timeStamp
);
if
(
_pRtpMaker_h264
){
_pRtpMaker_h264
->
makeRtp
(
frame
.
data
()
+
4
,
frame
.
size
()
-
4
,
frame
.
timeStamp
);
}
}
inline
void
RtmpToRtspMediaSource
::
onGetAAC
(
const
AACFrame
&
frame
)
{
if
(
m
_pRecorder
){
m
_pRecorder
->
inputAAC
((
char
*
)
frame
.
buffer
,
frame
.
aac_frame_length
,
frame
.
timeStamp
);
if
(
_pRecorder
){
_pRecorder
->
inputAAC
((
char
*
)
frame
.
buffer
,
frame
.
aac_frame_length
,
frame
.
timeStamp
);
}
if
(
m
_pRtpMaker_aac
)
{
m
_pRtpMaker_aac
->
makeRtp
((
char
*
)
frame
.
buffer
+
7
,
frame
.
aac_frame_length
-
7
,
frame
.
timeStamp
);
if
(
_pRtpMaker_aac
)
{
_pRtpMaker_aac
->
makeRtp
((
char
*
)
frame
.
buffer
+
7
,
frame
.
aac_frame_length
-
7
,
frame
.
timeStamp
);
}
}
...
...
@@ -73,40 +73,40 @@ void RtmpToRtspMediaSource::makeSDP() {
strSDP
+=
"i=ZL Live Stream
\r\n
"
;
strSDP
+=
"c=IN IP4 0.0.0.0
\r\n
"
;
strSDP
+=
"t=0 0
\r\n
"
;
if
(
m
_pParser
->
getDuration
()
<=
0
){
if
(
_pParser
->
getDuration
()
<=
0
){
strSDP
+=
"a=range:npt=0-
\r\n
"
;
}
else
{
strSDP
+=
StrPrinter
<<
"0-"
<<
m
_pParser
->
getDuration
()
<<
"
\r\n
"
<<
endl
;
strSDP
+=
StrPrinter
<<
"0-"
<<
_pParser
->
getDuration
()
<<
"
\r\n
"
<<
endl
;
}
strSDP
+=
"a=control:*
\r\n
"
;
//todo(xzl) 修复此处
// if (
m
_pParser->containVideo()) {
// if (_pParser->containVideo()) {
// uint32_t ssrc0;
// memcpy(&ssrc0, makeRandStr(4, false).data(), 4);
// auto lam = [this](const RtpPacket::Ptr &pkt, bool bKeyPos) {
//
m
_pRtspSrc->onGetRTP(pkt,bKeyPos);
// _pRtspSrc->onGetRTP(pkt,bKeyPos);
// };
//
// GET_CONFIG_AND_REGISTER(uint32_t,videoMtu,Config::Rtp::kVideoMtuSize);
//
m
_pRtpMaker_h264.reset(new RtpMaker_H264(lam, ssrc0,videoMtu));
// _pRtpMaker_h264.reset(new RtpMaker_H264(lam, ssrc0,videoMtu));
//
// char strTemp[100];
// int profile_level_id = 0;
// string strSPS =
m
_pParser->getSps().substr(4);
// string strPPS =
m
_pParser->getPps().substr(4);
// string strSPS =_pParser->getSps().substr(4);
// string strPPS =_pParser->getPps().substr(4);
// if (strSPS.length() >= 4) { // sanity check
// profile_level_id = (strSPS[1] << 16) | (strSPS[2] << 8) | strSPS[3]; // profile_idc|constraint_setN_flag|level_idc
// }
//
// //视频通道
// strSDP += StrPrinter << "m=video 0 RTP/AVP " <<
m
_pRtpMaker_h264->getPlayloadType()
// strSDP += StrPrinter << "m=video 0 RTP/AVP " << _pRtpMaker_h264->getPlayloadType()
// << "\r\n" << endl;
// strSDP += "b=AS:5100\r\n";
// strSDP += StrPrinter << "a=rtpmap:" <<
m
_pRtpMaker_h264->getPlayloadType()
// << " H264/" <<
m
_pRtpMaker_h264->getSampleRate() << "\r\n" << endl;
// strSDP += StrPrinter << "a=fmtp:" <<
m
_pRtpMaker_h264->getPlayloadType()
// strSDP += StrPrinter << "a=rtpmap:" << _pRtpMaker_h264->getPlayloadType()
// << " H264/" << _pRtpMaker_h264->getSampleRate() << "\r\n" << endl;
// strSDP += StrPrinter << "a=fmtp:" << _pRtpMaker_h264->getPlayloadType()
// << " packetization-mode=1;profile-level-id=" << endl;
//
// memset(strTemp, 0, 100);
...
...
@@ -121,41 +121,41 @@ void RtmpToRtspMediaSource::makeSDP() {
// av_base64_encode(strTemp, 100, (uint8_t *) strPPS.data(), strPPS.size());
// strSDP += strTemp;
// strSDP += "\r\n";
// strSDP += StrPrinter << "a=control:trackID=" <<
m
_pRtpMaker_h264->getInterleaved() / 2
// strSDP += StrPrinter << "a=control:trackID=" << _pRtpMaker_h264->getInterleaved() / 2
// << "\r\n" << endl;
// }
//
// if (
m
_pParser->containAudio()) {
// if (_pParser->containAudio()) {
// uint32_t ssrc1;
// memcpy(&ssrc1, makeRandStr(8, false).data() + 4, 4);
// auto lam = [this](const RtpPacket::Ptr &pkt, bool bKeyPos) {
//
m
_pRtspSrc->onGetRTP(pkt,bKeyPos);
// _pRtspSrc->onGetRTP(pkt,bKeyPos);
// };
// GET_CONFIG_AND_REGISTER(uint32_t,audioMtu,Config::Rtp::kAudioMtuSize);
//
m_pRtpMaker_aac.reset(new RtpMaker_AAC(lam, ssrc1, audioMtu,m
_pParser->getAudioSampleRate()));
//
_pRtpMaker_aac.reset(new RtpMaker_AAC(lam, ssrc1, audioMtu,
_pParser->getAudioSampleRate()));
//
// char configStr[32];
// const string & strAacCfg =
m
_pParser->getAudioCfg();
// const string & strAacCfg = _pParser->getAudioCfg();
// snprintf(configStr, sizeof(configStr), "%02X%02x", strAacCfg[0], strAacCfg[1]);
// strSDP += StrPrinter << "m=audio 0 RTP/AVP " <<
m
_pRtpMaker_aac->getPlayloadType()
// strSDP += StrPrinter << "m=audio 0 RTP/AVP " << _pRtpMaker_aac->getPlayloadType()
// << "\r\n" << endl;
// strSDP += "b=AS:96\r\n";
// strSDP += StrPrinter << "a=rtpmap:" <<
m
_pRtpMaker_aac->getPlayloadType()
// << " MPEG4-GENERIC/" <<
m
_pRtpMaker_aac->getSampleRate() << "\r\n"
// strSDP += StrPrinter << "a=rtpmap:" << _pRtpMaker_aac->getPlayloadType()
// << " MPEG4-GENERIC/" << _pRtpMaker_aac->getSampleRate() << "\r\n"
// << endl;
// strSDP += StrPrinter << "a=fmtp:" <<
m
_pRtpMaker_aac->getPlayloadType()
// strSDP += StrPrinter << "a=fmtp:" << _pRtpMaker_aac->getPlayloadType()
// << " streamtype=5;profile-level-id=1;mode=AAC-hbr;"
// << "sizelength=13;indexlength=3;indexdeltalength=3;config="
// << endl;
// strSDP.append(configStr, 4);
// strSDP += "\r\n";
// strSDP += StrPrinter << "a=control:trackID=" <<
m
_pRtpMaker_aac->getInterleaved() / 2
// strSDP += StrPrinter << "a=control:trackID=" << _pRtpMaker_aac->getInterleaved() / 2
// << "\r\n" << endl;
// }
m
_pRtspSrc
.
reset
(
new
RtspMediaSource
(
getVhost
(),
getApp
(),
getId
()));
m_pRtspSrc
->
setListener
(
m
_listener
);
m
_pRtspSrc
->
onGetSDP
(
strSDP
);
_pRtspSrc
.
reset
(
new
RtspMediaSource
(
getVhost
(),
getApp
(),
getId
()));
_pRtspSrc
->
setListener
(
_listener
);
_pRtspSrc
->
onGetSDP
(
strSDP
);
}
...
...
src/Rtmp/RtmpToRtspMediaSource.h
查看文件 @
39baaebc
...
...
@@ -65,12 +65,12 @@ public:
void
onGetMetaData
(
const
AMFValue
&
_metadata
)
override
{
try
{
m
_pParser
.
reset
(
new
RtmpParser
(
_metadata
));
m_pRecorder
.
reset
(
new
MediaRecorder
(
getVhost
(),
getApp
(),
getId
(),
m_pParser
,
m_bEnableHls
,
m
_bEnableMp4
));
_pParser
.
reset
(
new
RtmpParser
(
_metadata
));
_pRecorder
.
reset
(
new
MediaRecorder
(
getVhost
(),
getApp
(),
getId
(),
_pParser
,
_bEnableHls
,
_bEnableMp4
));
//todo(xzl) 修复此处
//
m
_pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1));
//
m
_pParser->setOnVideoCB(std::bind(&RtmpToRtspMediaSource::onGetH264, this, placeholders::_1));
// _pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAAC, this, placeholders::_1));
// _pParser->setOnVideoCB(std::bind(&RtmpToRtspMediaSource::onGetH264, this, placeholders::_1));
}
catch
(
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
}
...
...
@@ -78,23 +78,23 @@ public:
}
void
onGetMedia
(
const
RtmpPacket
::
Ptr
&
pkt
)
override
{
if
(
m
_pParser
)
{
if
(
!
m_pRtspSrc
&&
m
_pParser
->
isInited
())
{
if
(
_pParser
)
{
if
(
!
_pRtspSrc
&&
_pParser
->
isInited
())
{
makeSDP
();
}
m
_pParser
->
inputRtmp
(
pkt
);
_pParser
->
inputRtmp
(
pkt
);
}
RtmpMediaSource
::
onGetMedia
(
pkt
);
}
private
:
RtmpParser
::
Ptr
m
_pParser
;
RtspMediaSource
::
Ptr
m
_pRtspSrc
;
RtpMaker_AAC
::
Ptr
m
_pRtpMaker_aac
;
RtpMaker_H264
::
Ptr
m
_pRtpMaker_h264
;
MediaRecorder
::
Ptr
m
_pRecorder
;
bool
m
_bEnableHls
;
bool
m
_bEnableMp4
;
RtmpParser
::
Ptr
_pParser
;
RtspMediaSource
::
Ptr
_pRtspSrc
;
RtpMaker_AAC
::
Ptr
_pRtpMaker_aac
;
RtpMaker_H264
::
Ptr
_pRtpMaker_h264
;
MediaRecorder
::
Ptr
_pRecorder
;
bool
_bEnableHls
;
bool
_bEnableMp4
;
void
onGetH264
(
const
H264Frame
&
frame
);
void
onGetAAC
(
const
AACFrame
&
frame
);
void
makeSDP
();
...
...
src/Rtmp/amf.cpp
查看文件 @
39baaebc
...
...
@@ -36,24 +36,24 @@ using namespace ZL::Network;
/////////////////////AMFValue/////////////////////////////
inline
void
AMFValue
::
destroy
()
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_STRING
:
if
(
m
_value
.
string
)
{
delete
m
_value
.
string
;
m
_value
.
string
=
nullptr
;
if
(
_value
.
string
)
{
delete
_value
.
string
;
_value
.
string
=
nullptr
;
}
break
;
case
AMF_OBJECT
:
case
AMF_ECMA_ARRAY
:
if
(
m
_value
.
object
)
{
delete
m
_value
.
object
;
m
_value
.
object
=
nullptr
;
if
(
_value
.
object
)
{
delete
_value
.
object
;
_value
.
object
=
nullptr
;
}
break
;
case
AMF_STRICT_ARRAY
:
if
(
m
_value
.
array
)
{
delete
m
_value
.
array
;
m
_value
.
array
=
nullptr
;
if
(
_value
.
array
)
{
delete
_value
.
array
;
_value
.
array
=
nullptr
;
}
break
;
default
:
...
...
@@ -61,16 +61,16 @@ inline void AMFValue::destroy() {
}
}
inline
void
AMFValue
::
init
()
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_OBJECT
:
case
AMF_ECMA_ARRAY
:
m
_value
.
object
=
new
mapType
;
_value
.
object
=
new
mapType
;
break
;
case
AMF_STRING
:
m
_value
.
string
=
new
std
::
string
;
_value
.
string
=
new
std
::
string
;
break
;
case
AMF_STRICT_ARRAY
:
m
_value
.
array
=
new
arrayType
;
_value
.
array
=
new
arrayType
;
break
;
default
:
...
...
@@ -79,7 +79,7 @@ inline void AMFValue::init() {
}
AMFValue
::
AMFValue
(
AMFType
type
)
:
m
_type
(
type
)
{
_type
(
type
)
{
init
();
}
...
...
@@ -89,38 +89,38 @@ AMFValue::~AMFValue() {
}
AMFValue
::
AMFValue
(
const
char
*
s
)
:
m
_type
(
AMF_STRING
)
{
_type
(
AMF_STRING
)
{
init
();
*
m
_value
.
string
=
s
;
*
_value
.
string
=
s
;
}
AMFValue
::
AMFValue
(
const
std
::
string
&
s
)
:
m
_type
(
AMF_STRING
)
{
_type
(
AMF_STRING
)
{
init
();
*
m
_value
.
string
=
s
;
*
_value
.
string
=
s
;
}
AMFValue
::
AMFValue
(
double
n
)
:
m
_type
(
AMF_NUMBER
)
{
_type
(
AMF_NUMBER
)
{
init
();
m
_value
.
number
=
n
;
_value
.
number
=
n
;
}
AMFValue
::
AMFValue
(
int
i
)
:
m
_type
(
AMF_INTEGER
)
{
_type
(
AMF_INTEGER
)
{
init
();
m
_value
.
integer
=
i
;
_value
.
integer
=
i
;
}
AMFValue
::
AMFValue
(
bool
b
)
:
m
_type
(
AMF_BOOLEAN
)
{
_type
(
AMF_BOOLEAN
)
{
init
();
m
_value
.
boolean
=
b
;
_value
.
boolean
=
b
;
}
AMFValue
::
AMFValue
(
const
AMFValue
&
from
)
:
m
_type
(
AMF_NULL
)
{
_type
(
AMF_NULL
)
{
*
this
=
from
;
}
...
...
@@ -134,27 +134,27 @@ AMFValue& AMFValue::operator =(const AMFValue &from) {
}
AMFValue
&
AMFValue
::
operator
=
(
AMFValue
&&
from
)
{
destroy
();
m_type
=
from
.
m
_type
;
_type
=
from
.
_type
;
init
();
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_STRING
:
*
m_value
.
string
=
(
*
from
.
m
_value
.
string
);
*
_value
.
string
=
(
*
from
.
_value
.
string
);
break
;
case
AMF_OBJECT
:
case
AMF_ECMA_ARRAY
:
*
m_value
.
object
=
(
*
from
.
m
_value
.
object
);
*
_value
.
object
=
(
*
from
.
_value
.
object
);
break
;
case
AMF_STRICT_ARRAY
:
*
m_value
.
array
=
(
*
from
.
m
_value
.
array
);
*
_value
.
array
=
(
*
from
.
_value
.
array
);
break
;
case
AMF_NUMBER
:
m_value
.
number
=
from
.
m
_value
.
number
;
_value
.
number
=
from
.
_value
.
number
;
break
;
case
AMF_INTEGER
:
m_value
.
integer
=
from
.
m
_value
.
integer
;
_value
.
integer
=
from
.
_value
.
integer
;
break
;
case
AMF_BOOLEAN
:
m_value
.
boolean
=
from
.
m
_value
.
boolean
;
_value
.
boolean
=
from
.
_value
.
boolean
;
break
;
default
:
break
;
...
...
src/Rtmp/amf.h
查看文件 @
39baaebc
...
...
@@ -61,13 +61,13 @@ public:
~
AMFValue
();
void
clear
()
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_STRING
:
m
_value
.
string
->
clear
();
_value
.
string
->
clear
();
break
;
case
AMF_OBJECT
:
case
AMF_ECMA_ARRAY
:
m
_value
.
object
->
clear
();
_value
.
object
->
clear
();
break
;
default:
break
;
...
...
@@ -75,23 +75,23 @@ public:
}
AMFType
type
()
const
{
return
m
_type
;
return
_type
;
}
const
std
::
string
&
as_string
()
const
{
if
(
m
_type
!=
AMF_STRING
){
if
(
_type
!=
AMF_STRING
){
throw
std
::
runtime_error
(
"AMF not a string"
);
}
return
*
m
_value
.
string
;
return
*
_value
.
string
;
}
double
as_number
()
const
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_NUMBER
:
return
m
_value
.
number
;
return
_value
.
number
;
case
AMF_INTEGER
:
return
m
_value
.
integer
;
return
_value
.
integer
;
case
AMF_BOOLEAN
:
return
m
_value
.
boolean
;
return
_value
.
boolean
;
break
;
default
:
throw
std
::
runtime_error
(
"AMF not a number"
);
...
...
@@ -99,13 +99,13 @@ public:
}
}
int
as_integer
()
const
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_NUMBER
:
return
m
_value
.
number
;
return
_value
.
number
;
case
AMF_INTEGER
:
return
m
_value
.
integer
;
return
_value
.
integer
;
case
AMF_BOOLEAN
:
return
m
_value
.
boolean
;
return
_value
.
boolean
;
break
;
default
:
throw
std
::
runtime_error
(
"AMF not a integer"
);
...
...
@@ -113,13 +113,13 @@ public:
}
}
bool
as_boolean
()
const
{
switch
(
m
_type
)
{
switch
(
_type
)
{
case
AMF_NUMBER
:
return
m
_value
.
number
;
return
_value
.
number
;
case
AMF_INTEGER
:
return
m
_value
.
integer
;
return
_value
.
integer
;
case
AMF_BOOLEAN
:
return
m
_value
.
boolean
;
return
_value
.
boolean
;
break
;
default
:
throw
std
::
runtime_error
(
"AMF not a boolean"
);
...
...
@@ -128,11 +128,11 @@ public:
}
const
AMFValue
&
operator
[](
const
char
*
str
)
const
{
if
(
m_type
!=
AMF_OBJECT
&&
m
_type
!=
AMF_ECMA_ARRAY
)
{
if
(
_type
!=
AMF_OBJECT
&&
_type
!=
AMF_ECMA_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a object"
);
}
auto
i
=
m
_value
.
object
->
find
(
str
);
if
(
i
==
m
_value
.
object
->
end
())
{
auto
i
=
_value
.
object
->
find
(
str
);
if
(
i
==
_value
.
object
->
end
())
{
static
AMFValue
val
(
AMF_NULL
);
return
val
;
}
...
...
@@ -140,36 +140,36 @@ public:
}
template
<
typename
FUN
>
void
object_for_each
(
const
FUN
&
fun
)
const
{
if
(
m_type
!=
AMF_OBJECT
&&
m
_type
!=
AMF_ECMA_ARRAY
)
{
if
(
_type
!=
AMF_OBJECT
&&
_type
!=
AMF_ECMA_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a object"
);
}
for
(
auto
&
pr
:
*
(
m
_value
.
object
))
{
for
(
auto
&
pr
:
*
(
_value
.
object
))
{
fun
(
pr
.
first
,
pr
.
second
);
}
}
operator
bool
()
const
{
return
m
_type
!=
AMF_NULL
;
return
_type
!=
AMF_NULL
;
}
void
set
(
const
std
::
string
&
s
,
const
AMFValue
&
val
)
{
if
(
m_type
!=
AMF_OBJECT
&&
m
_type
!=
AMF_ECMA_ARRAY
)
{
if
(
_type
!=
AMF_OBJECT
&&
_type
!=
AMF_ECMA_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a object"
);
}
m
_value
.
object
->
emplace
(
s
,
val
);
_value
.
object
->
emplace
(
s
,
val
);
}
void
add
(
const
AMFValue
&
val
)
{
if
(
m
_type
!=
AMF_STRICT_ARRAY
)
{
if
(
_type
!=
AMF_STRICT_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a array"
);
}
assert
(
m
_type
==
AMF_STRICT_ARRAY
);
m
_value
.
array
->
push_back
(
val
);
assert
(
_type
==
AMF_STRICT_ARRAY
);
_value
.
array
->
push_back
(
val
);
}
private
:
typedef
std
::
map
<
std
::
string
,
AMFValue
>
mapType
;
typedef
std
::
vector
<
AMFValue
>
arrayType
;
AMFType
m
_type
;
AMFType
_type
;
union
{
std
::
string
*
string
;
double
number
;
...
...
@@ -177,20 +177,20 @@ private:
bool
boolean
;
mapType
*
object
;
arrayType
*
array
;
}
m
_value
;
}
_value
;
friend
class
AMFEncoder
;
const
mapType
&
getMap
()
const
{
if
(
m_type
!=
AMF_OBJECT
&&
m
_type
!=
AMF_ECMA_ARRAY
)
{
if
(
_type
!=
AMF_OBJECT
&&
_type
!=
AMF_ECMA_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a object"
);
}
return
*
m
_value
.
object
;
return
*
_value
.
object
;
}
const
arrayType
&
getArr
()
const
{
if
(
m
_type
!=
AMF_STRICT_ARRAY
)
{
if
(
_type
!=
AMF_STRICT_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a array"
);
}
return
*
m
_value
.
array
;
return
*
_value
.
array
;
}
inline
void
destroy
();
inline
void
init
();
...
...
src/RtmpCodec/AACRtmpCodec.cpp
查看文件 @
39baaebc
...
...
@@ -67,7 +67,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
RtmpPacket
::
Ptr
rtmpPkt
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
//////////header
uint8_t
is_config
=
false
;
rtmpPkt
->
strBuf
.
push_back
(
m
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
rtmpPkt
->
strBuf
.
append
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
());
...
...
@@ -108,12 +108,12 @@ void AACRtmpEncoder::makeAudioConfigPkt() {
uint8_t
flvSampleBit
=
iSampleBit
==
16
;
uint8_t
flvAudioType
=
10
;
//aac
m
_ui8AudioFlags
=
(
flvAudioType
<<
4
)
|
(
flvSampleRate
<<
2
)
|
(
flvSampleBit
<<
1
)
|
flvStereoOrMono
;
_ui8AudioFlags
=
(
flvAudioType
<<
4
)
|
(
flvSampleRate
<<
2
)
|
(
flvSampleBit
<<
1
)
|
flvStereoOrMono
;
RtmpPacket
::
Ptr
rtmpPkt
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
//////////header
uint8_t
is_config
=
true
;
rtmpPkt
->
strBuf
.
push_back
(
m
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
rtmpPkt
->
strBuf
.
append
(
_aac_cfg
);
...
...
src/RtmpCodec/AACRtmpCodec.h
查看文件 @
39baaebc
...
...
@@ -61,7 +61,7 @@ public:
private
:
void
makeAudioConfigPkt
();
uint8_t
m
_ui8AudioFlags
;
uint8_t
_ui8AudioFlags
;
};
}
//namespace Rtmp
...
...
src/RtmpCodec/H264RtmpCodec.cpp
查看文件 @
39baaebc
...
...
@@ -6,7 +6,7 @@
H264RtmpDecoder
::
H264RtmpDecoder
()
{
m
_h264frame
=
obtainFrame
();
_h264frame
=
obtainFrame
();
}
H264Frame
::
Ptr
H264RtmpDecoder
::
obtainFrame
()
{
...
...
@@ -26,12 +26,12 @@ bool H264RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &rtmp, bool key_pos) {
bool
H264RtmpDecoder
::
decodeRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
if
(
pkt
->
isCfgFrame
())
{
//缓存sps pps,后续插入到I帧之前
m
_sps
=
pkt
->
getH264SPS
();
m
_pps
=
pkt
->
getH264PPS
();
_sps
=
pkt
->
getH264SPS
();
_pps
=
pkt
->
getH264PPS
();
return
false
;
}
if
(
m
_sps
.
size
())
{
if
(
_sps
.
size
())
{
uint32_t
iTotalLen
=
pkt
->
strBuf
.
size
();
uint32_t
iOffset
=
5
;
while
(
iOffset
+
4
<
iTotalLen
){
...
...
@@ -54,8 +54,8 @@ inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t
switch
(
pcData
[
0
]
&
0x1F
)
{
case
5
:
{
//I frame
onGetH264
(
m_sps
.
data
(),
m
_sps
.
length
(),
ui32TimeStamp
);
onGetH264
(
m_pps
.
data
(),
m
_pps
.
length
(),
ui32TimeStamp
);
onGetH264
(
_sps
.
data
(),
_sps
.
length
(),
ui32TimeStamp
);
onGetH264
(
_pps
.
data
(),
_pps
.
length
(),
ui32TimeStamp
);
}
case
1
:
{
//I or P or B frame
...
...
@@ -68,14 +68,14 @@ inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t
}
}
inline
void
H264RtmpDecoder
::
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
)
{
m
_h264frame
->
type
=
pcData
[
0
]
&
0x1F
;
m
_h264frame
->
timeStamp
=
ui32TimeStamp
;
m
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
m
_h264frame
->
buffer
.
append
(
pcData
,
iLen
);
_h264frame
->
type
=
pcData
[
0
]
&
0x1F
;
_h264frame
->
timeStamp
=
ui32TimeStamp
;
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
->
buffer
.
append
(
pcData
,
iLen
);
//写入环形缓存
RtmpCodec
::
inputFrame
(
m
_h264frame
);
m
_h264frame
=
obtainFrame
();
RtmpCodec
::
inputFrame
(
_h264frame
);
_h264frame
=
obtainFrame
();
}
...
...
@@ -95,9 +95,9 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
switch
(
type
){
case
7
:{
//sps
if
(
m
_sps
.
empty
()){
m
_sps
=
string
(
pcData
,
iLen
);
if
(
!
m
_pps
.
empty
()){
if
(
_sps
.
empty
()){
_sps
=
string
(
pcData
,
iLen
);
if
(
!
_pps
.
empty
()){
makeVideoConfigPkt
();
}
}
...
...
@@ -105,9 +105,9 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
break
;
case
8
:{
//pps
if
(
m
_pps
.
empty
()){
m
_pps
=
string
(
pcData
,
iLen
);
if
(
!
m
_sps
.
empty
()){
if
(
_pps
.
empty
()){
_pps
=
string
(
pcData
,
iLen
);
if
(
!
_sps
.
empty
()){
makeVideoConfigPkt
();
}
}
...
...
@@ -158,23 +158,23 @@ void H264RtmpEncoder::makeVideoConfigPkt() {
////////////sps
rtmpPkt
->
strBuf
.
push_back
(
1
);
// version
//DebugL<<hexdump(
m_sps.data(), m
_sps.size());
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
1
]);
// profile
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
2
]);
// compat
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
3
]);
// level
//DebugL<<hexdump(
_sps.data(),
_sps.size());
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
1
]);
// profile
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
2
]);
// compat
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
3
]);
// level
rtmpPkt
->
strBuf
.
push_back
(
0xff
);
// 6 bits reserved + 2 bits nal size length - 1 (11)
rtmpPkt
->
strBuf
.
push_back
(
0xe1
);
// 3 bits reserved + 5 bits number of sps (00001)
uint16_t
size
=
m
_sps
.
size
();
uint16_t
size
=
_sps
.
size
();
size
=
htons
(
size
);
rtmpPkt
->
strBuf
.
append
((
char
*
)
&
size
,
2
);
rtmpPkt
->
strBuf
.
append
(
m
_sps
);
rtmpPkt
->
strBuf
.
append
(
_sps
);
/////////////pps
rtmpPkt
->
strBuf
.
push_back
(
1
);
// version
size
=
m
_pps
.
size
();
size
=
_pps
.
size
();
size
=
htons
(
size
);
rtmpPkt
->
strBuf
.
append
((
char
*
)
&
size
,
2
);
rtmpPkt
->
strBuf
.
append
(
m
_pps
);
rtmpPkt
->
strBuf
.
append
(
_pps
);
rtmpPkt
->
bodySize
=
rtmpPkt
->
strBuf
.
size
();
rtmpPkt
->
chunkId
=
CHUNK_VIDEO
;
...
...
src/RtmpCodec/H264RtmpCodec.h
查看文件 @
39baaebc
...
...
@@ -40,9 +40,9 @@ protected:
void
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
ui32TimeStamp
);
H264Frame
::
Ptr
obtainFrame
();
protected
:
H264Frame
::
Ptr
m
_h264frame
;
string
m
_sps
;
string
m
_pps
;
H264Frame
::
Ptr
_h264frame
;
string
_sps
;
string
_pps
;
};
/**
...
...
src/Rtsp/RtpBroadCaster.cpp
查看文件 @
39baaebc
...
...
@@ -50,17 +50,17 @@ static uint32_t addressToInt(const string &ip){
}
std
::
shared_ptr
<
uint32_t
>
MultiCastAddressMaker
::
obtain
(
uint32_t
iTry
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
GET_CONFIG_AND_REGISTER
(
string
,
addrMinStr
,
Config
::
MultiCast
::
kAddrMin
);
GET_CONFIG_AND_REGISTER
(
string
,
addrMaxStr
,
Config
::
MultiCast
::
kAddrMax
);
uint32_t
addrMin
=
addressToInt
(
addrMinStr
);
uint32_t
addrMax
=
addressToInt
(
addrMaxStr
);
if
(
m_iAddr
>
addrMax
||
m
_iAddr
==
0
){
m
_iAddr
=
addrMin
;
if
(
_iAddr
>
addrMax
||
_iAddr
==
0
){
_iAddr
=
addrMin
;
}
auto
iGotAddr
=
m
_iAddr
++
;
if
(
m_setBadAddr
.
find
(
iGotAddr
)
!=
m
_setBadAddr
.
end
()){
auto
iGotAddr
=
_iAddr
++
;
if
(
_setBadAddr
.
find
(
iGotAddr
)
!=
_setBadAddr
.
end
()){
//已经分配过了
if
(
iTry
){
return
obtain
(
--
iTry
);
...
...
@@ -69,7 +69,7 @@ std::shared_ptr<uint32_t> MultiCastAddressMaker::obtain(uint32_t iTry) {
ErrorL
;
return
nullptr
;
}
m
_setBadAddr
.
emplace
(
iGotAddr
);
_setBadAddr
.
emplace
(
iGotAddr
);
std
::
shared_ptr
<
uint32_t
>
ret
(
new
uint32_t
(
iGotAddr
),[](
uint32_t
*
ptr
){
MultiCastAddressMaker
::
Instance
().
release
(
*
ptr
);
delete
ptr
;
...
...
@@ -77,8 +77,8 @@ std::shared_ptr<uint32_t> MultiCastAddressMaker::obtain(uint32_t iTry) {
return
ret
;
}
void
MultiCastAddressMaker
::
release
(
uint32_t
iAddr
){
lock_guard
<
recursive_mutex
>
lck
(
m
_mtx
);
m
_setBadAddr
.
erase
(
iAddr
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
_setBadAddr
.
erase
(
iAddr
);
}
...
...
@@ -86,16 +86,16 @@ recursive_mutex RtpBroadCaster::g_mtx;
unordered_map
<
string
,
weak_ptr
<
RtpBroadCaster
>
>
RtpBroadCaster
::
g_mapBroadCaster
;
void
RtpBroadCaster
::
setDetachCB
(
void
*
listener
,
const
onDetach
&
cb
)
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
if
(
cb
){
m
_mapDetach
.
emplace
(
listener
,
cb
);
_mapDetach
.
emplace
(
listener
,
cb
);
}
else
{
m
_mapDetach
.
erase
(
listener
);
_mapDetach
.
erase
(
listener
);
}
}
RtpBroadCaster
::~
RtpBroadCaster
()
{
m
_pReader
->
setReadCB
(
nullptr
);
m
_pReader
->
setDetachCB
(
nullptr
);
_pReader
->
setReadCB
(
nullptr
);
_pReader
->
setDetachCB
(
nullptr
);
DebugL
;
}
RtpBroadCaster
::
RtpBroadCaster
(
const
string
&
strLocalIp
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strStream
)
{
...
...
@@ -104,55 +104,55 @@ RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strVhost,c
auto
strErr
=
StrPrinter
<<
"未找到媒体源:"
<<
strVhost
<<
" "
<<
strApp
<<
" "
<<
strStream
<<
endl
;
throw
std
::
runtime_error
(
strErr
);
}
m
_multiAddr
=
MultiCastAddressMaker
::
Instance
().
obtain
();
_multiAddr
=
MultiCastAddressMaker
::
Instance
().
obtain
();
for
(
auto
i
=
0
;
i
<
2
;
i
++
){
m
_apUdpSock
[
i
].
reset
(
new
Socket
());
if
(
!
m
_apUdpSock
[
i
]
->
bindUdpSock
(
0
,
strLocalIp
.
data
())){
_apUdpSock
[
i
].
reset
(
new
Socket
());
if
(
!
_apUdpSock
[
i
]
->
bindUdpSock
(
0
,
strLocalIp
.
data
())){
auto
strErr
=
StrPrinter
<<
"绑定UDP端口失败:"
<<
strLocalIp
<<
endl
;
throw
std
::
runtime_error
(
strErr
);
}
auto
fd
=
m
_apUdpSock
[
i
]
->
rawFD
();
auto
fd
=
_apUdpSock
[
i
]
->
rawFD
();
GET_CONFIG_AND_REGISTER
(
uint32_t
,
udpTTL
,
Config
::
MultiCast
::
kUdpTTL
);
SockUtil
::
setMultiTTL
(
fd
,
udpTTL
);
SockUtil
::
setMultiLOOP
(
fd
,
false
);
SockUtil
::
setMultiIF
(
fd
,
strLocalIp
.
data
());
struct
sockaddr_in
&
peerAddr
=
m
_aPeerUdpAddr
[
i
];
struct
sockaddr_in
&
peerAddr
=
_aPeerUdpAddr
[
i
];
peerAddr
.
sin_family
=
AF_INET
;
peerAddr
.
sin_port
=
htons
(
m
_apUdpSock
[
i
]
->
get_local_port
());
peerAddr
.
sin_addr
.
s_addr
=
htonl
(
*
m
_multiAddr
);
peerAddr
.
sin_port
=
htons
(
_apUdpSock
[
i
]
->
get_local_port
());
peerAddr
.
sin_addr
.
s_addr
=
htonl
(
*
_multiAddr
);
bzero
(
&
(
peerAddr
.
sin_zero
),
sizeof
peerAddr
.
sin_zero
);
}
m
_pReader
=
src
->
getRing
()
->
attach
();
m
_pReader
->
setReadCB
([
this
](
const
RtpPacket
::
Ptr
&
pkt
){
_pReader
=
src
->
getRing
()
->
attach
();
_pReader
->
setReadCB
([
this
](
const
RtpPacket
::
Ptr
&
pkt
){
int
i
=
(
int
)(
pkt
->
type
);
auto
&
pSock
=
m
_apUdpSock
[
i
];
auto
&
peerAddr
=
m
_aPeerUdpAddr
[
i
];
auto
&
pSock
=
_apUdpSock
[
i
];
auto
&
peerAddr
=
_aPeerUdpAddr
[
i
];
BufferRtp
::
Ptr
buffer
(
new
BufferRtp
(
pkt
,
4
));
pSock
->
send
(
buffer
,
SOCKET_DEFAULE_FLAGS
|
FLAG_MORE
,(
struct
sockaddr
*
)(
&
peerAddr
));
});
m
_pReader
->
setDetachCB
([
this
](){
unordered_map
<
void
*
,
onDetach
>
m
_mapDetach_copy
;
_pReader
->
setDetachCB
([
this
](){
unordered_map
<
void
*
,
onDetach
>
_mapDetach_copy
;
{
lock_guard
<
recursive_mutex
>
lck
(
m
_mtx
);
m_mapDetach_copy
=
std
::
move
(
m
_mapDetach
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
_mapDetach_copy
=
std
::
move
(
_mapDetach
);
}
for
(
auto
&
pr
:
m
_mapDetach_copy
){
for
(
auto
&
pr
:
_mapDetach_copy
){
pr
.
second
();
}
});
DebugL
<<
MultiCastAddressMaker
::
toString
(
*
m
_multiAddr
)
<<
" "
<<
m
_apUdpSock
[
0
]
->
get_local_port
()
<<
" "
<<
m
_apUdpSock
[
1
]
->
get_local_port
()
<<
" "
DebugL
<<
MultiCastAddressMaker
::
toString
(
*
_multiAddr
)
<<
" "
<<
_apUdpSock
[
0
]
->
get_local_port
()
<<
" "
<<
_apUdpSock
[
1
]
->
get_local_port
()
<<
" "
<<
strVhost
<<
" "
<<
strApp
<<
" "
<<
strStream
;
}
uint16_t
RtpBroadCaster
::
getPort
(
TrackType
trackType
){
return
m
_apUdpSock
[
trackType
]
->
get_local_port
();
return
_apUdpSock
[
trackType
]
->
get_local_port
();
}
string
RtpBroadCaster
::
getIP
(){
return
inet_ntoa
(
m
_aPeerUdpAddr
[
0
].
sin_addr
);
return
inet_ntoa
(
_aPeerUdpAddr
[
0
].
sin_addr
);
}
RtpBroadCaster
::
Ptr
RtpBroadCaster
::
make
(
const
string
&
strLocalIp
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strStream
){
try
{
...
...
src/Rtsp/RtpBroadCaster.h
查看文件 @
39baaebc
...
...
@@ -64,9 +64,9 @@ public:
private
:
MultiCastAddressMaker
(){};
void
release
(
uint32_t
iAddr
);
uint32_t
m
_iAddr
=
0
;
recursive_mutex
m
_mtx
;
unordered_set
<
uint32_t
>
m
_setBadAddr
;
uint32_t
_iAddr
=
0
;
recursive_mutex
_mtx
;
unordered_set
<
uint32_t
>
_setBadAddr
;
};
class
RtpBroadCaster
{
public
:
...
...
@@ -82,12 +82,12 @@ private:
static
unordered_map
<
string
,
weak_ptr
<
RtpBroadCaster
>
>
g_mapBroadCaster
;
static
Ptr
make
(
const
string
&
strLocalIp
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strStream
);
std
::
shared_ptr
<
uint32_t
>
m
_multiAddr
;
recursive_mutex
m
_mtx
;
unordered_map
<
void
*
,
onDetach
>
m
_mapDetach
;
RtspMediaSource
::
RingType
::
RingReader
::
Ptr
m
_pReader
;
Socket
::
Ptr
m
_apUdpSock
[
2
];
struct
sockaddr_in
m
_aPeerUdpAddr
[
2
];
std
::
shared_ptr
<
uint32_t
>
_multiAddr
;
recursive_mutex
_mtx
;
unordered_map
<
void
*
,
onDetach
>
_mapDetach
;
RtspMediaSource
::
RingType
::
RingReader
::
Ptr
_pReader
;
Socket
::
Ptr
_apUdpSock
[
2
];
struct
sockaddr_in
_aPeerUdpAddr
[
2
];
RtpBroadCaster
(
const
string
&
strLocalIp
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strStream
);
...
...
src/Rtsp/RtpParser.cpp
查看文件 @
39baaebc
...
...
@@ -68,7 +68,7 @@ RtpParser::RtpParser(const string& sdp) {
break
;
}
}
m
_fDuration
=
getTimeInSDP
(
sdp
);
_fDuration
=
getTimeInSDP
(
sdp
);
}
bool
RtpParser
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
)
{
...
...
src/Rtsp/RtpParser.h
查看文件 @
39baaebc
...
...
@@ -51,7 +51,7 @@ public:
bool
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
);
float
getDuration
()
const
override
{
return
m
_fDuration
;
return
_fDuration
;
}
/**
...
...
@@ -76,7 +76,7 @@ private:
inline
void
onGetAudioTrack
(
const
RtspTrack
&
audio
);
inline
void
onGetVideoTrack
(
const
RtspTrack
&
video
);
private
:
float
m
_fDuration
=
0
;
float
_fDuration
=
0
;
AudioTrack
::
Ptr
_audioTrack
;
VideoTrack
::
Ptr
_videoTrack
;
RtpCodec
::
Ptr
_audioRtpDecoder
;
...
...
src/Rtsp/Rtsp.h
查看文件 @
39baaebc
...
...
@@ -83,79 +83,79 @@ public:
break
;
}
if
(
start
==
buf
)
{
m
_strMethod
=
FindField
(
line
.
c_str
(),
NULL
,
" "
);
m
_strFullUrl
=
FindField
(
line
.
c_str
(),
" "
,
" "
);
auto
args_pos
=
m
_strFullUrl
.
find
(
'?'
);
_strMethod
=
FindField
(
line
.
c_str
(),
NULL
,
" "
);
_strFullUrl
=
FindField
(
line
.
c_str
(),
" "
,
" "
);
auto
args_pos
=
_strFullUrl
.
find
(
'?'
);
if
(
args_pos
!=
string
::
npos
){
m_strUrl
=
m
_strFullUrl
.
substr
(
0
,
args_pos
);
m_mapUrlArgs
=
parseArgs
(
m
_strFullUrl
.
substr
(
args_pos
+
1
));
_strUrl
=
_strFullUrl
.
substr
(
0
,
args_pos
);
_mapUrlArgs
=
parseArgs
(
_strFullUrl
.
substr
(
args_pos
+
1
));
}
else
{
m_strUrl
=
m
_strFullUrl
;
_strUrl
=
_strFullUrl
;
}
m_strTail
=
FindField
(
line
.
c_str
(),
(
m
_strFullUrl
+
" "
).
c_str
(),
NULL
);
_strTail
=
FindField
(
line
.
c_str
(),
(
_strFullUrl
+
" "
).
c_str
(),
NULL
);
}
else
{
auto
field
=
FindField
(
line
.
c_str
(),
NULL
,
": "
);
auto
value
=
FindField
(
line
.
c_str
(),
": "
,
NULL
);
if
(
field
.
size
()
!=
0
)
{
m
_mapHeaders
[
field
]
=
value
;
_mapHeaders
[
field
]
=
value
;
}
}
start
=
start
+
line
.
size
()
+
2
;
if
(
strncmp
(
start
,
"
\r\n
"
,
2
)
==
0
)
{
//协议解析完毕
m
_strContent
=
FindField
(
start
,
"
\r\n
"
,
NULL
);
_strContent
=
FindField
(
start
,
"
\r\n
"
,
NULL
);
break
;
}
}
}
const
string
&
Method
()
const
{
//rtsp方法
return
m
_strMethod
;
return
_strMethod
;
}
const
string
&
Url
()
const
{
//rtsp url
return
m
_strUrl
;
return
_strUrl
;
}
const
string
&
FullUrl
()
const
{
//rtsp url with args
return
m
_strFullUrl
;
return
_strFullUrl
;
}
const
string
&
Tail
()
const
{
//RTSP/1.0
return
m
_strTail
;
return
_strTail
;
}
const
string
&
operator
[](
const
char
*
name
)
const
{
//rtsp field
auto
it
=
m
_mapHeaders
.
find
(
name
);
if
(
it
==
m
_mapHeaders
.
end
())
{
return
m
_strNull
;
auto
it
=
_mapHeaders
.
find
(
name
);
if
(
it
==
_mapHeaders
.
end
())
{
return
_strNull
;
}
return
it
->
second
;
}
const
string
&
Content
()
const
{
return
m
_strContent
;
return
_strContent
;
}
void
Clear
()
{
m
_strMethod
.
clear
();
m
_strUrl
.
clear
();
m
_strFullUrl
.
clear
();
m
_strTail
.
clear
();
m
_strContent
.
clear
();
m
_mapHeaders
.
clear
();
m
_mapUrlArgs
.
clear
();
_strMethod
.
clear
();
_strUrl
.
clear
();
_strFullUrl
.
clear
();
_strTail
.
clear
();
_strContent
.
clear
();
_mapHeaders
.
clear
();
_mapUrlArgs
.
clear
();
}
void
setUrl
(
const
string
&
url
)
{
this
->
m
_strUrl
=
url
;
this
->
_strUrl
=
url
;
}
void
setContent
(
const
string
&
content
)
{
this
->
m
_strContent
=
content
;
this
->
_strContent
=
content
;
}
StrCaseMap
&
getValues
()
const
{
return
m
_mapHeaders
;
return
_mapHeaders
;
}
StrCaseMap
&
getUrlArgs
()
const
{
return
m
_mapUrlArgs
;
return
_mapUrlArgs
;
}
static
StrCaseMap
parseArgs
(
const
string
&
str
,
const
char
*
pair_delim
=
"&"
,
const
char
*
key_delim
=
"="
){
...
...
@@ -170,14 +170,14 @@ public:
}
private
:
string
m
_strMethod
;
string
m
_strUrl
;
string
m
_strTail
;
string
m
_strContent
;
string
m
_strNull
;
string
m
_strFullUrl
;
mutable
StrCaseMap
m
_mapHeaders
;
mutable
StrCaseMap
m
_mapUrlArgs
;
string
_strMethod
;
string
_strUrl
;
string
_strTail
;
string
_strContent
;
string
_strNull
;
string
_strFullUrl
;
mutable
StrCaseMap
_mapHeaders
;
mutable
StrCaseMap
_mapUrlArgs
;
};
typedef
struct
{
...
...
src/Rtsp/RtspMediaSource.h
查看文件 @
39baaebc
...
...
@@ -60,46 +60,46 @@ public:
RtspMediaSource
(
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
)
:
MediaSource
(
RTSP_SCHEMA
,
strVhost
,
strApp
,
strId
),
m
_pRing
(
new
RingBuffer
<
RtpPacket
::
Ptr
>
())
{
_pRing
(
new
RingBuffer
<
RtpPacket
::
Ptr
>
())
{
}
virtual
~
RtspMediaSource
()
{}
const
RingType
::
Ptr
&
getRing
()
const
{
//获取媒体源的rtp环形缓冲
return
m
_pRing
;
return
_pRing
;
}
const
string
&
getSdp
()
const
{
//获取该源的媒体描述信息
return
m
_strSdp
;
return
_strSdp
;
}
virtual
uint32_t
getSsrc
(
TrackType
trackType
)
{
return
m
_mapTracks
[
trackType
].
ssrc
;
return
_mapTracks
[
trackType
].
ssrc
;
}
virtual
uint16_t
getSeqence
(
TrackType
trackType
)
{
return
m
_mapTracks
[
trackType
].
seq
;
return
_mapTracks
[
trackType
].
seq
;
}
virtual
uint32_t
getTimestamp
(
TrackType
trackType
)
{
return
m
_mapTracks
[
trackType
].
timeStamp
;
return
_mapTracks
[
trackType
].
timeStamp
;
}
virtual
void
onGetSDP
(
const
string
&
sdp
)
{
//派生类设置该媒体源媒体描述信息
m
_strSdp
=
sdp
;
_strSdp
=
sdp
;
regist
();
}
virtual
void
onGetRTP
(
const
RtpPacket
::
Ptr
&
rtppt
,
bool
keyPos
)
{
auto
&
trackRef
=
m
_mapTracks
[
rtppt
->
type
];
auto
&
trackRef
=
_mapTracks
[
rtppt
->
type
];
trackRef
.
seq
=
rtppt
->
sequence
;
trackRef
.
timeStamp
=
rtppt
->
timeStamp
;
trackRef
.
ssrc
=
rtppt
->
ssrc
;
trackRef
.
type
=
rtppt
->
type
;
m
_pRing
->
write
(
rtppt
,
keyPos
);
_pRing
->
write
(
rtppt
,
keyPos
);
}
protected
:
unordered_map
<
int
,
RtspTrack
>
m
_mapTracks
;
string
m
_strSdp
;
//媒体描述信息
RingType
::
Ptr
m
_pRing
;
//rtp环形缓冲
unordered_map
<
int
,
RtspTrack
>
_mapTracks
;
string
_strSdp
;
//媒体描述信息
RingType
::
Ptr
_pRing
;
//rtp环形缓冲
};
}
/* namespace Rtsp */
...
...
src/Rtsp/RtspPlayer.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtsp/RtspPlayer.h
查看文件 @
39baaebc
...
...
@@ -101,45 +101,45 @@ private:
bool
sendDescribe
();
bool
sendRtspRequest
(
const
string
&
cmd
,
const
string
&
url
,
const
StrCaseMap
&
header
=
StrCaseMap
());
private
:
string
m
_strUrl
;
unsigned
int
m
_uiTrackCnt
=
0
;
RtspTrack
m
_aTrackInfo
[
2
];
string
_strUrl
;
unsigned
int
_uiTrackCnt
=
0
;
RtspTrack
_aTrackInfo
[
2
];
function
<
void
(
const
Parser
&
)
>
m
_onHandshake
;
RtspMediaSource
::
PoolType
m
_pktPool
;
function
<
void
(
const
Parser
&
)
>
_onHandshake
;
RtspMediaSource
::
PoolType
_pktPool
;
uint8_t
*
m
_pucRtpBuf
=
nullptr
;
unsigned
int
m
_uiRtpBufLen
=
0
;
Socket
::
Ptr
m
_apUdpSock
[
2
];
uint8_t
*
_pucRtpBuf
=
nullptr
;
unsigned
int
_uiRtpBufLen
=
0
;
Socket
::
Ptr
_apUdpSock
[
2
];
//rtsp info
string
m
_strSession
;
unsigned
int
m
_uiCseq
=
1
;
uint32_t
m
_aui32SsrcErrorCnt
[
2
]
=
{
0
,
0
};
string
m
_strContentBase
;
eRtpType
m
_eType
=
RTP_TCP
;
string
_strSession
;
unsigned
int
_uiCseq
=
1
;
uint32_t
_aui32SsrcErrorCnt
[
2
]
=
{
0
,
0
};
string
_strContentBase
;
eRtpType
_eType
=
RTP_TCP
;
/* RTP包排序所用参数 */
uint16_t
m
_aui16LastSeq
[
2
]
=
{
0
,
0
};
uint64_t
m
_aui64SeqOkCnt
[
2
]
=
{
0
,
0
};
bool
m
_abSortStarted
[
2
]
=
{
0
,
0
};
map
<
uint32_t
,
RtpPacket
::
Ptr
>
m
_amapRtpSort
[
2
];
uint16_t
_aui16LastSeq
[
2
]
=
{
0
,
0
};
uint64_t
_aui64SeqOkCnt
[
2
]
=
{
0
,
0
};
bool
_abSortStarted
[
2
]
=
{
0
,
0
};
map
<
uint32_t
,
RtpPacket
::
Ptr
>
_amapRtpSort
[
2
];
/* 丢包率统计需要用到的参数 */
uint16_t
m
_aui16FirstSeq
[
2
]
=
{
0
,
0
};
uint16_t
m
_aui16NowSeq
[
2
]
=
{
0
,
0
};
uint64_t
m
_aui64RtpRecv
[
2
]
=
{
0
,
0
};
uint16_t
_aui16FirstSeq
[
2
]
=
{
0
,
0
};
uint16_t
_aui16NowSeq
[
2
]
=
{
0
,
0
};
uint64_t
_aui64RtpRecv
[
2
]
=
{
0
,
0
};
//超时功能实现
Ticker
m
_rtpTicker
;
std
::
shared_ptr
<
Timer
>
m
_pPlayTimer
;
std
::
shared_ptr
<
Timer
>
m
_pRtpTimer
;
Ticker
_rtpTicker
;
std
::
shared_ptr
<
Timer
>
_pPlayTimer
;
std
::
shared_ptr
<
Timer
>
_pRtpTimer
;
//心跳定时器
std
::
shared_ptr
<
Timer
>
m
_pBeatTimer
;
std
::
shared_ptr
<
Timer
>
_pBeatTimer
;
//播放进度控制
float
m
_fSeekTo
=
0
;
double
m
_adFistStamp
[
2
]
=
{
0
,
0
};
double
m
_adNowStamp
[
2
]
=
{
0
,
0
};
Ticker
m
_aNowStampTicker
[
2
];
float
_fSeekTo
=
0
;
double
_adFistStamp
[
2
]
=
{
0
,
0
};
double
_adNowStamp
[
2
]
=
{
0
,
0
};
Ticker
_aNowStampTicker
[
2
];
};
}
/* namespace Rtsp */
...
...
src/Rtsp/RtspPlayerImp.h
查看文件 @
39baaebc
...
...
@@ -65,33 +65,33 @@ public:
private
:
//派生类回调函数
bool
onCheckSDP
(
const
string
&
sdp
,
const
RtspTrack
*
track
,
int
trackCnt
)
override
{
m_pRtspMediaSrc
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
m
_pMediaSrc
);
if
(
m
_pRtspMediaSrc
){
m
_pRtspMediaSrc
->
onGetSDP
(
sdp
);
_pRtspMediaSrc
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
_pMediaSrc
);
if
(
_pRtspMediaSrc
){
_pRtspMediaSrc
->
onGetSDP
(
sdp
);
}
try
{
m
_parser
.
reset
(
new
RtpParser
(
sdp
));
_parser
.
reset
(
new
RtpParser
(
sdp
));
//todo(xzl) 修复此处
//
m_parser->setOnVideoCB(m
_onGetVideoCB);
//
m_parser->setOnAudioCB(m
_onGetAudioCB);
//
_parser->setOnVideoCB(
_onGetVideoCB);
//
_parser->setOnAudioCB(
_onGetAudioCB);
return
true
;
}
catch
(
std
::
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
return
m
_pRtspMediaSrc
?
true
:
false
;
return
_pRtspMediaSrc
?
true
:
false
;
}
}
void
onRecvRTP
(
const
RtpPacket
::
Ptr
&
rtppt
,
const
RtspTrack
&
track
)
override
{
if
(
m
_parser
){
m
_parser
->
inputRtp
(
rtppt
);
if
(
_parser
){
_parser
->
inputRtp
(
rtppt
);
}
if
(
m
_pRtspMediaSrc
){
m
_pRtspMediaSrc
->
onGetRTP
(
rtppt
,
true
);
if
(
_pRtspMediaSrc
){
_pRtspMediaSrc
->
onGetRTP
(
rtppt
,
true
);
}
}
private
:
RtspMediaSource
::
Ptr
m
_pRtspMediaSrc
;
RtspMediaSource
::
Ptr
_pRtspMediaSrc
;
};
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtsp/RtspSession.h
查看文件 @
39baaebc
...
...
@@ -90,8 +90,8 @@ protected:
private
:
void
inputRtspOrRtcp
(
const
char
*
data
,
uint64_t
len
);
int
send
(
const
Buffer
::
Ptr
&
pkt
)
override
{
m
_ui64TotalBytes
+=
pkt
->
size
();
return
m
_pSender
->
send
(
pkt
,
_flags
);
_ui64TotalBytes
+=
pkt
->
size
();
return
_pSender
->
send
(
pkt
,
_flags
);
}
void
shutdown
()
override
;
void
shutdown_l
(
bool
close
);
...
...
@@ -123,16 +123,16 @@ private:
return
tmp
;
}
inline
int
getTrackIndexByTrackType
(
TrackType
type
)
{
for
(
unsigned
int
i
=
0
;
i
<
m
_uiTrackCnt
;
i
++
)
{
if
(
type
==
m
_aTrackInfo
[
i
].
type
)
{
for
(
unsigned
int
i
=
0
;
i
<
_uiTrackCnt
;
i
++
)
{
if
(
type
==
_aTrackInfo
[
i
].
type
)
{
return
i
;
}
}
return
-
1
;
}
inline
int
getTrackIndexByControlSuffix
(
const
string
&
controlSuffix
)
{
for
(
unsigned
int
i
=
0
;
i
<
m
_uiTrackCnt
;
i
++
)
{
if
(
controlSuffix
==
m
_aTrackInfo
[
i
].
controlSuffix
)
{
for
(
unsigned
int
i
=
0
;
i
<
_uiTrackCnt
;
i
++
)
{
if
(
controlSuffix
==
_aTrackInfo
[
i
].
controlSuffix
)
{
return
i
;
}
}
...
...
@@ -150,53 +150,53 @@ private:
static
void
onAuthDigest
(
const
weak_ptr
<
RtspSession
>
&
weakSelf
,
const
string
&
realm
,
const
string
&
strMd5
);
private
:
char
*
m
_pcBuf
=
nullptr
;
Ticker
m
_ticker
;
Parser
m
_parser
;
//rtsp解析类
string
m
_strUrl
;
string
m
_strSdp
;
string
m
_strSession
;
bool
m
_bFirstPlay
=
true
;
MediaInfo
m
_mediaInfo
;
std
::
weak_ptr
<
RtspMediaSource
>
m
_pMediaSrc
;
char
*
_pcBuf
=
nullptr
;
Ticker
_ticker
;
Parser
_parser
;
//rtsp解析类
string
_strUrl
;
string
_strSdp
;
string
_strSession
;
bool
_bFirstPlay
=
true
;
MediaInfo
_mediaInfo
;
std
::
weak_ptr
<
RtspMediaSource
>
_pMediaSrc
;
//RTP缓冲
weak_ptr
<
RingBuffer
<
RtpPacket
::
Ptr
>
>
m
_pWeakRing
;
RingBuffer
<
RtpPacket
::
Ptr
>::
RingReader
::
Ptr
m
_pRtpReader
;
weak_ptr
<
RingBuffer
<
RtpPacket
::
Ptr
>
>
_pWeakRing
;
RingBuffer
<
RtpPacket
::
Ptr
>::
RingReader
::
Ptr
_pRtpReader
;
PlayerBase
::
eRtpType
m
_rtpType
=
PlayerBase
::
RTP_UDP
;
bool
m
_bSetUped
=
false
;
int
m
_iCseq
=
0
;
unsigned
int
m
_uiTrackCnt
=
0
;
//媒体track个数
RtspTrack
m
_aTrackInfo
[
2
];
//媒体track信息,trackid idx 为数组下标
bool
m
_bGotAllPeerUdp
=
false
;
PlayerBase
::
eRtpType
_rtpType
=
PlayerBase
::
RTP_UDP
;
bool
_bSetUped
=
false
;
int
_iCseq
=
0
;
unsigned
int
_uiTrackCnt
=
0
;
//媒体track个数
RtspTrack
_aTrackInfo
[
2
];
//媒体track信息,trackid idx 为数组下标
bool
_bGotAllPeerUdp
=
false
;
#ifdef RTSP_SEND_RTCP
RtcpCounter
m
_aRtcpCnt
[
2
];
//rtcp统计,trackid idx 为数组下标
Ticker
m
_aRtcpTicker
[
2
];
//rtcp发送时间,trackid idx 为数组下标
RtcpCounter
_aRtcpCnt
[
2
];
//rtcp统计,trackid idx 为数组下标
Ticker
_aRtcpTicker
[
2
];
//rtcp发送时间,trackid idx 为数组下标
inline
void
sendRTCP
();
#endif
//RTP over UDP
bool
m
_abGotPeerUdp
[
2
]
=
{
false
,
false
};
//获取客户端udp端口计数
weak_ptr
<
Socket
>
m
_apUdpSock
[
2
];
//发送RTP的UDP端口,trackid idx 为数组下标
std
::
shared_ptr
<
struct
sockaddr
>
m
_apPeerUdpAddr
[
2
];
//播放器接收RTP的地址,trackid idx 为数组下标
bool
m
_bListenPeerUdpData
=
false
;
RtpBroadCaster
::
Ptr
m
_pBrdcaster
;
bool
_abGotPeerUdp
[
2
]
=
{
false
,
false
};
//获取客户端udp端口计数
weak_ptr
<
Socket
>
_apUdpSock
[
2
];
//发送RTP的UDP端口,trackid idx 为数组下标
std
::
shared_ptr
<
struct
sockaddr
>
_apPeerUdpAddr
[
2
];
//播放器接收RTP的地址,trackid idx 为数组下标
bool
_bListenPeerUdpData
=
false
;
RtpBroadCaster
::
Ptr
_pBrdcaster
;
//登录认证
string
m
_strNonce
;
string
_strNonce
;
//RTSP over HTTP
function
<
void
(
void
)
>
m
_onDestory
;
bool
m
_bBase64need
=
false
;
//是否需要base64解码
Socket
::
Ptr
m
_pSender
;
//回复rtsp时走的tcp通道,供quicktime用
function
<
void
(
void
)
>
_onDestory
;
bool
_bBase64need
=
false
;
//是否需要base64解码
Socket
::
Ptr
_pSender
;
//回复rtsp时走的tcp通道,供quicktime用
//quicktime 请求rtsp会产生两次tcp连接,
//一次发送 get 一次发送post,需要通过sessioncookie关联起来
string
m
_strSessionCookie
;
string
_strSessionCookie
;
//消耗的总流量
uint64_t
m
_ui64TotalBytes
=
0
;
uint64_t
_ui64TotalBytes
=
0
;
static
recursive_mutex
g_mtxGetter
;
//对quicktime上锁保护
static
recursive_mutex
g_mtxPostter
;
//对quicktime上锁保护
...
...
src/Rtsp/RtspToRtmpMediaSource.cpp
查看文件 @
39baaebc
...
...
@@ -43,7 +43,7 @@ RtspToRtmpMediaSource::RtspToRtmpMediaSource(const string &vhost,
const
string
&
id
,
bool
bEnableHls
,
bool
bEnableMp4
)
:
RtspMediaSource
(
vhost
,
app
,
id
),
m_bEnableHls
(
bEnableHls
),
m
_bEnableMp4
(
bEnableMp4
)
{
RtspMediaSource
(
vhost
,
app
,
id
),
_bEnableHls
(
bEnableHls
),
_bEnableMp4
(
bEnableMp4
)
{
}
RtspToRtmpMediaSource
::~
RtspToRtmpMediaSource
()
{
...
...
@@ -65,36 +65,36 @@ void RtspToRtmpMediaSource::makeVideoConfigPkt() {
rtmpPkt
->
strBuf
.
push_back
(
1
);
// version
//todo(xzl) 修复此处
string
m_sps
;
//= m
_pParser->getSps().substr(4);
string
m_pps
;
//= m
_pParser->getPps().substr(4);
//DebugL<<hexdump(
m_sps.data(), m
_sps.size());
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
1
]);
// profile
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
2
]);
// compat
rtmpPkt
->
strBuf
.
push_back
(
m
_sps
[
3
]);
// level
string
_sps
;
//=
_pParser->getSps().substr(4);
string
_pps
;
//=
_pParser->getPps().substr(4);
//DebugL<<hexdump(
_sps.data(),
_sps.size());
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
1
]);
// profile
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
2
]);
// compat
rtmpPkt
->
strBuf
.
push_back
(
_sps
[
3
]);
// level
rtmpPkt
->
strBuf
.
push_back
(
0xff
);
// 6 bits reserved + 2 bits nal size length - 1 (11)
rtmpPkt
->
strBuf
.
push_back
(
0xe1
);
// 3 bits reserved + 5 bits number of sps (00001)
uint16_t
size
=
m
_sps
.
size
();
uint16_t
size
=
_sps
.
size
();
size
=
htons
(
size
);
rtmpPkt
->
strBuf
.
append
((
char
*
)
&
size
,
2
);
rtmpPkt
->
strBuf
.
append
(
m
_sps
);
rtmpPkt
->
strBuf
.
append
(
_sps
);
/////////////pps
rtmpPkt
->
strBuf
.
push_back
(
1
);
// version
size
=
m
_pps
.
size
();
size
=
_pps
.
size
();
size
=
htons
(
size
);
rtmpPkt
->
strBuf
.
append
((
char
*
)
&
size
,
2
);
rtmpPkt
->
strBuf
.
append
(
m
_pps
);
rtmpPkt
->
strBuf
.
append
(
_pps
);
rtmpPkt
->
bodySize
=
rtmpPkt
->
strBuf
.
size
();
rtmpPkt
->
chunkId
=
CHUNK_VIDEO
;
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
timeStamp
=
0
;
rtmpPkt
->
typeId
=
MSG_VIDEO
;
m
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
}
void
RtspToRtmpMediaSource
::
onGetH264
(
const
H264Frame
&
frame
)
{
if
(
m
_pRecorder
){
m
_pRecorder
->
inputH264
((
char
*
)
frame
.
data
(),
frame
.
size
(),
frame
.
timeStamp
,
frame
.
type
);
if
(
_pRecorder
){
_pRecorder
->
inputH264
((
char
*
)
frame
.
data
(),
frame
.
size
(),
frame
.
timeStamp
,
frame
.
type
);
}
uint8_t
nal_type
=
frame
.
data
()[
4
]
&
0x1F
;
int8_t
flags
=
7
;
//h.264
...
...
@@ -124,17 +124,17 @@ void RtspToRtmpMediaSource::onGetH264(const H264Frame& frame) {
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
timeStamp
=
frame
.
timeStamp
;
rtmpPkt
->
typeId
=
MSG_VIDEO
;
m
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
}
void
RtspToRtmpMediaSource
::
onGetAAC
(
const
AACFrame
&
frame
)
{
if
(
m
_pRecorder
){
m
_pRecorder
->
inputAAC
((
char
*
)
frame
.
buffer
,
frame
.
aac_frame_length
,
frame
.
timeStamp
);
if
(
_pRecorder
){
_pRecorder
->
inputAAC
((
char
*
)
frame
.
buffer
,
frame
.
aac_frame_length
,
frame
.
timeStamp
);
}
RtmpPacket
::
Ptr
rtmpPkt
(
new
RtmpPacket
);
//////////header
uint8_t
is_config
=
false
;
rtmpPkt
->
strBuf
.
push_back
(
m
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
_ui8AudioFlags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
rtmpPkt
->
strBuf
.
append
((
char
*
)
frame
.
buffer
+
7
,
frame
.
aac_frame_length
-
7
);
...
...
@@ -143,15 +143,15 @@ void RtspToRtmpMediaSource::onGetAAC(const AACFrame& frame) {
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
timeStamp
=
frame
.
timeStamp
;
rtmpPkt
->
typeId
=
MSG_AUDIO
;
m
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
_pRtmpSrc
->
onGetMedia
(
rtmpPkt
);
}
void
RtspToRtmpMediaSource
::
makeAudioConfigPkt
()
{
//todo(xzl) 修复此处
#if 0
uint8_t flvStereoOrMono = (
m
_pParser->getAudioChannel() > 1);
uint8_t flvStereoOrMono = (_pParser->getAudioChannel() > 1);
uint8_t flvSampleRate;
switch (
m
_pParser->getAudioSampleRate()) {
switch (_pParser->getAudioSampleRate()) {
case 48000:
case 44100:
flvSampleRate = 3;
...
...
@@ -168,57 +168,57 @@ void RtspToRtmpMediaSource::makeAudioConfigPkt() {
flvSampleRate = 0;
break;
}
uint8_t flvSampleBit =
m
_pParser->getAudioSampleBit() == 16;
uint8_t flvSampleBit = _pParser->getAudioSampleBit() == 16;
uint8_t flvAudioType = 10; //aac
m
_ui8AudioFlags = (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono;
_ui8AudioFlags = (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono;
RtmpPacket::Ptr rtmpPkt(new RtmpPacket);
//////////header
uint8_t is_config = true;
rtmpPkt->strBuf.push_back(
m
_ui8AudioFlags);
rtmpPkt->strBuf.push_back(_ui8AudioFlags);
rtmpPkt->strBuf.push_back(!is_config);
rtmpPkt->strBuf.append(
m
_pParser->getAudioCfg());
rtmpPkt->strBuf.append(_pParser->getAudioCfg());
rtmpPkt->bodySize = rtmpPkt->strBuf.size();
rtmpPkt->chunkId = CHUNK_AUDIO;
rtmpPkt->streamId = STREAM_MEDIA;
rtmpPkt->timeStamp = 0;
rtmpPkt->typeId = MSG_AUDIO;
m
_pRtmpSrc->onGetMedia(rtmpPkt);
_pRtmpSrc->onGetMedia(rtmpPkt);
#endif
}
void
RtspToRtmpMediaSource
::
makeMetaData
()
{
m
_pRtmpSrc
.
reset
(
new
RtmpMediaSource
(
getVhost
(),
getApp
(),
getId
()));
m_pRtmpSrc
->
setListener
(
m
_listener
);
_pRtmpSrc
.
reset
(
new
RtmpMediaSource
(
getVhost
(),
getApp
(),
getId
()));
_pRtmpSrc
->
setListener
(
_listener
);
AMFValue
metaData
(
AMF_OBJECT
);
metaData
.
set
(
"duration"
,
m
_pParser
->
getDuration
());
metaData
.
set
(
"duration"
,
_pParser
->
getDuration
());
metaData
.
set
(
"fileSize"
,
0
);
//todo(xzl) 修复此处
#if 0
if (
m
_pParser->containVideo()) {
metaData.set("width",
m
_pParser->getVideoWidth());
metaData.set("height",
m
_pParser->getVideoHeight());
if (_pParser->containVideo()) {
metaData.set("width", _pParser->getVideoWidth());
metaData.set("height", _pParser->getVideoHeight());
metaData.set("videocodecid", "avc1"); //h.264
metaData.set("videodatarate", 5000);
metaData.set("framerate",
m
_pParser->getVideoFps());
metaData.set("framerate", _pParser->getVideoFps());
makeVideoConfigPkt();
}
if (
m
_pParser->containAudio()) {
if (_pParser->containAudio()) {
metaData.set("audiocodecid", "mp4a"); //aac
metaData.set("audiodatarate", 160);
metaData.set("audiosamplerate",
m
_pParser->getAudioSampleRate());
metaData.set("audiosamplesize",
m
_pParser->getAudioSampleBit());
metaData.set("audiochannels",
m
_pParser->getAudioChannel());
metaData.set("stereo",
m
_pParser->getAudioChannel() > 1);
metaData.set("audiosamplerate", _pParser->getAudioSampleRate());
metaData.set("audiosamplesize", _pParser->getAudioSampleBit());
metaData.set("audiochannels", _pParser->getAudioChannel());
metaData.set("stereo", _pParser->getAudioChannel() > 1);
makeAudioConfigPkt();
}
#endif
m
_pRtmpSrc
->
onGetMetaData
(
metaData
);
_pRtmpSrc
->
onGetMetaData
(
metaData
);
}
}
/* namespace Rtsp */
}
/* namespace ZL */
src/Rtsp/RtspToRtmpMediaSource.h
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtsp/UDPServer.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Rtsp/UDPServer.h
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Shell/ShellSession.cpp
查看文件 @
39baaebc
差异被折叠。
点击展开。
src/Shell/ShellSession.h
查看文件 @
39baaebc
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论