[FFmpeg-cvslog] lavf/avienc: Add palette after BITMAPINFOHEADER

Mats Peterson git at videolan.org
Sun Feb 21 03:45:39 CET 2016


ffmpeg | branch: master | Mats Peterson <matsp888 at yahoo.com> | Sat Feb 20 12:57:50 2016 +0100| [a51d82b85c83aa0d1a8295ed44a1c835065675e7] | committer: Michael Niedermayer

lavf/avienc: Add palette after BITMAPINFOHEADER

lavf/riffenc: Write space for palette
tests/ref/vsynth: Update 1 bpp files for pal8

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a51d82b85c83aa0d1a8295ed44a1c835065675e7
---

 libavformat/avienc.c              |   23 +++++++++++++++++++----
 libavformat/riffenc.c             |   24 ++++++++++++++++++++----
 tests/ref/vsynth/vsynth1-bpp1     |    8 ++++----
 tests/ref/vsynth/vsynth2-bpp1     |    8 ++++----
 tests/ref/vsynth/vsynth3-bpp1     |    8 ++++----
 tests/ref/vsynth/vsynth_lena-bpp1 |    8 ++++----
 6 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 0b0f8fc..7480c86 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -74,6 +74,9 @@ typedef struct AVIStream {
     int max_size;
     int sample_requested;
 
+    int64_t pal_offset;
+    int hdr_pal_done;
+
     int64_t last_dts;
 
     AVIIndex indexes;
@@ -359,6 +362,7 @@ static int avi_write_header(AVFormatContext *s)
                     && enc->pix_fmt == AV_PIX_FMT_RGB555LE
                     && enc->bits_per_coded_sample == 15)
                     enc->bits_per_coded_sample = 16;
+                avist->pal_offset = avio_tell(pb) + 40;
                 ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 0, 0);
                 pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,
                                               enc->bits_per_coded_sample);
@@ -652,6 +656,7 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
     int size               = pkt->size;
     AVIOContext *pb     = s->pb;
     AVCodecContext *enc = s->streams[stream_index]->codec;
+    AVIStream *avist    = s->streams[stream_index]->priv_data;
     int ret;
 
     if (enc->codec_id == AV_CODEC_ID_H264 && enc->codec_tag == MKTAG('H','2','6','4') && pkt->size) {
@@ -673,15 +678,25 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
         if (ret) {
             if (ret == CONTAINS_PAL) {
                 int pc_tag, i;
+                int pal_size = 1 << enc->bits_per_coded_sample;
+                if (!avist->hdr_pal_done) {
+                    int64_t cur_offset = avio_tell(pb);
+                    avio_seek(pb, avist->pal_offset, SEEK_SET);
+                    for (i = 0; i < pal_size; i++) {
+                        uint32_t v = AV_RL32(data + size - 4*pal_size + 4*i);
+                        avio_wl32(pb, v & 0xffffff);
+                    }
+                    avio_seek(pb, cur_offset, SEEK_SET);
+                    avist->hdr_pal_done++;
+                }
                 avi_stream2fourcc(tag, stream_index, enc->codec_type);
                 tag[2] = 'p'; tag[3] = 'c';
-
                 pc_tag = ff_start_tag(pb, tag);
                 avio_w8(pb, 0);
-                avio_w8(pb, 0);
+                avio_w8(pb, pal_size);
                 avio_wl16(pb, 0); // reserved
-                for (i = 0; i<256; i++) {
-                    uint32_t v = AV_RL32(data + size - 1024 + 4*i);
+                for (i = 0; i < pal_size; i++) {
+                    uint32_t v = AV_RL32(data + size - 4*pal_size + 4*i);
                     avio_wb32(pb, v<<8);
                 }
                 ff_end_tag(pb, pc_tag);
diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c
index ceb27f2..b626aaa 100644
--- a/libavformat/riffenc.c
+++ b/libavformat/riffenc.c
@@ -209,6 +209,12 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
     int keep_height = enc->extradata_size >= 9 &&
                       !memcmp(enc->extradata + enc->extradata_size - 9, "BottomUp", 9);
     int extradata_size = enc->extradata_size - 9*keep_height;
+    int raw_pal_avi;
+
+    raw_pal_avi = !for_asf && enc->codec_id == AV_CODEC_ID_RAWVIDEO &&
+            enc->bits_per_coded_sample >= 1 && enc->bits_per_coded_sample <= 8;
+    if (!enc->extradata_size && raw_pal_avi)
+        extradata_size = 4 * (1 << enc->bits_per_coded_sample);
 
     /* size */
     avio_wl32(pb, 40 + (ignore_extradata ? 0 :extradata_size));
@@ -228,10 +234,20 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
     avio_wl32(pb, 0);
 
     if (!ignore_extradata) {
-        avio_write(pb, enc->extradata, extradata_size);
-
-        if (!for_asf && extradata_size & 1)
-            avio_w8(pb, 0);
+        if (enc->extradata_size) {
+            avio_write(pb, enc->extradata, extradata_size);
+            if (!for_asf && extradata_size & 1)
+                avio_w8(pb, 0);
+        } else if (raw_pal_avi) {
+            int i;
+            for (i = 0; i < 1 << enc->bits_per_coded_sample; i++) {
+                /* Initialize 1 bpp palette to black & white */
+                if (!i && enc->bits_per_coded_sample == 1)
+                    avio_wl32(pb, 0xffffff);
+                else
+                    avio_wl32(pb, 0);
+            }
+        }
     }
 }
 
diff --git a/tests/ref/vsynth/vsynth1-bpp1 b/tests/ref/vsynth/vsynth1-bpp1
index 0bd1a77..92d5987 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
+0fcba876d3e499c0bebf7bb32a7f83f2 *tests/data/fate/vsynth1-bpp1.avi
+640460 tests/data/fate/vsynth1-bpp1.avi
+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..2a2a63e 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
+af7eae5293b820493d1f4e6d258d8da0 *tests/data/fate/vsynth2-bpp1.avi
+640460 tests/data/fate/vsynth2-bpp1.avi
+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 39f27f3..b3b757c 100644
--- a/tests/ref/vsynth/vsynth3-bpp1
+++ b/tests/ref/vsynth/vsynth3-bpp1
@@ -1,4 +1,4 @@
-d5689d1f5c2d4c28a345d5964a6161a8 *tests/data/fate/vsynth3-bpp1.avi
-20452 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
+01b0fbf35305b50b1c148c0a23f2cff4 *tests/data/fate/vsynth3-bpp1.avi
+20460 tests/data/fate/vsynth3-bpp1.avi
+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..57219cc 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
+930d019cbf8e06c67bdec58a3639c045 *tests/data/fate/vsynth_lena-bpp1.avi
+640460 tests/data/fate/vsynth_lena-bpp1.avi
+6183ba861d4e48d4aaefc514fde270e5 *tests/data/fate/vsynth_lena-bpp1.out.rawvideo
+stddev:   83.28 PSNR:  9.72 MAXDIFF:  215 bytes:  7603200/  7603200



More information about the ffmpeg-cvslog mailing list