[vlc-devel] [PATCH 0/6] Map some of the missing avcodec IDs

Daniel Verkamp daniel at drv.nu
Thu Feb 6 08:21:49 CET 2014


On Tue, Jan 21, 2014 at 5:45 PM, Daniel Verkamp <daniel at drv.nu> wrote:
> On Sun, Jan 12, 2014 at 8:58 AM, Jean-Baptiste Kempf <jb at videolan.org> wrote:
>> On 12 Jan, Daniel Verkamp wrote :
>>> On Sat, Jan 11, 2014 at 3:27 AM, Jean-Baptiste Kempf <jb at videolan.org> wrote:
>>> > On 10 Jan, Daniel Verkamp wrote :
>>> >> For now, I'm just sending the ones that I got to that actually work;
>>> >
> [...]
>>> > Did you try to force --no-avcodec-dr on those?
>>>
>>> I tried a few of the broken codecs with it now, but it seems to make
>>> no difference. The majority of these are 8-bit palette video formats;
>>> fixing that would allow a lot more codecs to work (even e.g. Smacker
>>> video, which is already mapped but doesn't work due to using a
>>> palette).
>>
>> Shouldn't it be simple to fix, by letting swscale module do the job?
>
> That sounds reasonable, but I don't understand VLC's video pipeline
> enough to implement that...
>
> It seems like palette passing should be doable, since it works in some
> cases (e.g. classic Windows clock.avi with palette works with VLC's
> native AVI demux + avcodec msrle).
>
> Thanks,
> -- Daniel Verkamp

I have done some more digging into the video palette decoding issue,
and it looks pretty clear that VLC is just totally ignoring
codec-provided palettes (as opposed to container-provided palettes
from e.g. AVI) from libavcodec.

Try this (totally bogus, for debugging only) patch with a Smacker
file, for instance:
http://samples.mplayerhq.hu/game-formats/smacker/smk-deen/credits.smk

You should see some decoded video with the wrong colors (as opposed to
all black).

diff --git a/modules/video_chroma/swscale.c b/modules/video_chroma/swscale.c
index 1751131..9e1f481 100644
--- a/modules/video_chroma/swscale.c
+++ b/modules/video_chroma/swscale.c
@@ -559,6 +559,12 @@ static void Convert( filter_t *p_filter, struct
SwsContext *ctx,
         if( p_filter->fmt_in.video.p_palette )
             memcpy( palette, p_filter->fmt_in.video.p_palette->palette,
                     __MIN( sizeof(video_palette_t), AVPALETTE_SIZE ) );
+        else
+            for (int i = 0; i < AVPALETTE_SIZE; i += 4)
+            {
+                palette[i + 0] = palette[i + 1] = palette[i + 2] = i;
+                palette[i + 3] = 0xFF;
+            }
         src[1] = palette;
         src_stride[1] = 4;
     }

The existence of this "if (palette)" is strange anyway - it's an error
condition if the palette is not provided, and the palette is just left
black, resulting in the current behavior.

I think the correct place to grab the palette is during
ffmpeg_CopyPicture, but my quick hack doesn't seem to work, and the
palette gets lost somewhere along the line - the "no palette" case is
still hit later on in swscale:

diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 83c5954..55511bf 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -891,6 +891,18 @@ static void ffmpeg_CopyPicture( decoder_t *p_dec,
         uint8_t *p_dst, *p_src;
         int i_src_stride, i_dst_stride;

+        if( p_ff_pic->palette_has_changed )
+        {
+            if( !p_dec->fmt_out.video.p_palette )
+            {
+                p_dec->fmt_out.video.p_palette = calloc( 1,
sizeof(video_palette_t) );
+                p_dec->fmt_out.video.p_palette->i_entries = 256;
+            }
+            memcpy( p_dec->fmt_out.video.p_palette->palette,
p_ff_pic->data[1], AVPALETTE_SIZE ); // TODO: are these in the same
format/size?
+        }
+
         for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
         {
             p_src  = p_ff_pic->data[i_plane];

Please feel free to pick this up and fix it; I probably won't have the
time to look into it further for a little while.

Thanks,
-- Daniel Verkamp



More information about the vlc-devel mailing list