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
946b00f4
Commit
946b00f4
authored
6 years ago
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初步实现265 rtp解包
parent
9511a9fe
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
126 行增加
和
102 行删除
+126
-102
src/Extension/Factory.cpp
+62
-41
src/Rtsp/RtspPlayer.cpp
+2
-0
src/RtspMuxer/H264RtpCodec.cpp
+4
-3
src/RtspMuxer/H265RtpCodec.cpp
+58
-58
没有找到文件。
src/Extension/Factory.cpp
查看文件 @
946b00f4
...
...
@@ -29,6 +29,7 @@
#include "RtmpMuxer/AACRtmpCodec.h"
#include "RtspMuxer/H264RtpCodec.h"
#include "RtspMuxer/AACRtpCodec.h"
#include "RtspMuxer/H265RtpCodec.h"
namespace
mediakit
{
...
...
@@ -107,47 +108,30 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
return
std
::
make_shared
<
H264Track
>
(
sps
,
pps
,
0
,
0
);
}
WarnL
<<
"暂不支持该sdp:"
<<
track
->
_codec
<<
" "
<<
track
->
_fmtp
;
return
nullptr
;
}
CodecId
Factory
::
getCodecIdByAmf
(
const
AMFValue
&
val
){
if
(
val
.
type
()
==
AMF_STRING
){
auto
str
=
val
.
as_string
();
if
(
str
==
"avc1"
){
return
CodecH264
;
}
if
(
str
==
"mp4a"
){
return
CodecAAC
;
if
(
strcasestr
(
track
->
_codec
.
data
(),
"h265"
)
!=
nullptr
)
{
//a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA=
int
pt
;
char
sprop_sps
[
128
]
=
{
0
},
sprop_pps
[
128
]
=
{
0
};
if
(
3
!=
sscanf
(
track
->
_fmtp
.
c_str
(),
"%d sprop-sps=%127[^;]; sprop-pps=%127[^;]"
,
&
pt
,
sprop_sps
,
sprop_pps
))
{
return
std
::
make_shared
<
H265Track
>
();
}
WarnL
<<
"暂不支持该Amf:"
<<
str
;
return
CodecInvalid
;
return
std
::
make_shared
<
H265Track
>
(
""
,
sprop_sps
,
sprop_pps
,
0
,
0
,
0
);
}
if
(
val
.
type
()
!=
AMF_NULL
){
auto
type_id
=
val
.
as_integer
();
switch
(
type_id
){
case
7
:{
return
CodecH264
;
}
case
10
:{
return
CodecAAC
;
}
default
:
WarnL
<<
"暂不支持该Amf:"
<<
type_id
;
return
CodecInvalid
;
}
}
WarnL
<<
"暂不支持该Amf:"
<<
val
.
type
();
return
CodecInvalid
;
WarnL
<<
"暂不支持该sdp:"
<<
track
->
_codec
<<
" "
<<
track
->
_fmtp
;
return
nullptr
;
}
Track
::
Ptr
Factory
::
getTrackByCodecId
(
CodecId
codecId
)
{
switch
(
codecId
){
case
CodecH264
:{
return
std
::
make_shared
<
H264Track
>
();
}
case
CodecH265
:{
return
std
::
make_shared
<
H265Track
>
();
}
case
CodecAAC
:{
return
std
::
make_shared
<
AACTrack
>
();
}
...
...
@@ -157,16 +141,6 @@ Track::Ptr Factory::getTrackByCodecId(CodecId codecId) {
}
}
Track
::
Ptr
Factory
::
getTrackByAmf
(
const
AMFValue
&
amf
)
{
CodecId
codecId
=
getCodecIdByAmf
(
amf
);
if
(
codecId
==
CodecInvalid
){
return
nullptr
;
}
return
getTrackByCodecId
(
codecId
);
}
RtpCodec
::
Ptr
Factory
::
getRtpEncoderById
(
CodecId
codecId
,
uint32_t
ui32Ssrc
,
uint32_t
ui32MtuSize
,
...
...
@@ -176,6 +150,8 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId,
switch
(
codecId
){
case
CodecH264
:
return
std
::
make_shared
<
H264RtpEncoder
>
(
ui32Ssrc
,
ui32MtuSize
,
ui32SampleRate
,
ui8PlayloadType
,
ui8Interleaved
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtpEncoder
>
(
ui32Ssrc
,
ui32MtuSize
,
ui32SampleRate
,
ui8PlayloadType
,
ui8Interleaved
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpEncoder
>
(
ui32Ssrc
,
ui32MtuSize
,
ui32SampleRate
,
ui8PlayloadType
,
ui8Interleaved
);
default
:
...
...
@@ -188,6 +164,8 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) {
switch
(
codecId
){
case
CodecH264
:
return
std
::
make_shared
<
H264RtpDecoder
>
();
case
CodecH265
:
return
std
::
make_shared
<
H265RtpDecoder
>
();
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpDecoder
>
();
default
:
...
...
@@ -196,6 +174,49 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) {
}
}
/////////////////////////////rtmp相关///////////////////////////////////////////
Track
::
Ptr
Factory
::
getTrackByAmf
(
const
AMFValue
&
amf
)
{
CodecId
codecId
=
getCodecIdByAmf
(
amf
);
if
(
codecId
==
CodecInvalid
){
return
nullptr
;
}
return
getTrackByCodecId
(
codecId
);
}
CodecId
Factory
::
getCodecIdByAmf
(
const
AMFValue
&
val
){
if
(
val
.
type
()
==
AMF_STRING
){
auto
str
=
val
.
as_string
();
if
(
str
==
"avc1"
){
return
CodecH264
;
}
if
(
str
==
"mp4a"
){
return
CodecAAC
;
}
WarnL
<<
"暂不支持该Amf:"
<<
str
;
return
CodecInvalid
;
}
if
(
val
.
type
()
!=
AMF_NULL
){
auto
type_id
=
val
.
as_integer
();
switch
(
type_id
){
case
7
:{
return
CodecH264
;
}
case
10
:{
return
CodecAAC
;
}
default
:
WarnL
<<
"暂不支持该Amf:"
<<
type_id
;
return
CodecInvalid
;
}
}
WarnL
<<
"暂不支持该Amf:"
<<
val
.
type
();
return
CodecInvalid
;
}
RtmpCodec
::
Ptr
Factory
::
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
)
{
switch
(
track
->
getCodecId
()){
case
CodecH264
:
...
...
This diff is collapsed.
Click to expand it.
src/Rtsp/RtspPlayer.cpp
查看文件 @
946b00f4
...
...
@@ -435,11 +435,13 @@ void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
auto
strControlSuffix
=
strTrack
.
substr
(
1
+
strTrack
.
rfind
(
'/'
),
strTrack
.
find
(
';'
)
-
strTrack
.
rfind
(
'/'
)
-
1
);
auto
strRtpTime
=
FindField
(
strTrack
.
data
(),
"rtptime="
,
";"
);
auto
idx
=
getTrackIndexByControlSuffix
(
strControlSuffix
);
if
(
idx
!=
-
1
){
_aiFistStamp
[
idx
]
=
atoll
(
strRtpTime
.
data
())
*
1000
/
_aTrackInfo
[
idx
]
->
_samplerate
;
_aiNowStamp
[
idx
]
=
_aiFistStamp
[
idx
];
DebugL
<<
"rtptime(ms):"
<<
strControlSuffix
<<
" "
<<
strRtpTime
;
}
}
}
onPlayResult_l
(
SockException
(
Err_success
,
"rtsp play success"
));
}
else
{
_pRtpTimer
.
reset
();
...
...
This diff is collapsed.
Click to expand it.
src/RtspMuxer/H264RtpCodec.cpp
查看文件 @
946b00f4
...
...
@@ -42,7 +42,7 @@ typedef struct {
unsigned
type
:
5
;
}
FU
;
bool
MakeNalu
(
uint8_t
in
,
NALU
&
nal
)
{
static
bool
MakeNalu
(
uint8_t
in
,
NALU
&
nal
)
{
nal
.
forbidden_zero_bit
=
in
>>
7
;
if
(
nal
.
forbidden_zero_bit
)
{
return
false
;
...
...
@@ -51,7 +51,7 @@ bool MakeNalu(uint8_t in, NALU &nal) {
nal
.
type
=
in
&
0x1f
;
return
true
;
}
bool
MakeFU
(
uint8_t
in
,
FU
&
fu
)
{
static
bool
MakeFU
(
uint8_t
in
,
FU
&
fu
)
{
fu
.
S
=
in
>>
7
;
fu
.
E
=
(
in
>>
6
)
&
0x01
;
fu
.
R
=
(
in
>>
5
)
&
0x01
;
...
...
@@ -62,7 +62,6 @@ bool MakeFU(uint8_t in, FU &fu) {
return
true
;
}
H264RtpDecoder
::
H264RtpDecoder
()
{
_h264frame
=
obtainFrame
();
}
...
...
@@ -157,8 +156,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
//写入环形缓存
auto
lastSeq
=
_h264frame
->
sequence
;
RtpCodec
::
inputFrame
(
frame
);
_h264frame
=
obtainFrame
();
_h264frame
->
sequence
=
lastSeq
;
}
...
...
This diff is collapsed.
Click to expand it.
src/RtspMuxer/H265RtpCodec.cpp
查看文件 @
946b00f4
...
...
@@ -28,41 +28,41 @@
namespace
mediakit
{
typedef
struct
{
unsigned
forbidden_zero_bit
:
1
;
unsigned
nal_ref_idc
:
2
;
unsigned
type
:
5
;
}
NALU
;
//41
//42 0 1
//43 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
//44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//45 |F| Type | LayerId | TID |
//46 +-------------+-----------------+
//48 F = 0
//49 Type = 49 (fragmentation unit (FU))
//50 LayerId = 0
//51 TID = 1
//56 /*
//57 create the FU header
//58
//59 0 1 2 3 4 5 6 7
//60 +-+-+-+-+-+-+-+-+
//61 |S|E| FuType |
//62 +---------------+
//63
//64 S = variable
//65 E = variable
//66 FuType = NAL unit type
//67
typedef
struct
{
unsigned
S
:
1
;
unsigned
E
:
1
;
unsigned
R
:
1
;
unsigned
type
:
5
;
unsigned
type
:
6
;
}
FU
;
bool
MakeNalu
(
uint8_t
in
,
NALU
&
nal
)
{
nal
.
forbidden_zero_bit
=
in
>>
7
;
if
(
nal
.
forbidden_zero_bit
)
{
return
false
;
}
nal
.
nal_ref_idc
=
(
in
&
0x60
)
>>
5
;
nal
.
type
=
in
&
0x1f
;
return
true
;
}
bool
MakeFU
(
uint8_t
in
,
FU
&
fu
)
{
static
void
MakeFU
(
uint8_t
in
,
FU
&
fu
)
{
fu
.
S
=
in
>>
7
;
fu
.
E
=
(
in
>>
6
)
&
0x01
;
fu
.
R
=
(
in
>>
5
)
&
0x01
;
fu
.
type
=
in
&
0x1f
;
if
(
fu
.
R
!=
0
)
{
return
false
;
}
return
true
;
fu
.
type
=
in
&
0x3f
;
}
H265RtpDecoder
::
H265RtpDecoder
()
{
_h265frame
=
obtainFrame
();
}
...
...
@@ -93,38 +93,35 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
const
uint8_t
*
frame
=
(
uint8_t
*
)
rtppack
->
payload
+
rtppack
->
offset
;
int
length
=
rtppack
->
length
-
rtppack
->
offset
;
NALU
nal
;
MakeNalu
(
*
frame
,
nal
);
if
(
nal
.
type
>=
0
&&
nal
.
type
<
24
)
{
//a full frame
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
type
=
nal
.
type
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
sequence
=
rtppack
->
sequence
;
auto
isIDR
=
_h265frame
->
type
==
5
;
onGetH265
(
_h265frame
);
return
(
isIDR
);
//i frame
}
int
nal
=
H265_TYPE
(
frame
[
0
]);
if
(
nal
.
type
==
28
)
{
//FU-A
if
(
nal
>
50
){
WarnL
<<
"不支持该类型的265 RTP包"
<<
nal
;
return
false
;
// packet discard, Unsupported (HEVC) NAL type
}
switch
(
nal
)
{
case
50
:
case
48
:
// aggregated packet (AP) - with two or more NAL units
WarnL
<<
"不支持该类型的265 RTP包"
<<
nal
;
return
false
;
case
49
:
{
// fragmentation unit (FU)
FU
fu
;
MakeFU
(
frame
[
1
],
fu
);
if
(
fu
.
S
==
1
)
{
//FU-A start
char
tmp
=
(
nal
.
forbidden_zero_bit
<<
7
|
nal
.
nal_ref_idc
<<
5
|
fu
.
type
);
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
push_back
(
tmp
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h265frame
->
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
buffer
.
push_back
(
0x01
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h265frame
->
type
=
fu
.
type
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
sequence
=
rtppack
->
sequence
;
return
(
_h265frame
->
type
==
5
);
//i frame
return
(
_h265frame
->
keyFrame
()
);
//i frame
}
if
(
rtppack
->
sequence
!=
(
uint16_t
)
(
_h265frame
->
sequence
+
1
))
{
if
(
rtppack
->
sequence
!=
(
uint16_t
)
(
_h265frame
->
sequence
+
1
))
{
_h265frame
->
buffer
.
clear
();
WarnL
<<
"丢包,帧废弃:"
<<
rtppack
->
sequence
<<
","
<<
_h265frame
->
sequence
;
return
false
;
...
...
@@ -132,33 +129,36 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
_h265frame
->
sequence
=
rtppack
->
sequence
;
if
(
fu
.
E
==
1
)
{
//FU-A end
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
auto
isIDR
=
_h265frame
->
type
==
5
;
auto
isIDR
=
_h265frame
->
keyFrame
()
;
onGetH265
(
_h265frame
);
return
isIDR
;
}
//FU-A mid
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
return
false
;
}
WarnL
<<
"不支持的rtp类型:"
<<
nal
.
type
<<
" "
<<
rtppack
->
sequence
;
return
false
;
// 29 FU-B 单NAL单元B模式
// 24 STAP-A 单一时间的组合包
// 25 STAP-B 单一时间的组合包
// 26 MTAP16 多个时间的组合包
// 27 MTAP24 多个时间的组合包
// 0 udef
// 30 udef
// 31 udef
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
->
type
=
nal
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
sequence
=
rtppack
->
sequence
;
auto
isIDR
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
(
isIDR
);
//i frame
}
}
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
//写入环形缓存
auto
lastSeq
=
_h265frame
->
sequence
;
RtpCodec
::
inputFrame
(
frame
);
_h265frame
=
obtainFrame
();
_h265frame
->
sequence
=
lastSeq
;
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论