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
dad01750
Commit
dad01750
authored
Jan 14, 2020
by
Luke
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into research
parents
2d9537ec
491ed6f8
隐藏空白字符变更
内嵌
并排
正在显示
31 个修改的文件
包含
331 行增加
和
173 行删除
+331
-173
README.md
+19
-0
api/include/mk_media.h
+2
-2
conf/config.ini
+0
-2
server/WebHook.cpp
+1
-1
src/Common/Device.cpp
+16
-2
src/Common/MediaSink.cpp
+50
-30
src/Common/MediaSink.h
+2
-1
src/Common/Stamp.cpp
+62
-3
src/Common/Stamp.h
+23
-1
src/Common/config.cpp
+0
-2
src/Common/config.h
+0
-2
src/Extension/AAC.h
+0
-1
src/Extension/AACRtmp.cpp
+1
-1
src/Extension/AACRtp.cpp
+1
-2
src/Extension/Frame.h
+0
-7
src/Extension/H264.h
+20
-19
src/Extension/H264Rtmp.cpp
+13
-9
src/Extension/H264Rtp.cpp
+23
-19
src/Extension/H264Rtp.h
+2
-0
src/Extension/H265.h
+23
-23
src/Extension/H265Rtp.cpp
+21
-17
src/Extension/H265Rtp.h
+2
-0
src/Http/WebSocketClient.h
+1
-1
src/Player/PlayerProxy.cpp
+14
-4
src/Record/MP4Reader.cpp
+7
-5
src/Rtmp/RtmpMediaSource.h
+6
-5
src/Rtmp/RtmpPlayerImp.h
+6
-0
src/Rtmp/RtmpProtocol.cpp
+5
-5
src/Rtmp/RtmpSession.cpp
+10
-3
src/Rtmp/RtmpSession.h
+1
-0
src/Rtsp/RtspSession.cpp
+0
-6
没有找到文件。
README.md
查看文件 @
dad01750
...
@@ -376,6 +376,25 @@ git submodule update --init
...
@@ -376,6 +376,25 @@ git submodule update --init
-
2、如果您的问题还没解决,可以提issue.
-
2、如果您的问题还没解决,可以提issue.
-
3、有些问题,如果不具备参考性的,无需在issue提的,可以在qq群提.
-
3、有些问题,如果不具备参考性的,无需在issue提的,可以在qq群提.
-
4、QQ私聊一般不接受无偿技术咨询和支持(谈谈人生理想还是可以的😂),毕竟精力有限,谢谢理解.
-
4、QQ私聊一般不接受无偿技术咨询和支持(谈谈人生理想还是可以的😂),毕竟精力有限,谢谢理解.
## 致谢
感谢以下各位对本项目包括但不限于代码贡献、问题反馈、资金捐赠等各种方式的支持!以下排名不分先后:
[
老陈
](
https://github.com/ireader
)
[
Gemfield
](
https://github.com/gemfield
)
[
南冠彤
](
https://github.com/nanguantong2
)
[
凹凸慢
](
https://github.com/tsingeye
)
[
chenxiaolei
](
https://github.com/chenxiaolei
)
[
史前小虫
](
https://github.com/zqsong
)
[
清涩绿茶
](
https://github.com/baiyfcu
)
[
3503207480
](
https://github.com/3503207480
)
[
DroidChow
](
https://github.com/DroidChow
)
[
阿塞
](
https://github.com/HuoQiShuai
)
[
火宣
](
https://github.com/ChinaCCF
)
[
γ瑞γミ
](
https://github.com/JerryLinGd
)
[
linkingvision
](
https://www.linkingvision.com/
)
[
茄子
](
https://github.com/taotaobujue2008
)
[
好心情
](
<
409257224@qq.com
>
)
## 捐赠
## 捐赠
欢迎捐赠以便更好的推动项目的发展,谢谢您的支持!
欢迎捐赠以便更好的推动项目的发展,谢谢您的支持!
...
...
api/include/mk_media.h
查看文件 @
dad01750
...
@@ -87,7 +87,7 @@ API_EXPORT void API_CALL mk_media_init_aac(mk_media ctx, int channel, int sample
...
@@ -87,7 +87,7 @@ API_EXPORT void API_CALL mk_media_init_aac(mk_media ctx, int channel, int sample
* @param data 单帧H264数据
* @param data 单帧H264数据
* @param len 单帧H264数据字节数
* @param len 单帧H264数据字节数
* @param dts 解码时间戳,单位毫秒
* @param dts 解码时间戳,单位毫秒
* @param
d
ts 播放时间戳,单位毫秒
* @param
p
ts 播放时间戳,单位毫秒
*/
*/
API_EXPORT
void
API_CALL
mk_media_input_h264
(
mk_media
ctx
,
void
*
data
,
int
len
,
uint32_t
dts
,
uint32_t
pts
);
API_EXPORT
void
API_CALL
mk_media_input_h264
(
mk_media
ctx
,
void
*
data
,
int
len
,
uint32_t
dts
,
uint32_t
pts
);
...
@@ -97,7 +97,7 @@ API_EXPORT void API_CALL mk_media_input_h264(mk_media ctx, void *data, int len,
...
@@ -97,7 +97,7 @@ API_EXPORT void API_CALL mk_media_input_h264(mk_media ctx, void *data, int len,
* @param data 单帧H265数据
* @param data 单帧H265数据
* @param len 单帧H265数据字节数
* @param len 单帧H265数据字节数
* @param dts 解码时间戳,单位毫秒
* @param dts 解码时间戳,单位毫秒
* @param
d
ts 播放时间戳,单位毫秒
* @param
p
ts 播放时间戳,单位毫秒
*/
*/
API_EXPORT
void
API_CALL
mk_media_input_h265
(
mk_media
ctx
,
void
*
data
,
int
len
,
uint32_t
dts
,
uint32_t
pts
);
API_EXPORT
void
API_CALL
mk_media_input_h265
(
mk_media
ctx
,
void
*
data
,
int
len
,
uint32_t
dts
,
uint32_t
pts
);
...
...
conf/config.ini
查看文件 @
dad01750
...
@@ -191,8 +191,6 @@ keepAliveSecond=15
...
@@ -191,8 +191,6 @@ keepAliveSecond=15
port
=
554
port
=
554
#rtsps服务器监听地址
#rtsps服务器监听地址
sslport
=
322
sslport
=
322
#在接收rtsp推流时,是否重新生成时间戳(很多推流器的时间戳着实很烂)
modifyStamp
=
0
[shell]
[shell]
#调试telnet服务器接受最大bufffer大小
#调试telnet服务器接受最大bufffer大小
...
...
server/WebHook.cpp
查看文件 @
dad01750
...
@@ -438,7 +438,7 @@ void installWebHook(){
...
@@ -438,7 +438,7 @@ void installWebHook(){
//如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
//如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
//追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
//追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpAccess
,[](
BroadcastHttpAccessArgs
){
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpAccess
,[](
BroadcastHttpAccessArgs
){
if
(
sender
.
get_peer_ip
()
==
"127.0.0.1"
&&
parser
.
Params
()
==
hook_adminparams
){
if
(
sender
.
get_peer_ip
()
==
"127.0.0.1"
||
parser
.
Params
()
==
hook_adminparams
){
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
invoker
(
""
,
""
,
60
*
60
);
invoker
(
""
,
""
,
60
*
60
);
return
;
return
;
...
...
src/Common/Device.cpp
查看文件 @
dad01750
...
@@ -104,7 +104,14 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
...
@@ -104,7 +104,14 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
}
else
{
}
else
{
prefixeSize
=
0
;
prefixeSize
=
0
;
}
}
inputFrame
(
std
::
make_shared
<
H264FrameNoCacheAble
>
((
char
*
)
pcData
,
iDataLen
,
dts
,
pts
,
prefixeSize
));
H264Frame
::
Ptr
frame
=
std
::
make_shared
<
H264Frame
>
();
frame
->
_dts
=
dts
;
frame
->
_pts
=
pts
;
frame
->
_buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
_buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
_prefix_size
=
4
;
inputFrame
(
frame
);
}
}
void
DevChannel
::
inputH265
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
dts
,
uint32_t
pts
)
{
void
DevChannel
::
inputH265
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
dts
,
uint32_t
pts
)
{
...
@@ -122,7 +129,14 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
...
@@ -122,7 +129,14 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
}
else
{
}
else
{
prefixeSize
=
0
;
prefixeSize
=
0
;
}
}
inputFrame
(
std
::
make_shared
<
H265FrameNoCacheAble
>
((
char
*
)
pcData
,
iDataLen
,
dts
,
pts
,
prefixeSize
));
H265Frame
::
Ptr
frame
=
std
::
make_shared
<
H265Frame
>
();
frame
->
_dts
=
dts
;
frame
->
_pts
=
pts
;
frame
->
_buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
_buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
_prefix_size
=
4
;
inputFrame
(
frame
);
}
}
void
DevChannel
::
inputAAC
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
uiStamp
,
bool
withAdtsHeader
)
{
void
DevChannel
::
inputAAC
(
const
char
*
pcData
,
int
iDataLen
,
uint32_t
uiStamp
,
bool
withAdtsHeader
)
{
...
...
src/Common/MediaSink.cpp
查看文件 @
dad01750
...
@@ -26,7 +26,11 @@
...
@@ -26,7 +26,11 @@
#include "MediaSink.h"
#include "MediaSink.h"
//最多等待未初始化的Track 10秒,超时之后会忽略未初始化的Track
//最多等待未初始化的Track 10秒,超时之后会忽略未初始化的Track
#define MAX_WAIT_MS 10000
#define MAX_WAIT_MS_READY 10000
//如果添加Track,最多等待3秒
#define MAX_WAIT_MS_ADD_TRACK 3000
namespace
mediakit
{
namespace
mediakit
{
...
@@ -34,23 +38,16 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
...
@@ -34,23 +38,16 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
//克隆Track,只拷贝其数据,不拷贝其数据转发关系
//克隆Track,只拷贝其数据,不拷贝其数据转发关系
auto
track
=
track_in
->
clone
();
auto
track
=
track_in
->
clone
();
auto
codec_id
=
track
->
getCodecId
();
auto
codec_id
=
track
->
getCodecId
();
_track_map
[
codec_id
]
=
track
;
_track_map
[
codec_id
]
=
track
;
auto
lam
=
[
this
,
track
](){
_allTrackReady
=
false
;
_trackReadyCallback
[
codec_id
]
=
[
this
,
track
]()
{
onTrackReady
(
track
);
onTrackReady
(
track
);
};
};
if
(
track
->
ready
()){
_ticker
.
resetTime
();
lam
();
}
else
{
_anyTrackUnReady
=
true
;
_allTrackReady
=
false
;
_trackReadyCallback
[
codec_id
]
=
lam
;
_ticker
.
resetTime
();
}
track
->
addDelegate
(
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
this
](
const
Frame
::
Ptr
&
frame
){
track
->
addDelegate
(
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
this
](
const
Frame
::
Ptr
&
frame
)
{
if
(
!
_anyTrackUnReady
)
{
if
(
_allTrackReady
)
{
onTrackFrame
(
frame
);
onTrackFrame
(
frame
);
}
}
}));
}));
...
@@ -58,7 +55,6 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
...
@@ -58,7 +55,6 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
void
MediaSink
::
resetTracks
()
{
void
MediaSink
::
resetTracks
()
{
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
_anyTrackUnReady
=
false
;
_allTrackReady
=
false
;
_allTrackReady
=
false
;
_track_map
.
clear
();
_track_map
.
clear
();
_trackReadyCallback
.
clear
();
_trackReadyCallback
.
clear
();
...
@@ -83,26 +79,50 @@ void MediaSink::inputFrame(const Frame::Ptr &frame) {
...
@@ -83,26 +79,50 @@ void MediaSink::inputFrame(const Frame::Ptr &frame) {
}
}
}
}
if
(
!
_allTrackReady
&&
(
_trackReadyCallback
.
empty
()
||
_ticker
.
elapsedTime
()
>
MAX_WAIT_MS
)){
if
(
!
_allTrackReady
){
_allTrackReady
=
true
;
if
(
_ticker
.
elapsedTime
()
>
MAX_WAIT_MS_READY
){
_anyTrackUnReady
=
false
;
//如果超过规定时间,那么不再等待并忽略未准备好的Track
emitAllTrackReady
();
return
;
}
if
(
!
_trackReadyCallback
.
empty
()){
if
(
!
_trackReadyCallback
.
empty
()){
//这是超时强制忽略未准备好的Track
//在超时时间内,如果存在未准备好的Track,那么继续等待
_trackReadyCallback
.
clear
();
return
;
//移除未准备好的Track
for
(
auto
it
=
_track_map
.
begin
()
;
it
!=
_track_map
.
end
()
;
){
if
(
!
it
->
second
->
ready
()){
it
=
_track_map
.
erase
(
it
);
continue
;
}
++
it
;
}
}
}
if
(
!
_track_map
.
empty
()){
if
(
_track_map
.
size
()
==
2
){
//最少有一个有效的Track
//如果已经添加了音视频Track,并且不存在未准备好的Track,那么说明所有Track都准备好了
onAllTrackReady
();
emitAllTrackReady
();
return
;
}
}
if
(
_track_map
.
size
()
==
1
&&
_ticker
.
elapsedTime
()
>
MAX_WAIT_MS_ADD_TRACK
){
//如果只有一个Track,那么在该Track添加后,我们最多还等待若干时间(可能后面还会添加Track)
emitAllTrackReady
();
return
;
}
}
}
void
MediaSink
::
emitAllTrackReady
()
{
_allTrackReady
=
true
;
if
(
!
_trackReadyCallback
.
empty
()){
//这是超时强制忽略未准备好的Track
_trackReadyCallback
.
clear
();
//移除未准备好的Track
for
(
auto
it
=
_track_map
.
begin
()
;
it
!=
_track_map
.
end
()
;
){
if
(
!
it
->
second
->
ready
()){
it
=
_track_map
.
erase
(
it
);
continue
;
}
++
it
;
}
}
if
(
!
_track_map
.
empty
()){
//最少有一个有效的Track
onAllTrackReady
();
}
}
}
}
...
...
src/Common/MediaSink.h
查看文件 @
dad01750
...
@@ -110,11 +110,12 @@ protected:
...
@@ -110,11 +110,12 @@ protected:
*/
*/
virtual
void
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{};
virtual
void
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{};
private
:
private
:
void
emitAllTrackReady
();
private
:
mutable
recursive_mutex
_mtx
;
mutable
recursive_mutex
_mtx
;
map
<
int
,
Track
::
Ptr
>
_track_map
;
map
<
int
,
Track
::
Ptr
>
_track_map
;
map
<
int
,
function
<
void
()
>
>
_trackReadyCallback
;
map
<
int
,
function
<
void
()
>
>
_trackReadyCallback
;
bool
_allTrackReady
=
false
;
bool
_allTrackReady
=
false
;
bool
_anyTrackUnReady
=
false
;
Ticker
_ticker
;
Ticker
_ticker
;
};
};
...
...
src/Common/Stamp.cpp
查看文件 @
dad01750
...
@@ -26,14 +26,18 @@
...
@@ -26,14 +26,18 @@
#include "Stamp.h"
#include "Stamp.h"
#define MAX_DELTA_STAMP 300
#define MAX_DELTA_STAMP 1000
#define MAX_CTS 500
#define ABS(x) ((x) > 0 ? (x) : (-x))
namespace
mediakit
{
namespace
mediakit
{
int64_t
DeltaStamp
::
deltaStamp
(
int64_t
stamp
)
{
int64_t
DeltaStamp
::
deltaStamp
(
int64_t
stamp
)
{
if
(
!
_last_stamp
){
if
(
!
_last_stamp
){
//第一次计算时间戳增量,时间戳增量为0
//第一次计算时间戳增量,时间戳增量为0
_last_stamp
=
stamp
;
if
(
stamp
){
_last_stamp
=
stamp
;
}
return
0
;
return
0
;
}
}
...
@@ -75,7 +79,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
...
@@ -75,7 +79,7 @@ void Stamp::revise(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_out,
dts_out
=
_relativeStamp
;
dts_out
=
_relativeStamp
;
//////////////以下是播放时间戳的计算//////////////////
//////////////以下是播放时间戳的计算//////////////////
if
(
pts_dts_diff
>
MAX_DELTA_STAMP
||
pts_dts_diff
<
-
MAX_DELTA_STAMP
){
if
(
ABS
(
pts_dts_diff
)
>
MAX_CTS
){
//如果差值太大,则认为由于回环导致时间戳错乱了
//如果差值太大,则认为由于回环导致时间戳错乱了
pts_dts_diff
=
0
;
pts_dts_diff
=
0
;
}
}
...
@@ -96,4 +100,58 @@ int64_t Stamp::getRelativeStamp() const {
...
@@ -96,4 +100,58 @@ int64_t Stamp::getRelativeStamp() const {
}
}
bool
DtsGenerator
::
getDts
(
uint32_t
pts
,
uint32_t
&
dts
){
bool
ret
=
false
;
if
(
pts
==
_last_pts
){
//pts未变,返回上次结果
if
(
_last_dts
){
dts
=
_last_dts
;
ret
=
true
;
}
return
ret
;
}
ret
=
getDts_l
(
pts
,
dts
);
if
(
ret
){
//保存本次结果
_last_dts
=
dts
;
}
//记录上次pts
_last_pts
=
pts
;
return
ret
;
}
bool
DtsGenerator
::
getDts_l
(
uint32_t
pts
,
uint32_t
&
dts
){
if
(
_sorter_max_size
==
1
){
//没有B帧
dts
=
pts
;
return
true
;
}
if
(
!
_sorter_max_size
){
if
(
pts
>
_last_max_pts
){
if
(
_frames_since_last_max_pts
&&
_count_sorter_max_size
++
>
0
){
_sorter_max_size
=
_frames_since_last_max_pts
;
_dts_pts_offset
=
(
pts
-
_last_max_pts
)
/
2
;
}
_frames_since_last_max_pts
=
0
;
_last_max_pts
=
pts
;
}
++
_frames_since_last_max_pts
;
}
_pts_sorter
.
emplace
(
pts
);
if
(
_sorter_max_size
&&
_pts_sorter
.
size
()
>
_sorter_max_size
){
auto
it
=
_pts_sorter
.
begin
();
dts
=
*
it
+
_dts_pts_offset
;
if
(
dts
>
pts
){
//dts不能大于pts(基本不可能到达这个逻辑)
dts
=
pts
;
}
_pts_sorter
.
erase
(
it
);
return
true
;
}
return
false
;
}
}
//
namespace
mediakit
}
//
namespace
mediakit
\ No newline at end of file
src/Common/Stamp.h
查看文件 @
dad01750
...
@@ -27,8 +27,9 @@
...
@@ -27,8 +27,9 @@
#ifndef ZLMEDIAKIT_STAMP_H
#ifndef ZLMEDIAKIT_STAMP_H
#define ZLMEDIAKIT_STAMP_H
#define ZLMEDIAKIT_STAMP_H
#include
"Util/TimeTicker.h"
#include
<set>
#include <cstdint>
#include <cstdint>
#include "Util/TimeTicker.h"
using
namespace
toolkit
;
using
namespace
toolkit
;
namespace
mediakit
{
namespace
mediakit
{
...
@@ -88,6 +89,27 @@ private:
...
@@ -88,6 +89,27 @@ private:
SmoothTicker
_ticker
;
SmoothTicker
_ticker
;
};
};
class
DtsGenerator
{
public
:
DtsGenerator
()
=
default
;
~
DtsGenerator
()
=
default
;
bool
getDts
(
uint32_t
pts
,
uint32_t
&
dts
);
private
:
bool
getDts_l
(
uint32_t
pts
,
uint32_t
&
dts
);
private
:
uint32_t
_dts_pts_offset
=
0
;
uint32_t
_last_dts
=
0
;
uint32_t
_last_pts
=
0
;
uint32_t
_last_max_pts
=
0
;
int
_frames_since_last_max_pts
=
0
;
int
_sorter_max_size
=
0
;
int
_count_sorter_max_size
=
0
;
set
<
uint32_t
>
_pts_sorter
;
};
}
//namespace mediakit
}
//namespace mediakit
#endif //ZLMEDIAKIT_STAMP_H
#endif //ZLMEDIAKIT_STAMP_H
src/Common/config.cpp
查看文件 @
dad01750
...
@@ -158,7 +158,6 @@ const string kAuthBasic = RTSP_FIELD"authBasic";
...
@@ -158,7 +158,6 @@ const string kAuthBasic = RTSP_FIELD"authBasic";
const
string
kHandshakeSecond
=
RTSP_FIELD
"handshakeSecond"
;
const
string
kHandshakeSecond
=
RTSP_FIELD
"handshakeSecond"
;
const
string
kKeepAliveSecond
=
RTSP_FIELD
"keepAliveSecond"
;
const
string
kKeepAliveSecond
=
RTSP_FIELD
"keepAliveSecond"
;
const
string
kDirectProxy
=
RTSP_FIELD
"directProxy"
;
const
string
kDirectProxy
=
RTSP_FIELD
"directProxy"
;
const
string
kModifyStamp
=
RTSP_FIELD
"modifyStamp"
;
onceToken
token
([](){
onceToken
token
([](){
//默认Md5方式认证
//默认Md5方式认证
...
@@ -166,7 +165,6 @@ onceToken token([](){
...
@@ -166,7 +165,6 @@ onceToken token([](){
mINI
::
Instance
()[
kHandshakeSecond
]
=
15
;
mINI
::
Instance
()[
kHandshakeSecond
]
=
15
;
mINI
::
Instance
()[
kKeepAliveSecond
]
=
15
;
mINI
::
Instance
()[
kKeepAliveSecond
]
=
15
;
mINI
::
Instance
()[
kDirectProxy
]
=
1
;
mINI
::
Instance
()[
kDirectProxy
]
=
1
;
mINI
::
Instance
()[
kModifyStamp
]
=
false
;
},
nullptr
);
},
nullptr
);
}
//namespace Rtsp
}
//namespace Rtsp
...
...
src/Common/config.h
查看文件 @
dad01750
...
@@ -232,8 +232,6 @@ extern const string kKeepAliveSecond;
...
@@ -232,8 +232,6 @@ extern const string kKeepAliveSecond;
//假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
//假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
//默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
//默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
extern
const
string
kDirectProxy
;
extern
const
string
kDirectProxy
;
//rtsp推流是否修改时间戳
extern
const
string
kModifyStamp
;
}
//namespace Rtsp
}
//namespace Rtsp
////////////RTMP服务器配置///////////
////////////RTMP服务器配置///////////
...
...
src/Extension/AAC.h
查看文件 @
dad01750
...
@@ -104,7 +104,6 @@ public:
...
@@ -104,7 +104,6 @@ public:
//表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
//表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
unsigned
int
no_raw_data_blocks_in_frame
;
//2 uimsfb
unsigned
int
no_raw_data_blocks_in_frame
;
//2 uimsfb
unsigned
char
buffer
[
2
*
1024
+
7
];
unsigned
char
buffer
[
2
*
1024
+
7
];
uint16_t
sequence
;
uint32_t
timeStamp
;
uint32_t
timeStamp
;
uint32_t
iPrefixSize
=
7
;
uint32_t
iPrefixSize
=
7
;
}
;
}
;
...
...
src/Extension/AACRtmp.cpp
查看文件 @
dad01750
...
@@ -102,7 +102,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -102,7 +102,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
rtmpPkt
->
bodySize
=
rtmpPkt
->
strBuf
.
size
();
rtmpPkt
->
bodySize
=
rtmpPkt
->
strBuf
.
size
();
rtmpPkt
->
chunkId
=
CHUNK_AUDIO
;
rtmpPkt
->
chunkId
=
CHUNK_AUDIO
;
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
timeStamp
=
frame
->
stamp
();
rtmpPkt
->
timeStamp
=
frame
->
dts
();
rtmpPkt
->
typeId
=
MSG_AUDIO
;
rtmpPkt
->
typeId
=
MSG_AUDIO
;
RtmpCodec
::
inputRtmp
(
rtmpPkt
,
false
);
RtmpCodec
::
inputRtmp
(
rtmpPkt
,
false
);
}
}
...
...
src/Extension/AACRtp.cpp
查看文件 @
dad01750
...
@@ -41,7 +41,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
...
@@ -41,7 +41,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
dts
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
...
@@ -149,7 +149,6 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
...
@@ -149,7 +149,6 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
memcpy
(
_adts
->
buffer
+
_adts
->
aac_frame_length
,
rtp_packet_payload
+
next_aac_payload_offset
,
cur_aac_payload_len
);
memcpy
(
_adts
->
buffer
+
_adts
->
aac_frame_length
,
rtp_packet_payload
+
next_aac_payload_offset
,
cur_aac_payload_len
);
_adts
->
aac_frame_length
+=
(
cur_aac_payload_len
);
_adts
->
aac_frame_length
+=
(
cur_aac_payload_len
);
if
(
rtppack
->
mark
==
true
)
{
if
(
rtppack
->
mark
==
true
)
{
_adts
->
sequence
=
rtppack
->
sequence
;
_adts
->
timeStamp
=
rtppack
->
timeStamp
;
_adts
->
timeStamp
=
rtppack
->
timeStamp
;
writeAdtsHeader
(
*
_adts
,
_adts
->
buffer
);
writeAdtsHeader
(
*
_adts
,
_adts
->
buffer
);
onGetAAC
(
_adts
);
onGetAAC
(
_adts
);
...
...
src/Extension/Frame.h
查看文件 @
dad01750
...
@@ -81,13 +81,6 @@ class Frame : public Buffer, public CodecInfo {
...
@@ -81,13 +81,6 @@ class Frame : public Buffer, public CodecInfo {
public
:
public
:
typedef
std
::
shared_ptr
<
Frame
>
Ptr
;
typedef
std
::
shared_ptr
<
Frame
>
Ptr
;
virtual
~
Frame
(){}
virtual
~
Frame
(){}
/**
* 时间戳,已经废弃,请使用dts() 、pts()接口
*/
inline
uint32_t
stamp
()
const
{
return
dts
();
};
/**
/**
* 返回解码时间戳,单位毫秒
* 返回解码时间戳,单位毫秒
...
...
src/Extension/H264.h
查看文件 @
dad01750
...
@@ -49,24 +49,25 @@ public:
...
@@ -49,24 +49,25 @@ public:
NAL_SPS
=
7
,
NAL_SPS
=
7
,
NAL_PPS
=
8
,
NAL_PPS
=
8
,
NAL_IDR
=
5
,
NAL_IDR
=
5
,
NAL_SEI
=
6
,
}
NalType
;
}
NalType
;
char
*
data
()
const
override
{
char
*
data
()
const
override
{
return
(
char
*
)
buffer
.
data
();
return
(
char
*
)
_
buffer
.
data
();
}
}
uint32_t
size
()
const
override
{
uint32_t
size
()
const
override
{
return
buffer
.
size
();
return
_
buffer
.
size
();
}
}
uint32_t
dts
()
const
override
{
uint32_t
dts
()
const
override
{
return
timeStamp
;
return
_dts
;
}
}
uint32_t
pts
()
const
override
{
uint32_t
pts
()
const
override
{
return
ptsStamp
?
ptsStamp
:
timeStamp
;
return
_pts
?
_pts
:
_dts
;
}
}
uint32_t
prefixSize
()
const
override
{
uint32_t
prefixSize
()
const
override
{
return
iPrefixS
ize
;
return
_prefix_s
ize
;
}
}
TrackType
getTrackType
()
const
override
{
TrackType
getTrackType
()
const
override
{
...
@@ -78,11 +79,11 @@ public:
...
@@ -78,11 +79,11 @@ public:
}
}
bool
keyFrame
()
const
override
{
bool
keyFrame
()
const
override
{
return
H264_TYPE
(
buffer
[
iPrefixS
ize
])
==
H264Frame
::
NAL_IDR
;
return
H264_TYPE
(
_buffer
[
_prefix_s
ize
])
==
H264Frame
::
NAL_IDR
;
}
}
bool
configFrame
()
const
override
{
bool
configFrame
()
const
override
{
switch
(
H264_TYPE
(
buffer
[
iPrefixS
ize
])
){
switch
(
H264_TYPE
(
_buffer
[
_prefix_s
ize
])
){
case
H264Frame
:
:
NAL_SPS
:
case
H264Frame
:
:
NAL_SPS
:
case
H264Frame
:
:
NAL_PPS
:
case
H264Frame
:
:
NAL_PPS
:
return
true
;
return
true
;
...
@@ -91,10 +92,10 @@ public:
...
@@ -91,10 +92,10 @@ public:
}
}
}
}
public
:
public
:
uint32_t
timeStamp
;
uint32_t
_dts
=
0
;
uint32_t
ptsStamp
=
0
;
uint32_t
_pts
=
0
;
string
buffer
;
uint32_t
_prefix_size
=
4
;
uint32_t
iPrefixSize
=
4
;
string
_buffer
;
};
};
...
@@ -339,19 +340,19 @@ private:
...
@@ -339,19 +340,19 @@ private:
if
(
!
_sps
.
empty
()){
if
(
!
_sps
.
empty
()){
auto
spsFrame
=
std
::
make_shared
<
H264Frame
>
();
auto
spsFrame
=
std
::
make_shared
<
H264Frame
>
();
spsFrame
->
iPrefixS
ize
=
4
;
spsFrame
->
_prefix_s
ize
=
4
;
spsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
buffer
.
append
(
_sps
);
spsFrame
->
_
buffer
.
append
(
_sps
);
spsFrame
->
timeStamp
=
frame
->
stamp
();
spsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
spsFrame
);
VideoTrack
::
inputFrame
(
spsFrame
);
}
}
if
(
!
_pps
.
empty
()){
if
(
!
_pps
.
empty
()){
auto
ppsFrame
=
std
::
make_shared
<
H264Frame
>
();
auto
ppsFrame
=
std
::
make_shared
<
H264Frame
>
();
ppsFrame
->
iPrefixS
ize
=
4
;
ppsFrame
->
_prefix_s
ize
=
4
;
ppsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
buffer
.
append
(
_pps
);
ppsFrame
->
_
buffer
.
append
(
_pps
);
ppsFrame
->
timeStamp
=
frame
->
stamp
();
ppsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
ppsFrame
);
VideoTrack
::
inputFrame
(
ppsFrame
);
}
}
}
}
...
...
src/Extension/H264Rtmp.cpp
查看文件 @
dad01750
...
@@ -35,8 +35,8 @@ H264RtmpDecoder::H264RtmpDecoder() {
...
@@ -35,8 +35,8 @@ H264RtmpDecoder::H264RtmpDecoder() {
H264Frame
::
Ptr
H264RtmpDecoder
::
obtainFrame
()
{
H264Frame
::
Ptr
H264RtmpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
obtainObj
();
auto
frame
=
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
_
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_prefix_s
ize
=
4
;
return
frame
;
return
frame
;
}
}
...
@@ -78,10 +78,10 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
...
@@ -78,10 +78,10 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
inline
void
H264RtmpDecoder
::
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
dts
,
uint32_t
pts
)
{
inline
void
H264RtmpDecoder
::
onGetH264
(
const
char
*
pcData
,
int
iLen
,
uint32_t
dts
,
uint32_t
pts
)
{
#if 1
#if 1
_h264frame
->
timeStamp
=
dts
;
_h264frame
->
_dts
=
dts
;
_h264frame
->
ptsStamp
=
pts
;
_h264frame
->
_pts
=
pts
;
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
->
buffer
.
append
(
pcData
,
iLen
);
_h264frame
->
_
buffer
.
append
(
pcData
,
iLen
);
//写入环形缓存
//写入环形缓存
RtmpCodec
::
inputFrame
(
_h264frame
);
RtmpCodec
::
inputFrame
(
_h264frame
);
...
@@ -140,7 +140,11 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -140,7 +140,11 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
}
}
}
}
if
(
_lastPacket
&&
_lastPacket
->
timeStamp
!=
frame
->
stamp
())
{
if
(
type
==
H264Frame
::
NAL_SEI
){
return
;
}
if
(
_lastPacket
&&
_lastPacket
->
timeStamp
!=
frame
->
dts
())
{
RtmpCodec
::
inputRtmp
(
_lastPacket
,
_lastPacket
->
isVideoKeyFrame
());
RtmpCodec
::
inputRtmp
(
_lastPacket
,
_lastPacket
->
isVideoKeyFrame
());
_lastPacket
=
nullptr
;
_lastPacket
=
nullptr
;
}
}
...
@@ -149,7 +153,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -149,7 +153,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
//I or P or B frame
//I or P or B frame
int8_t
flags
=
7
;
//h.264
int8_t
flags
=
7
;
//h.264
bool
is_config
=
false
;
bool
is_config
=
false
;
flags
|=
((
frame
->
keyFrame
(
)
?
FLV_KEY_FRAME
:
FLV_INTER_FRAME
)
<<
4
);
flags
|=
((
(
frame
->
configFrame
()
||
frame
->
keyFrame
()
)
?
FLV_KEY_FRAME
:
FLV_INTER_FRAME
)
<<
4
);
_lastPacket
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
_lastPacket
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
_lastPacket
->
strBuf
.
clear
();
_lastPacket
->
strBuf
.
clear
();
...
@@ -161,7 +165,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -161,7 +165,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
_lastPacket
->
chunkId
=
CHUNK_VIDEO
;
_lastPacket
->
chunkId
=
CHUNK_VIDEO
;
_lastPacket
->
streamId
=
STREAM_MEDIA
;
_lastPacket
->
streamId
=
STREAM_MEDIA
;
_lastPacket
->
timeStamp
=
frame
->
stamp
();
_lastPacket
->
timeStamp
=
frame
->
dts
();
_lastPacket
->
typeId
=
MSG_VIDEO
;
_lastPacket
->
typeId
=
MSG_VIDEO
;
}
}
...
...
src/Extension/H264Rtp.cpp
查看文件 @
dad01750
...
@@ -70,8 +70,8 @@ H264RtpDecoder::H264RtpDecoder() {
...
@@ -70,8 +70,8 @@ H264RtpDecoder::H264RtpDecoder() {
H264Frame
::
Ptr
H264RtpDecoder
::
obtainFrame
()
{
H264Frame
::
Ptr
H264RtpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
ResourcePoolHelper
<
H264Frame
>::
obtainObj
();
auto
frame
=
ResourcePoolHelper
<
H264Frame
>::
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
_
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_prefix_s
ize
=
4
;
return
frame
;
return
frame
;
}
}
...
@@ -113,9 +113,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -113,9 +113,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
nal
.
type
>=
0
&&
nal
.
type
<
24
)
{
if
(
nal
.
type
>=
0
&&
nal
.
type
<
24
)
{
//a full frame
//a full frame
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h264frame
->
keyFrame
();
auto
key
=
_h264frame
->
keyFrame
();
onGetH264
(
_h264frame
);
onGetH264
(
_h264frame
);
return
(
key
);
//i frame
return
(
key
);
//i frame
...
@@ -142,9 +142,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -142,9 +142,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
//过小的帧丢弃
//过小的帧丢弃
NALU
nal
;
NALU
nal
;
MakeNalu
(
ptr
[
0
],
nal
);
MakeNalu
(
ptr
[
0
],
nal
);
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
append
((
char
*
)
ptr
,
len
);
_h264frame
->
_
buffer
.
append
((
char
*
)
ptr
,
len
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
if
(
nal
.
type
==
H264Frame
::
NAL_IDR
){
if
(
nal
.
type
==
H264Frame
::
NAL_IDR
){
haveIDR
=
true
;
haveIDR
=
true
;
}
}
...
@@ -162,10 +162,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -162,10 +162,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
fu
.
S
)
{
if
(
fu
.
S
)
{
//该帧的第一个rtp包 FU-A start
//该帧的第一个rtp包 FU-A start
char
tmp
=
(
nal
.
forbidden_zero_bit
<<
7
|
nal
.
nal_ref_idc
<<
5
|
fu
.
type
);
char
tmp
=
(
nal
.
forbidden_zero_bit
<<
7
|
nal
.
nal_ref_idc
<<
5
|
fu
.
type
);
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
push_back
(
tmp
);
_h264frame
->
_
buffer
.
push_back
(
tmp
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
rtppack
->
sequence
;
return
_h264frame
->
keyFrame
();
return
_h264frame
->
keyFrame
();
...
@@ -173,22 +173,22 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -173,22 +173,22 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h264frame
->
buffer
.
clear
();
_h264frame
->
_
buffer
.
clear
();
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
return
false
;
}
}
if
(
!
fu
.
E
)
{
if
(
!
fu
.
E
)
{
//该帧的中间rtp包 FU-A mid
//该帧的中间rtp包 FU-A mid
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
rtppack
->
sequence
;
return
false
;
return
false
;
}
}
//该帧最后一个rtp包 FU-A end
//该帧最后一个rtp包 FU-A end
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h264frame
->
keyFrame
();
auto
key
=
_h264frame
->
keyFrame
();
onGetH264
(
_h264frame
);
onGetH264
(
_h264frame
);
return
key
;
return
key
;
...
@@ -209,8 +209,12 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -209,8 +209,12 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
}
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
//写入环形缓存
//根据pts计算dts
RtpCodec
::
inputFrame
(
frame
);
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
_h264frame
=
obtainFrame
();
_h264frame
=
obtainFrame
();
}
}
...
@@ -232,7 +236,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
...
@@ -232,7 +236,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
pts
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
//获取NALU的5bit 帧类型
//获取NALU的5bit 帧类型
unsigned
char
naluType
=
H264_TYPE
(
pcData
[
0
]);
unsigned
char
naluType
=
H264_TYPE
(
pcData
[
0
]);
...
...
src/Extension/H264Rtp.h
查看文件 @
dad01750
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "Rtsp/RtpCodec.h"
#include "Rtsp/RtpCodec.h"
#include "Util/ResourcePool.h"
#include "Util/ResourcePool.h"
#include "Extension/H264.h"
#include "Extension/H264.h"
#include "Common/Stamp.h"
using
namespace
toolkit
;
using
namespace
toolkit
;
namespace
mediakit
{
namespace
mediakit
{
...
@@ -66,6 +67,7 @@ private:
...
@@ -66,6 +67,7 @@ private:
H264Frame
::
Ptr
obtainFrame
();
H264Frame
::
Ptr
obtainFrame
();
private
:
private
:
H264Frame
::
Ptr
_h264frame
;
H264Frame
::
Ptr
_h264frame
;
DtsGenerator
_dts_generator
;
int
_lastSeq
=
0
;
int
_lastSeq
=
0
;
};
};
...
...
src/Extension/H265.h
查看文件 @
dad01750
...
@@ -74,23 +74,23 @@ public:
...
@@ -74,23 +74,23 @@ public:
}
NaleType
;
}
NaleType
;
char
*
data
()
const
override
{
char
*
data
()
const
override
{
return
(
char
*
)
buffer
.
data
();
return
(
char
*
)
_
buffer
.
data
();
}
}
uint32_t
size
()
const
override
{
uint32_t
size
()
const
override
{
return
buffer
.
size
();
return
_
buffer
.
size
();
}
}
uint32_t
dts
()
const
override
{
uint32_t
dts
()
const
override
{
return
timeStamp
;
return
_dts
;
}
}
uint32_t
pts
()
const
override
{
uint32_t
pts
()
const
override
{
return
ptsStamp
?
ptsStamp
:
timeStamp
;
return
_pts
?
_pts
:
_dts
;
}
}
uint32_t
prefixSize
()
const
override
{
uint32_t
prefixSize
()
const
override
{
return
iPrefixS
ize
;
return
_prefix_s
ize
;
}
}
TrackType
getTrackType
()
const
override
{
TrackType
getTrackType
()
const
override
{
...
@@ -102,11 +102,11 @@ public:
...
@@ -102,11 +102,11 @@ public:
}
}
bool
keyFrame
()
const
override
{
bool
keyFrame
()
const
override
{
return
isKeyFrame
(
H265_TYPE
(
buffer
[
iPrefixS
ize
]));
return
isKeyFrame
(
H265_TYPE
(
_buffer
[
_prefix_s
ize
]));
}
}
bool
configFrame
()
const
override
{
bool
configFrame
()
const
override
{
switch
(
H265_TYPE
(
buffer
[
iPrefixS
ize
])){
switch
(
H265_TYPE
(
_buffer
[
_prefix_s
ize
])){
case
H265Frame
:
:
NAL_VPS
:
case
H265Frame
:
:
NAL_VPS
:
case
H265Frame
:
:
NAL_SPS
:
case
H265Frame
:
:
NAL_SPS
:
case
H265Frame
:
:
NAL_PPS
:
case
H265Frame
:
:
NAL_PPS
:
...
@@ -131,10 +131,10 @@ public:
...
@@ -131,10 +131,10 @@ public:
}
}
public
:
public
:
uint32_t
timeStamp
;
uint32_t
_dts
=
0
;
uint32_t
ptsStamp
=
0
;
uint32_t
_pts
=
0
;
string
buffer
;
uint32_t
_prefix_size
=
4
;
uint32_t
iPrefixSize
=
4
;
string
_buffer
;
};
};
...
@@ -356,27 +356,27 @@ private:
...
@@ -356,27 +356,27 @@ private:
}
}
if
(
!
_vps
.
empty
()){
if
(
!
_vps
.
empty
()){
auto
vpsFrame
=
std
::
make_shared
<
H265Frame
>
();
auto
vpsFrame
=
std
::
make_shared
<
H265Frame
>
();
vpsFrame
->
iPrefixS
ize
=
4
;
vpsFrame
->
_prefix_s
ize
=
4
;
vpsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
vpsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
vpsFrame
->
buffer
.
append
(
_vps
);
vpsFrame
->
_
buffer
.
append
(
_vps
);
vpsFrame
->
timeStamp
=
frame
->
stamp
();
vpsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
vpsFrame
);
VideoTrack
::
inputFrame
(
vpsFrame
);
}
}
if
(
!
_sps
.
empty
())
{
if
(
!
_sps
.
empty
())
{
auto
spsFrame
=
std
::
make_shared
<
H265Frame
>
();
auto
spsFrame
=
std
::
make_shared
<
H265Frame
>
();
spsFrame
->
iPrefixS
ize
=
4
;
spsFrame
->
_prefix_s
ize
=
4
;
spsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
buffer
.
append
(
_sps
);
spsFrame
->
_
buffer
.
append
(
_sps
);
spsFrame
->
timeStamp
=
frame
->
stamp
();
spsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
spsFrame
);
VideoTrack
::
inputFrame
(
spsFrame
);
}
}
if
(
!
_pps
.
empty
())
{
if
(
!
_pps
.
empty
())
{
auto
ppsFrame
=
std
::
make_shared
<
H265Frame
>
();
auto
ppsFrame
=
std
::
make_shared
<
H265Frame
>
();
ppsFrame
->
iPrefixS
ize
=
4
;
ppsFrame
->
_prefix_s
ize
=
4
;
ppsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
buffer
.
append
(
_pps
);
ppsFrame
->
_
buffer
.
append
(
_pps
);
ppsFrame
->
timeStamp
=
frame
->
stamp
();
ppsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
ppsFrame
);
VideoTrack
::
inputFrame
(
ppsFrame
);
}
}
}
}
...
...
src/Extension/H265Rtp.cpp
查看文件 @
dad01750
...
@@ -70,8 +70,8 @@ H265RtpDecoder::H265RtpDecoder() {
...
@@ -70,8 +70,8 @@ H265RtpDecoder::H265RtpDecoder() {
H265Frame
::
Ptr
H265RtpDecoder
::
obtainFrame
()
{
H265Frame
::
Ptr
H265RtpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
ResourcePoolHelper
<
H265Frame
>::
obtainObj
();
auto
frame
=
ResourcePoolHelper
<
H265Frame
>::
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
_
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_prefix_s
ize
=
4
;
return
frame
;
return
frame
;
}
}
...
@@ -99,11 +99,11 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -99,11 +99,11 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
MakeFU
(
frame
[
2
],
fu
);
MakeFU
(
frame
[
2
],
fu
);
if
(
fu
.
S
)
{
if
(
fu
.
S
)
{
//该帧的第一个rtp包
//该帧的第一个rtp包
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
_
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
buffer
.
push_back
(
0x01
);
_h265frame
->
_
buffer
.
push_back
(
0x01
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
rtppack
->
sequence
;
return
(
_h265frame
->
keyFrame
());
//i frame
return
(
_h265frame
->
keyFrame
());
//i frame
...
@@ -111,22 +111,22 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -111,22 +111,22 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h265frame
->
buffer
.
clear
();
_h265frame
->
_
buffer
.
clear
();
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
return
false
;
}
}
if
(
!
fu
.
E
)
{
if
(
!
fu
.
E
)
{
//该帧的中间rtp包
//该帧的中间rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
rtppack
->
sequence
;
return
false
;
return
false
;
}
}
//该帧最后一个rtp包
//该帧最后一个rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h265frame
->
keyFrame
();
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
onGetH265
(
_h265frame
);
return
key
;
return
key
;
...
@@ -134,9 +134,9 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -134,9 +134,9 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
default
:
// 4.4.1. Single NAL Unit Packets (p24)
default
:
// 4.4.1. Single NAL Unit Packets (p24)
//a full frame
//a full frame
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h265frame
->
keyFrame
();
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
onGetH265
(
_h265frame
);
return
key
;
return
key
;
...
@@ -144,8 +144,12 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
...
@@ -144,8 +144,12 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
}
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
//写入环形缓存
//计算dts
RtpCodec
::
inputFrame
(
frame
);
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
_h265frame
=
obtainFrame
();
_h265frame
=
obtainFrame
();
}
}
...
@@ -167,7 +171,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
...
@@ -167,7 +171,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
uint8_t
*
pcData
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
uint8_t
*
pcData
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
pts
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
unsigned
char
naluType
=
H265_TYPE
(
pcData
[
0
]);
//获取NALU的5bit 帧类型
unsigned
char
naluType
=
H265_TYPE
(
pcData
[
0
]);
//获取NALU的5bit 帧类型
uiStamp
%=
cycleMS
;
uiStamp
%=
cycleMS
;
...
...
src/Extension/H265Rtp.h
查看文件 @
dad01750
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "Rtsp/RtpCodec.h"
#include "Rtsp/RtpCodec.h"
#include "Util/ResourcePool.h"
#include "Util/ResourcePool.h"
#include "Extension/H265.h"
#include "Extension/H265.h"
#include "Common/Stamp.h"
using
namespace
toolkit
;
using
namespace
toolkit
;
...
@@ -67,6 +68,7 @@ private:
...
@@ -67,6 +68,7 @@ private:
H265Frame
::
Ptr
obtainFrame
();
H265Frame
::
Ptr
obtainFrame
();
private
:
private
:
H265Frame
::
Ptr
_h265frame
;
H265Frame
::
Ptr
_h265frame
;
DtsGenerator
_dts_generator
;
int
_lastSeq
=
0
;
int
_lastSeq
=
0
;
};
};
...
...
src/Http/WebSocketClient.h
查看文件 @
dad01750
...
@@ -303,7 +303,7 @@ private:
...
@@ -303,7 +303,7 @@ private:
//拦截websocket数据接收
//拦截websocket数据接收
_onRecv
=
[
this
](
const
Buffer
::
Ptr
&
pBuf
){
_onRecv
=
[
this
](
const
Buffer
::
Ptr
&
pBuf
){
//解析websocket数据包
//解析websocket数据包
WebSocketSplitter
::
decode
((
uint8_t
*
)
pBuf
->
data
(),
pBuf
->
size
());
this
->
WebSocketSplitter
::
decode
((
uint8_t
*
)
pBuf
->
data
(),
pBuf
->
size
());
};
};
return
;
return
;
}
}
...
...
src/Player/PlayerProxy.cpp
查看文件 @
dad01750
...
@@ -219,16 +219,26 @@ public:
...
@@ -219,16 +219,26 @@ public:
virtual
~
MuteAudioMaker
(){}
virtual
~
MuteAudioMaker
(){}
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
{
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
{
if
(
frame
->
getTrackType
()
==
TrackVideo
){
if
(
frame
->
getTrackType
()
==
TrackVideo
){
auto
iAudioIndex
=
frame
->
stamp
()
/
MUTE_ADTS_DATA_MS
;
auto
iAudioIndex
=
frame
->
dts
()
/
MUTE_ADTS_DATA_MS
;
if
(
_iAudioIndex
!=
iAudioIndex
){
if
(
_iAudioIndex
!=
iAudioIndex
){
_iAudioIndex
=
iAudioIndex
;
_iAudioIndex
=
iAudioIndex
;
auto
aacFrame
=
std
::
make_shared
<
AACFrameNoCacheAble
>
((
char
*
)
MUTE_ADTS_DATA
,
auto
aacFrame
=
std
::
make_shared
<
AACFrameCacheAble
>
((
char
*
)
MUTE_ADTS_DATA
,
MUTE_ADTS_DATA_LEN
,
_iAudioIndex
*
MUTE_ADTS_DATA_MS
);
MUTE_ADTS_DATA_LEN
,
_iAudioIndex
*
MUTE_ADTS_DATA_MS
);
FrameDispatcher
::
inputFrame
(
aacFrame
);
FrameDispatcher
::
inputFrame
(
aacFrame
);
}
}
}
}
}
}
private
:
class
AACFrameCacheAble
:
public
AACFrameNoCacheAble
{
public
:
template
<
typename
...
ARGS
>
AACFrameCacheAble
(
ARGS
&&
...
args
)
:
AACFrameNoCacheAble
(
std
::
forward
<
ARGS
>
(
args
)...){};
virtual
~
AACFrameCacheAble
()
=
default
;
bool
cacheAble
()
const
override
{
return
true
;
}
};
private
:
private
:
int
_iAudioIndex
=
0
;
int
_iAudioIndex
=
0
;
};
};
...
...
src/Record/MP4Reader.cpp
查看文件 @
dad01750
...
@@ -225,8 +225,10 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
...
@@ -225,8 +225,10 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
uint32_t
numBytes
=
_video_sample_max_size
;
uint32_t
numBytes
=
_video_sample_max_size
;
MP4Duration
pRenderingOffset
;
MP4Duration
pRenderingOffset
;
if
(
MP4ReadSample
(
_hMP4File
,
_video_trId
,
iIdx
+
1
,
&
pBytes
,
&
numBytes
,
NULL
,
NULL
,
&
pRenderingOffset
,
&
_bSyncSample
)){
if
(
MP4ReadSample
(
_hMP4File
,
_video_trId
,
iIdx
+
1
,
&
pBytes
,
&
numBytes
,
NULL
,
NULL
,
&
pRenderingOffset
,
&
_bSyncSample
)){
if
(
!
justSeekSyncFrame
)
{
if
(
!
justSeekSyncFrame
)
{
uint32_t
iOffset
=
0
;
uint32_t
dts
=
(
double
)
_video_ms
*
iIdx
/
_video_num_samples
;
uint32_t
pts
=
dts
+
pRenderingOffset
/
90
;
uint32_t
iOffset
=
0
;
while
(
iOffset
<
numBytes
)
{
while
(
iOffset
<
numBytes
)
{
uint32_t
iFrameLen
;
uint32_t
iFrameLen
;
memcpy
(
&
iFrameLen
,
pBytes
+
iOffset
,
4
);
memcpy
(
&
iFrameLen
,
pBytes
+
iOffset
,
4
);
...
@@ -235,8 +237,7 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
...
@@ -235,8 +237,7 @@ inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
break
;
break
;
}
}
memcpy
(
pBytes
+
iOffset
,
"\x0\x0\x0\x1"
,
4
);
memcpy
(
pBytes
+
iOffset
,
"\x0\x0\x0\x1"
,
4
);
uint32_t
dts
=
(
double
)
_video_ms
*
iIdx
/
_video_num_samples
;
writeH264
(
pBytes
+
iOffset
,
iFrameLen
+
4
,
dts
,
pts
);
writeH264
(
pBytes
+
iOffset
,
iFrameLen
+
4
,
dts
,
dts
+
pRenderingOffset
/
90
);
iOffset
+=
(
iFrameLen
+
4
);
iOffset
+=
(
iFrameLen
+
4
);
}
}
}
else
if
(
_bSyncSample
){
}
else
if
(
_bSyncSample
){
...
@@ -260,9 +261,10 @@ inline bool MP4Reader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) {
...
@@ -260,9 +261,10 @@ inline bool MP4Reader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) {
uint8_t
*
pBytes
=
_adts
.
buffer
+
7
;
uint8_t
*
pBytes
=
_adts
.
buffer
+
7
;
if
(
MP4ReadSample
(
_hMP4File
,
_audio_trId
,
i
+
1
,
&
pBytes
,
&
numBytes
)){
if
(
MP4ReadSample
(
_hMP4File
,
_audio_trId
,
i
+
1
,
&
pBytes
,
&
numBytes
)){
if
(
!
justSeekSyncFrame
)
{
if
(
!
justSeekSyncFrame
)
{
uint32_t
dts
=
(
double
)
_audio_ms
*
i
/
_audio_num_samples
;
_adts
.
aac_frame_length
=
7
+
numBytes
;
_adts
.
aac_frame_length
=
7
+
numBytes
;
writeAdtsHeader
(
_adts
,
_adts
.
buffer
);
writeAdtsHeader
(
_adts
,
_adts
.
buffer
);
writeAAC
(
_adts
.
buffer
,
_adts
.
aac_frame_length
,
(
double
)
_audio_ms
*
i
/
_audio_num_sample
s
);
writeAAC
(
_adts
.
buffer
,
_adts
.
aac_frame_length
,
dt
s
);
}
}
}
else
{
}
else
{
ErrorL
<<
"读取音频失败:"
<<
i
+
1
;
ErrorL
<<
"读取音频失败:"
<<
i
+
1
;
...
...
src/Rtmp/RtmpMediaSource.h
查看文件 @
dad01750
...
@@ -72,7 +72,6 @@ public:
...
@@ -72,7 +72,6 @@ public:
const
string
&
stream_id
,
const
string
&
stream_id
,
int
ring_size
=
0
)
:
int
ring_size
=
0
)
:
MediaSource
(
RTMP_SCHEMA
,
vhost
,
app
,
stream_id
),
_ring_size
(
ring_size
)
{
MediaSource
(
RTMP_SCHEMA
,
vhost
,
app
,
stream_id
),
_ring_size
(
ring_size
)
{
_metadata
=
TitleMeta
().
getMetadata
();
}
}
virtual
~
RtmpMediaSource
()
{}
virtual
~
RtmpMediaSource
()
{}
...
@@ -117,6 +116,9 @@ public:
...
@@ -117,6 +116,9 @@ public:
virtual
void
setMetaData
(
const
AMFValue
&
metadata
)
{
virtual
void
setMetaData
(
const
AMFValue
&
metadata
)
{
lock_guard
<
recursive_mutex
>
lock
(
_mtx
);
lock_guard
<
recursive_mutex
>
lock
(
_mtx
);
_metadata
=
metadata
;
_metadata
=
metadata
;
if
(
_ring
){
regist
();
}
}
}
/**
/**
...
@@ -143,10 +145,9 @@ public:
...
@@ -143,10 +145,9 @@ public:
_ring
=
std
::
make_shared
<
RingType
>
(
_ring_size
,
std
::
move
(
lam
));
_ring
=
std
::
make_shared
<
RingType
>
(
_ring_size
,
std
::
move
(
lam
));
onReaderChanged
(
0
);
onReaderChanged
(
0
);
//如果输入了非config帧,
if
(
_metadata
){
//那么说明不再可能获取config帧以及metadata,
regist
();
//所以我们强制其为已注册
}
regist
();
}
}
_track_stamps_map
[
pkt
->
typeId
]
=
pkt
->
timeStamp
;
_track_stamps_map
[
pkt
->
typeId
]
=
pkt
->
timeStamp
;
_ring
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
_ring
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
...
...
src/Rtmp/RtmpPlayerImp.h
查看文件 @
dad01750
...
@@ -66,6 +66,7 @@ private:
...
@@ -66,6 +66,7 @@ private:
_pRtmpMediaSrc
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_pMediaSrc
);
_pRtmpMediaSrc
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_pMediaSrc
);
if
(
_pRtmpMediaSrc
){
if
(
_pRtmpMediaSrc
){
_pRtmpMediaSrc
->
setMetaData
(
val
);
_pRtmpMediaSrc
->
setMetaData
(
val
);
_set_meta_data
=
true
;
}
}
_delegate
.
reset
(
new
RtmpDemuxer
);
_delegate
.
reset
(
new
RtmpDemuxer
);
_delegate
->
loadMetaData
(
val
);
_delegate
->
loadMetaData
(
val
);
...
@@ -73,6 +74,10 @@ private:
...
@@ -73,6 +74,10 @@ private:
}
}
void
onMediaData
(
const
RtmpPacket
::
Ptr
&
chunkData
)
override
{
void
onMediaData
(
const
RtmpPacket
::
Ptr
&
chunkData
)
override
{
if
(
_pRtmpMediaSrc
){
if
(
_pRtmpMediaSrc
){
if
(
!
_set_meta_data
&&
!
chunkData
->
isCfgFrame
()){
_set_meta_data
=
true
;
_pRtmpMediaSrc
->
setMetaData
(
TitleMeta
().
getMetadata
());
}
_pRtmpMediaSrc
->
onWrite
(
chunkData
);
_pRtmpMediaSrc
->
onWrite
(
chunkData
);
}
}
if
(
!
_delegate
){
if
(
!
_delegate
){
...
@@ -83,6 +88,7 @@ private:
...
@@ -83,6 +88,7 @@ private:
}
}
private
:
private
:
RtmpMediaSource
::
Ptr
_pRtmpMediaSrc
;
RtmpMediaSource
::
Ptr
_pRtmpMediaSrc
;
bool
_set_meta_data
=
false
;
};
};
...
...
src/Rtmp/RtmpProtocol.cpp
查看文件 @
dad01750
...
@@ -332,7 +332,7 @@ void RtmpProtocol::handle_C0C1() {
...
@@ -332,7 +332,7 @@ void RtmpProtocol::handle_C0C1() {
//complex handsharke
//complex handsharke
handle_C1_complex
();
handle_C1_complex
();
#else
#else
WarnL
<<
"未打开ENABLE_OPENSSL宏,复杂握手采用简单方式处理!"
;
WarnL
<<
"未打开ENABLE_OPENSSL宏,复杂握手采用简单方式处理
,flash播放器可能无法播放
!"
;
handle_C1_simple
();
handle_C1_simple
();
#endif//ENABLE_OPENSSL
#endif//ENABLE_OPENSSL
}
}
...
@@ -372,10 +372,10 @@ void RtmpProtocol::handle_C1_complex(){
...
@@ -372,10 +372,10 @@ void RtmpProtocol::handle_C1_complex(){
check_C1_Digest
(
digest
,
c1_joined
);
check_C1_Digest
(
digest
,
c1_joined
);
send_complex_S0S1S2
(
0
,
digest
);
send_complex_S0S1S2
(
0
,
digest
);
InfoL
<<
"schema0"
;
//
InfoL << "schema0";
}
catch
(
std
::
exception
&
ex
){
}
catch
(
std
::
exception
&
ex
){
//貌似flash从来都不用schema1
//貌似flash从来都不用schema1
WarnL
<<
"try rtmp complex schema0 failed:"
<<
ex
.
what
();
//
WarnL << "try rtmp complex schema0 failed:" << ex.what();
try
{
try
{
/* c1s1 schema1
/* c1s1 schema1
time: 4bytes
time: 4bytes
...
@@ -389,9 +389,9 @@ void RtmpProtocol::handle_C1_complex(){
...
@@ -389,9 +389,9 @@ void RtmpProtocol::handle_C1_complex(){
check_C1_Digest
(
digest
,
c1_joined
);
check_C1_Digest
(
digest
,
c1_joined
);
send_complex_S0S1S2
(
1
,
digest
);
send_complex_S0S1S2
(
1
,
digest
);
InfoL
<<
"schema1"
;
//
InfoL << "schema1";
}
catch
(
std
::
exception
&
ex
){
}
catch
(
std
::
exception
&
ex
){
WarnL
<<
"try rtmp complex schema1 failed:"
<<
ex
.
what
();
//
WarnL << "try rtmp complex schema1 failed:" << ex.what();
handle_C1_simple
();
handle_C1_simple
();
}
}
}
}
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
dad01750
...
@@ -434,6 +434,7 @@ void RtmpSession::setMetaData(AMFDecoder &dec) {
...
@@ -434,6 +434,7 @@ void RtmpSession::setMetaData(AMFDecoder &dec) {
auto
metadata
=
dec
.
load
<
AMFValue
>
();
auto
metadata
=
dec
.
load
<
AMFValue
>
();
// dumpMetadata(metadata);
// dumpMetadata(metadata);
_pPublisherSrc
->
setMetaData
(
metadata
);
_pPublisherSrc
->
setMetaData
(
metadata
);
_set_meta_data
=
true
;
}
}
void
RtmpSession
::
onProcessCmd
(
AMFDecoder
&
dec
)
{
void
RtmpSession
::
onProcessCmd
(
AMFDecoder
&
dec
)
{
...
@@ -452,7 +453,7 @@ void RtmpSession::onProcessCmd(AMFDecoder &dec) {
...
@@ -452,7 +453,7 @@ void RtmpSession::onProcessCmd(AMFDecoder &dec) {
std
::
string
method
=
dec
.
load
<
std
::
string
>
();
std
::
string
method
=
dec
.
load
<
std
::
string
>
();
auto
it
=
s_cmd_functions
.
find
(
method
);
auto
it
=
s_cmd_functions
.
find
(
method
);
if
(
it
==
s_cmd_functions
.
end
())
{
if
(
it
==
s_cmd_functions
.
end
())
{
TraceP
(
this
)
<<
"can not support cmd:"
<<
method
;
//
TraceP(this) << "can not support cmd:" << method;
return
;
return
;
}
}
_dNowReqID
=
dec
.
load
<
double
>
();
_dNowReqID
=
dec
.
load
<
double
>
();
...
@@ -473,10 +474,11 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
...
@@ -473,10 +474,11 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
case
MSG_DATA3
:
{
case
MSG_DATA3
:
{
AMFDecoder
dec
(
chunkData
.
strBuf
,
chunkData
.
typeId
==
MSG_CMD3
?
1
:
0
);
AMFDecoder
dec
(
chunkData
.
strBuf
,
chunkData
.
typeId
==
MSG_CMD3
?
1
:
0
);
std
::
string
type
=
dec
.
load
<
std
::
string
>
();
std
::
string
type
=
dec
.
load
<
std
::
string
>
();
TraceP
(
this
)
<<
"notify:"
<<
type
;
if
(
type
==
"@setDataFrame"
)
{
if
(
type
==
"@setDataFrame"
)
{
setMetaData
(
dec
);
setMetaData
(
dec
);
}
}
else
{
TraceP
(
this
)
<<
"unknown notify:"
<<
type
;
}
}
}
break
;
break
;
case
MSG_AUDIO
:
case
MSG_AUDIO
:
...
@@ -490,6 +492,11 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
...
@@ -490,6 +492,11 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
_stamp
[
chunkData
.
typeId
%
2
].
revise
(
chunkData
.
timeStamp
,
chunkData
.
timeStamp
,
dts_out
,
dts_out
,
true
);
_stamp
[
chunkData
.
typeId
%
2
].
revise
(
chunkData
.
timeStamp
,
chunkData
.
timeStamp
,
dts_out
,
dts_out
,
true
);
chunkData
.
timeStamp
=
dts_out
;
chunkData
.
timeStamp
=
dts_out
;
}
}
if
(
!
_set_meta_data
&&
!
chunkData
.
isCfgFrame
()){
_set_meta_data
=
true
;
_pPublisherSrc
->
setMetaData
(
TitleMeta
().
getMetadata
());
}
_pPublisherSrc
->
onWrite
(
std
::
make_shared
<
RtmpPacket
>
(
std
::
move
(
chunkData
)));
_pPublisherSrc
->
onWrite
(
std
::
make_shared
<
RtmpPacket
>
(
std
::
move
(
chunkData
)));
}
}
break
;
break
;
...
...
src/Rtmp/RtmpSession.h
查看文件 @
dad01750
...
@@ -95,6 +95,7 @@ private:
...
@@ -95,6 +95,7 @@ private:
std
::
string
_strTcUrl
;
std
::
string
_strTcUrl
;
MediaInfo
_mediaInfo
;
MediaInfo
_mediaInfo
;
double
_dNowReqID
=
0
;
double
_dNowReqID
=
0
;
bool
_set_meta_data
=
false
;
Ticker
_ticker
;
//数据接收时间
Ticker
_ticker
;
//数据接收时间
RingBuffer
<
RtmpPacket
::
Ptr
>::
RingReader
::
Ptr
_pRingReader
;
RingBuffer
<
RtmpPacket
::
Ptr
>::
RingReader
::
Ptr
_pRingReader
;
std
::
shared_ptr
<
RtmpMediaSourceImp
>
_pPublisherSrc
;
std
::
shared_ptr
<
RtmpMediaSourceImp
>
_pPublisherSrc
;
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
dad01750
...
@@ -932,12 +932,6 @@ inline void RtspSession::send_NotAcceptable() {
...
@@ -932,12 +932,6 @@ inline void RtspSession::send_NotAcceptable() {
void
RtspSession
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
)
{
void
RtspSession
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
)
{
GET_CONFIG
(
bool
,
modify_stamp
,
Rtsp
::
kModifyStamp
);
if
(
modify_stamp
){
int64_t
dts_out
;
_stamp
[
trackidx
].
revise
(
rtppt
->
timeStamp
,
rtppt
->
timeStamp
,
dts_out
,
dts_out
,
true
);
rtppt
->
timeStamp
=
dts_out
;
}
_pushSrc
->
onWrite
(
rtppt
,
false
);
_pushSrc
->
onWrite
(
rtppt
,
false
);
}
}
inline
void
RtspSession
::
onRcvPeerUdpData
(
int
intervaled
,
const
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
)
{
inline
void
RtspSession
::
onRcvPeerUdpData
(
int
intervaled
,
const
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论