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
bacf8f10
Commit
bacf8f10
authored
Apr 18, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
G711支持多种规格
parent
5c3418a4
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
204 行增加
和
197 行删除
+204
-197
src/Common/Device.cpp
+1
-1
src/Common/MediaSink.cpp
+2
-2
src/Extension/AACRtmp.cpp
+3
-31
src/Extension/AACRtmp.h
+1
-1
src/Extension/Factory.cpp
+35
-66
src/Extension/Factory.h
+1
-8
src/Extension/G711.cpp
+1
-2
src/Extension/G711.h
+22
-18
src/Extension/G711Rtmp.cpp
+4
-42
src/Extension/G711Rtmp.h
+1
-1
src/Rtmp/Rtmp.cpp
+59
-1
src/Rtmp/Rtmp.h
+16
-15
src/Rtmp/RtmpDemuxer.cpp
+48
-5
src/Rtmp/RtmpDemuxer.h
+1
-1
src/Rtmp/RtmpSession.cpp
+0
-1
src/Rtsp/Rtsp.cpp
+8
-2
src/Rtsp/Rtsp.h
+1
-0
没有找到文件。
src/Common/Device.cpp
查看文件 @
bacf8f10
...
...
@@ -196,7 +196,7 @@ void DevChannel::initAudio(const AudioInfo& info) {
}
case
CodecG711A
:
case
CodecG711U
:
addTrack
(
std
::
make_shared
<
G711Track
>
(
info
.
codecId
));
break
;
case
CodecG711U
:
addTrack
(
std
::
make_shared
<
G711Track
>
(
info
.
codecId
,
info
.
iSampleRate
,
info
.
iChannel
,
info
.
iSampleBit
));
break
;
default
:
WarnL
<<
"不支持该类型的音频编码类型:"
<<
info
.
codecId
;
break
;
}
}
...
...
src/Common/MediaSink.cpp
查看文件 @
bacf8f10
...
...
@@ -42,8 +42,8 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
if
(
_allTrackReady
)
{
//运行至这里说明Track状态由未就绪切换为已就绪状态,那么这帧就不应该丢弃
onTrackFrame
(
frame
);
}
else
{
ErrorL
<<
"some track is unready,drop
frame of: "
<<
frame
->
getCodecName
();
}
else
if
(
frame
->
keyFrame
())
{
WarnL
<<
"some track is unready,drop key
frame of: "
<<
frame
->
getCodecName
();
}
}));
}
...
...
src/Extension/AACRtmp.cpp
查看文件 @
bacf8f10
...
...
@@ -104,7 +104,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
//header
uint8_t
is_config
=
false
;
rtmpPkt
->
strBuf
.
push_back
(
_
ui8AudioF
lags
);
rtmpPkt
->
strBuf
.
push_back
(
_
audio_flv_f
lags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
//aac data
...
...
@@ -117,44 +117,16 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
rtmpPkt
->
typeId
=
MSG_AUDIO
;
RtmpCodec
::
inputRtmp
(
rtmpPkt
,
false
);
}
}
void
AACRtmpEncoder
::
makeAudioConfigPkt
()
{
makeAdtsHeader
(
_aac_cfg
,
*
_adts
);
int
iSampleRate
,
iChannel
,
iSampleBit
=
16
;
getAACInfo
(
*
_adts
,
iSampleRate
,
iChannel
);
uint8_t
flvStereoOrMono
=
(
iChannel
>
1
);
uint8_t
flvSampleRate
;
switch
(
iSampleRate
)
{
case
48000
:
case
44100
:
flvSampleRate
=
3
;
break
;
case
24000
:
case
22050
:
flvSampleRate
=
2
;
break
;
case
12000
:
case
11025
:
flvSampleRate
=
1
;
break
;
default
:
flvSampleRate
=
0
;
break
;
}
uint8_t
flvSampleBit
=
iSampleBit
==
16
;
uint8_t
flvAudioType
=
FLV_CODEC_AAC
;
_ui8AudioFlags
=
(
flvAudioType
<<
4
)
|
(
flvSampleRate
<<
2
)
|
(
flvSampleBit
<<
1
)
|
flvStereoOrMono
;
_audio_flv_flags
=
getAudioRtmpFlags
(
std
::
make_shared
<
AACTrack
>
(
_aac_cfg
));
RtmpPacket
::
Ptr
rtmpPkt
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
rtmpPkt
->
strBuf
.
clear
();
//header
uint8_t
is_config
=
true
;
rtmpPkt
->
strBuf
.
push_back
(
_
ui8AudioF
lags
);
rtmpPkt
->
strBuf
.
push_back
(
_
audio_flv_f
lags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
//aac config
rtmpPkt
->
strBuf
.
append
(
_aac_cfg
);
...
...
src/Extension/AACRtmp.h
查看文件 @
bacf8f10
...
...
@@ -79,7 +79,7 @@ public:
private
:
void
makeAudioConfigPkt
();
private
:
uint8_t
_
ui8AudioF
lags
;
uint8_t
_
audio_flv_f
lags
;
AACTrack
::
Ptr
_track
;
};
...
...
src/Extension/Factory.cpp
查看文件 @
bacf8f10
...
...
@@ -48,11 +48,11 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
}
if
(
strcasecmp
(
track
->
_codec
.
data
(),
"PCMA"
)
==
0
)
{
return
std
::
make_shared
<
G711Track
>
(
CodecG711A
);
return
std
::
make_shared
<
G711Track
>
(
CodecG711A
,
track
->
_samplerate
,
track
->
_channel
,
16
);
}
if
(
strcasecmp
(
track
->
_codec
.
data
(),
"PCMU"
)
==
0
)
{
return
std
::
make_shared
<
G711Track
>
(
CodecG711U
);
return
std
::
make_shared
<
G711Track
>
(
CodecG711U
,
track
->
_samplerate
,
track
->
_channel
,
16
);
}
if
(
strcasecmp
(
track
->
_codec
.
data
(),
"h264"
)
==
0
)
{
...
...
@@ -88,29 +88,6 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
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
>
();
}
case
CodecG711A
:
{
return
std
::
make_shared
<
G711Track
>
(
CodecG711A
);
}
case
CodecG711U
:
{
return
std
::
make_shared
<
G711Track
>
(
CodecG711U
);
}
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
codecId
;
return
nullptr
;
}
}
RtpCodec
::
Ptr
Factory
::
getRtpEncoderBySdp
(
const
Sdp
::
Ptr
&
sdp
)
{
GET_CONFIG
(
uint32_t
,
audio_mtu
,
Rtp
::
kAudioMtuSize
);
GET_CONFIG
(
uint32_t
,
video_mtu
,
Rtp
::
kVideoMtuSize
);
...
...
@@ -134,35 +111,23 @@ RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) {
auto
interleaved
=
sdp
->
getTrackType
()
*
2
;
auto
codec_id
=
sdp
->
getCodecId
();
switch
(
codec_id
){
case
CodecH264
:
return
std
::
make_shared
<
H264RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
codec_id
;
return
nullptr
;
case
CodecH264
:
return
std
::
make_shared
<
H264RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtpEncoder
>
(
ssrc
,
mtu
,
sample_rate
,
pt
,
interleaved
);
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
codec_id
;
return
nullptr
;
}
}
RtpCodec
::
Ptr
Factory
::
getRtpDecoderByTrack
(
const
Track
::
Ptr
&
track
)
{
switch
(
track
->
getCodecId
()){
case
CodecH264
:
return
std
::
make_shared
<
H264RtpDecoder
>
();
case
CodecH265
:
return
std
::
make_shared
<
H265RtpDecoder
>
();
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpDecoder
>
(
track
->
clone
());
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtpDecoder
>
(
track
->
clone
());
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
track
->
getCodecName
();
return
nullptr
;
case
CodecH264
:
return
std
::
make_shared
<
H264RtpDecoder
>
();
case
CodecH265
:
return
std
::
make_shared
<
H265RtpDecoder
>
();
case
CodecAAC
:
return
std
::
make_shared
<
AACRtpDecoder
>
(
track
->
clone
());
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtpDecoder
>
(
track
->
clone
());
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
track
->
getCodecName
();
return
nullptr
;
}
}
...
...
@@ -190,15 +155,25 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){
case
FLV_CODEC_H264
:
return
CodecH264
;
case
FLV_CODEC_AAC
:
return
CodecAAC
;
case
FLV_CODEC_H265
:
return
CodecH265
;
default
:
WarnL
<<
"暂不支持该Amf:"
<<
type_id
;
return
CodecInvalid
;
default
:
WarnL
<<
"暂不支持该Amf:"
<<
type_id
;
return
CodecInvalid
;
}
}
return
CodecInvalid
;
}
Track
::
Ptr
getTrackByCodecId
(
CodecId
codecId
,
int
sample_rate
=
0
,
int
channels
=
0
,
int
sample_bit
=
0
)
{
switch
(
codecId
){
case
CodecH264
:
return
std
::
make_shared
<
H264Track
>
();
case
CodecH265
:
return
std
::
make_shared
<
H265Track
>
();
case
CodecAAC
:
return
std
::
make_shared
<
AACTrack
>
();
case
CodecG711A
:
case
CodecG711U
:
return
(
sample_rate
&&
channels
&&
sample_bit
)
?
std
::
make_shared
<
G711Track
>
(
codecId
,
sample_rate
,
channels
,
sample_bit
)
:
nullptr
;
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
codecId
;
return
nullptr
;
}
}
Track
::
Ptr
Factory
::
getVideoTrackByAmf
(
const
AMFValue
&
amf
)
{
CodecId
codecId
=
getVideoCodecIdByAmf
(
amf
);
if
(
codecId
==
CodecInvalid
){
...
...
@@ -230,28 +205,22 @@ static CodecId getAudioCodecIdByAmf(const AMFValue &val) {
return
CodecInvalid
;
}
Track
::
Ptr
Factory
::
getAudioTrackByAmf
(
const
AMFValue
&
amf
){
Track
::
Ptr
Factory
::
getAudioTrackByAmf
(
const
AMFValue
&
amf
,
int
sample_rate
,
int
channels
,
int
sample_bit
){
CodecId
codecId
=
getAudioCodecIdByAmf
(
amf
);
if
(
codecId
==
CodecInvalid
)
{
return
nullptr
;
}
return
getTrackByCodecId
(
codecId
);
return
getTrackByCodecId
(
codecId
,
sample_rate
,
channels
,
sample_bit
);
}
RtmpCodec
::
Ptr
Factory
::
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
)
{
switch
(
track
->
getCodecId
()){
case
CodecH264
:
return
std
::
make_shared
<
H264RtmpEncoder
>
(
track
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtmpEncoder
>
(
track
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtmpEncoder
>
(
track
);
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtmpEncoder
>
(
track
);
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
track
->
getCodecName
();
return
nullptr
;
case
CodecH264
:
return
std
::
make_shared
<
H264RtmpEncoder
>
(
track
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtmpEncoder
>
(
track
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtmpEncoder
>
(
track
);
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtmpEncoder
>
(
track
);
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
track
->
getCodecName
();
return
nullptr
;
}
}
...
...
src/Extension/Factory.h
查看文件 @
bacf8f10
...
...
@@ -24,13 +24,6 @@ namespace mediakit{
class
Factory
{
public
:
/**
* 根据CodecId获取Track,该Track的ready()状态一般都为false
* @param codecId 编解码器id
*/
static
Track
::
Ptr
getTrackByCodecId
(
CodecId
codecId
);
////////////////////////////////rtsp相关//////////////////////////////////
/**
* 根据sdp生成Track对象
...
...
@@ -61,7 +54,7 @@ public:
* 根据amf对象获取音频相应的Track
* @param amf rtmp metadata中的audiocodecid的值
*/
static
Track
::
Ptr
getAudioTrackByAmf
(
const
AMFValue
&
amf
);
static
Track
::
Ptr
getAudioTrackByAmf
(
const
AMFValue
&
amf
,
int
sample_rate
,
int
channels
,
int
sample_bit
);
/**
* 根据Track获取Rtmp的编解码器
...
...
src/Extension/G711.cpp
查看文件 @
bacf8f10
...
...
@@ -12,13 +12,12 @@
namespace
mediakit
{
Sdp
::
Ptr
G711Track
::
getSdp
()
{
if
(
!
ready
()){
WarnL
<<
getCodecName
()
<<
" Track未准备好"
;
return
nullptr
;
}
return
std
::
make_shared
<
G711Sdp
>
(
getCodecId
());
return
std
::
make_shared
<
G711Sdp
>
(
getCodecId
()
,
getAudioSampleRate
(),
getAudioChannel
()
);
}
}
//namespace mediakit
...
...
src/Extension/G711.h
查看文件 @
bacf8f10
...
...
@@ -102,8 +102,11 @@ public:
/**
* G711A G711U
*/
G711Track
(
CodecId
codecId
){
G711Track
(
CodecId
codecId
,
int
sample_rate
,
int
channels
,
int
sample_bit
){
_codecid
=
codecId
;
_sample_rate
=
sample_rate
;
_channels
=
channels
;
_sample_bit
=
sample_bit
;
}
/**
...
...
@@ -114,7 +117,7 @@ public:
}
/**
*
G711的Track不需要
初始化
*
是否已经
初始化
*/
bool
ready
()
override
{
return
true
;
...
...
@@ -124,21 +127,21 @@ public:
* 返回音频采样率
*/
int
getAudioSampleRate
()
const
override
{
return
8000
;
return
_sample_rate
;
}
/**
* 返回音频采样位数,一般为16或8
*/
int
getAudioSampleBit
()
const
override
{
return
16
;
return
_sample_bit
;
}
/**
* 返回音频通道数
*/
int
getAudioChannel
()
const
override
{
return
1
;
return
_channels
;
}
private
:
...
...
@@ -149,7 +152,10 @@ private:
//生成sdp
Sdp
::
Ptr
getSdp
()
override
;
private
:
CodecId
_codecid
=
CodecG711A
;
CodecId
_codecid
;
int
_sample_rate
;
int
_channels
;
int
_sample_bit
;
};
/**
...
...
@@ -160,11 +166,17 @@ public:
/**
* G711采样率固定为8000
* @param codecId G711A G711U
* @param sample_rate 音频采样率
* @param playload_type rtp playload
* @param bitrate 比特率
*/
G711Sdp
(
CodecId
codecId
)
:
Sdp
(
8000
,
payloadType
(
codecId
)),
_codecId
(
codecId
){
int
pt
=
payloadType
(
codecId
);
_printer
<<
"m=audio 0 RTP/AVP "
<<
pt
<<
"
\r\n
"
;
_printer
<<
"a=rtpmap:"
<<
pt
<<
(
codecId
==
CodecG711A
?
" PCMA/"
:
" PCMU/"
)
<<
8000
<<
"
\r\n
"
;
G711Sdp
(
CodecId
codecId
,
int
sample_rate
,
int
channels
,
int
playload_type
=
98
,
int
bitrate
=
128
)
:
Sdp
(
sample_rate
,
playload_type
),
_codecId
(
codecId
){
_printer
<<
"m=audio 0 RTP/AVP "
<<
playload_type
<<
"
\r\n
"
;
_printer
<<
"a=rtpmap:"
<<
playload_type
<<
(
codecId
==
CodecG711A
?
" PCMA/"
:
" PCMU/"
)
<<
sample_rate
<<
"/"
<<
channels
<<
"
\r\n
"
;
_printer
<<
"a=control:trackID="
<<
getTrackType
()
<<
"
\r\n
"
;
}
...
...
@@ -180,14 +192,6 @@ public:
return
_codecId
;
}
int
payloadType
(
CodecId
codecId
){
switch
(
codecId
){
case
CodecG711A
:
return
8
;
case
CodecG711U
:
return
0
;
default
:
return
-
1
;
}
}
private
:
_StrPrinter
_printer
;
CodecId
_codecId
;
...
...
src/Extension/G711Rtmp.cpp
查看文件 @
bacf8f10
...
...
@@ -27,7 +27,7 @@ G711Frame::Ptr G711RtmpDecoder::obtainFrame() {
bool
G711RtmpDecoder
::
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
,
bool
)
{
//拷贝G711负载
_frame
->
buffer
.
assign
(
pkt
->
strBuf
.
data
()
+
2
,
pkt
->
strBuf
.
size
()
-
2
);
_frame
->
buffer
.
assign
(
pkt
->
strBuf
.
data
()
+
1
,
pkt
->
strBuf
.
size
()
-
1
);
_frame
->
timeStamp
=
pkt
->
timeStamp
;
//写入环形缓存
RtmpCodec
::
inputFrame
(
_frame
);
...
...
@@ -38,55 +38,17 @@ bool G711RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) {
/////////////////////////////////////////////////////////////////////////////////////
G711RtmpEncoder
::
G711RtmpEncoder
(
const
Track
::
Ptr
&
track
)
:
G711RtmpDecoder
(
track
->
getCodecId
())
{
auto
g711_track
=
dynamic_pointer_cast
<
AudioTrack
>
(
track
);
if
(
!
g711_track
){
WarnL
<<
"无效的G711 track, 将忽略打包为RTMP"
;
return
;
}
auto
iSampleRate
=
g711_track
->
getAudioSampleRate
()
;
auto
iChannel
=
g711_track
->
getAudioChannel
();
auto
iSampleBit
=
g711_track
->
getAudioSampleBit
();
uint8_t
flvStereoOrMono
=
(
iChannel
>
1
);
uint8_t
flvSampleRate
;
switch
(
iSampleRate
)
{
case
48000
:
case
44100
:
flvSampleRate
=
3
;
break
;
case
24000
:
case
22050
:
flvSampleRate
=
2
;
break
;
case
12000
:
case
11025
:
flvSampleRate
=
1
;
break
;
default
:
flvSampleRate
=
0
;
break
;
}
uint8_t
flvSampleBit
=
iSampleBit
==
16
;
uint8_t
flvAudioType
;
switch
(
g711_track
->
getCodecId
()){
case
CodecG711A
:
flvAudioType
=
FLV_CODEC_G711A
;
break
;
case
CodecG711U
:
flvAudioType
=
FLV_CODEC_G711U
;
break
;
default
:
WarnL
<<
"无效的G711 track, 将忽略打包为RTMP"
;
return
;
}
_g711_flags
=
(
flvAudioType
<<
4
)
|
(
flvSampleRate
<<
2
)
|
(
flvSampleBit
<<
1
)
|
flvStereoOrMono
;
_audio_flv_flags
=
getAudioRtmpFlags
(
track
);
}
void
G711RtmpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
if
(
!
_
g711
_flags
){
if
(
!
_
audio_flv
_flags
){
return
;
}
RtmpPacket
::
Ptr
rtmpPkt
=
ResourcePoolHelper
<
RtmpPacket
>::
obtainObj
();
rtmpPkt
->
strBuf
.
clear
();
//header
uint8_t
is_config
=
false
;
rtmpPkt
->
strBuf
.
push_back
(
_g711_flags
);
rtmpPkt
->
strBuf
.
push_back
(
!
is_config
);
rtmpPkt
->
strBuf
.
push_back
(
_audio_flv_flags
);
//g711 data
rtmpPkt
->
strBuf
.
append
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
());
...
...
src/Extension/G711Rtmp.h
查看文件 @
bacf8f10
...
...
@@ -62,7 +62,7 @@ public:
*/
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
private
:
uint8_t
_
g711
_flags
=
0
;
uint8_t
_
audio_flv
_flags
=
0
;
};
}
//namespace mediakit
...
...
src/Rtmp/Rtmp.cpp
查看文件 @
bacf8f10
...
...
@@ -36,11 +36,68 @@ AudioMeta::AudioMeta(const AudioTrack::Ptr &audio,int datarate){
_metadata
.
set
(
"audiosamplesize"
,
audio
->
getAudioSampleBit
());
}
if
(
audio
->
getAudioChannel
()
>
0
){
_metadata
.
set
(
"audiochannels"
,
audio
->
getAudioChannel
());
_metadata
.
set
(
"stereo"
,
audio
->
getAudioChannel
()
>
1
);
}
_codecId
=
audio
->
getCodecId
();
_metadata
.
set
(
"audiocodecid"
,
Factory
::
getAmfByCodecId
(
_codecId
));
}
uint8_t
getAudioRtmpFlags
(
const
Track
::
Ptr
&
track
){
switch
(
track
->
getTrackType
()){
case
TrackAudio
:
{
auto
audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
track
);
if
(
!
audioTrack
)
{
WarnL
<<
"获取AudioTrack失败"
;
return
0
;
}
auto
iSampleRate
=
audioTrack
->
getAudioSampleRate
();
auto
iChannel
=
audioTrack
->
getAudioChannel
();
auto
iSampleBit
=
audioTrack
->
getAudioSampleBit
();
uint8_t
flvAudioType
;
switch
(
track
->
getCodecId
()){
case
CodecG711A
:
flvAudioType
=
FLV_CODEC_G711A
;
break
;
case
CodecG711U
:
flvAudioType
=
FLV_CODEC_G711U
;
break
;
case
CodecAAC
:
{
flvAudioType
=
FLV_CODEC_AAC
;
//aac不通过flags获取音频相关信息
iSampleRate
=
44100
;
iSampleBit
=
16
;
iChannel
=
2
;
break
;
}
default
:
WarnL
<<
"该编码格式不支持转换为RTMP: "
<<
track
->
getCodecName
();
return
0
;
}
uint8_t
flvSampleRate
;
switch
(
iSampleRate
)
{
case
44100
:
flvSampleRate
=
3
;
break
;
case
22050
:
flvSampleRate
=
2
;
break
;
case
11025
:
flvSampleRate
=
1
;
break
;
case
16000
:
// nellymoser only
case
8000
:
// nellymoser only
case
5512
:
// not MP3
flvSampleRate
=
0
;
break
;
default
:
WarnL
<<
"FLV does not support sample rate "
<<
iSampleRate
<<
" ,choose from (44100, 22050, 11025)"
;
return
0
;
}
uint8_t
flvStereoOrMono
=
(
iChannel
>
1
);
uint8_t
flvSampleBit
=
iSampleBit
==
16
;
return
(
flvAudioType
<<
4
)
|
(
flvSampleRate
<<
2
)
|
(
flvSampleBit
<<
1
)
|
flvStereoOrMono
;
}
default
:
return
0
;
}
}
}
//
namespace
mediakit
\ No newline at end of file
src/Rtmp/Rtmp.h
查看文件 @
bacf8f10
...
...
@@ -161,27 +161,26 @@ public:
strBuf
=
std
::
move
(
that
.
strBuf
);
}
bool
isVideoKeyFrame
()
const
{
return
typeId
==
MSG_VIDEO
&&
(
uint8_t
)
strBuf
[
0
]
>>
4
==
FLV_KEY_FRAME
&&
(
uint8_t
)
strBuf
[
1
]
==
1
;
return
typeId
==
MSG_VIDEO
&&
(
uint8_t
)
strBuf
[
0
]
>>
4
==
FLV_KEY_FRAME
&&
(
uint8_t
)
strBuf
[
1
]
==
1
;
}
bool
isCfgFrame
()
const
{
return
(
typeId
==
MSG_VIDEO
||
typeId
==
MSG_AUDIO
)
&&
(
uint8_t
)
strBuf
[
1
]
==
0
;
switch
(
typeId
){
case
MSG_VIDEO
:
return
strBuf
[
1
]
==
0
;
case
MSG_AUDIO
:
{
switch
(
getMediaType
()){
case
FLV_CODEC_AAC
:
return
strBuf
[
1
]
==
0
;
default
:
return
false
;
}
int
getMediaType
()
const
{
switch
(
typeId
)
{
case
MSG_VIDEO
:
{
return
(
uint8_t
)
strBuf
[
0
]
&
0x0F
;
}
break
;
case
MSG_AUDIO
:
{
return
(
uint8_t
)
strBuf
[
0
]
>>
4
;
default
:
return
false
;
}
break
;
default
:
break
;
}
return
0
;
int
getMediaType
()
const
{
switch
(
typeId
)
{
case
MSG_VIDEO
:
return
(
uint8_t
)
strBuf
[
0
]
&
0x0F
;
case
MSG_AUDIO
:
return
(
uint8_t
)
strBuf
[
0
]
>>
4
;
default
:
return
0
;
}
}
int
getAudioSampleRate
()
const
{
if
(
typeId
!=
MSG_AUDIO
)
{
...
...
@@ -314,6 +313,8 @@ private:
CodecId
_codecId
;
};
//根据音频track获取flags
uint8_t
getAudioRtmpFlags
(
const
Track
::
Ptr
&
track
);
}
//namespace mediakit
...
...
src/Rtmp/RtmpDemuxer.cpp
查看文件 @
bacf8f10
...
...
@@ -15,14 +15,55 @@ namespace mediakit {
void
RtmpDemuxer
::
loadMetaData
(
const
AMFValue
&
val
){
try
{
makeVideoTrack
(
val
[
"videocodecid"
]);
makeAudioTrack
(
val
[
"audiocodecid"
]);
int
audiosamplerate
=
0
;
int
audiochannels
=
0
;
int
audiosamplesize
=
0
;
const
AMFValue
*
audiocodecid
=
nullptr
;
const
AMFValue
*
videocodecid
=
nullptr
;
val
.
object_for_each
([
&
](
const
string
&
key
,
const
AMFValue
&
val
)
{
if
(
key
==
"duration"
)
{
_fDuration
=
val
.
as_number
();
return
;
}
if
(
key
==
"audiosamplerate"
){
audiosamplerate
=
val
.
as_integer
();
return
;
}
if
(
key
==
"audiosamplesize"
){
audiosamplesize
=
val
.
as_integer
();
return
;
}
if
(
key
==
"stereo"
){
audiochannels
=
val
.
as_boolean
()
?
2
:
1
;
return
;
}
if
(
key
==
"videocodecid"
){
//找到视频
videocodecid
=
&
val
;
return
;
}
if
(
key
==
"audiocodecid"
){
//找到音频
audiocodecid
=
&
val
;
return
;
}
});
if
(
videocodecid
){
//有视频
makeVideoTrack
(
*
videocodecid
);
}
if
(
audiocodecid
){
//有音频
makeAudioTrack
(
*
audiocodecid
,
audiosamplerate
,
audiochannels
,
audiosamplesize
);
}
}
catch
(
std
::
exception
&
ex
){
WarnL
<<
ex
.
what
();
}
...
...
@@ -46,7 +87,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
if
(
!
_tryedGetAudioTrack
)
{
_tryedGetAudioTrack
=
true
;
auto
codec
=
AMFValue
(
pkt
->
getMediaType
());
makeAudioTrack
(
codec
);
makeAudioTrack
(
codec
,
pkt
->
getAudioSampleRate
(),
pkt
->
getAudioChannel
(),
pkt
->
getAudioSampleBit
()
);
}
if
(
_audioRtmpDecoder
){
_audioRtmpDecoder
->
inputRtmp
(
pkt
,
false
);
...
...
@@ -69,6 +110,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
//设置rtmp解码器代理,生成的frame写入该Track
_videoRtmpDecoder
->
addDelegate
(
_videoTrack
);
onAddTrack
(
_videoTrack
);
_tryedGetVideoTrack
=
true
;
}
else
{
//找不到相应的rtmp解码器,该track无效
_videoTrack
.
reset
();
...
...
@@ -76,9 +118,9 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
}
}
void
RtmpDemuxer
::
makeAudioTrack
(
const
AMFValue
&
audioCodec
)
{
void
RtmpDemuxer
::
makeAudioTrack
(
const
AMFValue
&
audioCodec
,
int
sample_rate
,
int
channels
,
int
sample_bit
)
{
//生成Track对象
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getAudioTrackByAmf
(
audioCodec
));
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getAudioTrackByAmf
(
audioCodec
,
sample_rate
,
channels
,
sample_bit
));
if
(
_audioTrack
)
{
//生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_audioTrack
);
...
...
@@ -86,6 +128,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
//设置rtmp解码器代理,生成的frame写入该Track
_audioRtmpDecoder
->
addDelegate
(
_audioTrack
);
onAddTrack
(
_audioTrack
);
_tryedGetAudioTrack
=
true
;
}
else
{
//找不到相应的rtmp解码器,该track无效
_audioTrack
.
reset
();
...
...
src/Rtmp/RtmpDemuxer.h
查看文件 @
bacf8f10
...
...
@@ -40,7 +40,7 @@ public:
bool
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
);
private
:
void
makeVideoTrack
(
const
AMFValue
&
val
);
void
makeAudioTrack
(
const
AMFValue
&
val
);
void
makeAudioTrack
(
const
AMFValue
&
val
,
int
sample_rate
,
int
channels
,
int
sample_bit
);
private
:
bool
_tryedGetVideoTrack
=
false
;
bool
_tryedGetAudioTrack
=
false
;
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
bacf8f10
...
...
@@ -193,7 +193,6 @@ void RtmpSession::onCmd_deleteStream(AMFDecoder &dec) {
throw
std
::
runtime_error
(
StrPrinter
<<
"Stop publishing"
<<
endl
);
}
void
RtmpSession
::
sendPlayResponse
(
const
string
&
err
,
const
RtmpMediaSource
::
Ptr
&
src
){
bool
authSuccess
=
err
.
empty
();
bool
ok
=
(
src
.
operator
bool
()
&&
authSuccess
);
...
...
src/Rtsp/Rtsp.cpp
查看文件 @
bacf8f10
...
...
@@ -172,6 +172,7 @@ void SdpParser::load(const string &sdp) {
if
(
4
==
sscanf
(
opt_val
.
data
(),
" %15[^ ] %d %15[^ ] %d"
,
type
,
&
port
,
rtp
,
&
pt
))
{
track
->
_pt
=
pt
;
track
->
_samplerate
=
RtpPayload
::
getClockRate
(
pt
)
;
track
->
_channel
=
RtpPayload
::
getAudioChannel
(
pt
);
track
->
_type
=
toTrackType
(
type
);
track
->
_m
=
opt_val
;
track
->
_port
=
port
;
...
...
@@ -214,9 +215,14 @@ void SdpParser::load(const string &sdp) {
it
=
track
.
_attr
.
find
(
"rtpmap"
);
if
(
it
!=
track
.
_attr
.
end
()){
auto
rtpmap
=
it
->
second
;
int
pt
,
samplerate
;
int
pt
,
samplerate
,
channel
;
char
codec
[
16
]
=
{
0
};
if
(
3
==
sscanf
(
rtpmap
.
data
(),
"%d %15[^/]/%d"
,
&
pt
,
codec
,
&
samplerate
))
{
if
(
4
==
sscanf
(
rtpmap
.
data
(),
"%d %15[^/]/%d/%d"
,
&
pt
,
codec
,
&
samplerate
,
&
channel
))
{
track
.
_pt
=
pt
;
track
.
_codec
=
codec
;
track
.
_samplerate
=
samplerate
;
track
.
_channel
=
channel
;
}
else
if
(
3
==
sscanf
(
rtpmap
.
data
(),
"%d %15[^/]/%d"
,
&
pt
,
codec
,
&
samplerate
))
{
track
.
_pt
=
pt
;
track
.
_codec
=
codec
;
track
.
_samplerate
=
samplerate
;
...
...
src/Rtsp/Rtsp.h
查看文件 @
bacf8f10
...
...
@@ -128,6 +128,7 @@ public:
int
_pt
;
string
_codec
;
int
_samplerate
;
int
_channel
;
string
_fmtp
;
string
_control
;
string
_control_surffix
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论