Now handles non-standard 8 bpp raw AVI files created with "-vcodec rawvideo" that contain the palette at the end of each frame, like nut.

8 bpp raw QuickTime files created with "-vcodec rawvideo" won't work quite right, because they contain a palette both in the video sample description and at the end of each frame, which currently causes the stride to be calculated incorrectly. They are hugely non-standard anyway.

Original description follows:

This patch removes the monowhite switching code for 1 bpp raw AVI without a palette. I don't see any reason to keep it, since it's semantically incorrect to use monowhite for palettized data in my book, it adds unnecessary noise to the code, and it's inconsistent with the rest of the code in FFmpeg.

For black & white AVI or QuickTime files, in order to produce a monochrome nut file, force the pixel format with "-pix_fmt monow" or "-pix_fmt monob".

Another way is to use "ffmpeg -i 1bpp.avi -vcodec copy -vtag B1W0 1bpp.nut". The "-vtag" option is currently needed, otherwise FFmpeg will use a RGB[15] codec tag for some reason.

I have also updated the 1 bpp FATE test files (once again).

Mats

--
Mats Peterson
http://matsp888.no-ip.org/~mats/
>From 1600eeb442b1ebfd56a7f8882b93db3f2076b006 Mon Sep 17 00:00:00 2001
From: Mats Peterson <matsp...@yahoo.com>
Date: Fri, 12 Feb 2016 11:24:30 +0100
Subject: [PATCH v9] lavc/rawdec: Remove monowhite switching code for 1 bpp AVI without a palette

---
 libavcodec/rawdec.c               |   68 ++++++++++++++++---------------------
 tests/ref/vsynth/vsynth1-bpp1     |    4 +--
 tests/ref/vsynth/vsynth2-bpp1     |    4 +--
 tests/ref/vsynth/vsynth3-bpp1     |    4 +--
 tests/ref/vsynth/vsynth_lena-bpp1 |    4 +--
 5 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index b7ce2b6..cadeaff 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -46,6 +46,7 @@ typedef struct RawVideoContext {
     int is_pal8;
     int is_nut_mono;
     int is_nut_pal8;
+    int has_pkt_pal;
     int is_yuv2;
     int is_lt_16bpp; // 16bpp pixfmt and bits_per_coded_sample < 16
     int tff;
@@ -100,7 +101,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
             avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
         else {
             memset(context->palette->data, 0, AVPALETTE_SIZE);
-            if (avctx->bits_per_coded_sample <= 1)
+            if (avctx->bits_per_coded_sample == 1)
                 memset(context->palette->data, 0xff, 4);
         }
     }
@@ -121,17 +122,13 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
     if (avctx->codec_tag == MKTAG('B','1','W','0') ||
         avctx->codec_tag == MKTAG('B','0','W','1'))
         context->is_nut_mono = 1;
-    else if (avctx->codec_tag == MKTAG('P','A','L','8'))
+    else if (avctx->codec_tag == MKTAG('P','A','L',8))
         context->is_nut_pal8 = 1;
 
     if (avctx->codec_tag == AV_RL32("yuv2") &&
         avctx->pix_fmt   == AV_PIX_FMT_YUYV422)
         context->is_yuv2 = 1;
 
-    /* Temporary solution until PAL8 is implemented in nut */
-    if (context->is_pal8 && avctx->bits_per_coded_sample == 1)
-        avctx->pix_fmt = AV_PIX_FMT_NONE;
-
     return 0;
 }
 
@@ -192,33 +189,21 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    if (context->is_nut_mono)
-        stride = avctx->width / 8 + (avctx->width & 7 ? 1 : 0);
-    else if (context->is_nut_pal8)
-        stride = avctx->width;
-    else
-        stride = avpkt->size / avctx->height;
+    if ((avctx->bits_per_coded_sample == 8 || context->is_nut_pal8) &&
+        avctx->frame_number == 0 &&
+        !av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL))
+        context->has_pkt_pal = 1;
+
+    stride = (avpkt->size - (context->has_pkt_pal ? AVPALETTE_SIZE : 0)) / avctx->height;
 
-    if (stride == 0 || avpkt->size < stride * avctx->height) {
+    av_log(avctx, AV_LOG_DEBUG, "PACKET SIZE: %d\n", avpkt->size);
+    av_log(avctx, AV_LOG_DEBUG, "STRIDE: %d\n", stride);
+
+    if (stride <= 0 || avpkt->size < stride * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small (%d)\n", avpkt->size);
         return AVERROR_INVALIDDATA;
     }
 
-    /* Temporary solution until PAL8 is implemented in nut */
-    if (avctx->pix_fmt == AV_PIX_FMT_NONE &&
-        avctx->bits_per_coded_sample == 1 &&
-        avctx->frame_number == 0 &&
-        context->palette &&
-        AV_RB64(context->palette->data) == 0xFFFFFFFF00000000
-    ) {
-        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
-        if (!pal) {
-            avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
-            context->is_pal8 = 0;
-            context->is_mono = 1;
-        } else
-            avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    }
     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 
     if ((avctx->bits_per_coded_sample == 8 || avctx->bits_per_coded_sample == 4
@@ -380,18 +365,23 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
-                                                     NULL);
-
-        if (pal) {
-            av_buffer_unref(&context->palette);
-            context->palette = av_buffer_alloc(AVPALETTE_SIZE);
-            if (!context->palette) {
-                av_buffer_unref(&frame->buf[0]);
-                return AVERROR(ENOMEM);
-            }
-            memcpy(context->palette->data, pal, AVPALETTE_SIZE);
+        if (context->has_pkt_pal) {
+            memcpy(context->palette->data,
+                   avpkt->data + avpkt->size - AVPALETTE_SIZE, AVPALETTE_SIZE);
             frame->palette_has_changed = 1;
+        } else {
+            const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
+                                                         NULL);
+            if (pal) {
+                av_buffer_unref(&context->palette);
+                context->palette = av_buffer_alloc(AVPALETTE_SIZE);
+                if (!context->palette) {
+                    av_buffer_unref(&frame->buf[0]);
+                    return AVERROR(ENOMEM);
+                }
+                memcpy(context->palette->data, pal, AVPALETTE_SIZE);
+                frame->palette_has_changed = 1;
+            }
         }
     }
 
diff --git a/tests/ref/vsynth/vsynth1-bpp1 b/tests/ref/vsynth/vsynth1-bpp1
index 0bd1a77..0abadd6 100644
--- a/tests/ref/vsynth/vsynth1-bpp1
+++ b/tests/ref/vsynth/vsynth1-bpp1
@@ -1,4 +1,4 @@
 611de0803ff6bd0ef385dde59964a105 *tests/data/fate/vsynth1-bpp1.avi
 640452 tests/data/fate/vsynth1-bpp1.avi
-576b690e8a8921c54d777463b63a8307 *tests/data/fate/vsynth1-bpp1.out.rawvideo
-stddev:   97.41 PSNR:  8.36 MAXDIFF:  238 bytes:  7603200/  7603200
+cd1e1448d9895561347ceb66d0add34d *tests/data/fate/vsynth1-bpp1.out.rawvideo
+stddev:   84.48 PSNR:  9.60 MAXDIFF:  218 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-bpp1 b/tests/ref/vsynth/vsynth2-bpp1
index d283d6c..38e745f 100644
--- a/tests/ref/vsynth/vsynth2-bpp1
+++ b/tests/ref/vsynth/vsynth2-bpp1
@@ -1,4 +1,4 @@
 b51ad49892eb8f8912c5a983718a17bb *tests/data/fate/vsynth2-bpp1.avi
 640452 tests/data/fate/vsynth2-bpp1.avi
-338fb9039a4564e471bf8179f0c48a95 *tests/data/fate/vsynth2-bpp1.out.rawvideo
-stddev:   80.40 PSNR: 10.02 MAXDIFF:  238 bytes:  7603200/  7603200
+f0dfc0e87e5d96bce29a5944b1bd7471 *tests/data/fate/vsynth2-bpp1.out.rawvideo
+stddev:   68.98 PSNR: 11.36 MAXDIFF:  218 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth3-bpp1 b/tests/ref/vsynth/vsynth3-bpp1
index 5a65728..b4267cf 100644
--- a/tests/ref/vsynth/vsynth3-bpp1
+++ b/tests/ref/vsynth/vsynth3-bpp1
@@ -1,4 +1,4 @@
 98852649c5201df7d85d0e9b5a5b9f15 *tests/data/fate/vsynth3-bpp1.avi
 15352 tests/data/fate/vsynth3-bpp1.avi
-0b1ea21b69d384564dd3a978065443b2 *tests/data/fate/vsynth3-bpp1.out.rawvideo
-stddev:   97.64 PSNR:  8.34 MAXDIFF:  248 bytes:    86700/    86700
+52ae74ef7910e5b603c12288d425b9ae *tests/data/fate/vsynth3-bpp1.out.rawvideo
+stddev:   84.76 PSNR:  9.57 MAXDIFF:  232 bytes:    86700/    86700
diff --git a/tests/ref/vsynth/vsynth_lena-bpp1 b/tests/ref/vsynth/vsynth_lena-bpp1
index 63ab9e1..2577733 100644
--- a/tests/ref/vsynth/vsynth_lena-bpp1
+++ b/tests/ref/vsynth/vsynth_lena-bpp1
@@ -1,4 +1,4 @@
 2859022fac452b59e49a1189c4fbb3ec *tests/data/fate/vsynth_lena-bpp1.avi
 640452 tests/data/fate/vsynth_lena-bpp1.avi
-3be3497f8ca548c9196dcecc5bc7cb2b *tests/data/fate/vsynth_lena-bpp1.out.rawvideo
-stddev:   96.52 PSNR:  8.44 MAXDIFF:  231 bytes:  7603200/  7603200
+6183ba861d4e48d4aaefc514fde270e5 *tests/data/fate/vsynth_lena-bpp1.out.rawvideo
+stddev:   83.28 PSNR:  9.72 MAXDIFF:  215 bytes:  7603200/  7603200
-- 
1.7.10.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to