[MPlayer-dev-eng] [PATCH] (bit hackish) palette support for libav*

Reimar Doeffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Mon Jan 29 14:34:19 CET 2007


Hello,
attached patch fixes e.g.
http://samples.mplayerhq.hu/V-codecs/KMVC/AIRSTRKE.AVI on big-endian
and
http://samples.mplayerhq.hu/game-formats/interplay-mve/baldursgate-camp.mve
in general.
Does it seems clean enough for you to be applied as-is (and yes, I
noticed AVPaletteControl is deprecated and the later file probably
should preferably be fixed in libavformat/libavcodec directly).

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libmpcodecs/vd_ffmpeg.c
===================================================================
--- libmpcodecs/vd_ffmpeg.c	(revision 22060)
+++ libmpcodecs/vd_ffmpeg.c	(working copy)
@@ -386,9 +386,12 @@
 	break;
     }
     /* Pass palette to codec */
-    if (sh->bih && (sh->bih->biBitCount <= 8)) {
+    if (sh->bih && (sh->bih->biBitCount <= 8) || sh->has_palette) {
         avctx->palctrl = calloc(1,sizeof(AVPaletteControl));
         avctx->palctrl->palette_changed = 1;
+        if (sh->has_palette)
+            memcpy(avctx->palctrl->palette, sh->palette, FFMIN(VID_PALETTE_SIZE, AVPALETTE_SIZE));
+        else
         if (sh->bih->biSize-sizeof(BITMAPINFOHEADER))
             /* Palette size in biSize */
             memcpy(avctx->palctrl->palette, sh->bih+1,
@@ -717,6 +720,12 @@
     uint32_t chunktab;	// offset to chunk offset array
 } dp_hdr_t;
 
+void swap_palette(void *pal) {
+    int i;
+    uint32_t *p = pal;
+    for (i = 0; i < AVPALETTE_COUNT; i++)
+        p[i] = le2me_32(p[i]);
+}
 
 // decode a frame
 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
@@ -747,6 +756,10 @@
 
     avctx->hurry_up=(flags&3)?((flags&2)?2:1):0;
 
+    if (sh->has_palette && sh->palette_changed && avctx->palctrl) {
+        avctx->palctrl->palette_changed = 1;
+        memcpy(avctx->palctrl->palette, sh->palette, FFMIN(VID_PALETTE_SIZE, AVPALETTE_SIZE));
+    }
 //    if(sh->ds->demuxer->type == DEMUXER_TYPE_REAL){
     if(   sh->format == mmioFOURCC('R', 'V', '1', '0')
        || sh->format == mmioFOURCC('R', 'V', '1', '3')
@@ -884,6 +897,10 @@
 	mpi->stride[2]*=2;
     }
     
+#ifdef WORDS_BIGENDIAN
+    if (mpi->bpp == 8)
+        swap_palette(mpi->planes[1]);
+#endif
 /* to comfirm with newer lavc style */
     mpi->qscale =pic->qscale_table;
     mpi->qstride=pic->qstride;
Index: libmpdemux/stheader.h
===================================================================
--- libmpdemux/stheader.h	(revision 22060)
+++ libmpdemux/stheader.h	(working copy)
@@ -4,6 +4,9 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#define VID_PALETTE_SIZE 1024
+#define VID_PALETTE_NUM 256
+
 // Stream headers:
 
 typedef struct {
@@ -88,6 +91,9 @@
   AVIStreamHeader video;
   BITMAPINFOHEADER* bih;
   void* ImageDesc; // for quicktime codecs
+  int has_palette;
+  int palette_changed;
+  unsigned int palette[VID_PALETTE_NUM];
   // codec-specific:
   void* context;   // codec-specific stuff (usually HANDLE or struct pointer)
 } sh_video_t;
Index: libmpdemux/demux_lavf.c
===================================================================
--- libmpdemux/demux_lavf.c	(revision 22060)
+++ libmpdemux/demux_lavf.c	(working copy)
@@ -181,6 +181,13 @@
 
     return DEMUXER_TYPE_LAVF;
 }
+
+static void copy_palette(sh_video_t *sh, AVPaletteControl *pc) {
+    sh->has_palette = 1;
+    sh->palette_changed = 1;
+    pc->palette_changed = 0;
+    memcpy(sh->palette, pc->palette, FFMIN(VID_PALETTE_SIZE, AVPALETTE_SIZE));
+}
     
 static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
     AVFormatContext *avfc;
@@ -358,6 +365,9 @@
             sh_video->ds= demuxer->video;
             if(codec->extradata_size)
                 memcpy(sh_video->bih + 1, codec->extradata, codec->extradata_size);
+            if (codec->palctrl)
+                copy_palette(sh_video, codec->palctrl);
+
             if( mp_msg_test(MSGT_HEADER,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
 /*    short 	biPlanes;
     int  	biXPelsPerMeter;
@@ -414,12 +424,15 @@
             mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id);
         }
     } else if(id==demux->video->id){
+        AVPaletteControl *pc = priv->avfc->streams[id]->codec->palctrl;
         // video
         ds=demux->video;
         if(!ds->sh){
             ds->sh=demux->v_streams[id];
             mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id);
         }
+        if (pc && pc->palette_changed)
+            copy_palette(ds->sh, pc);
     } else {
         av_free_packet(&pkt);
         return 1;


More information about the MPlayer-dev-eng mailing list