changeset 34313:8f2167abd6e0

Try harder to extract a sensible palette from extradata. Fixes samples/V-codecs/QPEG/MITSUMI.AVI.
author reimar
date Tue, 06 Dec 2011 19:59:16 +0000
parents d2a41814c879
children b2c01a543421
files libmpcodecs/vd_ffmpeg.c libmpdemux/aviheader.c libmpdemux/stheader.h
diffstat 3 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/vd_ffmpeg.c	Mon Dec 05 18:27:40 2011 +0000
+++ b/libmpcodecs/vd_ffmpeg.c	Tue Dec 06 19:59:16 2011 +0000
@@ -787,15 +787,21 @@
     pkt.flags = AV_PKT_FLAG_KEY;
     if (!ctx->palette_sent && sh->bih && sh->bih->biBitCount <= 8) {
         /* Pass palette to codec */
+        uint8_t *pal_data = (uint8_t *)(sh->bih+1);
         unsigned palsize = sh->bih->biSize - sizeof(*sh->bih);
-        if (palsize == 0) {
-            /* Palette size in biClrUsed */
-            palsize = sh->bih->biClrUsed * 4;
+        unsigned needed_size = 4 << sh->bih->biBitCount;
+        // Assume palette outside bih in rest of chunk.
+        // Fixes samples/V-codecs/QPEG/MITSUMI.AVI
+        if (palsize < needed_size &&
+            sh->bih_size > sh->bih->biSize &&
+            sh->bih_size - sh->bih->biSize > palsize) {
+            pal_data = (uint8_t *)sh->bih + sh->bih->biSize;
+            palsize = sh->bih_size - sh->bih->biSize;
         }
         // if still 0, we simply have no palette in extradata.
         if (palsize) {
             uint8_t *pal = av_packet_new_side_data(&pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
-            memcpy(pal, sh->bih+1, FFMIN(palsize, AVPALETTE_SIZE));
+            memcpy(pal, pal_data, FFMIN(palsize, AVPALETTE_SIZE));
         }
         ctx->palette_sent = 1;
     }
--- a/libmpdemux/aviheader.c	Mon Dec 05 18:27:40 2011 +0000
+++ b/libmpdemux/aviheader.c	Tue Dec 06 19:59:16 2011 +0000
@@ -267,7 +267,8 @@
       break; }
     case ckidSTREAMFORMAT: {      // read 'strf'
       if(last_fccType==streamtypeVIDEO){
-        sh_video->bih=calloc(FFMAX(chunksize, sizeof(*sh_video->bih)), 1);
+        sh_video->bih_size = FFMAX(chunksize, sizeof(*sh_video->bih));
+        sh_video->bih=calloc(sh_video->bih_size, 1);
 //        sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize);
         mp_msg(MSGT_HEADER, MSGL_V, "Found 'bih', %u bytes of %zu\n",
                chunksize, sizeof(*sh_video->bih));
--- a/libmpdemux/stheader.h	Mon Dec 05 18:27:40 2011 +0000
+++ b/libmpdemux/stheader.h	Tue Dec 06 19:59:16 2011 +0000
@@ -116,6 +116,7 @@
   // win32-compatible codec parameters:
   AVIStreamHeader video;
   BITMAPINFOHEADER* bih;
+  int bih_size;
   void* ImageDesc; // for quicktime codecs
 } sh_video_t;