From 80800258310fa4b54f6033a80b0f4bdce80c1d0a Mon Sep 17 00:00:00 2001 From: Mike Melanson Date: Thu, 30 Oct 2003 06:00:19 +0000 Subject: deploy revised ffmpeg palette API CVS patchset: 5641 CVS date: 2003/10/30 06:00:19 --- src/libffmpeg/libavcodec/avcodec.h | 33 ++++++++++++---- src/libffmpeg/libavcodec/idcinvideo.c | 27 ++++--------- src/libffmpeg/libavcodec/interplayvideo.c | 37 +++++------------- src/libffmpeg/libavcodec/utils.c | 9 +++++ src/libffmpeg/libavcodec/vqavideo.c | 7 ++-- src/libffmpeg/libavcodec/xan.c | 64 +++++++++++++++++-------------- src/libffmpeg/xine_decoder.c | 37 ++++++------------ 7 files changed, 101 insertions(+), 113 deletions(-) diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index 47ab4c095..90b20f425 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -16,7 +16,7 @@ extern "C" { #define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION "0.4.8" -#define LIBAVCODEC_BUILD 4687 +#define LIBAVCODEC_BUILD 4688 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -117,6 +117,9 @@ enum CodecID { CODEC_ID_ROQ_DPCM, CODEC_ID_INTERPLAY_DPCM, CODEC_ID_XAN_DPCM, + + CODEC_ID_MPEG2TS, /* _FAKE_ codec to indicate a raw MPEG2 transport + stream (only used by libavformat) */ }; /* CODEC_ID_MP3LAME is absolete */ @@ -126,6 +129,7 @@ enum CodecType { CODEC_TYPE_UNKNOWN = -1, CODEC_TYPE_VIDEO, CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, }; /** @@ -449,7 +453,13 @@ typedef struct AVPanScan{ * - decoding: set by lavc\ */\ AVPanScan *pan_scan;\ - + \ + /**\ + * tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: set by lavc (default 0)\ + */\ + int palette_has_changed;\ #define FF_QSCALE_TYPE_MPEG1 0 #define FF_QSCALE_TYPE_MPEG2 1 @@ -918,6 +928,7 @@ typedef struct AVCodecContext { #define FF_DCT_MMX 3 #define FF_DCT_MLIB 4 #define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 /** * luminance masking (0-> disabled). @@ -1340,6 +1351,13 @@ typedef struct AVCodecContext { * - decoding: unused */ int lmax; + + /** + * Palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: set by user. + */ + struct AVPaletteControl *palctrl; } AVCodecContext; @@ -1421,17 +1439,18 @@ typedef struct AVPicture { * This structure defines a method for communicating palette changes * between and demuxer and a decoder. */ +#define AVPALETTE_SIZE 256 typedef struct AVPaletteControl { /* demuxer sets this to 1 to indicate the palette has changed; * decoder resets to 0 */ int palette_changed; - /* 256 3-byte RGB palette entries; the components should be - * formatted in the buffer as "RGBRGB..." and should be scaled to - * 8 bits if they originally represented 6-bit VGA palette - * components */ - unsigned char palette[256 * 3]; + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from a IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled */ + unsigned int palette[AVPALETTE_SIZE]; } AVPaletteControl; diff --git a/src/libffmpeg/libavcodec/idcinvideo.c b/src/libffmpeg/libavcodec/idcinvideo.c index d516e39fb..b3a658296 100644 --- a/src/libffmpeg/libavcodec/idcinvideo.c +++ b/src/libffmpeg/libavcodec/idcinvideo.c @@ -72,8 +72,6 @@ typedef struct IdcinContext { unsigned char *buf; int size; - unsigned char palette[PALETTE_COUNT * 4]; - hnode_t huff_nodes[256][HUF_TOKENS*2]; int num_huff_nodes[256]; @@ -218,27 +216,11 @@ static int idcin_decode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size) { IdcinContext *s = (IdcinContext *)avctx->priv_data; - AVPaletteControl *palette_control = - (AVPaletteControl *)avctx->extradata; - int i; - unsigned int *palette32; - int palette_index = 0; - unsigned char r, g, b; + AVPaletteControl *palette_control = avctx->palctrl; s->buf = buf; s->size = buf_size; - if (palette_control->palette_changed) { - palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = palette_control->palette[palette_index++] * 1; - g = palette_control->palette[palette_index++] * 1; - b = palette_control->palette[palette_index++] * 1; - palette32[i] = (r << 16) | (g << 8) | (b); - } - palette_control->palette_changed = 0; - } - if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); @@ -250,7 +232,12 @@ static int idcin_decode_frame(AVCodecContext *avctx, idcin_decode_vlcs(s); /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); + memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4); + /* If palette changed inform application*/ + if (palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->frame.palette_has_changed = 1; + } *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/src/libffmpeg/libavcodec/interplayvideo.c b/src/libffmpeg/libavcodec/interplayvideo.c index a8a7c0f56..72e037747 100644 --- a/src/libffmpeg/libavcodec/interplayvideo.c +++ b/src/libffmpeg/libavcodec/interplayvideo.c @@ -65,8 +65,6 @@ typedef struct IpvideoContext { unsigned char *buf; int size; - unsigned char palette[PALETTE_COUNT * 4]; - unsigned char *stream_ptr; unsigned char *stream_end; unsigned char *pixel_ptr; @@ -83,21 +81,6 @@ typedef struct IpvideoContext { return -1; \ } -static void ipvideo_new_palette(IpvideoContext *s, unsigned char *palette) { - - int i; - unsigned char r, g, b; - unsigned int *palette32; - - palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette++; - g = *palette++; - b = *palette++; - palette32[i] = (r << 16) | (g << 8) | (b); - } -} - #define COPY_FROM_CURRENT() \ motion_offset = current_offset; \ motion_offset += y * s->stride; \ @@ -828,7 +811,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s) code_counts[x] = 0; /* this is PAL8, so make the palette available */ - memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); + memcpy(s->current_frame.data[1], s->avctx->palctrl->palette, PALETTE_COUNT * 4); s->stride = s->current_frame.linesize[0]; s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */ @@ -874,9 +857,8 @@ static int ipvideo_decode_init(AVCodecContext *avctx) s->avctx = avctx; - if (s->avctx->extradata_size != sizeof(AVPaletteControl)) { - printf (" Interplay video: expected extradata_size of %d\n", - (int)sizeof(AVPaletteControl)); + if (s->avctx->palctrl == NULL) { + printf (" Interplay video: palette expected.\n"); return -1; } @@ -916,13 +898,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size) { IpvideoContext *s = avctx->priv_data; - AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata; - - if (palette_control->palette_changed) { - /* load the new palette and reset the palette control */ - ipvideo_new_palette(s, palette_control->palette); - palette_control->palette_changed = 0; - } + AVPaletteControl *palette_control = avctx->palctrl; s->decoding_map = buf; s->buf = buf + s->decoding_map_size; @@ -936,6 +912,11 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, ipvideo_decode_opcodes(s); + if (palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->current_frame.palette_has_changed = 1; + } + *data_size = sizeof(AVFrame); *(AVFrame*)data = s->current_frame; diff --git a/src/libffmpeg/libavcodec/utils.c b/src/libffmpeg/libavcodec/utils.c index 34051ad3a..ace54ef11 100644 --- a/src/libffmpeg/libavcodec/utils.c +++ b/src/libffmpeg/libavcodec/utils.c @@ -318,6 +318,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){ s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; + s->palctrl = NULL; } /** @@ -523,6 +524,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) else if (enc->sub_id == 1) codec_name = "mp1"; } + } else if (enc->codec_id == CODEC_ID_MPEG2TS) { + /* fake mpeg2 transport stream codec (currently not + registered) */ + codec_name = "mpeg2ts"; } else if (enc->codec_name[0] != '\0') { codec_name = enc->codec_name; } else { @@ -605,6 +610,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) break; } break; + case CODEC_TYPE_DATA: + snprintf(buf, buf_size, "Data: %s", codec_name); + bitrate = enc->bit_rate; + break; default: av_abort(); } diff --git a/src/libffmpeg/libavcodec/vqavideo.c b/src/libffmpeg/libavcodec/vqavideo.c index 174116dbc..8f4ac173f 100644 --- a/src/libffmpeg/libavcodec/vqavideo.c +++ b/src/libffmpeg/libavcodec/vqavideo.c @@ -120,7 +120,7 @@ typedef struct VqaContext { unsigned char *buf; int size; - unsigned char palette[PALETTE_COUNT * 4]; + unsigned int palette[PALETTE_COUNT]; int width; /* width of a frame */ int height; /* height of a frame */ @@ -311,7 +311,6 @@ static void vqa_decode_chunk(VqaContext *s) unsigned int index = 0; int i; unsigned char r, g, b; - unsigned int *palette32; int index_shift; int cbf0_chunk = -1; @@ -407,13 +406,12 @@ static void vqa_decode_chunk(VqaContext *s) return; } cpl0_chunk += CHUNK_PREAMBLE_SIZE; - palette32 = (unsigned int *)s->palette; for (i = 0; i < chunk_size / 3; i++) { /* scale by 4 to transform 6-bit palette -> 8-bit */ r = s->buf[cpl0_chunk++] * 4; g = s->buf[cpl0_chunk++] * 4; b = s->buf[cpl0_chunk++] * 4; - palette32[i] = (r << 16) | (g << 8) | (b); + s->palette[i] = (r << 16) | (g << 8) | (b); } } @@ -583,6 +581,7 @@ static int vqa_decode_frame(AVCodecContext *avctx, /* make the palette available on the way out */ memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); + s->frame.palette_has_changed = 1; *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/src/libffmpeg/libavcodec/xan.c b/src/libffmpeg/libavcodec/xan.c index 8359782e6..49e207677 100644 --- a/src/libffmpeg/libavcodec/xan.c +++ b/src/libffmpeg/libavcodec/xan.c @@ -115,9 +115,8 @@ static int xan_decode_init(AVCodecContext *avctx) s->avctx = avctx; if ((avctx->codec->id == CODEC_ID_XAN_WC3) && - (s->avctx->extradata_size != sizeof(AVPaletteControl))) { - printf (" WC3 Xan video: expected extradata_size of %d\n", - sizeof(AVPaletteControl)); + (s->avctx->palctrl == NULL)) { + printf (" WC3 Xan video: palette expected.\n"); return -1; } @@ -253,12 +252,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) } static void inline xan_wc3_build_palette(XanContext *s, - unsigned char *palette_data) + unsigned int *palette_data) { int i; unsigned char r, g, b; unsigned short *palette16; unsigned int *palette32; + unsigned int pal_elem; /* transform the palette passed through the palette control structure * into the necessary internal format depending on colorspace */ @@ -268,9 +268,10 @@ static void inline xan_wc3_build_palette(XanContext *s, case PIX_FMT_RGB555: palette16 = (unsigned short *)s->palette; for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette_data++; - g = *palette_data++; - b = *palette_data++; + pal_elem = palette_data[i]; + r = (pal_elem >> 16) & 0xff; + g = (pal_elem >> 8) & 0xff; + b = pal_elem & 0xff; palette16[i] = ((r >> 3) << 10) | ((g >> 3) << 5) | @@ -281,9 +282,10 @@ static void inline xan_wc3_build_palette(XanContext *s, case PIX_FMT_RGB565: palette16 = (unsigned short *)s->palette; for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette_data++; - g = *palette_data++; - b = *palette_data++; + pal_elem = palette_data[i]; + r = (pal_elem >> 16) & 0xff; + g = (pal_elem >> 8) & 0xff; + b = pal_elem & 0xff; palette16[i] = ((r >> 3) << 11) | ((g >> 2) << 5) | @@ -293,17 +295,22 @@ static void inline xan_wc3_build_palette(XanContext *s, case PIX_FMT_RGB24: for (i = 0; i < PALETTE_COUNT; i++) { - s->palette[i * 4 + 0] = *palette_data++; - s->palette[i * 4 + 1] = *palette_data++; - s->palette[i * 4 + 2] = *palette_data++; + pal_elem = palette_data[i]; + r = (pal_elem >> 16) & 0xff; + g = (pal_elem >> 8) & 0xff; + b = pal_elem & 0xff; + s->palette[i * 4 + 0] = r; + s->palette[i * 4 + 1] = g; + s->palette[i * 4 + 2] = b; } break; case PIX_FMT_BGR24: for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette_data++; - g = *palette_data++; - b = *palette_data++; + pal_elem = palette_data[i]; + r = (pal_elem >> 16) & 0xff; + g = (pal_elem >> 8) & 0xff; + b = pal_elem & 0xff; s->palette[i * 4 + 0] = b; s->palette[i * 4 + 1] = g; s->palette[i * 4 + 2] = r; @@ -313,19 +320,15 @@ static void inline xan_wc3_build_palette(XanContext *s, case PIX_FMT_PAL8: case PIX_FMT_RGBA32: palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette_data++; - g = *palette_data++; - b = *palette_data++; - palette32[i] = (r << 16) | (g << 8) | (b); - } + memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int)); break; case PIX_FMT_YUV444P: for (i = 0; i < PALETTE_COUNT; i++) { - r = *palette_data++; - g = *palette_data++; - b = *palette_data++; + pal_elem = palette_data[i]; + r = (pal_elem >> 16) & 0xff; + g = (pal_elem >> 8) & 0xff; + b = pal_elem & 0xff; s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); @@ -730,8 +733,11 @@ static void xan_wc3_decode_frame(XanContext *s) { } /* for PAL8, make the palette available on the way out */ - if (s->avctx->pix_fmt == PIX_FMT_PAL8) + if (s->avctx->pix_fmt == PIX_FMT_PAL8) { memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); + s->current_frame.palette_has_changed = 1; + s->avctx->palctrl->palette_changed = 0; + } } static void xan_wc4_decode_frame(XanContext *s) { @@ -742,13 +748,15 @@ static int xan_decode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size) { XanContext *s = avctx->priv_data; - AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata; + AVPaletteControl *palette_control = avctx->palctrl; int keyframe = 0; if (palette_control->palette_changed) { /* load the new palette and reset the palette control */ xan_wc3_build_palette(s, palette_control->palette); - palette_control->palette_changed = 0; + /* If pal8 we clear flag when we copy palette */ + if (s->avctx->pix_fmt != PIX_FMT_PAL8) + palette_control->palette_changed = 0; keyframe = 1; } diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c index 0ec30a994..dfc8c0b10 100644 --- a/src/libffmpeg/xine_decoder.c +++ b/src/libffmpeg/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.132 2003/10/27 22:26:03 jstembridge Exp $ + * $Id: xine_decoder.c,v 1.133 2003/10/30 06:00:19 tmmm Exp $ * * xine decoder plugin using ffmpeg * @@ -104,6 +104,7 @@ struct ff_video_decoder_s { int output_format; yuv_planes_t yuv; + AVPaletteControl palette_control; }; typedef struct { @@ -231,6 +232,8 @@ static void init_video_codec (ff_video_decoder_t *this, xine_bmiheader *bih) { */ this->context->pix_fmt = -1; + this->context->palctrl = &this->palette_control; + if( bih && bih->biSize > sizeof(xine_bmiheader) ) { this->context->extradata_size = bih->biSize - sizeof(xine_bmiheader); this->context->extradata = malloc(this->context->extradata_size); @@ -238,14 +241,7 @@ static void init_video_codec (ff_video_decoder_t *this, xine_bmiheader *bih) { (uint8_t *)bih + sizeof(xine_bmiheader), this->context->extradata_size ); } - if ((this->codec->id == CODEC_ID_XAN_WC3) || - (this->codec->id == CODEC_ID_INTERPLAY_VIDEO)) { - /* dupe certain decoders by giving them an empty palette; these - * decoders do not care about the palette during initialization */ - this->context->extradata_size = sizeof(AVPaletteControl); - this->context->extradata = xine_xmalloc(this->context->extradata_size); - } - + if(bih) this->context->bits_per_sample = bih->biBitCount; @@ -940,19 +936,10 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { init_video_codec (this, (xine_bmiheader *)buf->content ); init_postprocess (this); - free(this->context->extradata); - this->context->extradata = NULL; - this->context->extradata_size = 0; - } else if (buf->decoder_flags & BUF_FLAG_SPECIAL) { /* take care of all the various types of special buffers */ - /* first, free any previous extradata chunk */ - free(this->context->extradata); - this->context->extradata = NULL; - this->context->extradata_size = 0; - if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM) { this->context->extradata_size = buf->decoder_info[2]; @@ -966,16 +953,14 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { palette_entry_t *demuxer_palette; AVPaletteControl *decoder_palette; - this->context->extradata_size = sizeof(AVPaletteControl); - this->context->extradata = xine_xmalloc(this->context->extradata_size); - - decoder_palette = (AVPaletteControl *)this->context->extradata; + decoder_palette = (AVPaletteControl *)this->context->palctrl; demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; for (i = 0; i < buf->decoder_info[2]; i++) { - decoder_palette->palette[i * 3 + 0] = demuxer_palette[i].r; - decoder_palette->palette[i * 3 + 1] = demuxer_palette[i].g; - decoder_palette->palette[i * 3 + 2] = demuxer_palette[i].b; + decoder_palette->palette[i] = + (demuxer_palette[i].r << 16) | + (demuxer_palette[i].g << 8) | + (demuxer_palette[i].b << 0); } decoder_palette->palette_changed = 1; } @@ -1264,7 +1249,7 @@ static void ff_dispose (video_decoder_t *this_gen) { if(this->context && this->context->slice_offset) free(this->context->slice_offset); - + if(this->context && this->context->extradata) free(this->context->extradata); -- cgit v1.2.3