lavfi/drawutils: support NV12 and NV21

parent b2244fa0
...@@ -205,8 +205,6 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) ...@@ -205,8 +205,6 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
return AVERROR(ENOSYS); return AVERROR(ENOSYS);
nb_planes = FFMAX(nb_planes, c->plane + 1); nb_planes = FFMAX(nb_planes, c->plane + 1);
} }
if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3)
return AVERROR(ENOSYS); /* exclude NV12 and NV21 */
memset(draw, 0, sizeof(*draw)); memset(draw, 0, sizeof(*draw));
draw->desc = desc; draw->desc = desc;
draw->format = format; draw->format = format;
...@@ -214,7 +212,7 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) ...@@ -214,7 +212,7 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
for (i = 0; i < ((desc->nb_components - 1) | 1); i++) for (i = 0; i < (desc->nb_components - !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); i++)
draw->comp_mask[desc->comp[i].plane] |= draw->comp_mask[desc->comp[i].plane] |=
1 << desc->comp[i].offset; 1 << desc->comp[i].offset;
return 0; return 0;
...@@ -243,20 +241,21 @@ void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4 ...@@ -243,20 +241,21 @@ void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4
color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8); color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8);
} }
} }
} else if (draw->nb_planes == 3 || draw->nb_planes == 4) { } else if (draw->nb_planes >= 2) {
/* assume YUV */ /* assume YUV */
color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); const AVPixFmtDescriptor *desc = draw->desc;
color->comp[1].u8[0] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0); color->comp[desc->comp[0].plane].u8[desc->comp[0].offset] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
color->comp[2].u8[0] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0); color->comp[desc->comp[1].plane].u8[desc->comp[1].offset] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
color->comp[desc->comp[2].plane].u8[desc->comp[2].offset] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
color->comp[3].u8[0] = rgba[3]; color->comp[3].u8[0] = rgba[3];
if (draw->desc->comp[0].depth > 8) #define EXPAND(compn) \
color->comp[0].u16[0] = color->comp[0].u8[0] << (draw->desc->comp[0].depth - 8); if (desc->comp[compn].depth > 8) \
if (draw->desc->comp[1].depth > 8) color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \
color->comp[1].u16[0] = color->comp[1].u8[0] << (draw->desc->comp[1].depth - 8); color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << (draw->desc->comp[compn].depth - 8)
if (draw->desc->comp[2].depth > 8) EXPAND(3);
color->comp[2].u16[0] = color->comp[2].u8[0] << (draw->desc->comp[2].depth - 8); EXPAND(2);
if (draw->desc->comp[3].depth > 8) EXPAND(1);
color->comp[3].u16[0] = color->comp[3].u8[0] << (draw->desc->comp[3].depth - 8); EXPAND(0);
} else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) { } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) {
color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
color->comp[1].u8[0] = rgba[3]; color->comp[1].u8[0] = rgba[3];
...@@ -450,7 +449,7 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, ...@@ -450,7 +449,7 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
/* 0x101 * alpha is in the [ 2 ; 0x1001] range */ /* 0x101 * alpha is in the [ 2 ; 0x1001] range */
alpha = 0x101 * color->rgba[3] + 0x2; alpha = 0x101 * color->rgba[3] + 0x2;
} }
nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */ nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA);
for (plane = 0; plane < nb_planes; plane++) { for (plane = 0; plane < nb_planes; plane++) {
nb_comp = draw->pixelstep[plane]; nb_comp = draw->pixelstep[plane];
p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
...@@ -627,7 +626,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, ...@@ -627,7 +626,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
} else { } else {
alpha = (0x101 * color->rgba[3] + 0x2) >> 8; alpha = (0x101 * color->rgba[3] + 0x2) >> 8;
} }
nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */ nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA);
for (plane = 0; plane < nb_planes; plane++) { for (plane = 0; plane < nb_planes; plane++) {
nb_comp = draw->pixelstep[plane]; nb_comp = draw->pixelstep[plane];
p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
......
...@@ -13,6 +13,8 @@ gbrp14le 9ae804cf217bec0a737c36c20573cbe5 ...@@ -13,6 +13,8 @@ gbrp14le 9ae804cf217bec0a737c36c20573cbe5
gbrp9le 9a86dab5661c213ce2b7e00ae48b4d1f gbrp9le 9a86dab5661c213ce2b7e00ae48b4d1f
gray ddc663a0491df3959d9c5795dceaa72e gray ddc663a0491df3959d9c5795dceaa72e
gray16le 468bda6155bdc7a7a20c34d6e599fd16 gray16le 468bda6155bdc7a7a20c34d6e599fd16
nv12 381574979cb04be10c9168540310afad
nv21 0fdeb2cdd56cf5a7147dc273456fa217
rgb0 78d500c8361ab6423a4826a00268c908 rgb0 78d500c8361ab6423a4826a00268c908
rgb24 17f9e2e0c609009acaf2175c42d4a2a5 rgb24 17f9e2e0c609009acaf2175c42d4a2a5
rgba b157c90191463d34fb3ce77b36c96386 rgba b157c90191463d34fb3ce77b36c96386
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment