From 09ede13fc4ca1c43b2d2d25a5a32d67fd28f219c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 19 May 2015 13:13:36 -0500 Subject: [PATCH] FS-7500 add switch_img_letterbox and use it for the mirror input function --- src/include/switch_core_video.h | 1 + src/mod/codecs/mod_avcodec/mod_avcodec.c | 16 ++++--- src/mod/codecs/mod_openh264/mod_openh264.cpp | 13 ++++-- src/switch_core_media.c | 7 ++- src/switch_core_video.c | 45 ++++++++++++++++++++ 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/include/switch_core_video.h b/src/include/switch_core_video.h index c2a1fffd47..ac4b40c1cd 100644 --- a/src/include/switch_core_video.h +++ b/src/include/switch_core_video.h @@ -363,6 +363,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_convert(switch_image_t *src, switch_c SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_bool_t full, const char *text); SWITCH_DECLARE(switch_image_t *) switch_img_read_file(const char* file_name); +SWITCH_DECLARE(switch_status_t) switch_img_letterbox(switch_image_t *img, switch_image_t **imgP, int width, int height, const char *color); /** @} */ diff --git a/src/mod/codecs/mod_avcodec/mod_avcodec.c b/src/mod/codecs/mod_avcodec/mod_avcodec.c index 82a432c185..9496e5f9ad 100644 --- a/src/mod/codecs/mod_avcodec/mod_avcodec.c +++ b/src/mod/codecs/mod_avcodec/mod_avcodec.c @@ -182,7 +182,7 @@ static switch_status_t init_x264(h264_codec_context_t *context, uint32_t width, context->bandwidth = 5120; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "initializing x264 handle %dx%d bw:%d\n", width, height, context->bandwidth); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "initializing x264 handle %dx%d bw:%d\n", context->codec_settings.video.width, context->codec_settings.video.height, context->bandwidth); if (xh) { @@ -697,12 +697,16 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, if (context->change_bandwidth) { context->codec_settings.video.bandwidth = context->change_bandwidth; context->change_bandwidth = 0; - init_x264(context, 0, 0); + if (init_x264(context, 0, 0) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } if (!context->x264_handle) { - init_x264(context, width, height); + if (init_x264(context, width, height) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } @@ -715,8 +719,10 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, if (context->x264_params.i_width != width || context->x264_params.i_height != height) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "picture size changed from %dx%d to %dx%d, reinitializing encoder\n", - context->x264_params.i_width, context->x264_params.i_width, width, height); - init_x264(context, width, height); + context->x264_params.i_width, context->x264_params.i_height, width, height); + if (init_x264(context, width, height) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(frame, SFF_WAIT_KEY_FRAME); } diff --git a/src/mod/codecs/mod_openh264/mod_openh264.cpp b/src/mod/codecs/mod_openh264/mod_openh264.cpp index e357e0a67d..fa2ddfaf1e 100644 --- a/src/mod/codecs/mod_openh264/mod_openh264.cpp +++ b/src/mod/codecs/mod_openh264/mod_openh264.cpp @@ -192,11 +192,18 @@ static switch_size_t buffer_h264_nalu(h264_codec_context_t *context, switch_fram nalu_idc = (nalu_hdr & 0x60) >> 5; nalu_type = nalu_hdr & 0x1f; - if (!context->got_sps && nalu_type != 7) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting SPS/PPS, Got %d\n", nalu_type); - return 0; + if (context->got_sps <= 0) { + context->got_sps--; + if ((abs(context->got_sps) % 30) == 0) { + switch_set_flag(frame, SFF_WAIT_KEY_FRAME); + } + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "waiting pps\n"); + //return SWITCH_STATUS_RESTART; } + if (context->got_sps <= 0 && nalu_type == 7) context->got_sps = 1; + + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "XXX GOT %d len:%d\n", nalu_type, frame->datalen); if (!context->got_sps) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index a510f22915..fd76c6d65a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -10326,14 +10326,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor /* When desired, scale video to match the input signal (if output is bigger) */ if (switch_channel_test_flag(session->channel, CF_VIDEO_READY) && smh->vid_params.width && switch_channel_test_flag(session->channel, CF_VIDEO_MIRROR_INPUT) && - (smh->vid_params.width * smh->vid_params.height) < (img->d_w * img->d_h)) { + ((smh->vid_params.width != img->d_w) || (smh->vid_params.height != img->d_h))) { - switch_img_copy(img, &dup_img); - switch_img_fit(&dup_img, smh->vid_params.width, smh->vid_params.height); + switch_img_letterbox(img, &dup_img, smh->vid_params.width, smh->vid_params.height, "#000000f"); img = dup_img; } - + if (session->bugs) { switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 8cb6f320aa..61fa8fae96 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -1677,6 +1677,51 @@ SWITCH_DECLARE(switch_status_t) switch_img_write_png(switch_image_t *img, char* #endif +SWITCH_DECLARE(switch_status_t) switch_img_letterbox(switch_image_t *img, switch_image_t **imgP, int width, int height, const char *color) +{ + int img_w = 0, img_h = 0; + double screen_aspect = 0, img_aspect = 0; + int x_pos = 0; + int y_pos = 0; + switch_image_t *IMG = NULL, *scale_img = NULL; + switch_rgb_color_t bgcolor = { 0 }; + + switch_assert(imgP); + *imgP = NULL; + + if (img->d_w == width && img->d_h == height) { + switch_img_copy(img, imgP); + return SWITCH_STATUS_SUCCESS; + } + + IMG = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, width, height, 1); + switch_color_set_rgb(&bgcolor, color); + switch_img_fill(IMG, 0, 0, IMG->d_w, IMG->d_h, &bgcolor); + + img_w = IMG->d_w; + img_h = IMG->d_h; + + screen_aspect = (double) IMG->d_w / IMG->d_h; + img_aspect = (double) img->d_w / img->d_h; + + + if (screen_aspect > img_aspect) { + img_w = img_aspect * IMG->d_h; + x_pos = (IMG->d_w - img_w) / 2; + } else if (screen_aspect < img_aspect) { + img_h = IMG->d_w / img_aspect; + y_pos = (IMG->d_h - img_h) / 2; + } + + switch_img_scale(img, &scale_img, img_w, img_h); + switch_img_patch(IMG, scale_img, x_pos, y_pos); + switch_img_free(&scale_img); + + *imgP = IMG; + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, int height) { switch_image_t *src, *tmp = NULL;