From ed78d3899404f5258bf51e138b0c0c18765afb37 Mon Sep 17 00:00:00 2001 From: Seven Du <dujinfang@gmail.com> Date: Wed, 24 Feb 2016 18:34:35 +0800 Subject: [PATCH] FS-8867: create conversion function stubs in the core so modules do not need to use libyuv directly --- src/include/switch_core_video.h | 25 ++++- src/include/switch_vpx.h | 30 ++++- src/mod/applications/mod_cv/mod_cv.cpp | 14 +-- src/mod/formats/mod_imagick/mod_imagick.c | 9 +- src/mod/formats/mod_vlc/mod_vlc.c | 3 +- src/switch_core_video.c | 128 +++++++++++++++++++--- 6 files changed, 165 insertions(+), 44 deletions(-) diff --git a/src/include/switch_core_video.h b/src/include/switch_core_video.h index 33413cd6f4..0e9ebdd320 100644 --- a/src/include/switch_core_video.h +++ b/src/include/switch_core_video.h @@ -339,7 +339,30 @@ SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, SWITCH_DECLARE(switch_img_position_t) parse_img_position(const char *name); SWITCH_DECLARE(switch_img_fit_t) parse_img_fit(const char *name); SWITCH_DECLARE(void) switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP); -SWITCH_DECLARE(switch_status_t) switch_img_convert(switch_image_t *src, switch_convert_fmt_t fmt, void *dest, switch_size_t *size); + +/*!\brief convert img to raw format +* +* dest should be pre-allocated and big enough for the target fmt +* +* \param[in] src The image descriptor +* \param[in] dest The target memory address +* \param[in] size The size of target memory address used for bounds check +* \param[in] fmt The target format +*/ +SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt); +/*!\brief convert raw memory to switch_img_t +* +* if dest is NULL then a new img is created, user should destroy it later, +* otherwize it will re-used the dest img, and the dest img size must match the src width and height, +* width and height can be 0 in the latter case and it will figure out according to the dest img +* +* \param[in] dest The image descriptor +* \param[in] src The raw data memory address +* \param[in] fmt The raw data format +* \param[in] width The raw data width +* \param[in] height The raw data height +*/ +SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *src, switch_img_fmt_t fmt, int width, int height); 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); diff --git a/src/include/switch_vpx.h b/src/include/switch_vpx.h index a975775a7a..f2791678f7 100644 --- a/src/include/switch_vpx.h +++ b/src/include/switch_vpx.h @@ -59,9 +59,33 @@ SWITCH_BEGIN_EXTERN_C #define VPX_IMG_FMT_HIGH 0x800 /**< Image uses 16bit framebuffer */ #endif -#define SWITCH_IMG_FMT_HIGH VPX_IMG_FMT_HIGH -#define SWITCH_IMG_FMT_I420 VPX_IMG_FMT_I420 -#define SWITCH_IMG_FMT_ARGB VPX_IMG_FMT_ARGB +#define SWITCH_IMG_FMT_NONE VPX_IMG_FMT_NONE +#define SWITCH_IMG_FMT_RGB24 VPX_IMG_FMT_RGB24 +#define SWITCH_IMG_FMT_RGB32 VPX_IMG_FMT_RGB32 +#define SWITCH_IMG_FMT_RGB565 VPX_IMG_FMT_RGB565 +#define SWITCH_IMG_FMT_RGB555 VPX_IMG_FMT_RGB555 +#define SWITCH_IMG_FMT_UYVY VPX_IMG_FMT_UYVY +#define SWITCH_IMG_FMT_YUY2 VPX_IMG_FMT_YUY2 +#define SWITCH_IMG_FMT_YVYU VPX_IMG_FMT_YVYU +#define SWITCH_IMG_FMT_BGR24 VPX_IMG_FMT_BGR24 +#define SWITCH_IMG_FMT_RGB32_LE VPX_IMG_FMT_RGB32_LE +#define SWITCH_IMG_FMT_ARGB VPX_IMG_FMT_ARGB +#define SWITCH_IMG_FMT_ARGB_LE VPX_IMG_FMT_ARGB_LE +#define SWITCH_IMG_FMT_RGB565_LE VPX_IMG_FMT_RGB565_LE +#define SWITCH_IMG_FMT_RGB555_LE VPX_IMG_FMT_RGB555_LE +#define SWITCH_IMG_FMT_YV12 VPX_IMG_FMT_YV12 +#define SWITCH_IMG_FMT_I420 VPX_IMG_FMT_I420 +#define SWITCH_IMG_FMT_VPXYV12 VPX_IMG_FMT_VPXYV12 +#define SWITCH_IMG_FMT_VPXI420 VPX_IMG_FMT_VPXI420 +#define SWITCH_IMG_FMT_I422 VPX_IMG_FMT_I422 +#define SWITCH_IMG_FMT_I444 VPX_IMG_FMT_I444 +#define SWITCH_IMG_FMT_I440 VPX_IMG_FMT_I440 +#define SWITCH_IMG_FMT_444A VPX_IMG_FMT_444A +#define SWITCH_IMG_FMT_I42016 VPX_IMG_FMT_I42016 +#define SWITCH_IMG_FMT_I42216 VPX_IMG_FMT_I42216 +#define SWITCH_IMG_FMT_I44416 VPX_IMG_FMT_I44416 +#define SWITCH_IMG_FMT_I44016 VPX_IMG_FMT_I44016 +/* experimental */ #define SWITCH_IMG_FMT_GD VPX_IMG_FMT_NONE typedef vpx_img_fmt_t switch_img_fmt_t; diff --git a/src/mod/applications/mod_cv/mod_cv.cpp b/src/mod/applications/mod_cv/mod_cv.cpp index 9f5d95dac0..5183adc40c 100644 --- a/src/mod/applications/mod_cv/mod_cv.cpp +++ b/src/mod/applications/mod_cv/mod_cv.cpp @@ -39,7 +39,6 @@ using namespace std; using namespace cv; #include <switch.h> -#include <libyuv.h> #include <cv.h> #include "cvaux.h" @@ -724,12 +723,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi switch_assert(context->rawImage->width * 3 == context->rawImage->widthStep); } - libyuv::I420ToRGB24(frame->img->planes[0], frame->img->stride[0], - frame->img->planes[1], frame->img->stride[1], - frame->img->planes[2], frame->img->stride[2], - (uint8_t *)context->rawImage->imageData, context->rawImage->widthStep, - context->rawImage->width, context->rawImage->height); - + switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep * context->h, SWITCH_IMG_FMT_RGB24); detectAndDraw(context); if (context->detected.simo_count > 20) { @@ -824,11 +818,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi } if (context->rawImage && (context->debug || !context->overlay_count)) { - libyuv::RGB24ToI420((uint8_t *)context->rawImage->imageData, context->w * 3, - frame->img->planes[0], frame->img->stride[0], - frame->img->planes[1], frame->img->stride[1], - frame->img->planes[2], frame->img->stride[2], - context->rawImage->width, context->rawImage->height); + switch_img_from_raw(frame->img, (uint8_t *)context->rawImage->imageData, SWITCH_IMG_FMT_RGB24, context->rawImage->width, context->rawImage->height); } int abs = 0; diff --git a/src/mod/formats/mod_imagick/mod_imagick.c b/src/mod/formats/mod_imagick/mod_imagick.c index 4c04b91cdf..060889f16a 100644 --- a/src/mod/formats/mod_imagick/mod_imagick.c +++ b/src/mod/formats/mod_imagick/mod_imagick.c @@ -34,8 +34,6 @@ #include <switch.h> -#include <libyuv.h> - #if defined(__clang__) /* the imagemagick header files are very badly broken on clang. They really should be fixing this, in the mean time, this dirty hack works */ @@ -263,12 +261,7 @@ static switch_status_t read_page(pdf_file_context_t *context) return SWITCH_STATUS_FALSE; } - RAWToI420(storage, w * 3, - context->img->planes[0], context->img->stride[0], - context->img->planes[1], context->img->stride[1], - context->img->planes[2], context->img->stride[2], - context->img->d_w, context->img->d_h); - + switch_img_from_raw(context->img, storage, SWITCH_IMG_FMT_BGR24, w, h); free(storage); } else { switch_image_t *img = switch_img_alloc(NULL, SWITCH_IMG_FMT_ARGB, image->columns, image->rows, 0); diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index 32798099be..e9769fc084 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -1642,8 +1642,7 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t * } *output = context->video_frame_buffer; - *size = 0; - switch_img_convert(img, SWITCH_CONVERT_FMT_YUYV, *output, size); + switch_img_to_raw(img, *output, *size, SWITCH_IMG_FMT_YUY2); switch_img_free(&img); return 0; } diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 4ea9669d6c..e226b95376 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -1936,29 +1936,121 @@ SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, return SWITCH_STATUS_FALSE; } -SWITCH_DECLARE(switch_status_t) switch_img_convert(switch_image_t *src, switch_convert_fmt_t fmt, void *dest, switch_size_t *size) +static inline uint32_t switch_img_fmt2fourcc(switch_img_fmt_t fmt) { #ifdef SWITCH_HAVE_YUV - switch_assert(src->fmt == SWITCH_IMG_FMT_I420); + uint32_t fourcc; - switch (fmt) { - case SWITCH_CONVERT_FMT_YUYV: - { - switch_size_t size_in = *size; - ConvertFromI420(src->planes[0], src->stride[0], - src->planes[1], src->stride[1], - src->planes[2], src->stride[2], - dest, size_in, - src->d_w, src->d_h, - FOURCC_YUY2); - *size = src->d_w * src->d_h * 2; + switch(fmt) { + case SWITCH_IMG_FMT_NONE: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_RGB24: fourcc = FOURCC_24BG; break; + case SWITCH_IMG_FMT_RGB32: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_RGB565: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_RGB555: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_UYVY: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_YUY2: fourcc = FOURCC_YUY2; break; + case SWITCH_IMG_FMT_YVYU: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_BGR24: fourcc = FOURCC_RAW ; break; + case SWITCH_IMG_FMT_RGB32_LE: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_ARGB: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_ARGB_LE: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_RGB565_LE: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_RGB555_LE: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_YV12: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I420: fourcc = FOURCC_I420; break; + case SWITCH_IMG_FMT_VPXYV12: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_VPXI420: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I422: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I444: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I440: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_444A: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I42016: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I42216: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I44416: fourcc = FOURCC_ANY ; break; + case SWITCH_IMG_FMT_I44016: fourcc = FOURCC_ANY ; break; + default: fourcc = FOURCC_ANY; + } - return SWITCH_STATUS_SUCCESS; - } - default: - abort(); - break; + return fourcc; +#else + return 0xFFFFFFFF; +#endif +} + +SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt) +{ +#ifdef SWITCH_HAVE_YUV + uint32_t fourcc; + int ret; + + switch_assert(src->fmt == SWITCH_IMG_FMT_I420); // todo: support other formats + switch_assert(dest); + + fourcc = switch_img_fmt2fourcc(fmt); + + if (fourcc == FOURCC_ANY) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported format: %d\n", fmt); + return SWITCH_STATUS_FALSE; } + + ret = ConvertFromI420(src->planes[0], src->stride[0], + src->planes[1], src->stride[1], + src->planes[2], src->stride[2], + dest, size, + src->d_w, src->d_h, + fourcc); + + return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; +#else + return SWITCH_STATUS_FALSE; +#endif +} + +SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *src, switch_img_fmt_t fmt, int width, int height) +{ +#ifdef SWITCH_HAVE_YUV + uint32_t fourcc; + int ret; + + fourcc = switch_img_fmt2fourcc(fmt); + + if (fourcc == FOURCC_ANY) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported format: %d\n", fmt); + return SWITCH_STATUS_FALSE; + } + + if (!dest && width > 0 && height > 0) dest = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, width, height, 1); + if (!dest) return SWITCH_STATUS_FALSE; + + if (width == 0 || height == 0) { + width = dest->d_w; + height = dest->d_h; + } + +/* + int ConvertToI420(const uint8* src_frame, size_t src_size, + uint8* dst_y, int dst_stride_y, + uint8* dst_u, int dst_stride_u, + uint8* dst_v, int dst_stride_v, + int crop_x, int crop_y, + int src_width, int src_height, + int crop_width, int crop_height, + enum RotationMode rotation, + uint32 format); + + src_size is only used when FOURCC_MJPG which we don't support so always 0 +*/ + + ret = ConvertToI420(src, 0, + dest->planes[0], dest->stride[0], + dest->planes[1], dest->stride[1], + dest->planes[2], dest->stride[2], + 0, 0, + width, height, + width, height, + 0, fourcc); + + return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; #else return SWITCH_STATUS_FALSE; #endif