Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
ac140fb6
提交
ac140fb6
authored
1月 29, 2015
作者:
Anthony Minessale
提交者:
Michael Jerris
5月 28, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
FS-7500: codec tweaks
上级
13c3f053
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
110 行增加
和
65 行删除
+110
-65
mod_openh264.cpp
src/mod/codecs/mod_openh264/mod_openh264.cpp
+76
-48
mod_vpx.c
src/mod/codecs/mod_vpx/mod_vpx.c
+22
-12
switch_core_media.c
src/switch_core_media.c
+12
-5
没有找到文件。
src/mod/codecs/mod_openh264/mod_openh264.cpp
浏览文件 @
ac140fb6
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
#include "codec_api.h"
#include "codec_api.h"
//#include "inc/logging.h" // for debug
//#include "inc/logging.h" // for debug
#define FPS
30
.0f // frame rate
#define FPS
15
.0f // frame rate
#define H264_NALU_BUFFER_SIZE 65536
#define H264_NALU_BUFFER_SIZE 65536
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE //NALU Slice Size
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE //NALU Slice Size
...
@@ -70,66 +70,90 @@ typedef struct h264_codec_context_s {
...
@@ -70,66 +70,90 @@ typedef struct h264_codec_context_s {
int
need_key_frame
;
int
need_key_frame
;
switch_size_t
last_received_timestamp
;
switch_size_t
last_received_timestamp
;
switch_bool_t
last_received_complete_picture
;
switch_bool_t
last_received_complete_picture
;
switch_codec_settings_t
codec_settings
;
unsigned
int
bandwidth
;
}
h264_codec_context_t
;
}
h264_codec_context_t
;
int
FillSpecificParameters
(
SEncParamExt
&
param
)
{
int
FillSpecificParameters
(
h264_codec_context_t
*
context
)
{
SEncParamExt
*
param
;
param
=
&
context
->
encoder_params
;
if
(
!
context
->
codec_settings
.
video
.
width
)
{
context
->
codec_settings
.
video
.
width
=
1280
;
}
if
(
!
context
->
codec_settings
.
video
.
height
)
{
context
->
codec_settings
.
video
.
height
=
720
;
}
if
(
context
->
codec_settings
.
video
.
bandwidth
)
{
context
->
bandwidth
=
context
->
codec_settings
.
video
.
bandwidth
;
}
else
{
context
->
bandwidth
=
context
->
codec_settings
.
video
.
width
*
context
->
codec_settings
.
video
.
height
/
1024
;
}
if
(
context
->
bandwidth
>
5120
)
{
context
->
bandwidth
=
5120
;
}
/* Test for temporal, spatial, SNR scalability */
/* Test for temporal, spatial, SNR scalability */
param
.
iPicWidth
=
1280
;
// width of picture in samples
param
->
iPicWidth
=
1280
;
// width of picture in samples
param
.
iPicHeight
=
720
;
// height of picture in samples
param
->
iPicHeight
=
720
;
// height of picture in samples
param
.
iTargetBitrate
=
1250000
;
//1280 * 720 * 8; // target bitrate desired
param
->
iTargetBitrate
=
context
->
bandwidth
;
param
.
iRCMode
=
RC_QUALITY_MODE
;
// rc mode control
param
->
iRCMode
=
RC_QUALITY_MODE
;
// rc mode control
param
.
iTemporalLayerNum
=
1
;
// layer number at temporal level
param
->
iTemporalLayerNum
=
1
;
// layer number at temporal level
param
.
iSpatialLayerNum
=
1
;
// layer number at spatial level
param
->
iSpatialLayerNum
=
1
;
// layer number at spatial level
param
.
bEnableDenoise
=
0
;
// denoise control
param
->
bEnableDenoise
=
0
;
// denoise control
param
.
bEnableBackgroundDetection
=
1
;
// background detection control
param
->
bEnableBackgroundDetection
=
1
;
// background detection control
param
.
bEnableSceneChangeDetect
=
1
;
param
->
bEnableSceneChangeDetect
=
1
;
//param
.
bEnableFrameSkip = 1;
//param
->
bEnableFrameSkip = 1;
param
.
iMultipleThreadIdc
=
1
;
param
->
iMultipleThreadIdc
=
1
;
param
.
bEnableAdaptiveQuant
=
1
;
// adaptive quantization control
param
->
bEnableAdaptiveQuant
=
1
;
// adaptive quantization control
param
.
bEnableLongTermReference
=
0
;
// long term reference control
param
->
bEnableLongTermReference
=
0
;
// long term reference control
param
.
iLtrMarkPeriod
=
30
;
param
->
iLtrMarkPeriod
=
30
;
param
.
iLoopFilterAlphaC0Offset
=
0
;
param
->
iLoopFilterAlphaC0Offset
=
0
;
param
.
iLoopFilterBetaOffset
=
0
;
param
->
iLoopFilterBetaOffset
=
0
;
param
.
iComplexityMode
=
MEDIUM_COMPLEXITY
;
param
->
iComplexityMode
=
MEDIUM_COMPLEXITY
;
param
.
uiIntraPeriod
=
FPS
*
3
;
// period of Intra frame
param
->
uiIntraPeriod
=
FPS
*
3
;
// period of Intra frame
#ifdef MT_ENABLED
#ifdef MT_ENABLED
param
.
bEnableSpsPpsIdAddition
=
1
;
param
->
bEnableSpsPpsIdAddition
=
1
;
#else
#else
param
.
bEnableSpsPpsIdAddition
=
0
;
param
->
bEnableSpsPpsIdAddition
=
0
;
#endif
#endif
param
.
bPrefixNalAddingCtrl
=
0
;
param
->
bPrefixNalAddingCtrl
=
0
;
int
iIndexLayer
=
0
;
int
iIndexLayer
=
0
;
param
.
sSpatialLayers
[
iIndexLayer
].
iVideoWidth
=
1280
;
param
->
sSpatialLayers
[
iIndexLayer
].
iVideoWidth
=
1280
;
param
.
sSpatialLayers
[
iIndexLayer
].
iVideoHeight
=
720
;
param
->
sSpatialLayers
[
iIndexLayer
].
iVideoHeight
=
720
;
param
.
sSpatialLayers
[
iIndexLayer
].
fFrameRate
=
(
double
)
(
FPS
*
1.0
f
);
param
->
sSpatialLayers
[
iIndexLayer
].
fFrameRate
=
(
double
)
(
FPS
*
1.0
f
);
// param
.
sSpatialLayers[iIndexLayer].iQualityLayerNum = 1;
// param
->
sSpatialLayers[iIndexLayer].iQualityLayerNum = 1;
param
.
sSpatialLayers
[
iIndexLayer
].
iSpatialBitrate
=
param
.
iTargetBitrate
;
param
->
sSpatialLayers
[
iIndexLayer
].
iSpatialBitrate
=
param
->
iTargetBitrate
;
//param
.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = param.
iTargetBitrate;
//param
->sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = param->
iTargetBitrate;
//param
.
sSpatialLayers[iIndexLayer].uiLevelIdc = LEVEL_1_3;
//param
->
sSpatialLayers[iIndexLayer].uiLevelIdc = LEVEL_1_3;
param
.
sSpatialLayers
[
iIndexLayer
].
uiProfileIdc
=
PRO_BASELINE
;
param
->
sSpatialLayers
[
iIndexLayer
].
uiProfileIdc
=
PRO_BASELINE
;
param
.
iUsageType
=
CAMERA_VIDEO_REAL_TIME
;
param
->
iUsageType
=
CAMERA_VIDEO_REAL_TIME
;
param
.
bEnableFrameCroppingFlag
=
1
;
param
->
bEnableFrameCroppingFlag
=
1
;
//param
.
iMaxBitrate = 1250000;
//param
->
iMaxBitrate = 1250000;
//param
.
iTargetBitrate = 1250000;
//param
->
iTargetBitrate = 1250000;
#ifdef MT_ENABLED
#ifdef MT_ENABLED
param
.
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
uiSliceMode
=
SM_DYN_SLICE
;
param
->
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
uiSliceMode
=
SM_DYN_SLICE
;
param
.
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
sSliceArgument
.
uiSliceSizeConstraint
=
SLICE_SIZE
;
param
->
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
sSliceArgument
.
uiSliceSizeConstraint
=
SLICE_SIZE
;
param
.
uiMaxNalSize
=
SLICE_SIZE
;
param
->
uiMaxNalSize
=
SLICE_SIZE
;
#else
#else
param
.
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
uiSliceMode
=
SM_SINGLE_SLICE
;
param
->
sSpatialLayers
[
iIndexLayer
].
sSliceCfg
.
uiSliceMode
=
SM_SINGLE_SLICE
;
#endif
#endif
float
fMaxFr
=
param
.
sSpatialLayers
[
param
.
iSpatialLayerNum
-
1
].
fFrameRate
;
float
fMaxFr
=
param
->
sSpatialLayers
[
param
->
iSpatialLayerNum
-
1
].
fFrameRate
;
for
(
int32_t
i
=
param
.
iSpatialLayerNum
-
2
;
i
>=
0
;
--
i
)
{
for
(
int32_t
i
=
param
->
iSpatialLayerNum
-
2
;
i
>=
0
;
--
i
)
{
if
(
param
.
sSpatialLayers
[
i
].
fFrameRate
>
fMaxFr
+
EPSN
)
{
if
(
param
->
sSpatialLayers
[
i
].
fFrameRate
>
fMaxFr
+
EPSN
)
{
fMaxFr
=
param
.
sSpatialLayers
[
i
].
fFrameRate
;
fMaxFr
=
param
->
sSpatialLayers
[
i
].
fFrameRate
;
}
}
}
}
param
.
fMaxFrameRate
=
fMaxFr
;
param
->
fMaxFrameRate
=
fMaxFr
;
return
0
;
return
0
;
}
}
...
@@ -376,6 +400,10 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
...
@@ -376,6 +400,10 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
context
=
(
h264_codec_context_t
*
)
switch_core_alloc
(
codec
->
memory_pool
,
sizeof
(
h264_codec_context_t
));
context
=
(
h264_codec_context_t
*
)
switch_core_alloc
(
codec
->
memory_pool
,
sizeof
(
h264_codec_context_t
));
memset
(
context
,
0
,
sizeof
(
*
context
));
memset
(
context
,
0
,
sizeof
(
*
context
));
if
(
codec_settings
)
{
context
->
codec_settings
=
*
codec_settings
;
}
if
(
decoding
)
{
if
(
decoding
)
{
WelsCreateDecoder
(
&
context
->
decoder
);
WelsCreateDecoder
(
&
context
->
decoder
);
...
@@ -407,7 +435,7 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
...
@@ -407,7 +435,7 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
goto
error
;
goto
error
;
}
}
FillSpecificParameters
(
context
->
encoder_params
);
FillSpecificParameters
(
context
);
}
}
//if (encoding | decoding) WelsStderrSetTraceLevel(10);
//if (encoding | decoding) WelsStderrSetTraceLevel(10);
...
@@ -627,9 +655,9 @@ end:
...
@@ -627,9 +655,9 @@ end:
switch_set_flag
(
frame
,
SFF_WAIT_KEY_FRAME
);
switch_set_flag
(
frame
,
SFF_WAIT_KEY_FRAME
);
}
}
if
(
frame
->
img
)
{
if
(
!
frame
->
img
)
{
switch_set_flag
(
frame
,
SFF_USE_VIDEO_TIMESTAMP
);
//
switch_set_flag(frame, SFF_USE_VIDEO_TIMESTAMP);
}
else
{
//
} else {
status
=
SWITCH_STATUS_MORE_DATA
;
status
=
SWITCH_STATUS_MORE_DATA
;
}
}
...
...
src/mod/codecs/mod_vpx/mod_vpx.c
浏览文件 @
ac140fb6
...
@@ -38,7 +38,6 @@
...
@@ -38,7 +38,6 @@
#include <vpx/vp8dx.h>
#include <vpx/vp8dx.h>
#include <vpx/vp8.h>
#include <vpx/vp8.h>
#define FPS 15
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
#define KEY_FRAME_MIN_FREQ 1000000
#define KEY_FRAME_MIN_FREQ 1000000
...
@@ -64,12 +63,12 @@ struct vpx_context {
...
@@ -64,12 +63,12 @@ struct vpx_context {
int
fps
;
int
fps
;
int
format
;
int
format
;
int
intra_period
;
int
intra_period
;
int
pts
;
int
num
;
int
num
;
int
partition_index
;
int
partition_index
;
const
vpx_codec_cx_pkt_t
*
pkt
;
const
vpx_codec_cx_pkt_t
*
pkt
;
int
pkt_pos
;
int
pkt_pos
;
vpx_codec_iter_t
iter
;
vpx_codec_iter_t
iter
;
uint32_t
last_ts
;
vpx_codec_ctx_t
decoder
;
vpx_codec_ctx_t
decoder
;
uint8_t
decoder_init
;
uint8_t
decoder_init
;
switch_buffer_t
*
vpx_packet_buffer
;
switch_buffer_t
*
vpx_packet_buffer
;
...
@@ -99,15 +98,13 @@ static switch_status_t init_codec(switch_codec_t *codec)
...
@@ -99,15 +98,13 @@ static switch_status_t init_codec(switch_codec_t *codec)
if
(
context
->
codec_settings
.
video
.
bandwidth
)
{
if
(
context
->
codec_settings
.
video
.
bandwidth
)
{
context
->
bandwidth
=
context
->
codec_settings
.
video
.
bandwidth
;
context
->
bandwidth
=
context
->
codec_settings
.
video
.
bandwidth
;
}
else
{
}
else
{
int
x
=
(
context
->
codec_settings
.
video
.
width
/
100
)
+
1
;
context
->
bandwidth
=
context
->
codec_settings
.
video
.
width
*
context
->
codec_settings
.
video
.
height
/
1024
;
context
->
bandwidth
=
context
->
codec_settings
.
video
.
width
*
context
->
codec_settings
.
video
.
height
*
x
;
}
}
if
(
context
->
bandwidth
>
125000
0
)
{
if
(
context
->
bandwidth
>
512
0
)
{
context
->
bandwidth
=
125000
0
;
context
->
bandwidth
=
512
0
;
}
}
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
codec
->
session
),
SWITCH_LOG_NOTICE
,
switch_log_printf
(
SWITCH_CHANNEL_SESSION_LOG
(
codec
->
session
),
SWITCH_LOG_NOTICE
,
"VPX reset encoder picture from %dx%d to %dx%d %u BW
\n
"
,
"VPX reset encoder picture from %dx%d to %dx%d %u BW
\n
"
,
config
->
g_w
,
config
->
g_h
,
context
->
codec_settings
.
video
.
width
,
context
->
codec_settings
.
video
.
height
,
context
->
bandwidth
);
config
->
g_w
,
config
->
g_h
,
context
->
codec_settings
.
video
.
width
,
context
->
codec_settings
.
video
.
height
,
context
->
bandwidth
);
...
@@ -119,7 +116,7 @@ static switch_status_t init_codec(switch_codec_t *codec)
...
@@ -119,7 +116,7 @@ static switch_status_t init_codec(switch_codec_t *codec)
config
->
g_h
=
context
->
codec_settings
.
video
.
height
;
config
->
g_h
=
context
->
codec_settings
.
video
.
height
;
config
->
rc_target_bitrate
=
context
->
bandwidth
;
config
->
rc_target_bitrate
=
context
->
bandwidth
;
config
->
g_timebase
.
num
=
1
;
config
->
g_timebase
.
num
=
1
;
config
->
g_timebase
.
den
=
1
000
;
config
->
g_timebase
.
den
=
90
000
;
config
->
g_error_resilient
=
VPX_ERROR_RESILIENT_PARTITIONS
;
config
->
g_error_resilient
=
VPX_ERROR_RESILIENT_PARTITIONS
;
config
->
g_lag_in_frames
=
0
;
// 0- no frame lagging
config
->
g_lag_in_frames
=
0
;
// 0- no frame lagging
...
@@ -374,11 +371,10 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t
...
@@ -374,11 +371,10 @@ static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t
static
switch_status_t
switch_vpx_encode
(
switch_codec_t
*
codec
,
switch_frame_t
*
frame
)
static
switch_status_t
switch_vpx_encode
(
switch_codec_t
*
codec
,
switch_frame_t
*
frame
)
{
{
vpx_context_t
*
context
=
(
vpx_context_t
*
)
codec
->
private_info
;
vpx_context_t
*
context
=
(
vpx_context_t
*
)
codec
->
private_info
;
uint32_t
duration
=
90000
/
FPS
;
int
width
=
0
;
int
width
=
0
;
int
height
=
0
;
int
height
=
0
;
vpx_enc_frame_flags_t
vpx_flags
=
0
;
vpx_enc_frame_flags_t
vpx_flags
=
0
;
int32_t
dur
=
0
;
if
(
frame
->
flags
&
SFF_SAME_IMAGE
)
{
if
(
frame
->
flags
&
SFF_SAME_IMAGE
)
{
return
consume_partition
(
context
,
frame
);
return
consume_partition
(
context
,
frame
);
...
@@ -423,7 +419,20 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *
...
@@ -423,7 +419,20 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *
}
}
}
}
if
(
vpx_codec_encode
(
&
context
->
encoder
,
(
vpx_image_t
*
)
frame
->
img
,
context
->
pts
,
duration
,
vpx_flags
,
VPX_DL_REALTIME
)
!=
VPX_CODEC_OK
)
{
if
(
context
->
last_ts
)
{
dur
=
frame
->
timestamp
-
context
->
last_ts
;
if
(
dur
<
0
||
dur
>
90000
)
{
dur
=
0
;
}
}
if
(
!
dur
)
{
dur
=
1
;
}
if
(
vpx_codec_encode
(
&
context
->
encoder
,
(
vpx_image_t
*
)
frame
->
img
,
frame
->
timestamp
,
dur
,
vpx_flags
,
VPX_DL_REALTIME
)
!=
VPX_CODEC_OK
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"VP8 encode error %d:%s
\n
"
,
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"VP8 encode error %d:%s
\n
"
,
context
->
encoder
.
err
,
context
->
encoder
.
err_detail
);
context
->
encoder
.
err
,
context
->
encoder
.
err_detail
);
...
@@ -431,8 +440,8 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *
...
@@ -431,8 +440,8 @@ static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *
return
SWITCH_STATUS_FALSE
;
return
SWITCH_STATUS_FALSE
;
}
}
context
->
pts
+=
duration
;
context
->
iter
=
NULL
;
context
->
iter
=
NULL
;
context
->
last_ts
=
frame
->
timestamp
;
return
consume_partition
(
context
,
frame
);
return
consume_partition
(
context
,
frame
);
}
}
...
@@ -521,6 +530,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
...
@@ -521,6 +530,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
// possible packet loss
// possible packet loss
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_WARNING
,
"Reset
\n
"
);
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_WARNING
,
"Reset
\n
"
);
context
->
need_key_frame
=
1
;
context
->
need_key_frame
=
1
;
context
->
last_ts
=
0
;
switch_goto_status
(
SWITCH_STATUS_RESTART
,
end
);
switch_goto_status
(
SWITCH_STATUS_RESTART
,
end
);
}
}
...
...
src/switch_core_media.c
浏览文件 @
ac140fb6
...
@@ -1515,7 +1515,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
...
@@ -1515,7 +1515,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
session
->
media_handle
->
mparams
=
params
;
session
->
media_handle
->
mparams
=
params
;
if
(
!
session
->
media_handle
->
mparams
->
video_key_freq
)
{
if
(
!
session
->
media_handle
->
mparams
->
video_key_freq
)
{
session
->
media_handle
->
mparams
->
video_key_freq
=
5
000000
;
session
->
media_handle
->
mparams
->
video_key_freq
=
30
000000
;
}
}
if
(
!
session
->
media_handle
->
mparams
->
video_key_first
)
{
if
(
!
session
->
media_handle
->
mparams
->
video_key_first
)
{
...
@@ -2366,14 +2366,21 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess
...
@@ -2366,14 +2366,21 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess
break
;
break
;
case
SWITCH_MEDIA_TYPE_VIDEO
:
case
SWITCH_MEDIA_TYPE_VIDEO
:
{
{
const
char
*
bwv
=
switch_channel_get_variable
(
session
->
channel
,
"
video_codec
_bandwidth"
);
const
char
*
bwv
=
switch_channel_get_variable
(
session
->
channel
,
"
rtp_video_max
_bandwidth"
);
uint32_t
bw
=
0
;
uint32_t
bw
=
0
;
if
(
!
bwv
)
{
bwv
=
switch_channel_get_variable
(
session
->
channel
,
"rtp_video_max_bandwidth_out"
);
}
if
(
bwv
&&
(
bw
=
(
uint32_t
)
atol
(
bwv
)))
{
if
(
bwv
&&
(
bw
=
(
uint32_t
)
atol
(
bwv
)))
{
if
(
switch_stristr
(
"
kb
"
,
bwv
))
{
if
(
switch_stristr
(
"
KB
"
,
bwv
))
{
bw
*=
125
;
bw
*=
8
;
}
else
if
(
switch_stristr
(
"mb"
,
bwv
))
{
}
else
if
(
switch_stristr
(
"mb"
,
bwv
))
{
bw
*=
125000
;
bw
*=
1024
;
}
else
if
(
switch_stristr
(
"MB"
,
bwv
))
{
bw
*=
8192
;
}
}
engine
->
codec_settings
.
video
.
bandwidth
=
bw
;
engine
->
codec_settings
.
video
.
bandwidth
=
bw
;
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论