Browse code

lavfi/drawutils: support NV12 and NV21

Rodger Combs authored on 2016/05/10 10:52:06
Showing 2 changed files
... ...
@@ -205,8 +205,6 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
205 205
             return AVERROR(ENOSYS);
206 206
         nb_planes = FFMAX(nb_planes, c->plane + 1);
207 207
     }
208
-    if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3)
209
-        return AVERROR(ENOSYS); /* exclude NV12 and NV21 */
210 208
     memset(draw, 0, sizeof(*draw));
211 209
     draw->desc      = desc;
212 210
     draw->format    = format;
... ...
@@ -214,7 +212,7 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
214 214
     memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
215 215
     draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
216 216
     draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
217
-    for (i = 0; i < ((desc->nb_components - 1) | 1); i++)
217
+    for (i = 0; i < (desc->nb_components - !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); i++)
218 218
         draw->comp_mask[desc->comp[i].plane] |=
219 219
             1 << desc->comp[i].offset;
220 220
     return 0;
... ...
@@ -243,20 +241,21 @@ void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4
243 243
                     color->comp[rgba_map[i]].u16[0] = color->comp[rgba_map[i]].u8[0] << (draw->desc->comp[rgba_map[i]].depth - 8);
244 244
             }
245 245
         }
246
-    } else if (draw->nb_planes == 3 || draw->nb_planes == 4) {
246
+    } else if (draw->nb_planes >= 2) {
247 247
         /* assume YUV */
248
-        color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
249
-        color->comp[1].u8[0] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
250
-        color->comp[2].u8[0] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
248
+        const AVPixFmtDescriptor *desc = draw->desc;
249
+        color->comp[desc->comp[0].plane].u8[desc->comp[0].offset] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
250
+        color->comp[desc->comp[1].plane].u8[desc->comp[1].offset] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
251
+        color->comp[desc->comp[2].plane].u8[desc->comp[2].offset] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
251 252
         color->comp[3].u8[0] = rgba[3];
252
-        if (draw->desc->comp[0].depth > 8)
253
-            color->comp[0].u16[0] = color->comp[0].u8[0] << (draw->desc->comp[0].depth - 8);
254
-        if (draw->desc->comp[1].depth > 8)
255
-            color->comp[1].u16[0] = color->comp[1].u8[0] << (draw->desc->comp[1].depth - 8);
256
-        if (draw->desc->comp[2].depth > 8)
257
-            color->comp[2].u16[0] = color->comp[2].u8[0] << (draw->desc->comp[2].depth - 8);
258
-        if (draw->desc->comp[3].depth > 8)
259
-            color->comp[3].u16[0] = color->comp[3].u8[0] << (draw->desc->comp[3].depth - 8);
253
+#define EXPAND(compn) \
254
+        if (desc->comp[compn].depth > 8) \
255
+            color->comp[desc->comp[compn].plane].u16[desc->comp[compn].offset] = \
256
+            color->comp[desc->comp[compn].plane].u8[desc->comp[compn].offset] << (draw->desc->comp[compn].depth - 8)
257
+        EXPAND(3);
258
+        EXPAND(2);
259
+        EXPAND(1);
260
+        EXPAND(0);
260 261
     } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) {
261 262
         color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
262 263
         color->comp[1].u8[0] = rgba[3];
... ...
@@ -450,7 +449,7 @@ void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
450 450
         /* 0x101 * alpha is in the [ 2 ; 0x1001] range */
451 451
         alpha = 0x101 * color->rgba[3] + 0x2;
452 452
     }
453
-    nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
453
+    nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA);
454 454
     for (plane = 0; plane < nb_planes; plane++) {
455 455
         nb_comp = draw->pixelstep[plane];
456 456
         p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
... ...
@@ -627,7 +626,7 @@ void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
627 627
     } else {
628 628
         alpha = (0x101 * color->rgba[3] + 0x2) >> 8;
629 629
     }
630
-    nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
630
+    nb_planes = draw->nb_planes - !!(draw->desc->flags & AV_PIX_FMT_FLAG_ALPHA);
631 631
     for (plane = 0; plane < nb_planes; plane++) {
632 632
         nb_comp = draw->pixelstep[plane];
633 633
         p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
... ...
@@ -13,6 +13,8 @@ gbrp14le            9ae804cf217bec0a737c36c20573cbe5
13 13
 gbrp9le             9a86dab5661c213ce2b7e00ae48b4d1f
14 14
 gray                ddc663a0491df3959d9c5795dceaa72e
15 15
 gray16le            468bda6155bdc7a7a20c34d6e599fd16
16
+nv12                381574979cb04be10c9168540310afad
17
+nv21                0fdeb2cdd56cf5a7147dc273456fa217
16 18
 rgb0                78d500c8361ab6423a4826a00268c908
17 19
 rgb24               17f9e2e0c609009acaf2175c42d4a2a5
18 20
 rgba                b157c90191463d34fb3ce77b36c96386