From 7ed5e7888c338359e83457d1fd9277e2bc94dc71 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Thu, 21 Feb 2013 22:21:48 +0200 Subject: ffmpeg_video_decoder: re-enabled palette video decoding --- src/combined/ffmpeg/ff_video_decoder.c | 50 ++++++++++++++++++++++++++-------- src/combined/ffmpeg/ffmpeg_compat.h | 9 ++++++ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 670ccce26..a9c935ce0 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -134,8 +134,11 @@ struct ff_video_decoder_s { xine_list_t *dr1_frames; -#ifdef AVPaletteControl +#if AVPALETTE == 1 AVPaletteControl palette_control; +#elif AVPALETTE == 2 + uint32_t palette[256]; + int palette_changed; #endif int color_matrix, full2mpeg; @@ -1199,18 +1202,14 @@ static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *b buf->decoder_info[2]); } -#ifdef AVPaletteControl else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) { unsigned int i; + palette_entry_t *demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; - palette_entry_t *demuxer_palette; - AVPaletteControl *decoder_palette; - - lprintf("BUF_SPECIAL_PALETTE\n"); - this->context->palctrl = &this->palette_control; - decoder_palette = (AVPaletteControl *)this->context->palctrl; - demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; +#if AVPALETTE == 1 + AVPaletteControl *decoder_palette = &this->palette_control; + lprintf ("BUF_SPECIAL_PALETTE\n"); for (i = 0; i < buf->decoder_info[2]; i++) { decoder_palette->palette[i] = (demuxer_palette[i].r << 16) | @@ -1218,9 +1217,19 @@ static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *b (demuxer_palette[i].b << 0); } decoder_palette->palette_changed = 1; + this->context->palctrl = decoder_palette; - } +#elif AVPALETTE == 2 + lprintf ("BUF_SPECIAL_PALETTE\n"); + for (i = 0; i < buf->decoder_info[2]; i++) { + this->palette[i] = + (demuxer_palette[i].r << 16) | + (demuxer_palette[i].g << 8) | + (demuxer_palette[i].b << 0); + } + this->palette_changed = 1; #endif + } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) { int i; @@ -1576,6 +1585,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { avpkt.data = (uint8_t *)&chunk_buf[offset]; avpkt.size = this->size; avpkt.flags = AV_PKT_FLAG_KEY; +# if AVPALETTE == 2 + if (this->palette_changed) { + uint8_t *sd = av_packet_new_side_data (&avpkt, AV_PKT_DATA_PALETTE, 256 * 4); + if (sd) + memcpy (sd, this->palette, 256 * 4); + } +# endif # if ENABLE_VAAPI if(this->accel) { len = this->accel->avcodec_decode_video2 ( this->accel_img, this->context, this->av_frame, @@ -1586,6 +1602,18 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { len = avcodec_decode_video2 (this->context, this->av_frame, &got_picture, &avpkt); } +# if AVPALETTE == 2 + if (this->palette_changed) { + /* TJ. Oh dear and sigh. + AVPacket side data handling is broken even in ffmpeg 1.1.1 - see avcodec/avpacket.c + The suggested av_free_packet () would leave a memory leak here, and + ff_packet_free_side_data () is private. */ + avpkt.data = NULL; + avpkt.size = 0; + av_destruct_packet (&avpkt); + this->palette_changed = 0; + } +# endif #else # if ENABLE_VAAPI if(this->accel) { @@ -2026,7 +2054,7 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, this->av_frame = avcodec_alloc_frame(); this->context = avcodec_alloc_context(); this->context->opaque = this; -#ifdef AVPaletteControl +#if AVPALETTE == 1 this->context->palctrl = NULL; #endif diff --git a/src/combined/ffmpeg/ffmpeg_compat.h b/src/combined/ffmpeg/ffmpeg_compat.h index f025dfec6..0acead897 100644 --- a/src/combined/ffmpeg/ffmpeg_compat.h +++ b/src/combined/ffmpeg/ffmpeg_compat.h @@ -105,4 +105,13 @@ # define AVFRAMEAGE 1 #endif +#if LIBAVCODEC_VERSION_MAJOR < 53 +/* release 0.7.x (libavcodec 52) has deprecated AVCodecContext.palctrl but for backwards compatibility no + working alternative. */ +# define AVPALETTE 1 +#else +/* pass palette as AVPacket side data */ +# define AVPALETTE 2 +#endif + #endif /* XINE_AVCODEC_COMPAT_H */ -- cgit v1.2.3