📄 imgconvert.c
字号:
picture->linesize[3] = width;
return 2 * size + 2 * size2;
case PIX_FMT_NV12:
case PIX_FMT_NV21:
w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift;
h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift;
size2 = w2 * h2 * 2;
picture->data[0] = ptr;
picture->data[1] = picture->data[0] + size;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width;
picture->linesize[1] = w2;
picture->linesize[2] = 0;
picture->linesize[3] = 0;
return size + 2 * size2;
case PIX_FMT_RGB24:
case PIX_FMT_BGR24:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width * 3;
return size * 3;
case PIX_FMT_RGB32:
case PIX_FMT_BGR32:
case PIX_FMT_RGB32_1:
case PIX_FMT_BGR32_1:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width * 4;
return size * 4;
case PIX_FMT_GRAY16BE:
case PIX_FMT_GRAY16LE:
case PIX_FMT_BGR555:
case PIX_FMT_BGR565:
case PIX_FMT_RGB555:
case PIX_FMT_RGB565:
case PIX_FMT_YUYV422:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width * 2;
return size * 2;
case PIX_FMT_UYVY422:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width * 2;
return size * 2;
case PIX_FMT_UYYVYY411:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width + width/2;
return size + size/2;
case PIX_FMT_RGB8:
case PIX_FMT_BGR8:
case PIX_FMT_RGB4_BYTE:
case PIX_FMT_BGR4_BYTE:
case PIX_FMT_GRAY8:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width;
return size;
case PIX_FMT_RGB4:
case PIX_FMT_BGR4:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width / 2;
return size / 2;
case PIX_FMT_MONOWHITE:
case PIX_FMT_MONOBLACK:
picture->data[0] = ptr;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = (width + 7) >> 3;
return picture->linesize[0] * height;
case PIX_FMT_PAL8:
size2 = (size + 3) & ~3;
picture->data[0] = ptr;
picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */
picture->data[2] = NULL;
picture->data[3] = NULL;
picture->linesize[0] = width;
picture->linesize[1] = 4;
return size2 + 256 * 4;
default:
fail:
picture->data[0] = NULL;
picture->data[1] = NULL;
picture->data[2] = NULL;
picture->data[3] = NULL;
return -1;
}
}
int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
unsigned char *dest, int dest_size)
{
const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
int i, j, w, h, data_planes;
const unsigned char* s;
int size = avpicture_get_size(pix_fmt, width, height);
if (size > dest_size || size < 0)
return -1;
if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
if (pix_fmt == PIX_FMT_YUYV422 ||
pix_fmt == PIX_FMT_UYVY422 ||
pix_fmt == PIX_FMT_BGR565 ||
pix_fmt == PIX_FMT_BGR555 ||
pix_fmt == PIX_FMT_RGB565 ||
pix_fmt == PIX_FMT_RGB555)
w = width * 2;
else if (pix_fmt == PIX_FMT_UYYVYY411)
w = width + width/2;
else if (pix_fmt == PIX_FMT_PAL8)
w = width;
else
w = width * (pf->depth * pf->nb_channels / 8);
data_planes = 1;
h = height;
} else {
data_planes = pf->nb_channels;
w = (width*pf->depth + 7)/8;
h = height;
}
for (i=0; i<data_planes; i++) {
if (i == 1) {
w = width >> pf->x_chroma_shift;
h = height >> pf->y_chroma_shift;
}
s = src->data[i];
for(j=0; j<h; j++) {
memcpy(dest, s, w);
dest += w;
s += src->linesize[i];
}
}
if (pf->pixel_type == FF_PIXEL_PALETTE)
memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
return size;
}
int avpicture_get_size(int pix_fmt, int width, int height)
{
AVPicture dummy_pict;
return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
}
int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
int has_alpha)
{
const PixFmtInfo *pf, *ps;
int loss;
ps = &pix_fmt_info[src_pix_fmt];
pf = &pix_fmt_info[dst_pix_fmt];
/* compute loss */
loss = 0;
pf = &pix_fmt_info[dst_pix_fmt];
if (pf->depth < ps->depth ||
(dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
loss |= FF_LOSS_DEPTH;
if (pf->x_chroma_shift > ps->x_chroma_shift ||
pf->y_chroma_shift > ps->y_chroma_shift)
loss |= FF_LOSS_RESOLUTION;
switch(pf->color_type) {
case FF_COLOR_RGB:
if (ps->color_type != FF_COLOR_RGB &&
ps->color_type != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_GRAY:
if (ps->color_type != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_YUV:
if (ps->color_type != FF_COLOR_YUV)
loss |= FF_LOSS_COLORSPACE;
break;
case FF_COLOR_YUV_JPEG:
if (ps->color_type != FF_COLOR_YUV_JPEG &&
ps->color_type != FF_COLOR_YUV &&
ps->color_type != FF_COLOR_GRAY)
loss |= FF_LOSS_COLORSPACE;
break;
default:
/* fail safe test */
if (ps->color_type != pf->color_type)
loss |= FF_LOSS_COLORSPACE;
break;
}
if (pf->color_type == FF_COLOR_GRAY &&
ps->color_type != FF_COLOR_GRAY)
loss |= FF_LOSS_CHROMA;
if (!pf->is_alpha && (ps->is_alpha && has_alpha))
loss |= FF_LOSS_ALPHA;
if (pf->pixel_type == FF_PIXEL_PALETTE &&
(ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
loss |= FF_LOSS_COLORQUANT;
return loss;
}
static int avg_bits_per_pixel(int pix_fmt)
{
int bits;
const PixFmtInfo *pf;
pf = &pix_fmt_info[pix_fmt];
switch(pf->pixel_type) {
case FF_PIXEL_PACKED:
switch(pix_fmt) {
case PIX_FMT_YUYV422:
case PIX_FMT_UYVY422:
case PIX_FMT_RGB565:
case PIX_FMT_RGB555:
case PIX_FMT_BGR565:
case PIX_FMT_BGR555:
bits = 16;
break;
case PIX_FMT_UYYVYY411:
bits = 12;
break;
default:
bits = pf->depth * pf->nb_channels;
break;
}
break;
case FF_PIXEL_PLANAR:
if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) {
bits = pf->depth * pf->nb_channels;
} else {
bits = pf->depth + ((2 * pf->depth) >>
(pf->x_chroma_shift + pf->y_chroma_shift));
}
break;
case FF_PIXEL_PALETTE:
bits = 8;
break;
default:
bits = -1;
break;
}
return bits;
}
static int avcodec_find_best_pix_fmt1(int pix_fmt_mask,
int src_pix_fmt,
int has_alpha,
int loss_mask)
{
int dist, i, loss, min_dist, dst_pix_fmt;
/* find exact color match with smallest size */
dst_pix_fmt = -1;
min_dist = 0x7fffffff;
for(i = 0;i < PIX_FMT_NB; i++) {
if (pix_fmt_mask & (1 << i)) {
loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
if (loss == 0) {
dist = avg_bits_per_pixel(i);
if (dist < min_dist) {
min_dist = dist;
dst_pix_fmt = i;
}
}
}
}
return dst_pix_fmt;
}
int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
int has_alpha, int *loss_ptr)
{
int dst_pix_fmt, loss_mask, i;
static const int loss_mask_order[] = {
~0, /* no loss first */
~FF_LOSS_ALPHA,
~FF_LOSS_RESOLUTION,
~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
~FF_LOSS_COLORQUANT,
~FF_LOSS_DEPTH,
0,
};
/* try with successive loss */
i = 0;
for(;;) {
loss_mask = loss_mask_order[i++];
dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
has_alpha, loss_mask);
if (dst_pix_fmt >= 0)
goto found;
if (loss_mask == 0)
break;
}
return -1;
found:
if (loss_ptr)
*loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
return dst_pix_fmt;
}
void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
const uint8_t *src, int src_wrap,
int width, int height)
{
if((!dst) || (!src))
return;
for(;height > 0; height--) {
memcpy(dst, src, width);
dst += dst_wrap;
src += src_wrap;
}
}
void av_picture_copy(AVPicture *dst, const AVPicture *src,
int pix_fmt, int width, int height)
{
int bwidth, bits, i;
const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
pf = &pix_fmt_info[pix_fmt];
switch(pf->pixel_type) {
case FF_PIXEL_PACKED:
switch(pix_fmt) {
case PIX_FMT_YUYV422:
case PIX_FMT_UYVY422:
case PIX_FMT_RGB565:
case PIX_FMT_RGB555:
case PIX_FMT_BGR565:
case PIX_FMT_BGR555:
bits = 16;
break;
case PIX_FMT_UYYVYY411:
bits = 12;
break;
default:
bits = pf->depth * pf->nb_channels;
break;
}
bwidth = (width * bits + 7) >> 3;
ff_img_copy_plane(dst->data[0], dst->linesize[0],
src->data[0], src->linesize[0],
bwidth, height);
break;
case FF_PIXEL_PLANAR:
for(i = 0; i < pf->nb_channels; i++) {
int w, h;
w = width;
h = height;
if (i == 1 || i == 2) {
w >>= pf->x_chroma_shift;
h >>= pf->y_chroma_shift;
}
bwidth = (w * pf->depth + 7) >> 3;
ff_img_copy_plane(dst->data[i], dst->linesize[i],
src->data[i], src->linesize[i],
bwidth, h);
}
break;
case FF_PIXEL_PALETTE:
ff_img_copy_plane(dst->data[0], dst->linesize[0],
src->data[0], src->linesize[0],
width, height);
/* copy the palette */
ff_img_copy_plane(dst->data[1], dst->linesize[1],
src->data[1], src->linesize[1],
4, 256);
break;
}
}
/* XXX: totally non optimized */
static void yuyv422_to_yuv420p(AVPicture *dst, const AVPicture *src,
int width, int height)
{
const uint8_t *p, *p1;
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
int w;
p1 = src->data[0];
lum1 = dst->data[0];
cb1 = dst->data[1];
cr1 = dst->data[2];
for(;height >= 1; height -= 2) {
p = p1;
lum = lum1;
cb = cb1;
cr = cr1;
for(w = width; w >= 2; w -= 2) {
lum[0] = p[0];
cb[0] = p[1];
lum[1] = p[2];
cr[0] = p[3];
p += 4;
lum += 2;
cb++;
cr++;
}
if (w) {
lum[0] = p[0];
cb[0] = p[1];
cr[0] = p[3];
cb++;
cr++;
}
p1 += src->linesize[0];
lum1 += dst->linesize[0];
if (height>1) {
p = p1;
lum = lum1;
for(w = width; w >= 2; w -= 2) {
lum[0] = p[0];
lum[1] = p[2];
p += 4;
lum += 2;
}
if (w) {
lum[0] = p[0];
}
p1 += src->linesize[0];
lum1 += dst->linesize[0];
}
cb1 += dst->linesize[1];
cr1 += dst->linesize[2];
}
}
static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src,
int width, int height)
{
const uint8_t *p, *p1;
uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
int w;
p1 = src->data[0];
lum1 = dst->data[0];
cb1 = dst->data[1];
cr1 = dst->data[2];
for(;height >= 1; height -= 2) {
p = p1;
lum = lum1;
cb = cb1;
cr = cr1;
for(w = width; w >= 2; w -= 2) {
lum[0] = p[1];
cb[0] = p[0];
lum[1] = p[3];
cr[0] = p[2];
p += 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -