[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