FS-7500: codec tweaks
This commit is contained in:
parent
13c3f053ab
commit
ac140fb6dd
|
@ -39,7 +39,7 @@
|
|||
#include "codec_api.h"
|
||||
//#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 SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE //NALU Slice Size
|
||||
|
||||
|
@ -70,66 +70,90 @@ typedef struct h264_codec_context_s {
|
|||
int need_key_frame;
|
||||
switch_size_t last_received_timestamp;
|
||||
switch_bool_t last_received_complete_picture;
|
||||
switch_codec_settings_t codec_settings;
|
||||
unsigned int bandwidth;
|
||||
} 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 */
|
||||
param.iPicWidth = 1280; // width of picture in samples
|
||||
param.iPicHeight = 720; // height of picture in samples
|
||||
param.iTargetBitrate = 1250000;//1280 * 720 * 8; // target bitrate desired
|
||||
param.iRCMode = RC_QUALITY_MODE; // rc mode control
|
||||
param.iTemporalLayerNum = 1; // layer number at temporal level
|
||||
param.iSpatialLayerNum = 1; // layer number at spatial level
|
||||
param.bEnableDenoise = 0; // denoise control
|
||||
param.bEnableBackgroundDetection = 1; // background detection control
|
||||
param.bEnableSceneChangeDetect= 1;
|
||||
//param.bEnableFrameSkip = 1;
|
||||
param.iMultipleThreadIdc= 1;
|
||||
param.bEnableAdaptiveQuant = 1; // adaptive quantization control
|
||||
param.bEnableLongTermReference = 0; // long term reference control
|
||||
param.iLtrMarkPeriod = 30;
|
||||
param.iLoopFilterAlphaC0Offset= 0;
|
||||
param.iLoopFilterBetaOffset= 0;
|
||||
param.iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
param.uiIntraPeriod = FPS * 3; // period of Intra frame
|
||||
param->iPicWidth = 1280; // width of picture in samples
|
||||
param->iPicHeight = 720; // height of picture in samples
|
||||
param->iTargetBitrate = context->bandwidth;
|
||||
param->iRCMode = RC_QUALITY_MODE; // rc mode control
|
||||
param->iTemporalLayerNum = 1; // layer number at temporal level
|
||||
param->iSpatialLayerNum = 1; // layer number at spatial level
|
||||
param->bEnableDenoise = 0; // denoise control
|
||||
param->bEnableBackgroundDetection = 1; // background detection control
|
||||
param->bEnableSceneChangeDetect= 1;
|
||||
//param->bEnableFrameSkip = 1;
|
||||
param->iMultipleThreadIdc= 1;
|
||||
param->bEnableAdaptiveQuant = 1; // adaptive quantization control
|
||||
param->bEnableLongTermReference = 0; // long term reference control
|
||||
param->iLtrMarkPeriod = 30;
|
||||
param->iLoopFilterAlphaC0Offset= 0;
|
||||
param->iLoopFilterBetaOffset= 0;
|
||||
param->iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
param->uiIntraPeriod = FPS * 3; // period of Intra frame
|
||||
#ifdef MT_ENABLED
|
||||
param.bEnableSpsPpsIdAddition = 1;
|
||||
param->bEnableSpsPpsIdAddition = 1;
|
||||
#else
|
||||
param.bEnableSpsPpsIdAddition = 0;
|
||||
param->bEnableSpsPpsIdAddition = 0;
|
||||
#endif
|
||||
param.bPrefixNalAddingCtrl = 0;
|
||||
param->bPrefixNalAddingCtrl = 0;
|
||||
|
||||
int iIndexLayer = 0;
|
||||
param.sSpatialLayers[iIndexLayer].iVideoWidth = 1280;
|
||||
param.sSpatialLayers[iIndexLayer].iVideoHeight = 720;
|
||||
param.sSpatialLayers[iIndexLayer].fFrameRate = (double) (FPS * 1.0f);
|
||||
// param.sSpatialLayers[iIndexLayer].iQualityLayerNum = 1;
|
||||
param.sSpatialLayers[iIndexLayer].iSpatialBitrate = param.iTargetBitrate;
|
||||
//param.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = param.iTargetBitrate;
|
||||
//param.sSpatialLayers[iIndexLayer].uiLevelIdc = LEVEL_1_3;
|
||||
param.sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_BASELINE;
|
||||
param->sSpatialLayers[iIndexLayer].iVideoWidth = 1280;
|
||||
param->sSpatialLayers[iIndexLayer].iVideoHeight = 720;
|
||||
param->sSpatialLayers[iIndexLayer].fFrameRate = (double) (FPS * 1.0f);
|
||||
// param->sSpatialLayers[iIndexLayer].iQualityLayerNum = 1;
|
||||
param->sSpatialLayers[iIndexLayer].iSpatialBitrate = param->iTargetBitrate;
|
||||
//param->sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = param->iTargetBitrate;
|
||||
//param->sSpatialLayers[iIndexLayer].uiLevelIdc = LEVEL_1_3;
|
||||
param->sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_BASELINE;
|
||||
|
||||
|
||||
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
param.bEnableFrameCroppingFlag = 1;
|
||||
//param.iMaxBitrate = 1250000;
|
||||
//param.iTargetBitrate = 1250000;
|
||||
param->iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
param->bEnableFrameCroppingFlag = 1;
|
||||
//param->iMaxBitrate = 1250000;
|
||||
//param->iTargetBitrate = 1250000;
|
||||
|
||||
#ifdef MT_ENABLED
|
||||
param.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_DYN_SLICE;
|
||||
param.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = SLICE_SIZE;
|
||||
param.uiMaxNalSize = SLICE_SIZE;
|
||||
param->sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_DYN_SLICE;
|
||||
param->sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = SLICE_SIZE;
|
||||
param->uiMaxNalSize = SLICE_SIZE;
|
||||
#else
|
||||
param.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
param->sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
#endif
|
||||
|
||||
float fMaxFr = param.sSpatialLayers[param.iSpatialLayerNum - 1].fFrameRate;
|
||||
for (int32_t i = param.iSpatialLayerNum - 2; i >= 0; --i) {
|
||||
if (param.sSpatialLayers[i].fFrameRate > fMaxFr + EPSN) {
|
||||
fMaxFr = param.sSpatialLayers[i].fFrameRate;
|
||||
float fMaxFr = param->sSpatialLayers[param->iSpatialLayerNum - 1].fFrameRate;
|
||||
for (int32_t i = param->iSpatialLayerNum - 2; i >= 0; --i) {
|
||||
if (param->sSpatialLayers[i].fFrameRate > fMaxFr + EPSN) {
|
||||
fMaxFr = param->sSpatialLayers[i].fFrameRate;
|
||||
}
|
||||
}
|
||||
param.fMaxFrameRate = fMaxFr;
|
||||
param->fMaxFrameRate = fMaxFr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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));
|
||||
memset(context, 0, sizeof(*context));
|
||||
|
||||
if (codec_settings) {
|
||||
context->codec_settings = *codec_settings;
|
||||
}
|
||||
|
||||
if (decoding) {
|
||||
WelsCreateDecoder(&context->decoder);
|
||||
|
||||
|
@ -407,7 +435,7 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
|
|||
goto error;
|
||||
}
|
||||
|
||||
FillSpecificParameters(context->encoder_params);
|
||||
FillSpecificParameters(context);
|
||||
}
|
||||
|
||||
//if (encoding | decoding) WelsStderrSetTraceLevel(10);
|
||||
|
@ -627,9 +655,9 @@ end:
|
|||
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
|
||||
}
|
||||
|
||||
if (frame->img) {
|
||||
switch_set_flag(frame, SFF_USE_VIDEO_TIMESTAMP);
|
||||
} else {
|
||||
if (!frame->img) {
|
||||
//switch_set_flag(frame, SFF_USE_VIDEO_TIMESTAMP);
|
||||
//} else {
|
||||
status = SWITCH_STATUS_MORE_DATA;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include <vpx/vp8dx.h>
|
||||
#include <vpx/vp8.h>
|
||||
|
||||
#define FPS 15
|
||||
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
|
||||
#define KEY_FRAME_MIN_FREQ 1000000
|
||||
|
||||
|
@ -64,12 +63,12 @@ struct vpx_context {
|
|||
int fps;
|
||||
int format;
|
||||
int intra_period;
|
||||
int pts;
|
||||
int num;
|
||||
int partition_index;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
int pkt_pos;
|
||||
vpx_codec_iter_t iter;
|
||||
uint32_t last_ts;
|
||||
vpx_codec_ctx_t decoder;
|
||||
uint8_t decoder_init;
|
||||
switch_buffer_t *vpx_packet_buffer;
|
||||
|
@ -99,15 +98,13 @@ static switch_status_t init_codec(switch_codec_t *codec)
|
|||
if (context->codec_settings.video.bandwidth) {
|
||||
context->bandwidth = context->codec_settings.video.bandwidth;
|
||||
} else {
|
||||
int x = (context->codec_settings.video.width / 100) + 1;
|
||||
context->bandwidth = context->codec_settings.video.width * context->codec_settings.video.height * x;
|
||||
context->bandwidth = context->codec_settings.video.width * context->codec_settings.video.height / 1024;
|
||||
}
|
||||
|
||||
if (context->bandwidth > 1250000) {
|
||||
context->bandwidth = 1250000;
|
||||
if (context->bandwidth > 5120) {
|
||||
context->bandwidth = 5120;
|
||||
}
|
||||
|
||||
|
||||
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",
|
||||
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)
|
|||
config->g_h = context->codec_settings.video.height;
|
||||
config->rc_target_bitrate = context->bandwidth;
|
||||
config->g_timebase.num = 1;
|
||||
config->g_timebase.den = 1000;
|
||||
config->g_timebase.den = 90000;
|
||||
config->g_error_resilient = VPX_ERROR_RESILIENT_PARTITIONS;
|
||||
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
|
|||
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;
|
||||
uint32_t duration = 90000 / FPS;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
vpx_enc_frame_flags_t vpx_flags = 0;
|
||||
|
||||
int32_t dur = 0;
|
||||
|
||||
if (frame->flags & SFF_SAME_IMAGE) {
|
||||
return consume_partition(context, frame);
|
||||
|
@ -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",
|
||||
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 *
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
context->pts += duration;
|
||||
context->iter = NULL;
|
||||
context->last_ts = frame->timestamp;
|
||||
|
||||
return consume_partition(context, frame);
|
||||
}
|
||||
|
@ -521,6 +530,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
|
|||
// possible packet loss
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Reset\n");
|
||||
context->need_key_frame = 1;
|
||||
context->last_ts = 0;
|
||||
switch_goto_status(SWITCH_STATUS_RESTART, end);
|
||||
}
|
||||
|
||||
|
|
|
@ -1515,7 +1515,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
|
|||
session->media_handle->mparams = params;
|
||||
|
||||
if (!session->media_handle->mparams->video_key_freq) {
|
||||
session->media_handle->mparams->video_key_freq = 5000000;
|
||||
session->media_handle->mparams->video_key_freq = 30000000;
|
||||
}
|
||||
|
||||
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
|
|||
break;
|
||||
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;
|
||||
|
||||
if (!bwv) {
|
||||
bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth_out");
|
||||
}
|
||||
|
||||
|
||||
if (bwv && (bw = (uint32_t) atol(bwv))) {
|
||||
if (switch_stristr("kb", bwv)) {
|
||||
bw *= 125;
|
||||
if (switch_stristr("KB", bwv)) {
|
||||
bw *= 8;
|
||||
} else if (switch_stristr("mb", bwv)) {
|
||||
bw *= 125000;
|
||||
bw *= 1024;
|
||||
} else if (switch_stristr("MB", bwv)) {
|
||||
bw *= 8192;
|
||||
}
|
||||
engine->codec_settings.video.bandwidth = bw;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue