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
9fa6e9d8
Commit
9fa6e9d8
authored
Jan 14, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加dts生成算法,兼容含B帧的rtsp推流
parent
b55db11d
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
188 行增加
和
111 行删除
+188
-111
src/Common/Device.cpp
+10
-10
src/Common/Stamp.cpp
+54
-4
src/Common/Stamp.h
+23
-1
src/Extension/AACRtmp.cpp
+1
-1
src/Extension/AACRtp.cpp
+1
-1
src/Extension/Frame.h
+0
-7
src/Extension/H264.h
+19
-19
src/Extension/H264Rtmp.cpp
+8
-8
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/Player/PlayerProxy.cpp
+1
-1
没有找到文件。
src/Common/Device.cpp
查看文件 @
9fa6e9d8
...
...
@@ -106,11 +106,11 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
}
H264Frame
::
Ptr
frame
=
std
::
make_shared
<
H264Frame
>
();
frame
->
timeStamp
=
dts
;
frame
->
ptsStamp
=
pts
;
frame
->
buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
iPrefixS
ize
=
4
;
frame
->
_dts
=
dts
;
frame
->
_pts
=
pts
;
frame
->
_
buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
_
buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
_prefix_s
ize
=
4
;
inputFrame
(
frame
);
}
...
...
@@ -131,11 +131,11 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
}
H265Frame
::
Ptr
frame
=
std
::
make_shared
<
H265Frame
>
();
frame
->
timeStamp
=
dts
;
frame
->
ptsStamp
=
pts
;
frame
->
buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
iPrefixS
ize
=
4
;
frame
->
_dts
=
dts
;
frame
->
_pts
=
pts
;
frame
->
_
buffer
.
assign
(
"
\x00\x00\x00\x01
"
,
4
);
frame
->
_
buffer
.
append
(
pcData
+
prefixeSize
,
iDataLen
-
prefixeSize
);
frame
->
_prefix_s
ize
=
4
;
inputFrame
(
frame
);
}
...
...
src/Common/Stamp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -42,13 +42,14 @@ int64_t DeltaStamp::deltaStamp(int64_t stamp) {
}
int64_t
ret
=
stamp
-
_last_stamp
;
if
(
ABS
(
ret
)
<
MAX_DELTA_STAMP
){
//时间戳
变化不明显
if
(
ret
>=
0
){
//时间戳
增量为正,返回之
_last_stamp
=
stamp
;
return
ret
;
//在直播情况下,时间戳增量不得大于MAX_DELTA_STAMP
return
ret
<
MAX_DELTA_STAMP
?
ret
:
(
_playback
?
ret
:
0
);
}
//时间戳
变化太明显,可能回环了或者seek
了
//时间戳
增量为负,说明时间戳回环了或回退
了
_last_stamp
=
stamp
;
return
_playback
?
ret
:
0
;
}
...
...
@@ -99,4 +100,52 @@ 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
(
pts
>
_last_max_pts
){
if
(
!
_sorter_max_size
&&
_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
;
InfoL
<<
_sorter_max_size
<<
" "
<<
_dts_pts_offset
;
}
_frames_since_last_max_pts
=
0
;
_last_max_pts
=
pts
;
}
_pts_sorter
.
emplace
(
pts
);
++
_frames_since_last_max_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
\ No newline at end of file
src/Common/Stamp.h
查看文件 @
9fa6e9d8
...
...
@@ -27,8 +27,9 @@
#ifndef ZLMEDIAKIT_STAMP_H
#define ZLMEDIAKIT_STAMP_H
#include
"Util/TimeTicker.h"
#include
<set>
#include <cstdint>
#include "Util/TimeTicker.h"
using
namespace
toolkit
;
namespace
mediakit
{
...
...
@@ -88,6 +89,27 @@ private:
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
#endif //ZLMEDIAKIT_STAMP_H
src/Extension/AACRtmp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -102,7 +102,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
rtmpPkt
->
bodySize
=
rtmpPkt
->
strBuf
.
size
();
rtmpPkt
->
chunkId
=
CHUNK_AUDIO
;
rtmpPkt
->
streamId
=
STREAM_MEDIA
;
rtmpPkt
->
timeStamp
=
frame
->
stamp
();
rtmpPkt
->
timeStamp
=
frame
->
dts
();
rtmpPkt
->
typeId
=
MSG_AUDIO
;
RtmpCodec
::
inputRtmp
(
rtmpPkt
,
false
);
}
...
...
src/Extension/AACRtp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -41,7 +41,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
dts
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
...
...
src/Extension/Frame.h
查看文件 @
9fa6e9d8
...
...
@@ -81,13 +81,6 @@ class Frame : public Buffer, public CodecInfo {
public
:
typedef
std
::
shared_ptr
<
Frame
>
Ptr
;
virtual
~
Frame
(){}
/**
* 时间戳,已经废弃,请使用dts() 、pts()接口
*/
inline
uint32_t
stamp
()
const
{
return
dts
();
};
/**
* 返回解码时间戳,单位毫秒
...
...
src/Extension/H264.h
查看文件 @
9fa6e9d8
...
...
@@ -53,21 +53,21 @@ public:
}
NalType
;
char
*
data
()
const
override
{
return
(
char
*
)
buffer
.
data
();
return
(
char
*
)
_
buffer
.
data
();
}
uint32_t
size
()
const
override
{
return
buffer
.
size
();
return
_
buffer
.
size
();
}
uint32_t
dts
()
const
override
{
return
timeStamp
;
return
_dts
;
}
uint32_t
pts
()
const
override
{
return
ptsStamp
?
ptsStamp
:
timeStamp
;
return
_pts
?
_pts
:
_dts
;
}
uint32_t
prefixSize
()
const
override
{
return
iPrefixS
ize
;
return
_prefix_s
ize
;
}
TrackType
getTrackType
()
const
override
{
...
...
@@ -79,11 +79,11 @@ public:
}
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
{
switch
(
H264_TYPE
(
buffer
[
iPrefixS
ize
])
){
switch
(
H264_TYPE
(
_buffer
[
_prefix_s
ize
])
){
case
H264Frame
:
:
NAL_SPS
:
case
H264Frame
:
:
NAL_PPS
:
return
true
;
...
...
@@ -92,10 +92,10 @@ public:
}
}
public
:
uint32_t
timeStamp
;
uint32_t
ptsStamp
=
0
;
string
buffer
;
uint32_t
iPrefixSize
=
4
;
uint32_t
_dts
=
0
;
uint32_t
_pts
=
0
;
uint32_t
_prefix_size
=
4
;
string
_buffer
;
};
...
...
@@ -340,19 +340,19 @@ private:
if
(
!
_sps
.
empty
()){
auto
spsFrame
=
std
::
make_shared
<
H264Frame
>
();
spsFrame
->
iPrefixS
ize
=
4
;
spsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
buffer
.
append
(
_sps
);
spsFrame
->
timeStamp
=
frame
->
stamp
();
spsFrame
->
_prefix_s
ize
=
4
;
spsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
_
buffer
.
append
(
_sps
);
spsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
spsFrame
);
}
if
(
!
_pps
.
empty
()){
auto
ppsFrame
=
std
::
make_shared
<
H264Frame
>
();
ppsFrame
->
iPrefixS
ize
=
4
;
ppsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
buffer
.
append
(
_pps
);
ppsFrame
->
timeStamp
=
frame
->
stamp
();
ppsFrame
->
_prefix_s
ize
=
4
;
ppsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
_
buffer
.
append
(
_pps
);
ppsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
ppsFrame
);
}
}
...
...
src/Extension/H264Rtmp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -35,8 +35,8 @@ H264RtmpDecoder::H264RtmpDecoder() {
H264Frame
::
Ptr
H264RtmpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_
buffer
.
clear
();
frame
->
_prefix_s
ize
=
4
;
return
frame
;
}
...
...
@@ -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
)
{
#if 1
_h264frame
->
timeStamp
=
dts
;
_h264frame
->
ptsStamp
=
pts
;
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
->
buffer
.
append
(
pcData
,
iLen
);
_h264frame
->
_dts
=
dts
;
_h264frame
->
_pts
=
pts
;
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
//添加264头
_h264frame
->
_
buffer
.
append
(
pcData
,
iLen
);
//写入环形缓存
RtmpCodec
::
inputFrame
(
_h264frame
);
...
...
@@ -144,7 +144,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
return
;
}
if
(
_lastPacket
&&
_lastPacket
->
timeStamp
!=
frame
->
stamp
())
{
if
(
_lastPacket
&&
_lastPacket
->
timeStamp
!=
frame
->
dts
())
{
RtmpCodec
::
inputRtmp
(
_lastPacket
,
_lastPacket
->
isVideoKeyFrame
());
_lastPacket
=
nullptr
;
}
...
...
@@ -165,7 +165,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
_lastPacket
->
chunkId
=
CHUNK_VIDEO
;
_lastPacket
->
streamId
=
STREAM_MEDIA
;
_lastPacket
->
timeStamp
=
frame
->
stamp
();
_lastPacket
->
timeStamp
=
frame
->
dts
();
_lastPacket
->
typeId
=
MSG_VIDEO
;
}
...
...
src/Extension/H264Rtp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -70,8 +70,8 @@ H264RtpDecoder::H264RtpDecoder() {
H264Frame
::
Ptr
H264RtpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
ResourcePoolHelper
<
H264Frame
>::
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_
buffer
.
clear
();
frame
->
_prefix_s
ize
=
4
;
return
frame
;
}
...
...
@@ -113,9 +113,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
nal
.
type
>=
0
&&
nal
.
type
<
24
)
{
//a full frame
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h264frame
->
keyFrame
();
onGetH264
(
_h264frame
);
return
(
key
);
//i frame
...
...
@@ -142,9 +142,9 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
//过小的帧丢弃
NALU
nal
;
MakeNalu
(
ptr
[
0
],
nal
);
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
append
((
char
*
)
ptr
,
len
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
append
((
char
*
)
ptr
,
len
);
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
if
(
nal
.
type
==
H264Frame
::
NAL_IDR
){
haveIDR
=
true
;
}
...
...
@@ -162,10 +162,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
fu
.
S
)
{
//该帧的第一个rtp包 FU-A start
char
tmp
=
(
nal
.
forbidden_zero_bit
<<
7
|
nal
.
nal_ref_idc
<<
5
|
fu
.
type
);
_h264frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
buffer
.
push_back
(
tmp
);
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_
buffer
.
push_back
(
tmp
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
_h264frame
->
keyFrame
();
...
...
@@ -173,22 +173,22 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h264frame
->
buffer
.
clear
();
_h264frame
->
_
buffer
.
clear
();
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
}
if
(
!
fu
.
E
)
{
//该帧的中间rtp包 FU-A mid
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
false
;
}
//该帧最后一个rtp包 FU-A end
_h264frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h264frame
->
_
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h264frame
->
keyFrame
();
onGetH264
(
_h264frame
);
return
key
;
...
...
@@ -209,8 +209,12 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
//根据pts计算dts
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
_h264frame
=
obtainFrame
();
}
...
...
@@ -232,7 +236,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
pts
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
//获取NALU的5bit 帧类型
unsigned
char
naluType
=
H264_TYPE
(
pcData
[
0
]);
...
...
src/Extension/H264Rtp.h
查看文件 @
9fa6e9d8
...
...
@@ -30,6 +30,7 @@
#include "Rtsp/RtpCodec.h"
#include "Util/ResourcePool.h"
#include "Extension/H264.h"
#include "Common/Stamp.h"
using
namespace
toolkit
;
namespace
mediakit
{
...
...
@@ -66,6 +67,7 @@ private:
H264Frame
::
Ptr
obtainFrame
();
private
:
H264Frame
::
Ptr
_h264frame
;
DtsGenerator
_dts_generator
;
int
_lastSeq
=
0
;
};
...
...
src/Extension/H265.h
查看文件 @
9fa6e9d8
...
...
@@ -74,23 +74,23 @@ public:
}
NaleType
;
char
*
data
()
const
override
{
return
(
char
*
)
buffer
.
data
();
return
(
char
*
)
_
buffer
.
data
();
}
uint32_t
size
()
const
override
{
return
buffer
.
size
();
return
_
buffer
.
size
();
}
uint32_t
dts
()
const
override
{
return
timeStamp
;
return
_dts
;
}
uint32_t
pts
()
const
override
{
return
ptsStamp
?
ptsStamp
:
timeStamp
;
return
_pts
?
_pts
:
_dts
;
}
uint32_t
prefixSize
()
const
override
{
return
iPrefixS
ize
;
return
_prefix_s
ize
;
}
TrackType
getTrackType
()
const
override
{
...
...
@@ -102,11 +102,11 @@ public:
}
bool
keyFrame
()
const
override
{
return
isKeyFrame
(
H265_TYPE
(
buffer
[
iPrefixS
ize
]));
return
isKeyFrame
(
H265_TYPE
(
_buffer
[
_prefix_s
ize
]));
}
bool
configFrame
()
const
override
{
switch
(
H265_TYPE
(
buffer
[
iPrefixS
ize
])){
switch
(
H265_TYPE
(
_buffer
[
_prefix_s
ize
])){
case
H265Frame
:
:
NAL_VPS
:
case
H265Frame
:
:
NAL_SPS
:
case
H265Frame
:
:
NAL_PPS
:
...
...
@@ -131,10 +131,10 @@ public:
}
public
:
uint32_t
timeStamp
;
uint32_t
ptsStamp
=
0
;
string
buffer
;
uint32_t
iPrefixSize
=
4
;
uint32_t
_dts
=
0
;
uint32_t
_pts
=
0
;
uint32_t
_prefix_size
=
4
;
string
_buffer
;
};
...
...
@@ -356,27 +356,27 @@ private:
}
if
(
!
_vps
.
empty
()){
auto
vpsFrame
=
std
::
make_shared
<
H265Frame
>
();
vpsFrame
->
iPrefixS
ize
=
4
;
vpsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
vpsFrame
->
buffer
.
append
(
_vps
);
vpsFrame
->
timeStamp
=
frame
->
stamp
();
vpsFrame
->
_prefix_s
ize
=
4
;
vpsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
vpsFrame
->
_
buffer
.
append
(
_vps
);
vpsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
vpsFrame
);
}
if
(
!
_sps
.
empty
())
{
auto
spsFrame
=
std
::
make_shared
<
H265Frame
>
();
spsFrame
->
iPrefixS
ize
=
4
;
spsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
buffer
.
append
(
_sps
);
spsFrame
->
timeStamp
=
frame
->
stamp
();
spsFrame
->
_prefix_s
ize
=
4
;
spsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
_
buffer
.
append
(
_sps
);
spsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
spsFrame
);
}
if
(
!
_pps
.
empty
())
{
auto
ppsFrame
=
std
::
make_shared
<
H265Frame
>
();
ppsFrame
->
iPrefixS
ize
=
4
;
ppsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
buffer
.
append
(
_pps
);
ppsFrame
->
timeStamp
=
frame
->
stamp
();
ppsFrame
->
_prefix_s
ize
=
4
;
ppsFrame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
_
buffer
.
append
(
_pps
);
ppsFrame
->
_dts
=
frame
->
dts
();
VideoTrack
::
inputFrame
(
ppsFrame
);
}
}
...
...
src/Extension/H265Rtp.cpp
查看文件 @
9fa6e9d8
...
...
@@ -70,8 +70,8 @@ H265RtpDecoder::H265RtpDecoder() {
H265Frame
::
Ptr
H265RtpDecoder
::
obtainFrame
()
{
//从缓存池重新申请对象,防止覆盖已经写入环形缓存的对象
auto
frame
=
ResourcePoolHelper
<
H265Frame
>::
obtainObj
();
frame
->
buffer
.
clear
();
frame
->
iPrefixS
ize
=
4
;
frame
->
_
buffer
.
clear
();
frame
->
_prefix_s
ize
=
4
;
return
frame
;
}
...
...
@@ -99,11 +99,11 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
MakeFU
(
frame
[
2
],
fu
);
if
(
fu
.
S
)
{
//该帧的第一个rtp包
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
buffer
.
push_back
(
0x01
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
_
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
_
buffer
.
push_back
(
0x01
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
(
_h265frame
->
keyFrame
());
//i frame
...
...
@@ -111,22 +111,22 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h265frame
->
buffer
.
clear
();
_h265frame
->
_
buffer
.
clear
();
WarnL
<<
"rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
}
if
(
!
fu
.
E
)
{
//该帧的中间rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
false
;
}
//该帧最后一个rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
key
;
...
...
@@ -134,9 +134,9 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
default
:
// 4.4.1. Single NAL Unit Packets (p24)
//a full frame
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
_
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
_
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
_pts
=
rtppack
->
timeStamp
;
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
key
;
...
...
@@ -144,8 +144,12 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
//计算dts
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
_h265frame
=
obtainFrame
();
}
...
...
@@ -167,7 +171,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
uint8_t
*
pcData
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
pts
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
unsigned
char
naluType
=
H265_TYPE
(
pcData
[
0
]);
//获取NALU的5bit 帧类型
uiStamp
%=
cycleMS
;
...
...
src/Extension/H265Rtp.h
查看文件 @
9fa6e9d8
...
...
@@ -30,6 +30,7 @@
#include "Rtsp/RtpCodec.h"
#include "Util/ResourcePool.h"
#include "Extension/H265.h"
#include "Common/Stamp.h"
using
namespace
toolkit
;
...
...
@@ -67,6 +68,7 @@ private:
H265Frame
::
Ptr
obtainFrame
();
private
:
H265Frame
::
Ptr
_h265frame
;
DtsGenerator
_dts_generator
;
int
_lastSeq
=
0
;
};
...
...
src/Player/PlayerProxy.cpp
查看文件 @
9fa6e9d8
...
...
@@ -219,7 +219,7 @@ public:
virtual
~
MuteAudioMaker
(){}
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
{
if
(
frame
->
getTrackType
()
==
TrackVideo
){
auto
iAudioIndex
=
frame
->
stamp
()
/
MUTE_ADTS_DATA_MS
;
auto
iAudioIndex
=
frame
->
dts
()
/
MUTE_ADTS_DATA_MS
;
if
(
_iAudioIndex
!=
iAudioIndex
){
_iAudioIndex
=
iAudioIndex
;
auto
aacFrame
=
std
::
make_shared
<
AACFrameCacheAble
>
((
char
*
)
MUTE_ADTS_DATA
,
MUTE_ADTS_DATA_LEN
,
_iAudioIndex
*
MUTE_ADTS_DATA_MS
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论