📄 imgconvert.c
字号:
{
AVPicture tmpsrc = *src;
tmpsrc.data[0]++;
gray16_to_gray(dst, &tmpsrc, width, height);
}
static void gray16_to_gray16(AVPicture *dst, const AVPicture *src,
int width, int height)
{
int x, y, src_wrap, dst_wrap;
uint16_t *s, *d;
s = src->data[0];
src_wrap = (src->linesize[0] - width * 2)/2;
d = dst->data[0];
dst_wrap = (dst->linesize[0] - width * 2)/2;
for(y=0; y<height; y++){
for(x=0; x<width; x++){
*d++ = bswap_16(*s++);
}
s += src_wrap;
d += dst_wrap;
}
}
typedef struct ConvertEntry {
void (*convert)(AVPicture *dst,
const AVPicture *src, int width, int height);
} ConvertEntry;
/* Add each new conversion function in this table. In order to be able
to convert from any format to any format, the following constraints
must be satisfied:
- all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24
- all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8
- all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGB32
- PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from
PIX_FMT_RGB24.
- PIX_FMT_422 must convert to and from PIX_FMT_422P.
The other conversion functions are just optimisations for common cases.
*/
static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = {
[PIX_FMT_YUV420P] = {
[PIX_FMT_YUYV422] = {
.convert = yuv420p_to_yuyv422,
},
[PIX_FMT_RGB555] = {
.convert = yuv420p_to_rgb555
},
[PIX_FMT_RGB565] = {
.convert = yuv420p_to_rgb565
},
[PIX_FMT_BGR24] = {
.convert = yuv420p_to_bgr24
},
[PIX_FMT_RGB24] = {
.convert = yuv420p_to_rgb24
},
[PIX_FMT_RGB32] = {
.convert = yuv420p_to_rgb32
},
[PIX_FMT_UYVY422] = {
.convert = yuv420p_to_uyvy422,
},
},
[PIX_FMT_YUV422P] = {
[PIX_FMT_YUYV422] = {
.convert = yuv422p_to_yuyv422,
},
[PIX_FMT_UYVY422] = {
.convert = yuv422p_to_uyvy422,
},
},
[PIX_FMT_YUV444P] = {
[PIX_FMT_RGB24] = {
.convert = yuv444p_to_rgb24
},
},
[PIX_FMT_YUVJ420P] = {
[PIX_FMT_RGB555] = {
.convert = yuvj420p_to_rgb555
},
[PIX_FMT_RGB565] = {
.convert = yuvj420p_to_rgb565
},
[PIX_FMT_BGR24] = {
.convert = yuvj420p_to_bgr24
},
[PIX_FMT_RGB24] = {
.convert = yuvj420p_to_rgb24
},
[PIX_FMT_RGB32] = {
.convert = yuvj420p_to_rgb32
},
},
[PIX_FMT_YUVJ444P] = {
[PIX_FMT_RGB24] = {
.convert = yuvj444p_to_rgb24
},
},
[PIX_FMT_YUYV422] = {
[PIX_FMT_YUV420P] = {
.convert = yuyv422_to_yuv420p,
},
[PIX_FMT_YUV422P] = {
.convert = yuyv422_to_yuv422p,
},
},
[PIX_FMT_UYVY422] = {
[PIX_FMT_YUV420P] = {
.convert = uyvy422_to_yuv420p,
},
[PIX_FMT_YUV422P] = {
.convert = uyvy422_to_yuv422p,
},
},
[PIX_FMT_RGB24] = {
[PIX_FMT_YUV420P] = {
.convert = rgb24_to_yuv420p
},
[PIX_FMT_RGB565] = {
.convert = rgb24_to_rgb565
},
[PIX_FMT_RGB555] = {
.convert = rgb24_to_rgb555
},
[PIX_FMT_RGB32] = {
.convert = rgb24_to_rgb32
},
[PIX_FMT_BGR24] = {
.convert = rgb24_to_bgr24
},
[PIX_FMT_GRAY8] = {
.convert = rgb24_to_gray
},
[PIX_FMT_PAL8] = {
.convert = rgb24_to_pal8
},
[PIX_FMT_YUV444P] = {
.convert = rgb24_to_yuv444p
},
[PIX_FMT_YUVJ420P] = {
.convert = rgb24_to_yuvj420p
},
[PIX_FMT_YUVJ444P] = {
.convert = rgb24_to_yuvj444p
},
},
[PIX_FMT_RGB32] = {
[PIX_FMT_RGB24] = {
.convert = rgb32_to_rgb24
},
[PIX_FMT_BGR24] = {
.convert = rgb32_to_bgr24
},
[PIX_FMT_RGB565] = {
.convert = rgb32_to_rgb565
},
[PIX_FMT_RGB555] = {
.convert = rgb32_to_rgb555
},
[PIX_FMT_PAL8] = {
.convert = rgb32_to_pal8
},
[PIX_FMT_YUV420P] = {
.convert = rgb32_to_yuv420p
},
[PIX_FMT_GRAY8] = {
.convert = rgb32_to_gray
},
},
[PIX_FMT_BGR24] = {
[PIX_FMT_RGB32] = {
.convert = bgr24_to_rgb32
},
[PIX_FMT_RGB24] = {
.convert = bgr24_to_rgb24
},
[PIX_FMT_YUV420P] = {
.convert = bgr24_to_yuv420p
},
[PIX_FMT_GRAY8] = {
.convert = bgr24_to_gray
},
},
[PIX_FMT_RGB555] = {
[PIX_FMT_RGB24] = {
.convert = rgb555_to_rgb24
},
[PIX_FMT_RGB32] = {
.convert = rgb555_to_rgb32
},
[PIX_FMT_YUV420P] = {
.convert = rgb555_to_yuv420p
},
[PIX_FMT_GRAY8] = {
.convert = rgb555_to_gray
},
},
[PIX_FMT_RGB565] = {
[PIX_FMT_RGB32] = {
.convert = rgb565_to_rgb32
},
[PIX_FMT_RGB24] = {
.convert = rgb565_to_rgb24
},
[PIX_FMT_YUV420P] = {
.convert = rgb565_to_yuv420p
},
[PIX_FMT_GRAY8] = {
.convert = rgb565_to_gray
},
},
[PIX_FMT_GRAY16BE] = {
[PIX_FMT_GRAY8] = {
.convert = gray16be_to_gray
},
[PIX_FMT_GRAY16LE] = {
.convert = gray16_to_gray16
},
},
[PIX_FMT_GRAY16LE] = {
[PIX_FMT_GRAY8] = {
.convert = gray16le_to_gray
},
[PIX_FMT_GRAY16BE] = {
.convert = gray16_to_gray16
},
},
[PIX_FMT_GRAY8] = {
[PIX_FMT_RGB555] = {
.convert = gray_to_rgb555
},
[PIX_FMT_RGB565] = {
.convert = gray_to_rgb565
},
[PIX_FMT_RGB24] = {
.convert = gray_to_rgb24
},
[PIX_FMT_BGR24] = {
.convert = gray_to_bgr24
},
[PIX_FMT_RGB32] = {
.convert = gray_to_rgb32
},
[PIX_FMT_MONOWHITE] = {
.convert = gray_to_monowhite
},
[PIX_FMT_MONOBLACK] = {
.convert = gray_to_monoblack
},
[PIX_FMT_GRAY16LE] = {
.convert = gray_to_gray16
},
[PIX_FMT_GRAY16BE] = {
.convert = gray_to_gray16
},
},
[PIX_FMT_MONOWHITE] = {
[PIX_FMT_GRAY8] = {
.convert = monowhite_to_gray
},
},
[PIX_FMT_MONOBLACK] = {
[PIX_FMT_GRAY8] = {
.convert = monoblack_to_gray
},
},
[PIX_FMT_PAL8] = {
[PIX_FMT_RGB555] = {
.convert = pal8_to_rgb555
},
[PIX_FMT_RGB565] = {
.convert = pal8_to_rgb565
},
[PIX_FMT_BGR24] = {
.convert = pal8_to_bgr24
},
[PIX_FMT_RGB24] = {
.convert = pal8_to_rgb24
},
[PIX_FMT_RGB32] = {
.convert = pal8_to_rgb32
},
},
[PIX_FMT_UYYVYY411] = {
[PIX_FMT_YUV411P] = {
.convert = uyyvyy411_to_yuv411p,
},
},
};
int avpicture_alloc(AVPicture *picture,
int pix_fmt, int width, int height)
{
int size;
void *ptr;
size = avpicture_get_size(pix_fmt, width, height);
if(size<0)
goto fail;
ptr = av_malloc(size);
if (!ptr)
goto fail;
avpicture_fill(picture, ptr, pix_fmt, width, height);
return 0;
fail:
memset(picture, 0, sizeof(AVPicture));
return -1;
}
void avpicture_free(AVPicture *picture)
{
av_free(picture->data[0]);
}
/* return true if yuv planar */
static inline int is_yuv_planar(const PixFmtInfo *ps)
{
return (ps->color_type == FF_COLOR_YUV ||
ps->color_type == FF_COLOR_YUV_JPEG) &&
ps->pixel_type == FF_PIXEL_PLANAR;
}
int av_picture_crop(AVPicture *dst, const AVPicture *src,
int pix_fmt, int top_band, int left_band)
{
int y_shift;
int x_shift;
if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
return -1;
y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
dst->linesize[0] = src->linesize[0];
dst->linesize[1] = src->linesize[1];
dst->linesize[2] = src->linesize[2];
return 0;
}
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
int pix_fmt, int padtop, int padbottom, int padleft, int padright,
int *color)
{
uint8_t *optr;
int y_shift;
int x_shift;
int yheight;
int i, y;
if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
!is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
for (i = 0; i < 3; i++) {
x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0;
y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0;
if (padtop || padleft) {
memset(dst->data[i], color[i],
dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
}
if (padleft || padright) {
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
optr += dst->linesize[i];
}
}
if (src) { /* first line */
uint8_t *iptr = src->data[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(padleft >> x_shift);
memcpy(optr, iptr, src->linesize[i]);
iptr += src->linesize[i];
optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
(dst->linesize[i] - (padright >> x_shift));
yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
for (y = 0; y < yheight; y++) {
memset(optr, color[i], (padleft + padright) >> x_shift);
memcpy(optr + ((padleft + padright) >> x_shift), iptr,
src->linesize[i]);
iptr += src->linesize[i];
optr += dst->linesize[i];
}
}
if (padbottom || padright) {
optr = dst->data[i] + dst->linesize[i] *
((height - padbottom) >> y_shift) - (padright >> x_shift);
memset(optr, color[i],dst->linesize[i] *
(padbottom >> y_shift) + (padright >> x_shift));
}
}
return 0;
}
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
void img_copy(AVPicture *dst, const AVPicture *src,
int pix_fmt, int width, int height)
{
av_picture_copy(dst, src, pix_fmt, width, height);
}
int img_crop(AVPicture *dst, const AVPicture *src,
int pix_fmt, int top_band, int left_band)
{
return av_picture_crop(dst, src, pix_fmt, top_band, left_band);
}
int img_pad(AVPicture *dst, const AVPicture *src, int height, int width,
int pix_fmt, int padtop, int padbottom, int padleft, int padright,
int *color)
{
return av_picture_pad(dst, src, height, width, pix_fmt, padtop, padbottom, padleft, padright, color);
}
#endif
#ifndef CONFIG_SWSCALER
/* XXX: always use linesize. Return -1 if not supported */
int img_convert(AVPicture *dst, int dst_pix_fmt,
const AVPicture *src, int src_pix_fmt,
int src_width, int src_height)
{
static int inited;
int i, ret, dst_width, dst_height, int_pix_fmt;
const PixFmtInfo *src_pix, *dst_pix;
const ConvertEntry *ce;
AVPicture tmp1, *tmp = &tmp1;
if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||
dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)
return -1;
if (src_width <= 0 || src_height <= 0)
return 0;
if (!inited) {
inited = 1;
img_convert_init();
}
dst_width = src_width;
dst_height = src_height;
dst_pix = &pix_fmt_info[dst_pix_fmt];
src_pix = &pix_fmt_info[src_pix_fmt];
if (src_pix_fmt == dst_pix_fmt) {
/* no conversion needed: just copy */
av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);
return 0;
}
ce = &convert_table[src_pix_fmt][dst_pix_fmt];
if (ce->convert) {
/* specific conversion routine */
ce->convert(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -