mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-06-01 19:20:05 +00:00
[mod_av] make key_frame_min_freq work to prevent generate key frames too frequently
This commit is contained in:
parent
128d4776f8
commit
7cd3bf5af2
@ -385,6 +385,7 @@ typedef struct h264_codec_context_s {
|
|||||||
switch_image_t *img;
|
switch_image_t *img;
|
||||||
switch_image_t *encimg;
|
switch_image_t *encimg;
|
||||||
int need_key_frame;
|
int need_key_frame;
|
||||||
|
switch_time_t last_keyframe_request;
|
||||||
switch_bool_t nalu_28_start;
|
switch_bool_t nalu_28_start;
|
||||||
|
|
||||||
int change_bandwidth;
|
int change_bandwidth;
|
||||||
@ -420,7 +421,7 @@ struct avcodec_globals {
|
|||||||
int debug;
|
int debug;
|
||||||
uint32_t max_bitrate;
|
uint32_t max_bitrate;
|
||||||
uint32_t rtp_slice_size;
|
uint32_t rtp_slice_size;
|
||||||
uint32_t key_frame_min_freq;
|
uint32_t key_frame_min_freq; // in ms
|
||||||
uint32_t enc_threads;
|
uint32_t enc_threads;
|
||||||
uint32_t dec_threads;
|
uint32_t dec_threads;
|
||||||
|
|
||||||
@ -1567,10 +1568,14 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||||||
|
|
||||||
avframe->pts = context->pts++;
|
avframe->pts = context->pts++;
|
||||||
|
|
||||||
if (context->need_key_frame) {
|
if (context->need_key_frame && (context->last_keyframe_request + avcodec_globals.key_frame_min_freq) < switch_time_now()) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5, "Send AV KEYFRAME\n");
|
if (avcodec_globals.debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Generate/Send AV KEYFRAME\n");
|
||||||
|
}
|
||||||
|
|
||||||
avframe->pict_type = AV_PICTURE_TYPE_I;
|
avframe->pict_type = AV_PICTURE_TYPE_I;
|
||||||
avframe->key_frame = 1;
|
avframe->key_frame = 1;
|
||||||
|
context->last_keyframe_request = switch_time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
@ -1585,7 +1590,7 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->need_key_frame) {
|
if (context->need_key_frame && avframe->key_frame == 1) {
|
||||||
avframe->pict_type = 0;
|
avframe->pict_type = 0;
|
||||||
avframe->key_frame = 0;
|
avframe->key_frame = 0;
|
||||||
context->need_key_frame = 0;
|
context->need_key_frame = 0;
|
||||||
@ -1633,8 +1638,12 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||||||
context->nalus[i].start = p;
|
context->nalus[i].start = p;
|
||||||
context->nalus[i].eat = p;
|
context->nalus[i].eat = p;
|
||||||
|
|
||||||
if (mod_av_globals.debug && (*p & 0x1f) == 7) {
|
if ((*p & 0x1f) == 7) { // Got Keyframe
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
|
// prevent to generate key frame too frequently
|
||||||
|
context->last_keyframe_request = switch_time_now();
|
||||||
|
if (mod_av_globals.debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context->nalus[i].len = p - context->nalus[i].start;
|
context->nalus[i].len = p - context->nalus[i].start;
|
||||||
|
@ -50,7 +50,7 @@ static fctcl_init_t my_cl_options[] = {
|
|||||||
|
|
||||||
FST_CORE_BEGIN("conf")
|
FST_CORE_BEGIN("conf")
|
||||||
{
|
{
|
||||||
const char *loop_;
|
const char *loop_;
|
||||||
fctcl_install(my_cl_options);
|
fctcl_install(my_cl_options);
|
||||||
|
|
||||||
loop_ = fctcl_val("--loop");
|
loop_ = fctcl_val("--loop");
|
||||||
@ -73,7 +73,11 @@ FST_CORE_BEGIN("conf")
|
|||||||
uint8_t buf[SWITCH_DEFAULT_VIDEO_SIZE + 12];
|
uint8_t buf[SWITCH_DEFAULT_VIDEO_SIZE + 12];
|
||||||
switch_frame_t frame = { 0 };
|
switch_frame_t frame = { 0 };
|
||||||
int packets = 0;
|
int packets = 0;
|
||||||
|
int frames = 0;
|
||||||
|
int last_key_frame = 0;
|
||||||
|
int key_frames = 0;
|
||||||
switch_status_t encode_status;
|
switch_status_t encode_status;
|
||||||
|
int debug_level = 9;
|
||||||
|
|
||||||
switch_set_string(codec_settings.video.config_profile_name, "conference");
|
switch_set_string(codec_settings.video.config_profile_name, "conference");
|
||||||
|
|
||||||
@ -105,6 +109,8 @@ FST_CORE_BEGIN("conf")
|
|||||||
frame.timestamp = 0;
|
frame.timestamp = 0;
|
||||||
frame.img = img;
|
frame.img = img;
|
||||||
|
|
||||||
|
switch_core_codec_control(&codec, SCC_DEBUG, SCCT_NONE, &debug_level, SCCT_INT, NULL, NULL, NULL);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE;
|
frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE;
|
||||||
encode_status = switch_core_codec_encode_video(&codec, &frame);
|
encode_status = switch_core_codec_encode_video(&codec, &frame);
|
||||||
@ -120,8 +126,21 @@ FST_CORE_BEGIN("conf")
|
|||||||
|
|
||||||
if (frame.datalen == 0) break;
|
if (frame.datalen == 0) break;
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[%d]: %02x %02x | m=%d | %d\n", loop, buf[12], buf[13], frame.m, frame.datalen);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "[%d]: %02x %02x | m=%d | %d\n", frames, buf[12], buf[13], frame.m, frame.datalen);
|
||||||
packets++;
|
packets++;
|
||||||
|
|
||||||
|
if (frame.m) frames++;
|
||||||
|
|
||||||
|
if (frames % 20 == 2) {
|
||||||
|
switch_core_codec_control(&codec, SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[12] == 0x67) {
|
||||||
|
key_frames++;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Key Frame %d last=%d diff=%d\n",
|
||||||
|
key_frames, last_key_frame, frames - last_key_frame);
|
||||||
|
last_key_frame = frames;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while(encode_status == SWITCH_STATUS_MORE_DATA || loop-- > 1);
|
} while(encode_status == SWITCH_STATUS_MORE_DATA || loop-- > 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user