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
a86398b6
Commit
a86398b6
authored
Jul 22, 2023
by
xia-chu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化与完善rtmp协议相关代码
rtmp相关常量由宏改为枚举 明确rtmp包一些字段赋值含义
parent
47add544
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
160 行增加
和
145 行删除
+160
-145
src/Extension/AACRtmp.cpp
+29
-34
src/Extension/Factory.cpp
+17
-17
src/Extension/H264Rtmp.cpp
+45
-49
src/Extension/H265Rtmp.cpp
+19
-22
src/Rtmp/Rtmp.cpp
+0
-0
src/Rtmp/Rtmp.h
+49
-22
src/Rtmp/RtmpDemuxer.cpp
+1
-1
没有找到文件。
src/Extension/AACRtmp.cpp
查看文件 @
a86398b6
...
@@ -18,7 +18,7 @@ namespace mediakit {
...
@@ -18,7 +18,7 @@ namespace mediakit {
static
string
getAacCfg
(
const
RtmpPacket
&
thiz
)
{
static
string
getAacCfg
(
const
RtmpPacket
&
thiz
)
{
string
ret
;
string
ret
;
if
(
thiz
.
getMediaType
()
!=
FLV_CODEC_AAC
)
{
if
(
(
RtmpAudioCodec
)
thiz
.
getRtmpCodecId
()
!=
RtmpAudioCodec
::
aac
)
{
return
ret
;
return
ret
;
}
}
if
(
!
thiz
.
isCfgFrame
())
{
if
(
!
thiz
.
isCfgFrame
())
{
...
@@ -93,51 +93,45 @@ void AACRtmpEncoder::makeConfigPacket() {
...
@@ -93,51 +93,45 @@ void AACRtmpEncoder::makeConfigPacket() {
bool
AACRtmpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
bool
AACRtmpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
if
(
_aac_cfg
.
empty
())
{
if
(
_aac_cfg
.
empty
())
{
if
(
frame
->
prefixSize
())
{
if
(
frame
->
prefixSize
())
{
//包含adts头,从adts头获取aac配置信息
//
包含adts头,从adts头获取aac配置信息
_aac_cfg
=
makeAacConfig
((
uint8_t
*
)
(
frame
->
data
()),
frame
->
prefixSize
());
_aac_cfg
=
makeAacConfig
((
uint8_t
*
)(
frame
->
data
()),
frame
->
prefixSize
());
}
}
makeConfigPacket
();
makeConfigPacket
();
}
}
if
(
_aac_cfg
.
empty
())
{
if
(
_aac_cfg
.
empty
())
{
return
false
;
return
false
;
}
}
auto
rtmpPkt
=
RtmpPacket
::
create
();
auto
pkt
=
RtmpPacket
::
create
();
//header
// header
uint8_t
is_config
=
false
;
pkt
->
buffer
.
push_back
(
_audio_flv_flags
);
rtmpPkt
->
buffer
.
push_back
(
_audio_flv_flags
);
pkt
->
buffer
.
push_back
((
uint8_t
)
RtmpAACPacketType
::
aac_raw
);
rtmpPkt
->
buffer
.
push_back
(
!
is_config
);
// aac data
pkt
->
buffer
.
append
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
());
//aac data
pkt
->
body_size
=
pkt
->
buffer
.
size
();
rtmpPkt
->
buffer
.
append
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
());
pkt
->
chunk_id
=
CHUNK_AUDIO
;
pkt
->
stream_index
=
STREAM_MEDIA
;
rtmpPkt
->
body_size
=
rtmpPkt
->
buffer
.
size
();
pkt
->
time_stamp
=
frame
->
dts
();
rtmpPkt
->
chunk_id
=
CHUNK_AUDIO
;
pkt
->
type_id
=
MSG_AUDIO
;
rtmpPkt
->
stream_index
=
STREAM_MEDIA
;
RtmpCodec
::
inputRtmp
(
pkt
);
rtmpPkt
->
time_stamp
=
frame
->
dts
();
rtmpPkt
->
type_id
=
MSG_AUDIO
;
RtmpCodec
::
inputRtmp
(
rtmpPkt
);
return
true
;
return
true
;
}
}
void
AACRtmpEncoder
::
makeAudioConfigPkt
()
{
void
AACRtmpEncoder
::
makeAudioConfigPkt
()
{
_audio_flv_flags
=
getAudioRtmpFlags
(
std
::
make_shared
<
AACTrack
>
(
_aac_cfg
));
_audio_flv_flags
=
getAudioRtmpFlags
(
std
::
make_shared
<
AACTrack
>
(
_aac_cfg
));
auto
rtmpPkt
=
RtmpPacket
::
create
();
auto
pkt
=
RtmpPacket
::
create
();
// header
//header
pkt
->
buffer
.
push_back
(
_audio_flv_flags
);
uint8_t
is_config
=
true
;
pkt
->
buffer
.
push_back
((
uint8_t
)
RtmpAACPacketType
::
aac_config_header
);
rtmpPkt
->
buffer
.
push_back
(
_audio_flv_flags
);
// aac config
rtmpPkt
->
buffer
.
push_back
(
!
is_config
);
pkt
->
buffer
.
append
(
_aac_cfg
);
//aac config
pkt
->
body_size
=
pkt
->
buffer
.
size
();
rtmpPkt
->
buffer
.
append
(
_aac_cfg
);
pkt
->
chunk_id
=
CHUNK_AUDIO
;
pkt
->
stream_index
=
STREAM_MEDIA
;
rtmpPkt
->
body_size
=
rtmpPkt
->
buffer
.
size
();
pkt
->
time_stamp
=
0
;
rtmpPkt
->
chunk_id
=
CHUNK_AUDIO
;
pkt
->
type_id
=
MSG_AUDIO
;
rtmpPkt
->
stream_index
=
STREAM_MEDIA
;
RtmpCodec
::
inputRtmp
(
pkt
);
rtmpPkt
->
time_stamp
=
0
;
rtmpPkt
->
type_id
=
MSG_AUDIO
;
RtmpCodec
::
inputRtmp
(
rtmpPkt
);
}
}
}
//
namespace
mediakit
}
//
namespace
mediakit
\ No newline at end of file
src/Extension/Factory.cpp
查看文件 @
a86398b6
...
@@ -201,11 +201,11 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){
...
@@ -201,11 +201,11 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){
}
}
if
(
val
.
type
()
!=
AMF_NULL
)
{
if
(
val
.
type
()
!=
AMF_NULL
)
{
auto
type_id
=
val
.
as_integer
();
auto
type_id
=
(
RtmpVideoCodec
)
val
.
as_integer
();
switch
(
type_id
)
{
switch
(
type_id
)
{
case
FLV_CODEC_H264
:
return
CodecH264
;
case
RtmpVideoCodec
:
:
h264
:
return
CodecH264
;
case
FLV_CODEC_H265
:
return
CodecH265
;
case
RtmpVideoCodec
:
:
h265
:
return
CodecH265
;
default
:
WarnL
<<
"暂不支持该视频Amf:"
<<
type_id
;
return
CodecInvalid
;
default
:
WarnL
<<
"暂不支持该视频Amf:"
<<
(
int
)
type_id
;
return
CodecInvalid
;
}
}
}
}
return
CodecInvalid
;
return
CodecInvalid
;
...
@@ -243,13 +243,13 @@ static CodecId getAudioCodecIdByAmf(const AMFValue &val) {
...
@@ -243,13 +243,13 @@ static CodecId getAudioCodecIdByAmf(const AMFValue &val) {
}
}
if
(
val
.
type
()
!=
AMF_NULL
)
{
if
(
val
.
type
()
!=
AMF_NULL
)
{
auto
type_id
=
val
.
as_integer
();
auto
type_id
=
(
RtmpAudioCodec
)
val
.
as_integer
();
switch
(
type_id
)
{
switch
(
type_id
)
{
case
FLV_CODEC_AAC
:
return
CodecAAC
;
case
RtmpAudioCodec
:
:
aac
:
return
CodecAAC
;
case
FLV_CODEC_G711A
:
return
CodecG711A
;
case
RtmpAudioCodec
:
:
g711a
:
return
CodecG711A
;
case
FLV_CODEC_G711U
:
return
CodecG711U
;
case
RtmpAudioCodec
:
:
g711u
:
return
CodecG711U
;
case
FLV_CODEC_OPUS
:
return
CodecOpus
;
case
RtmpAudioCodec
:
:
opus
:
return
CodecOpus
;
default
:
WarnL
<<
"暂不支持该音频Amf:"
<<
type_id
;
return
CodecInvalid
;
default
:
WarnL
<<
"暂不支持该音频Amf:"
<<
(
int
)
type_id
;
return
CodecInvalid
;
}
}
}
}
...
@@ -291,13 +291,13 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track, bool is_enc
...
@@ -291,13 +291,13 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track, bool is_enc
}
}
AMFValue
Factory
::
getAmfByCodecId
(
CodecId
codecId
)
{
AMFValue
Factory
::
getAmfByCodecId
(
CodecId
codecId
)
{
switch
(
codecId
){
switch
(
codecId
)
{
case
CodecAAC
:
return
AMFValue
(
FLV_CODEC_AAC
);
case
CodecAAC
:
return
AMFValue
(
(
int
)
RtmpAudioCodec
::
aac
);
case
CodecH264
:
return
AMFValue
(
FLV_CODEC_H
264
);
case
CodecH264
:
return
AMFValue
(
(
int
)
RtmpVideoCodec
::
h
264
);
case
CodecH265
:
return
AMFValue
(
FLV_CODEC_H
265
);
case
CodecH265
:
return
AMFValue
(
(
int
)
RtmpVideoCodec
::
h
265
);
case
CodecG711A
:
return
AMFValue
(
FLV_CODEC_G711A
);
case
CodecG711A
:
return
AMFValue
(
(
int
)
RtmpAudioCodec
::
g711a
);
case
CodecG711U
:
return
AMFValue
(
FLV_CODEC_G711U
);
case
CodecG711U
:
return
AMFValue
(
(
int
)
RtmpAudioCodec
::
g711u
);
case
CodecOpus
:
return
AMFValue
(
FLV_CODEC_OPUS
);
case
CodecOpus
:
return
AMFValue
(
(
int
)
RtmpAudioCodec
::
opus
);
default
:
return
AMFValue
(
AMF_NULL
);
default
:
return
AMFValue
(
AMF_NULL
);
}
}
}
}
...
...
src/Extension/H264Rtmp.cpp
查看文件 @
a86398b6
...
@@ -30,7 +30,7 @@ H264Frame::Ptr H264RtmpDecoder::obtainFrame() {
...
@@ -30,7 +30,7 @@ H264Frame::Ptr H264RtmpDecoder::obtainFrame() {
* 返回不带0x00 00 00 01头的sps pps
* 返回不带0x00 00 00 01头的sps pps
*/
*/
static
bool
getH264Config
(
const
RtmpPacket
&
thiz
,
string
&
sps
,
string
&
pps
)
{
static
bool
getH264Config
(
const
RtmpPacket
&
thiz
,
string
&
sps
,
string
&
pps
)
{
if
(
thiz
.
getMediaType
()
!=
FLV_CODEC_H
264
)
{
if
(
(
RtmpVideoCodec
)
thiz
.
getRtmpCodecId
()
!=
RtmpVideoCodec
::
h
264
)
{
return
false
;
return
false
;
}
}
if
(
!
thiz
.
isCfgFrame
())
{
if
(
!
thiz
.
isCfgFrame
())
{
...
@@ -159,22 +159,21 @@ bool H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -159,22 +159,21 @@ bool H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
}
}
return
_merger
.
inputFrame
(
frame
,
[
this
](
uint64_t
dts
,
uint64_t
pts
,
const
Buffer
::
Ptr
&
,
bool
have_key_frame
)
{
return
_merger
.
inputFrame
(
frame
,
[
this
](
uint64_t
dts
,
uint64_t
pts
,
const
Buffer
::
Ptr
&
,
bool
have_key_frame
)
{
//flags
// flags
_rtmp_packet
->
buffer
[
0
]
=
FLV_CODEC_H264
|
((
have_key_frame
?
FLV_KEY_FRAME
:
FLV_INTER_FRAME
)
<<
4
);
_rtmp_packet
->
buffer
[
0
]
=
(
uint8_t
)
RtmpVideoCodec
::
h264
|
((
uint8_t
)(
have_key_frame
?
RtmpFrameType
::
key_frame
:
RtmpFrameType
::
inter_frame
)
<<
4
);
//not config
_rtmp_packet
->
buffer
[
1
]
=
(
uint8_t
)
RtmpH264PacketType
::
h264_nalu
;
_rtmp_packet
->
buffer
[
1
]
=
true
;
int32_t
cts
=
pts
-
dts
;
int32_t
cts
=
pts
-
dts
;
// cts
//cts
set_be24
(
&
_rtmp_packet
->
buffer
[
2
],
cts
);
set_be24
(
&
_rtmp_packet
->
buffer
[
2
],
cts
);
_rtmp_packet
->
time_stamp
=
dts
;
_rtmp_packet
->
time_stamp
=
dts
;
_rtmp_packet
->
body_size
=
_rtmp_packet
->
buffer
.
size
();
_rtmp_packet
->
body_size
=
_rtmp_packet
->
buffer
.
size
();
_rtmp_packet
->
chunk_id
=
CHUNK_VIDEO
;
_rtmp_packet
->
chunk_id
=
CHUNK_VIDEO
;
_rtmp_packet
->
stream_index
=
STREAM_MEDIA
;
_rtmp_packet
->
stream_index
=
STREAM_MEDIA
;
_rtmp_packet
->
type_id
=
MSG_VIDEO
;
_rtmp_packet
->
type_id
=
MSG_VIDEO
;
// 输出rtmp packet
//输出rtmp packet
RtmpCodec
::
inputRtmp
(
_rtmp_packet
);
RtmpCodec
::
inputRtmp
(
_rtmp_packet
);
_rtmp_packet
=
nullptr
;
_rtmp_packet
=
nullptr
;
},
&
_rtmp_packet
->
buffer
);
},
&
_rtmp_packet
->
buffer
);
}
}
void
H264RtmpEncoder
::
makeVideoConfigPkt
()
{
void
H264RtmpEncoder
::
makeVideoConfigPkt
()
{
...
@@ -182,42 +181,39 @@ void H264RtmpEncoder::makeVideoConfigPkt() {
...
@@ -182,42 +181,39 @@ void H264RtmpEncoder::makeVideoConfigPkt() {
WarnL
<<
"sps长度不足4字节"
;
WarnL
<<
"sps长度不足4字节"
;
return
;
return
;
}
}
int8_t
flags
=
FLV_CODEC_H264
;
auto
flags
=
(
uint8_t
)
RtmpVideoCodec
::
h264
;
flags
|=
(
FLV_KEY_FRAME
<<
4
);
flags
|=
((
uint8_t
)
RtmpFrameType
::
key_frame
<<
4
);
bool
is_config
=
true
;
auto
pkt
=
RtmpPacket
::
create
();
// header
auto
rtmpPkt
=
RtmpPacket
::
create
();
pkt
->
buffer
.
push_back
(
flags
);
//header
pkt
->
buffer
.
push_back
((
uint8_t
)
RtmpH264PacketType
::
h264_config_header
);
rtmpPkt
->
buffer
.
push_back
(
flags
);
// cts
rtmpPkt
->
buffer
.
push_back
(
!
is_config
);
pkt
->
buffer
.
append
(
"\x0\x0\x0"
,
3
);
//cts
// AVCDecoderConfigurationRecord start
rtmpPkt
->
buffer
.
append
(
"\x0\x0\x0"
,
3
);
pkt
->
buffer
.
push_back
(
1
);
// version
pkt
->
buffer
.
push_back
(
_sps
[
1
]);
// profile
//AVCDecoderConfigurationRecord start
pkt
->
buffer
.
push_back
(
_sps
[
2
]);
// compat
rtmpPkt
->
buffer
.
push_back
(
1
);
// version
pkt
->
buffer
.
push_back
(
_sps
[
3
]);
// level
rtmpPkt
->
buffer
.
push_back
(
_sps
[
1
]);
// profile
pkt
->
buffer
.
push_back
((
char
)
0xff
);
// 6 bits reserved + 2 bits nal size length - 1 (11)
rtmpPkt
->
buffer
.
push_back
(
_sps
[
2
]);
// compat
pkt
->
buffer
.
push_back
((
char
)
0xe1
);
// 3 bits reserved + 5 bits number of sps (00001)
rtmpPkt
->
buffer
.
push_back
(
_sps
[
3
]);
// level
// sps
rtmpPkt
->
buffer
.
push_back
((
char
)
0xff
);
// 6 bits reserved + 2 bits nal size length - 1 (11)
rtmpPkt
->
buffer
.
push_back
((
char
)
0xe1
);
// 3 bits reserved + 5 bits number of sps (00001)
//sps
uint16_t
size
=
(
uint16_t
)
_sps
.
size
();
uint16_t
size
=
(
uint16_t
)
_sps
.
size
();
size
=
htons
(
size
);
size
=
htons
(
size
);
rtmpPkt
->
buffer
.
append
((
char
*
)
&
size
,
2
);
pkt
->
buffer
.
append
((
char
*
)
&
size
,
2
);
rtmpP
kt
->
buffer
.
append
(
_sps
);
p
kt
->
buffer
.
append
(
_sps
);
//pps
//
pps
rtmpP
kt
->
buffer
.
push_back
(
1
);
// version
p
kt
->
buffer
.
push_back
(
1
);
// version
size
=
(
uint16_t
)
_pps
.
size
();
size
=
(
uint16_t
)
_pps
.
size
();
size
=
htons
(
size
);
size
=
htons
(
size
);
rtmpPkt
->
buffer
.
append
((
char
*
)
&
size
,
2
);
pkt
->
buffer
.
append
((
char
*
)
&
size
,
2
);
rtmpP
kt
->
buffer
.
append
(
_pps
);
p
kt
->
buffer
.
append
(
_pps
);
rtmpPkt
->
body_size
=
rtmpP
kt
->
buffer
.
size
();
pkt
->
body_size
=
p
kt
->
buffer
.
size
();
rtmpP
kt
->
chunk_id
=
CHUNK_VIDEO
;
p
kt
->
chunk_id
=
CHUNK_VIDEO
;
rtmpP
kt
->
stream_index
=
STREAM_MEDIA
;
p
kt
->
stream_index
=
STREAM_MEDIA
;
rtmpP
kt
->
time_stamp
=
0
;
p
kt
->
time_stamp
=
0
;
rtmpP
kt
->
type_id
=
MSG_VIDEO
;
p
kt
->
type_id
=
MSG_VIDEO
;
RtmpCodec
::
inputRtmp
(
rtmpP
kt
);
RtmpCodec
::
inputRtmp
(
p
kt
);
}
}
}
//namespace mediakit
}
//namespace mediakit
src/Extension/H265Rtmp.cpp
查看文件 @
a86398b6
...
@@ -50,7 +50,7 @@ static bool decode_HEVCDecoderConfigurationRecord(uint8_t *extra, size_t bytes,
...
@@ -50,7 +50,7 @@ static bool decode_HEVCDecoderConfigurationRecord(uint8_t *extra, size_t bytes,
* 返回不带0x00 00 00 01头的sps
* 返回不带0x00 00 00 01头的sps
*/
*/
static
bool
getH265ConfigFrame
(
const
RtmpPacket
&
thiz
,
string
&
frame
)
{
static
bool
getH265ConfigFrame
(
const
RtmpPacket
&
thiz
,
string
&
frame
)
{
if
(
thiz
.
getMediaType
()
!=
FLV_CODEC_H
265
)
{
if
(
(
RtmpVideoCodec
)
thiz
.
getRtmpCodecId
()
!=
RtmpVideoCodec
::
h
265
)
{
return
false
;
return
false
;
}
}
if
(
!
thiz
.
isCfgFrame
())
{
if
(
!
thiz
.
isCfgFrame
())
{
...
@@ -243,34 +243,31 @@ bool H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
...
@@ -243,34 +243,31 @@ bool H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
}
}
return
_merger
.
inputFrame
(
frame
,
[
this
](
uint64_t
dts
,
uint64_t
pts
,
const
Buffer
::
Ptr
&
,
bool
have_key_frame
)
{
return
_merger
.
inputFrame
(
frame
,
[
this
](
uint64_t
dts
,
uint64_t
pts
,
const
Buffer
::
Ptr
&
,
bool
have_key_frame
)
{
// flags
// flags
_rtmp_packet
->
buffer
[
0
]
=
FLV_CODEC_H265
|
((
have_key_frame
?
FLV_KEY_FRAME
:
FLV_INTER_FRAME
)
<<
4
);
_rtmp_packet
->
buffer
[
0
]
=
(
uint8_t
)
RtmpVideoCodec
::
h265
|
((
uint8_t
)(
have_key_frame
?
RtmpFrameType
::
key_frame
:
RtmpFrameType
::
inter_frame
)
<<
4
);
// not config
_rtmp_packet
->
buffer
[
1
]
=
(
uint8_t
)
RtmpH264PacketType
::
h264_nalu
;
_rtmp_packet
->
buffer
[
1
]
=
true
;
int32_t
cts
=
pts
-
dts
;
int32_t
cts
=
pts
-
dts
;
// cts
// cts
set_be24
(
&
_rtmp_packet
->
buffer
[
2
],
cts
);
set_be24
(
&
_rtmp_packet
->
buffer
[
2
],
cts
);
_rtmp_packet
->
time_stamp
=
dts
;
_rtmp_packet
->
body_size
=
_rtmp_packet
->
buffer
.
size
();
_rtmp_packet
->
time_stamp
=
dts
;
_rtmp_packet
->
chunk_id
=
CHUNK_VIDEO
;
_rtmp_packet
->
body_size
=
_rtmp_packet
->
buffer
.
size
();
_rtmp_packet
->
stream_index
=
STREAM_MEDIA
;
_rtmp_packet
->
chunk_id
=
CHUNK_VIDEO
;
_rtmp_packet
->
type_id
=
MSG_VIDEO
;
_rtmp_packet
->
stream_index
=
STREAM_MEDIA
;
// 输出rtmp packet
_rtmp_packet
->
type_id
=
MSG_VIDEO
;
RtmpCodec
::
inputRtmp
(
_rtmp_packet
);
// 输出rtmp packet
_rtmp_packet
=
nullptr
;
RtmpCodec
::
inputRtmp
(
_rtmp_packet
);
},
&
_rtmp_packet
->
buffer
);
_rtmp_packet
=
nullptr
;
},
&
_rtmp_packet
->
buffer
);
}
}
void
H265RtmpEncoder
::
makeVideoConfigPkt
()
{
void
H265RtmpEncoder
::
makeVideoConfigPkt
()
{
#ifdef ENABLE_MP4
#ifdef ENABLE_MP4
int8_t
flags
=
FLV_CODEC_H265
;
auto
flags
=
(
uint8_t
)
RtmpVideoCodec
::
h265
;
flags
|=
(
FLV_KEY_FRAME
<<
4
);
flags
|=
((
uint8_t
)
RtmpFrameType
::
key_frame
<<
4
);
bool
is_config
=
true
;
auto
pkt
=
RtmpPacket
::
create
();
auto
pkt
=
RtmpPacket
::
create
();
// header
// header
pkt
->
buffer
.
push_back
(
flags
);
pkt
->
buffer
.
push_back
(
flags
);
pkt
->
buffer
.
push_back
(
!
is_config
);
pkt
->
buffer
.
push_back
(
(
uint8_t
)
RtmpH264PacketType
::
h264_config_header
);
// cts
// cts
pkt
->
buffer
.
append
(
"\x0\x0\x0"
,
3
);
pkt
->
buffer
.
append
(
"\x0\x0\x0"
,
3
);
...
...
src/Rtmp/Rtmp.cpp
查看文件 @
a86398b6
差异被折叠。
点击展开。
src/Rtmp/Rtmp.h
查看文件 @
a86398b6
...
@@ -63,18 +63,6 @@
...
@@ -63,18 +63,6 @@
#define CHUNK_AUDIO 6
/*音频chunkID*/
#define CHUNK_AUDIO 6
/*音频chunkID*/
#define CHUNK_VIDEO 7
/*视频chunkID*/
#define CHUNK_VIDEO 7
/*视频chunkID*/
#define FLV_KEY_FRAME 1
#define FLV_INTER_FRAME 2
#define FLV_CODEC_AAC 10
#define FLV_CODEC_H264 7
//金山扩展: https://github.com/ksvc/FFmpeg/wiki
#define FLV_CODEC_H265 12
#define FLV_CODEC_G711A 7
#define FLV_CODEC_G711U 8
//参考学而思网校: https://github.com/notedit/rtmp/commit/6e314ac5b29611431f8fb5468596b05815743c10
#define FLV_CODEC_OPUS 13
namespace
mediakit
{
namespace
mediakit
{
#if defined(_WIN32)
#if defined(_WIN32)
...
@@ -181,12 +169,9 @@ public:
...
@@ -181,12 +169,9 @@ public:
}
}
void
clear
();
void
clear
();
bool
isVideoKeyFrame
()
const
;
bool
isVideoKeyFrame
()
const
;
bool
isCfgFrame
()
const
;
bool
isCfgFrame
()
const
;
int
getRtmpCodecId
()
const
;
int
getMediaType
()
const
;
int
getAudioSampleRate
()
const
;
int
getAudioSampleRate
()
const
;
int
getAudioSampleBit
()
const
;
int
getAudioSampleBit
()
const
;
int
getAudioChannel
()
const
;
int
getAudioChannel
()
const
;
...
@@ -269,6 +254,10 @@ private:
...
@@ -269,6 +254,10 @@ private:
//根据音频track获取flags
//根据音频track获取flags
uint8_t
getAudioRtmpFlags
(
const
Track
::
Ptr
&
track
);
uint8_t
getAudioRtmpFlags
(
const
Track
::
Ptr
&
track
);
////////////////// rtmp video //////////////////////////
//https://rtmp.veriskope.com/pdf/video_file_format_spec_v10_1.pdf
// UB [4]; Type of video frame.
enum
class
RtmpFrameType
:
uint8_t
{
enum
class
RtmpFrameType
:
uint8_t
{
reserved
=
0
,
reserved
=
0
,
key_frame
=
1
,
// key frame (for AVC, a seekable frame)
key_frame
=
1
,
// key frame (for AVC, a seekable frame)
...
@@ -278,6 +267,7 @@ enum class RtmpFrameType : uint8_t {
...
@@ -278,6 +267,7 @@ enum class RtmpFrameType : uint8_t {
video_info_frame
=
5
,
// video info/command frame
video_info_frame
=
5
,
// video info/command frame
};
};
// UB [4]; Codec Identifier.
enum
class
RtmpVideoCodec
:
uint8_t
{
enum
class
RtmpVideoCodec
:
uint8_t
{
h263
=
2
,
// Sorenson H.263
h263
=
2
,
// Sorenson H.263
screen_video
=
3
,
// Screen video
screen_video
=
3
,
// Screen video
...
@@ -288,12 +278,15 @@ enum class RtmpVideoCodec : uint8_t {
...
@@ -288,12 +278,15 @@ enum class RtmpVideoCodec : uint8_t {
h265
=
12
,
// 国内扩展
h265
=
12
,
// 国内扩展
};
};
// UI8;
enum
class
RtmpH264PacketType
:
uint8_t
{
enum
class
RtmpH264PacketType
:
uint8_t
{
h264_config_header
=
0
,
// AVC sequence header(sps/pps)
h264_config_header
=
0
,
// AVC
or HEVC
sequence header(sps/pps)
h264_nalu
=
1
,
// AVC NALU
h264_nalu
=
1
,
// AVC
or HEVC
NALU
h264_end_seq
=
2
,
// AVC end of sequence (lower level NALU sequence ender is not REQUIRED or supported)
h264_end_seq
=
2
,
// AVC
or HEVC
end of sequence (lower level NALU sequence ender is not REQUIRED or supported)
};
};
// https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp.pdf
// UB[4]
enum
class
RtmpPacketType
:
uint8_t
{
enum
class
RtmpPacketType
:
uint8_t
{
PacketTypeSequenceStart
=
0
,
PacketTypeSequenceStart
=
0
,
PacketTypeCodedFrames
=
1
,
PacketTypeCodedFrames
=
1
,
...
@@ -321,15 +314,49 @@ enum class RtmpPacketType : uint8_t {
...
@@ -321,15 +314,49 @@ enum class RtmpPacketType : uint8_t {
PacketTypeMPEG2TSSequenceStart
=
5
,
PacketTypeMPEG2TSSequenceStart
=
5
,
};
};
////////////////// rtmp audio //////////////////////////
//https://rtmp.veriskope.com/pdf/video_file_format_spec_v10_1.pdf
// UB [4]; Format of SoundData
enum
class
RtmpAudioCodec
:
uint8_t
{
/**
0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16 kHz mono
5 = Nellymoser 8 kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM
8 = G.711 mu-law logarithmic PCM
9 = reserved
10 = AAC
11 = Speex
14 = MP3 8 kHz
15 = Device-specific sound
*/
g711a
=
7
,
g711u
=
8
,
aac
=
10
,
opus
=
13
// 国内扩展
};
// UI8;
enum
class
RtmpAACPacketType
:
uint8_t
{
aac_config_header
=
0
,
// AAC sequence header
aac_raw
=
1
,
// AAC raw
};
////////////////////////////////////////////
struct
RtmpPacketInfo
{
struct
RtmpPacketInfo
{
CodecId
codec
=
CodecInvalid
;
CodecId
codec
=
CodecInvalid
;
bool
is_enhanced
;
bool
is_enhanced
;
union
{
union
{
struct
{
struct
{
RtmpFrameType
frame_type
;
RtmpFrameType
frame_type
;
RtmpVideoCodec
rtmp_codec
;
RtmpPacketType
pkt_type
;
// enhanced = true
RtmpPacketType
pkt_type
;
RtmpH264PacketType
h264_pkt_type
;
// enhanced = false
RtmpH264PacketType
h264_pkt_type
;
}
video
;
}
video
;
};
};
};
};
...
...
src/Rtmp/RtmpDemuxer.cpp
查看文件 @
a86398b6
...
@@ -132,7 +132,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
...
@@ -132,7 +132,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
case
MSG_AUDIO
:
{
case
MSG_AUDIO
:
{
if
(
!
_try_get_audio_track
)
{
if
(
!
_try_get_audio_track
)
{
_try_get_audio_track
=
true
;
_try_get_audio_track
=
true
;
auto
codec
=
AMFValue
(
pkt
->
get
MediaType
());
auto
codec
=
AMFValue
(
pkt
->
get
RtmpCodecId
());
makeAudioTrack
(
codec
,
pkt
->
getAudioSampleRate
(),
pkt
->
getAudioChannel
(),
pkt
->
getAudioSampleBit
(),
0
);
makeAudioTrack
(
codec
,
pkt
->
getAudioSampleRate
(),
pkt
->
getAudioChannel
(),
pkt
->
getAudioSampleBit
(),
0
);
}
}
if
(
_audio_rtmp_decoder
)
{
if
(
_audio_rtmp_decoder
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论