switch_image_t *img;
switch_image_t *encimg;
int need_key_frame;
+ switch_time_t last_keyframe_request;
switch_bool_t nalu_28_start;
int change_bandwidth;
int debug;
uint32_t max_bitrate;
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 dec_threads;
avframe->pts = context->pts++;
- if (context->need_key_frame) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5, "Send AV KEYFRAME\n");
+ if (context->need_key_frame && (context->last_keyframe_request + avcodec_globals.key_frame_min_freq) < switch_time_now()) {
+ 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->key_frame = 1;
+ context->last_keyframe_request = switch_time_now();
}
/* encode the image */
goto error;
}
- if (context->need_key_frame) {
+ if (context->need_key_frame && avframe->key_frame == 1) {
avframe->pict_type = 0;
avframe->key_frame = 0;
context->need_key_frame = 0;
context->nalus[i].start = p;
context->nalus[i].eat = p;
- if (mod_av_globals.debug && (*p & 0x1f) == 7) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
+ if ((*p & 0x1f) == 7) { // Got Keyframe
+ // 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 {
context->nalus[i].len = p - context->nalus[i].start;
FST_CORE_BEGIN("conf")
{
- const char *loop_;
+ const char *loop_;
fctcl_install(my_cl_options);
loop_ = fctcl_val("--loop");
uint8_t buf[SWITCH_DEFAULT_VIDEO_SIZE + 12];
switch_frame_t frame = { 0 };
int packets = 0;
+ int frames = 0;
+ int last_key_frame = 0;
+ int key_frames = 0;
switch_status_t encode_status;
+ int debug_level = 9;
switch_set_string(codec_settings.video.config_profile_name, "conference");
frame.timestamp = 0;
frame.img = img;
+ switch_core_codec_control(&codec, SCC_DEBUG, SCCT_NONE, &debug_level, SCCT_INT, NULL, NULL, NULL);
+
do {
frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE;
encode_status = switch_core_codec_encode_video(&codec, &frame);
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++;
+
+ 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);