[vlc-commits] avcodec: fix palette propagation

Thomas Guillem git at videolan.org
Mon Sep 26 19:27:33 CEST 2016


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Sep 26 18:53:12 2016 +0200| [3e541f1ac5680828cc8dafba4b634f807600b666] | committer: Thomas Guillem

avcodec: fix palette propagation

closes #9940, #14975
see #17446

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3e541f1ac5680828cc8dafba4b634f807600b666
---

 modules/codec/avcodec/video.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 6b18458..2708ca3 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -135,6 +135,13 @@ static int lavc_GetVideoFormat(decoder_t *dec, video_format_t *restrict fmt,
         if (GetVlcChroma(fmt, pix_fmt))
             return -1;
 
+        /* The libavcodec palette can only be fetched when the first output
+         * frame is decoded. Assume that the current chroma is RGB32 while we
+         * are waiting for a valid palette. Indeed, fmt_out.video.p_palette
+         * doesn't trigger a new vout request, but a new chroma yes. */
+        if (pix_fmt == AV_PIX_FMT_PAL8 && !dec->fmt_out.video.p_palette)
+            fmt->i_chroma = VLC_CODEC_RGB32;
+
         avcodec_align_dimensions2(ctx, &width, &height, aligns);
     }
     else /* hardware decoding */
@@ -902,6 +909,36 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             continue;
         }
 
+        if( p_context->pix_fmt == AV_PIX_FMT_PAL8
+         && !p_dec->fmt_out.video.p_palette )
+        {
+            /* See AV_PIX_FMT_PAL8 comment in avc_GetVideoFormat(): update the
+             * fmt_out palette and change the fmt_out chroma to request a new
+             * vout */
+            assert( p_dec->fmt_out.video.i_chroma != VLC_CODEC_RGBP );
+
+            video_palette_t *p_palette;
+            p_palette = p_dec->fmt_out.video.p_palette
+                      = malloc( sizeof(video_palette_t) );
+            if( !p_palette )
+            {
+                p_dec->b_error = true;
+                av_frame_free(&frame);
+                break;
+            }
+            static_assert( sizeof(p_palette->palette) == AVPALETTE_SIZE,
+                           "Palette size mismatch between vlc and libavutil" );
+            assert( frame->data[1] != NULL );
+            memcpy( p_palette->palette, frame->data[1], AVPALETTE_SIZE );
+            p_palette->i_entries = AVPALETTE_COUNT;
+            p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBP;
+            if( decoder_UpdateVideoFormat( p_dec ) )
+            {
+                av_frame_free(&frame);
+                continue;
+            }
+        }
+
         picture_t *p_pic = frame->opaque;
         if( p_pic == NULL )
         {   /* When direct rendering is not used, get_format() and get_buffer()



More information about the vlc-commits mailing list