Merge pull request #1206 in FS/freeswitch from bugfix/FS-10094-alpha-video-support to master

* commit 'd1625f85a526ca97546b79c589a9fa39fdd60d2e':
  FS-10094 Alpha Video support
This commit is contained in:
Anthony Minessale II 2017-03-15 10:25:47 -05:00
commit 589023b52c
3 changed files with 245 additions and 60 deletions

View File

@ -440,11 +440,29 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src
uint8_t *dst_planes[], int dst_stride[], uint8_t *dst_planes[], int dst_stride[],
int width, int height); int width, int height);
/*!\brief I420 to ARGB Convertion*/
SWITCH_DECLARE(switch_status_t) switch_I420ToARGB(const uint8_t *src_y, int src_stride_y,
const uint8_t *src_u, int src_stride_u,
const uint8_t *src_v, int src_stride_v,
uint8_t *dst_argb, int dst_stride_argb,
int width, int height);
SWITCH_DECLARE(switch_status_t) switch_RGBAToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height);
SWITCH_DECLARE(switch_status_t) switch_ABGRToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height);
SWITCH_DECLARE(switch_status_t) switch_ARGBToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height);
/*!\brief chromakey an img, img must be RGBA and return modified img */ /*!\brief chromakey an img, img must be RGBA and return modified img */
SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold); SWITCH_DECLARE(void) switch_img_chromakey(switch_image_t *img, switch_rgb_color_t *mask, int threshold);
SWITCH_DECLARE(switch_status_t) switch_chromakey_clear_colors(switch_chromakey_t *ck); SWITCH_DECLARE(switch_status_t) switch_chromakey_clear_colors(switch_chromakey_t *ck);
SWITCH_DECLARE(switch_status_t) switch_chromakey_autocolor(switch_chromakey_t *ck, switch_shade_t autocolor, uint32_t threshold); SWITCH_DECLARE(switch_status_t) switch_chromakey_autocolor(switch_chromakey_t *ck, switch_shade_t autocolor, uint32_t threshold);
SWITCH_DECLARE(switch_status_t) switch_chromakey_add_color(switch_chromakey_t *ck, switch_rgb_color_t *color, uint32_t threshold); SWITCH_DECLARE(switch_status_t) switch_chromakey_add_color(switch_chromakey_t *ck, switch_rgb_color_t *color, uint32_t threshold);
SWITCH_DECLARE(switch_status_t) switch_chromakey_destroy(switch_chromakey_t **ckP); SWITCH_DECLARE(switch_status_t) switch_chromakey_destroy(switch_chromakey_t **ckP);

View File

@ -126,20 +126,61 @@ static void av_unused fill_avframe(AVFrame *pict, switch_image_t *img)
static void av_unused avframe2img(AVFrame *pict, switch_image_t *img) static void av_unused avframe2img(AVFrame *pict, switch_image_t *img)
{ {
int i; int i, j;
uint8_t *y = pict->data[0];
uint8_t *u = pict->data[1];
uint8_t *v = pict->data[2];
/* Y */ if (img->fmt == SWITCH_IMG_FMT_I420) {
for (i = 0; i < img->d_h; i++) { if (pict->format == AV_PIX_FMT_YUV420P) {
memcpy(&img->planes[0][i * img->stride[0]], y + i * pict->linesize[0], img->d_w); switch_I420_copy2(pict->data, pict->linesize, img->planes, img->stride, img->d_w, img->d_h);
} } else if (pict->format == AV_PIX_FMT_YUVA420P) {
int linesize[3];
linesize[0] = pict->linesize[0];
linesize[1] = pict->linesize[1];
linesize[2] = pict->linesize[2] + pict->linesize[0];
/* U/V */ switch_I420_copy2(pict->data, linesize, img->planes, img->stride, img->d_w, img->d_h);
for(i = 0; i < pict->height / 2; i++) { }
memcpy(&img->planes[1][i * img->stride[1]], u + i * pict->linesize[1], img->d_w / 2);
memcpy(&img->planes[2][i * img->stride[2]], v + i * pict->linesize[2], img->d_w / 2); } else if (img->fmt == SWITCH_IMG_FMT_ARGB) {
if (pict->format == AV_PIX_FMT_YUV420P) {
switch_rgb_color_t *color = (switch_rgb_color_t *)img->planes[SWITCH_PLANE_PACKED];
uint8_t *alpha = pict->data[3];
/*!\brief I420 to ARGB Convertion*/
switch_I420ToARGB(pict->data[0], pict->linesize[0],
pict->data[1], pict->linesize[1],
pict->data[2], pict->linesize[2],
img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h);
for (j = 0; j < img->d_h; j++) {
for (i = 0; i < img->d_w; i++) {
color->a = *alpha++;
color++;
}
color = (switch_rgb_color_t *)(img->planes[SWITCH_PLANE_PACKED] + img->stride[SWITCH_PLANE_PACKED] * j);
}
} else if (pict->format == AV_PIX_FMT_RGBA) {
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
switch_RGBAToARGB(pict->data[0], pict->linesize[0],
mg->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h);
#else
switch_ABGRToARGB(pict->data[0], pict->linesize[0],
img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h);
#endif
} else if (pict->format == AV_PIX_FMT_BGRA) {
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
switch_BGRAToARGB(pict->data[0], pict->linesize[0],
, img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
, img->d_w, img->d_h);
#else
switch_ARGBToARGB(pict->data[0], pict->linesize[0],
img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h);
#endif
}
} }
} }
@ -1289,6 +1330,7 @@ struct av_file_context {
switch_bool_t read_paused; switch_bool_t read_paused;
int errs; int errs;
switch_file_handle_t *handle; switch_file_handle_t *handle;
switch_bool_t alpha_mode;
}; };
typedef struct av_file_context av_file_context_t; typedef struct av_file_context av_file_context_t;
@ -1310,13 +1352,15 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h
{ {
AVCodec *audio_codec = NULL; AVCodec *audio_codec = NULL;
AVCodec *video_codec = NULL; AVCodec *video_codec = NULL;
AVDictionary *opts = NULL;
int error; int error;
int i; int i;
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
// av_dict_set(&opts, "c:v", "libvpx", 0);
/** Open the input file to read from it. */ /** Open the input file to read from it. */
if ((error = avformat_open_input(&context->fc, filename, NULL, if ((error = avformat_open_input(&context->fc, filename, NULL, NULL)) < 0) {
NULL)) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open input file '%s' (error '%s')\n", filename, get_error_text(error)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open input file '%s' (error '%s')\n", filename, get_error_text(error));
switch_goto_status(SWITCH_STATUS_FALSE, err); switch_goto_status(SWITCH_STATUS_FALSE, err);
} }
@ -1325,11 +1369,14 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "file %s is %sseekable\n", filename, handle->seekable ? "" : "not "); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "file %s is %sseekable\n", filename, handle->seekable ? "" : "not ");
/** Get information on the input file (number of streams etc.). */ /** Get information on the input file (number of streams etc.). */
if ((error = avformat_find_stream_info(context->fc, NULL)) < 0) { if ((error = avformat_find_stream_info(context->fc, opts ? &opts : NULL)) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open find stream info (error '%s')\n", get_error_text(error)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open find stream info (error '%s')\n", get_error_text(error));
if (opts) av_dict_free(&opts);
switch_goto_status(SWITCH_STATUS_FALSE, err); switch_goto_status(SWITCH_STATUS_FALSE, err);
} }
if (opts) av_dict_free(&opts);
av_dump_format(context->fc, 0, filename, 0); av_dump_format(context->fc, 0, filename, 0);
for (i = 0; i< context->fc->nb_streams; i++) { for (i = 0; i< context->fc->nb_streams; i++) {
@ -1534,11 +1581,17 @@ again:
// av_frame_free(&vframe); // av_frame_free(&vframe);
// continue; // continue;
//} //}
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got_data=%d, error=%d\n", got_data, error);
if (got_data && error >= 0) { if (got_data && error >= 0) {
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got picture %dx%d fmt: %d pktpts:%lld pktdts:%lld\n", vframe->width, vframe->height, vframe->format, vframe->pkt_pts, vframe->pkt_dts); switch_img_fmt_t fmt = SWITCH_IMG_FMT_I420;
if (context->alpha_mode && (
if (vframe->format != AV_PIX_FMT_YUV420P) { vframe->format == AV_PIX_FMT_YUVA420P ||
vframe->format == AV_PIX_FMT_RGBA ||
vframe->format == AV_PIX_FMT_ARGB ||
vframe->format == AV_PIX_FMT_BGRA )) {
fmt = SWITCH_IMG_FMT_ARGB;
} else if (vframe->format != AV_PIX_FMT_YUV420P) {
AVFrame *frm = vframe; AVFrame *frm = vframe;
int ret; int ret;
@ -1580,7 +1633,7 @@ again:
} }
} }
img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, vframe->width, vframe->height, 1); img = switch_img_alloc(NULL, fmt, vframe->width, vframe->height, 1);
if (img) { if (img) {
int64_t *pts = malloc(sizeof(int64_t)); int64_t *pts = malloc(sizeof(int64_t));
@ -1610,6 +1663,7 @@ again:
} }
} }
} }
av_frame_free(&vframe); av_frame_free(&vframe);
if (eof) { if (eof) {
@ -1716,8 +1770,12 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa
context->offset = DFT_RECORD_OFFSET; context->offset = DFT_RECORD_OFFSET;
context->handle = handle; context->handle = handle;
if (handle->params && (tmp = switch_event_get_header(handle->params, "av_video_offset"))) { if (handle->params) {
context->offset = atoi(tmp); if ((tmp = switch_event_get_header(handle->params, "av_video_offset"))) {
context->offset = atoi(tmp);
} else if ((tmp = switch_event_get_header(handle->params, "alpha_mode"))) {
context->alpha_mode = switch_true(tmp);
}
} }
switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);

View File

@ -350,7 +350,7 @@ SWITCH_DECLARE(void) switch_img_attenuate(switch_image_t *img)
img->user_priv = (void *)(intptr_t)1; img->user_priv = (void *)(intptr_t)1;
ARGBAttenuate(img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED], ARGBAttenuate(img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED], img->d_w, img->d_h); img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED], img->d_w, img->d_h);
} }
@ -538,36 +538,56 @@ SWITCH_DECLARE(void) switch_img_patch_rect(switch_image_t *IMG, int X, int Y, sw
SWITCH_DECLARE(void) switch_img_copy(switch_image_t *img, switch_image_t **new_img) SWITCH_DECLARE(void) switch_img_copy(switch_image_t *img, switch_image_t **new_img)
{ {
#ifdef SWITCH_HAVE_YUV
switch_img_fmt_t new_fmt = img->fmt;
switch_assert(img); switch_assert(img);
switch_assert(new_img); switch_assert(new_img);
#ifdef SWITCH_HAVE_YUV
if (img->fmt != SWITCH_IMG_FMT_I420 && img->fmt != SWITCH_IMG_FMT_ARGB) return; if (img->fmt != SWITCH_IMG_FMT_I420 && img->fmt != SWITCH_IMG_FMT_ARGB) return;
if (*new_img != NULL) { if (*new_img) {
if (img->fmt != (*new_img)->fmt || img->d_w != (*new_img)->d_w || img->d_h != (*new_img)->d_w) { if ((*new_img)->fmt != SWITCH_IMG_FMT_I420 && (*new_img)->fmt != SWITCH_IMG_FMT_ARGB) return;
if (img->d_w != (*new_img)->d_w || img->d_h != (*new_img)->d_w ) {
new_fmt = (*new_img)->fmt;
switch_img_free(new_img); switch_img_free(new_img);
} }
} }
if (*new_img == NULL) { if (*new_img == NULL) {
*new_img = switch_img_alloc(NULL, img->fmt, img->d_w, img->d_h, 1); *new_img = switch_img_alloc(NULL, new_fmt, img->d_w, img->d_h, 1);
} }
switch_assert(*new_img); switch_assert(*new_img);
if (img->fmt == SWITCH_IMG_FMT_I420) { if (img->fmt == SWITCH_IMG_FMT_I420) {
I420Copy(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y], if (new_fmt == SWITCH_IMG_FMT_I420) {
img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U], I420Copy(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y],
img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V], img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U],
(*new_img)->planes[SWITCH_PLANE_Y], (*new_img)->stride[SWITCH_PLANE_Y], img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V],
(*new_img)->planes[SWITCH_PLANE_U], (*new_img)->stride[SWITCH_PLANE_U], (*new_img)->planes[SWITCH_PLANE_Y], (*new_img)->stride[SWITCH_PLANE_Y],
(*new_img)->planes[SWITCH_PLANE_V], (*new_img)->stride[SWITCH_PLANE_V], (*new_img)->planes[SWITCH_PLANE_U], (*new_img)->stride[SWITCH_PLANE_U],
img->d_w, img->d_h); (*new_img)->planes[SWITCH_PLANE_V], (*new_img)->stride[SWITCH_PLANE_V],
img->d_w, img->d_h);
} else if (new_fmt == SWITCH_IMG_FMT_ARGB) {
I420ToARGB(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y],
img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U],
img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V],
(*new_img)->planes[SWITCH_PLANE_PACKED], (*new_img)->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h);
}
} else if (img->fmt == SWITCH_IMG_FMT_ARGB) { } else if (img->fmt == SWITCH_IMG_FMT_ARGB) {
ARGBCopy(img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED], if (new_fmt == SWITCH_IMG_FMT_ARGB) {
ARGBCopy(img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
(*new_img)->planes[SWITCH_PLANE_PACKED], (*new_img)->stride[SWITCH_PLANE_PACKED], (*new_img)->planes[SWITCH_PLANE_PACKED], (*new_img)->stride[SWITCH_PLANE_PACKED],
img->d_w, img->d_h); img->d_w, img->d_h);
} else if (new_fmt == SWITCH_IMG_FMT_I420) {
ARGBToI420(img->planes[SWITCH_PLANE_PACKED], img->stride[SWITCH_PLANE_PACKED],
(*new_img)->planes[SWITCH_PLANE_Y], (*new_img)->stride[SWITCH_PLANE_Y],
(*new_img)->planes[SWITCH_PLANE_U], (*new_img)->stride[SWITCH_PLANE_U],
(*new_img)->planes[SWITCH_PLANE_V], (*new_img)->stride[SWITCH_PLANE_V],
img->d_w, img->d_h);
}
} }
#else #else
return; return;
@ -732,7 +752,7 @@ static inline void switch_core_rgb2hsl(switch_rgb_color_t *rgb, switch_hsl_color
static inline void switch_core_rgb2lab(switch_rgb_color_t *rgb, switch_lab_color_t *lab) static inline void switch_core_rgb2lab(switch_rgb_color_t *rgb, switch_lab_color_t *lab)
{ {
double x,y,z; double x,y,z;
double r = rgb->r; double r = rgb->r;
double g = rgb->g; double g = rgb->g;
double b = rgb->b; double b = rgb->b;
@ -916,7 +936,7 @@ struct switch_chromakey_s {
uint32_t gg; uint32_t gg;
uint32_t bb; uint32_t bb;
uint32_t color_count; uint32_t color_count;
switch_rgb_color_t auto_color; switch_rgb_color_t auto_color;
int no_cache; int no_cache;
int frames_read; int frames_read;
@ -979,7 +999,7 @@ SWITCH_DECLARE(switch_status_t) switch_chromakey_autocolor(switch_chromakey_t *c
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
SWITCH_DECLARE(switch_status_t) switch_chromakey_add_color(switch_chromakey_t *ck, switch_rgb_color_t *color, uint32_t threshold) SWITCH_DECLARE(switch_status_t) switch_chromakey_add_color(switch_chromakey_t *ck, switch_rgb_color_t *color, uint32_t threshold)
{ {
switch_assert(ck); switch_assert(ck);
@ -1054,10 +1074,10 @@ static inline int get_max(switch_rgb_color_t *c1)
static inline int switch_color_dom_cmp(switch_rgb_color_t *c1, switch_rgb_color_t *c2) static inline int switch_color_dom_cmp(switch_rgb_color_t *c1, switch_rgb_color_t *c2)
{ {
int c1_max = get_max(c1); int c1_max = get_max(c1);
int c2_max = get_max(c2); int c2_max = get_max(c2);
if (c1_max && c1_max == c2_max) return 1; if (c1_max && c1_max == c2_max) return 1;
return 0; return 0;
@ -1089,7 +1109,7 @@ static inline int switch_color_distance_cheap(switch_rgb_color_t *c1, switch_rgb
static inline void get_dom(switch_shade_t autocolor, switch_rgb_color_t *color, int *domP, int *aP, int *bP) static inline void get_dom(switch_shade_t autocolor, switch_rgb_color_t *color, int *domP, int *aP, int *bP)
{ {
int dom, a, b; int dom, a, b;
switch(autocolor) { switch(autocolor) {
case SWITCH_SHADE_RED: case SWITCH_SHADE_RED:
dom = color->r; dom = color->r;
@ -1172,7 +1192,7 @@ SWITCH_DECLARE(void) switch_chromakey_process(switch_chromakey_t *ck, switch_ima
#ifdef DEBUG_CHROMA #ifdef DEBUG_CHROMA
total_pixel++; total_pixel++;
#endif #endif
if (!ck->no_cache && cache_img && cache_pixel) { if (!ck->no_cache && cache_img && cache_pixel) {
switch_rgb_color_t *cache_color = (switch_rgb_color_t *)cache_pixel; switch_rgb_color_t *cache_color = (switch_rgb_color_t *)cache_pixel;
@ -1217,7 +1237,7 @@ SWITCH_DECLARE(void) switch_chromakey_process(switch_chromakey_t *ck, switch_ima
if (dom > a && dom > b && dom > tol) { if (dom > a && dom > b && dom > tol) {
if (dom - a > a_tol && dom - b > b_tol) { if (dom - a > a_tol && dom - b > b_tol) {
hits = 1; hits = 1;
} }
} }
} }
} }
@ -1231,7 +1251,7 @@ SWITCH_DECLARE(void) switch_chromakey_process(switch_chromakey_t *ck, switch_ima
checked++; checked++;
#endif #endif
} }
end: end:
if (same > 100 && last_color && switch_color_dom_cmp(color, last_color)) { if (same > 100 && last_color && switch_color_dom_cmp(color, last_color)) {
@ -2567,17 +2587,26 @@ SWITCH_DECLARE(switch_status_t) switch_img_write_png(switch_image_t *img, char*
png_bytep buffer = NULL; png_bytep buffer = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
buffer = malloc(img->d_w * img->d_h * 3); if (img->fmt == SWITCH_IMG_FMT_I420) {
switch_assert(buffer); png.format = PNG_FORMAT_RGB;
buffer = malloc(img->d_w * img->d_h * 3);
switch_assert(buffer);
I420ToRAW( img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y], I420ToRAW(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y],
img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U], img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U],
img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V], img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V],
buffer, img->d_w * 3, buffer, img->d_w * 3,
img->d_w, img->d_h); img->d_w, img->d_h);
} else if (img->fmt == SWITCH_IMG_FMT_ARGB) {
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
png.format = PNG_FORMAT_ARGB;
#else
png.format = PNG_FORMAT_BGRA;
#endif
buffer = img->planes[SWITCH_PLANE_PACKED];
}
png.version = PNG_IMAGE_VERSION; png.version = PNG_IMAGE_VERSION;
png.format = PNG_FORMAT_RGB;
png.width = img->d_w; png.width = img->d_w;
png.height = img->d_h; png.height = img->d_h;
@ -2586,7 +2615,10 @@ SWITCH_DECLARE(switch_status_t) switch_img_write_png(switch_image_t *img, char*
status = SWITCH_STATUS_FALSE; status = SWITCH_STATUS_FALSE;
} }
switch_safe_free(buffer); if (img->fmt == SWITCH_IMG_FMT_I420) {
free(buffer);
}
return status; return status;
} }
@ -2879,7 +2911,6 @@ SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *des
uint32_t fourcc; uint32_t fourcc;
int ret; int ret;
switch_assert(src->fmt == SWITCH_IMG_FMT_I420); // todo: support other formats
switch_assert(dest); switch_assert(dest);
fourcc = switch_img_fmt2fourcc(fmt); fourcc = switch_img_fmt2fourcc(fmt);
@ -2889,12 +2920,21 @@ SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *des
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
ret = ConvertFromI420(src->planes[0], src->stride[0], if (src->fmt == SWITCH_IMG_FMT_I420) {
src->planes[1], src->stride[1], ret = ConvertFromI420(src->planes[0], src->stride[0],
src->planes[2], src->stride[2], src->planes[1], src->stride[1],
dest, stride, src->planes[2], src->stride[2],
src->d_w, src->d_h, dest, stride,
fourcc); src->d_w, src->d_h,
fourcc);
} else if (src->fmt == SWITCH_IMG_FMT_ARGB && fmt == src->fmt) {
ret = ARGBCopy(src->planes[SWITCH_PLANE_PACKED], src->stride[SWITCH_PLANE_PACKED],
dest, stride,
src->d_w, src->d_h);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Convertion not supported %d -> %d\n", src->fmt, fmt);
return SWITCH_STATUS_FALSE;
}
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else #else
@ -2906,7 +2946,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *
{ {
#ifdef SWITCH_HAVE_YUV #ifdef SWITCH_HAVE_YUV
uint32_t fourcc; uint32_t fourcc;
int ret; int ret = -1;
fourcc = switch_img_fmt2fourcc(fmt); fourcc = switch_img_fmt2fourcc(fmt);
@ -2937,7 +2977,8 @@ SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *
src_size is only used when FOURCC_MJPG which we don't support so always 0 src_size is only used when FOURCC_MJPG which we don't support so always 0
*/ */
ret = ConvertToI420(src, 0, if (dest->fmt == SWITCH_IMG_FMT_I420) {
ret = ConvertToI420(src, 0,
dest->planes[0], dest->stride[0], dest->planes[0], dest->stride[0],
dest->planes[1], dest->stride[1], dest->planes[1], dest->stride[1],
dest->planes[2], dest->stride[2], dest->planes[2], dest->stride[2],
@ -2945,6 +2986,14 @@ SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *
width, height, width, height,
width, height, width, height,
0, fourcc); 0, fourcc);
} else if (dest->fmt == SWITCH_IMG_FMT_ARGB) {
ConvertToARGB(src, 0,
dest->planes[0], width * 4,
0, 0,
width, height,
width, height,
0, fourcc);
}
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else #else
@ -2962,9 +3011,9 @@ SWITCH_DECLARE(switch_status_t) switch_img_scale(switch_image_t *src, switch_ima
dest = *destP; dest = *destP;
} }
if (!dest) dest = switch_img_alloc(NULL, src->fmt, width, height, 1); if (dest && src->fmt != dest->fmt) switch_img_free(&dest);
switch_assert(src->fmt == dest->fmt); if (!dest) dest = switch_img_alloc(NULL, src->fmt, width, height, 1);
if (src->fmt == SWITCH_IMG_FMT_I420) { if (src->fmt == SWITCH_IMG_FMT_I420) {
ret = I420Scale(src->planes[0], src->stride[0], ret = I420Scale(src->planes[0], src->stride[0],
@ -3126,6 +3175,66 @@ SWITCH_DECLARE(switch_status_t) switch_I420_copy2(uint8_t *src_planes[], int src
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
#endif #endif
} }
SWITCH_DECLARE(switch_status_t) switch_I420ToARGB(const uint8_t *src_y, int src_stride_y,
const uint8_t *src_u, int src_stride_u,
const uint8_t *src_v, int src_stride_v,
uint8_t *dst_argb, int dst_stride_argb,
int width, int height)
{
#ifdef SWITCH_HAVE_YUV
int ret = I420ToARGB(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
dst_argb, dst_stride_argb, width, height);
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else
return SWITCH_STATUS_FALSE;
#endif
}
SWITCH_DECLARE(switch_status_t) switch_RGBAToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height)
{
#ifdef SWITCH_HAVE_YUV
int ret = RGBAToARGB(src_frame, src_stride_frame, dst_argb, dst_stride_argb, width, height);
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else
return SWITCH_STATUS_FALSE;
#endif
}
SWITCH_DECLARE(switch_status_t) switch_ABGRToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height)
{
#ifdef SWITCH_HAVE_YUV
int ret = ABGRToARGB(src_frame, src_stride_frame, dst_argb, dst_stride_argb, width, height);
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else
return SWITCH_STATUS_FALSE;
#endif
}
SWITCH_DECLARE(switch_status_t) switch_ARGBToARGB(const uint8_t* src_frame, int src_stride_frame,
uint8_t* dst_argb, int dst_stride_argb,
int width, int height)
{
#ifdef SWITCH_HAVE_YUV
int ret = ARGBToARGB(src_frame, src_stride_frame, dst_argb, dst_stride_argb, width, height);
return ret == 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
#else
return SWITCH_STATUS_FALSE;
#endif
}
/* For Emacs: /* For Emacs:
* Local Variables: * Local Variables:
* mode:c * mode:c