diff mbox series

[FFmpeg-devel,1/3] avformat/dvdvideodec: add CLUT utilities and subtitle palette support

Message ID 20240306071913.2735832-1-marth64@proxyid.net
State New
Headers show
Series [FFmpeg-devel,1/3] avformat/dvdvideodec: add CLUT utilities and subtitle palette support | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Marth64 March 6, 2024, 7:19 a.m. UTC
Since last iteration: removes unused variable in dvdclut.c

Signed-off-by: Marth64 <marth64@proxyid.net>
---
 doc/demuxers.texi         |  5 +++
 libavformat/Makefile      |  2 +-
 libavformat/dvdclut.c     | 75 +++++++++++++++++++++++++++++++++++++++
 libavformat/dvdclut.h     | 37 +++++++++++++++++++
 libavformat/dvdvideodec.c | 15 ++++++++
 5 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 libavformat/dvdclut.c
 create mode 100644 libavformat/dvdclut.h

Comments

Stefano Sabatini March 6, 2024, 3:09 p.m. UTC | #1
On date Wednesday 2024-03-06 01:19:11 -0600, Marth64 wrote:
> Since last iteration: removes unused variable in dvdclut.c
> 
> Signed-off-by: Marth64 <marth64@proxyid.net>
> ---
>  doc/demuxers.texi         |  5 +++
>  libavformat/Makefile      |  2 +-
>  libavformat/dvdclut.c     | 75 +++++++++++++++++++++++++++++++++++++++
>  libavformat/dvdclut.h     | 37 +++++++++++++++++++
>  libavformat/dvdvideodec.c | 15 ++++++++
>  5 files changed, 133 insertions(+), 1 deletion(-)
>  create mode 100644 libavformat/dvdclut.c
>  create mode 100644 libavformat/dvdclut.h
> 
> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
> index f4bac8f3b3..1a17c6db16 100644
> --- a/doc/demuxers.texi
> +++ b/doc/demuxers.texi
> @@ -394,6 +394,11 @@ often with junk data intended for controlling a real DVD player's
>  buffering speed and with no other material data value.
>  Default is 1, true.
>  

> +@item clut_rgb @var{bool}
> +Output subtitle palettes (CLUTs) as RGB, required for Matroska.
> +Disable to output the palette in its original YUV colorspace.
> +Default is 1, true.

Can you expand about this? When is matroska used in a DVD?

Can we make the setting automatic in case matroska is detected?

[...]

LGTM otherwise.
Timo Rothenpieler March 6, 2024, 3:17 p.m. UTC | #2
On 06/03/2024 16:09, Stefano Sabatini wrote:
> On date Wednesday 2024-03-06 01:19:11 -0600, Marth64 wrote:
>> Since last iteration: removes unused variable in dvdclut.c
>>
>> Signed-off-by: Marth64 <marth64@proxyid.net>
>> ---
>>   doc/demuxers.texi         |  5 +++
>>   libavformat/Makefile      |  2 +-
>>   libavformat/dvdclut.c     | 75 +++++++++++++++++++++++++++++++++++++++
>>   libavformat/dvdclut.h     | 37 +++++++++++++++++++
>>   libavformat/dvdvideodec.c | 15 ++++++++
>>   5 files changed, 133 insertions(+), 1 deletion(-)
>>   create mode 100644 libavformat/dvdclut.c
>>   create mode 100644 libavformat/dvdclut.h
>>
>> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
>> index f4bac8f3b3..1a17c6db16 100644
>> --- a/doc/demuxers.texi
>> +++ b/doc/demuxers.texi
>> @@ -394,6 +394,11 @@ often with junk data intended for controlling a real DVD player's
>>   buffering speed and with no other material data value.
>>   Default is 1, true.
>>   
> 
>> +@item clut_rgb @var{bool}
>> +Output subtitle palettes (CLUTs) as RGB, required for Matroska.
>> +Disable to output the palette in its original YUV colorspace.
>> +Default is 1, true.
> 
> Can you expand about this? When is matroska used in a DVD?

Sounds to me like muxing _to_ matroska needs RGB palettes, but DVDs 
bring YUV ones.

> Can we make the setting automatic in case matroska is detected?
> 
> [...]
> 
> LGTM otherwise.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Marth64 March 6, 2024, 3:36 p.m. UTC | #3
Good morning,

DVD subtitle palettes, which are natively YUV, are currently carried as
a hex string in their respective subtitle streams and have
no concept of colorspace tagging (even predating dvd demuxer). The
convention is to convert
them to RGB prior to storage. Common players will only render
the palettes properly if they are stored as RGB. Even ffmpeg itself
expects this, and already does -in libavformat- the YUV-RGB conversions,
specifically in mov.c and movenc.c.

The point of this patch is to provide a consolidation of the code
that deals with creating the extradata as well as the RGB conversion.
That can then (1) enable usable palette support for DVD demuxer if it is
merged
and (2) start the process of consolidating the related conversions in
MOV muxer/demuxer and eventually find a way to properly tag
the colorspace.

Thank you!

On Wed, Mar 6, 2024 at 09:18 Timo Rothenpieler <timo@rothenpieler.org>
wrote:

> On 06/03/2024 16:09, Stefano Sabatini wrote:
> > On date Wednesday 2024-03-06 01:19:11 -0600, Marth64 wrote:
> >> Since last iteration: removes unused variable in dvdclut.c
> >>
> >> Signed-off-by: Marth64 <marth64@proxyid.net>
> >> ---
> >>   doc/demuxers.texi         |  5 +++
> >>   libavformat/Makefile      |  2 +-
> >>   libavformat/dvdclut.c     | 75 +++++++++++++++++++++++++++++++++++++++
> >>   libavformat/dvdclut.h     | 37 +++++++++++++++++++
> >>   libavformat/dvdvideodec.c | 15 ++++++++
> >>   5 files changed, 133 insertions(+), 1 deletion(-)
> >>   create mode 100644 libavformat/dvdclut.c
> >>   create mode 100644 libavformat/dvdclut.h
> >>
> >> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
> >> index f4bac8f3b3..1a17c6db16 100644
> >> --- a/doc/demuxers.texi
> >> +++ b/doc/demuxers.texi
> >> @@ -394,6 +394,11 @@ often with junk data intended for controlling a
> real DVD player's
> >>   buffering speed and with no other material data value.
> >>   Default is 1, true.
> >>
> >
> >> +@item clut_rgb @var{bool}
> >> +Output subtitle palettes (CLUTs) as RGB, required for Matroska.
> >> +Disable to output the palette in its original YUV colorspace.
> >> +Default is 1, true.
> >
> > Can you expand about this? When is matroska used in a DVD?
>
> Sounds to me like muxing _to_ matroska needs RGB palettes, but DVDs
> bring YUV ones.
>
> > Can we make the setting automatic in case matroska is detected?
> >
> > [...]
> >
> > LGTM otherwise.
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Marth64 March 6, 2024, 3:43 p.m. UTC | #4
It is true that this is necessary when muxing to Matroska, but it is also
the case for MOV - the MOV muxer expects RGB prior to converting to YUV
again. So this would be needed for MOV also, despite the awkward conversion
circle. I should update the document to reflect this.


On Wed, Mar 6, 2024 at 09:36 Marth64 <marth64@proxyid.net> wrote:

> Good morning,
>
> DVD subtitle palettes, which are natively YUV, are currently carried as
> a hex string in their respective subtitle streams and have
> no concept of colorspace tagging (even predating dvd demuxer). The
> convention is to convert
> them to RGB prior to storage. Common players will only render
> the palettes properly if they are stored as RGB. Even ffmpeg itself
> expects this, and already does -in libavformat- the YUV-RGB conversions,
> specifically in mov.c and movenc.c.
>
> The point of this patch is to provide a consolidation of the code
> that deals with creating the extradata as well as the RGB conversion.
> That can then (1) enable usable palette support for DVD demuxer if it is
> merged
> and (2) start the process of consolidating the related conversions in
> MOV muxer/demuxer and eventually find a way to properly tag
> the colorspace.
>
> Thank you!
>
> On Wed, Mar 6, 2024 at 09:18 Timo Rothenpieler <timo@rothenpieler.org>
> wrote:
>
>> On 06/03/2024 16:09, Stefano Sabatini wrote:
>> > On date Wednesday 2024-03-06 01:19:11 -0600, Marth64 wrote:
>> >> Since last iteration: removes unused variable in dvdclut.c
>> >>
>> >> Signed-off-by: Marth64 <marth64@proxyid.net>
>> >> ---
>> >>   doc/demuxers.texi         |  5 +++
>> >>   libavformat/Makefile      |  2 +-
>> >>   libavformat/dvdclut.c     | 75
>> +++++++++++++++++++++++++++++++++++++++
>> >>   libavformat/dvdclut.h     | 37 +++++++++++++++++++
>> >>   libavformat/dvdvideodec.c | 15 ++++++++
>> >>   5 files changed, 133 insertions(+), 1 deletion(-)
>> >>   create mode 100644 libavformat/dvdclut.c
>> >>   create mode 100644 libavformat/dvdclut.h
>> >>
>> >> diff --git a/doc/demuxers.texi b/doc/demuxers.texi
>> >> index f4bac8f3b3..1a17c6db16 100644
>> >> --- a/doc/demuxers.texi
>> >> +++ b/doc/demuxers.texi
>> >> @@ -394,6 +394,11 @@ often with junk data intended for controlling a
>> real DVD player's
>> >>   buffering speed and with no other material data value.
>> >>   Default is 1, true.
>> >>
>> >
>> >> +@item clut_rgb @var{bool}
>> >> +Output subtitle palettes (CLUTs) as RGB, required for Matroska.
>> >> +Disable to output the palette in its original YUV colorspace.
>> >> +Default is 1, true.
>> >
>> > Can you expand about this? When is matroska used in a DVD?
>>
>> Sounds to me like muxing _to_ matroska needs RGB palettes, but DVDs
>> bring YUV ones.
>>
>> > Can we make the setting automatic in case matroska is detected?
>> >
>> > [...]
>> >
>> > LGTM otherwise.
>> > _______________________________________________
>> > ffmpeg-devel mailing list
>> > ffmpeg-devel@ffmpeg.org
>> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> >
>> > To unsubscribe, visit link above, or email
>> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>>
>
Stefano Sabatini March 6, 2024, 4 p.m. UTC | #5
On date Wednesday 2024-03-06 09:43:26 -0600, Marth64 wrote:
> It is true that this is necessary when muxing to Matroska, but it is also
> the case for MOV - the MOV muxer expects RGB prior to converting to YUV
> again. So this would be needed for MOV also, despite the awkward conversion
> circle. I should update the document to reflect this.

So we might drop the reference to Matroska, or change to something as:

Output subtitle palettes (CLUTs) as RGB, as required for example when
for subtitles rendering in Matroska or MP4 video.
...

I assume there is no heuristic to distinguish RGB/YUV (one trick might
be to add some custom metadata for the colorspace so that it can then
be read by the encoder).

Also I wonder if this is should not rather be an option for the
Matroska/MP4 renderer, to avoid duplicating the code.

> On Wed, Mar 6, 2024 at 09:36 Marth64 <marth64@proxyid.net> wrote:
> 
> > Good morning,
> >
> > DVD subtitle palettes, which are natively YUV, are currently carried as
> > a hex string in their respective subtitle streams and have
> > no concept of colorspace tagging (even predating dvd demuxer). The
> > convention is to convert
> > them to RGB prior to storage. Common players will only render
> > the palettes properly if they are stored as RGB. Even ffmpeg itself
> > expects this, and already does -in libavformat- the YUV-RGB conversions,
> > specifically in mov.c and movenc.c.
> >
> > The point of this patch is to provide a consolidation of the code
> > that deals with creating the extradata as well as the RGB conversion.
> > That can then (1) enable usable palette support for DVD demuxer if it is
> > merged
> > and (2) start the process of consolidating the related conversions in
> > MOV muxer/demuxer and eventually find a way to properly tag
> > the colorspace.
> >
> > Thank you!
Anton Khirnov March 7, 2024, 9:53 a.m. UTC | #6
Quoting Marth64 (2024-03-06 16:36:32)
> Good morning,
> 
> DVD subtitle palettes, which are natively YUV, are currently carried as
> a hex string in their respective subtitle streams and have
> no concept of colorspace tagging (even predating dvd demuxer). The
> convention is to convert
> them to RGB prior to storage. Common players will only render
> the palettes properly if they are stored as RGB. Even ffmpeg itself
> expects this, and already does -in libavformat- the YUV-RGB conversions,
> specifically in mov.c and movenc.c.
> 
> The point of this patch is to provide a consolidation of the code
> that deals with creating the extradata as well as the RGB conversion.
> That can then (1) enable usable palette support for DVD demuxer if it is
> merged
> and (2) start the process of consolidating the related conversions in
> MOV muxer/demuxer and eventually find a way to properly tag
> the colorspace.

Is there any reason ever to export YUV palette? Should this even be an
option?
Andreas Rheinhardt March 7, 2024, 10:36 a.m. UTC | #7
Anton Khirnov:
> Quoting Marth64 (2024-03-06 16:36:32)
>> Good morning,
>>
>> DVD subtitle palettes, which are natively YUV, are currently carried as
>> a hex string in their respective subtitle streams and have
>> no concept of colorspace tagging (even predating dvd demuxer). The
>> convention is to convert
>> them to RGB prior to storage. Common players will only render
>> the palettes properly if they are stored as RGB. Even ffmpeg itself
>> expects this, and already does -in libavformat- the YUV-RGB conversions,
>> specifically in mov.c and movenc.c.
>>
>> The point of this patch is to provide a consolidation of the code
>> that deals with creating the extradata as well as the RGB conversion.
>> That can then (1) enable usable palette support for DVD demuxer if it is
>> merged
>> and (2) start the process of consolidating the related conversions in
>> MOV muxer/demuxer and eventually find a way to properly tag
>> the colorspace.
> 
> Is there any reason ever to export YUV palette? Should this even be an
> option?
> 

Is the conversion lossless?

- Andreas
diff mbox series

Patch

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index f4bac8f3b3..1a17c6db16 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -394,6 +394,11 @@  often with junk data intended for controlling a real DVD player's
 buffering speed and with no other material data value.
 Default is 1, true.
 
+@item clut_rgb @var{bool}
+Output subtitle palettes (CLUTs) as RGB, required for Matroska.
+Disable to output the palette in its original YUV colorspace.
+Default is 1, true.
+
 @end table
 
 @subsection Examples
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 8811a0ffc9..a3bfc209c3 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -194,7 +194,7 @@  OBJS-$(CONFIG_DTS_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_DV_MUXER)                  += dvenc.o
 OBJS-$(CONFIG_DVBSUB_DEMUXER)            += dvbsub.o rawdec.o
 OBJS-$(CONFIG_DVBTXT_DEMUXER)            += dvbtxt.o rawdec.o
-OBJS-$(CONFIG_DVDVIDEO_DEMUXER)          += dvdvideodec.o
+OBJS-$(CONFIG_DVDVIDEO_DEMUXER)          += dvdvideodec.o dvdclut.o
 OBJS-$(CONFIG_DXA_DEMUXER)               += dxa.o
 OBJS-$(CONFIG_EA_CDATA_DEMUXER)          += eacdata.o
 OBJS-$(CONFIG_EA_DEMUXER)                += electronicarts.o
diff --git a/libavformat/dvdclut.c b/libavformat/dvdclut.c
new file mode 100644
index 0000000000..cd4b103e4b
--- /dev/null
+++ b/libavformat/dvdclut.c
@@ -0,0 +1,75 @@ 
+/*
+ * DVD-Video subpicture CLUT (Color Lookup Table) utilities
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/bprint.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/common.h"
+
+#include "dvdclut.h"
+#include "internal.h"
+
+int ff_dvdclut_palette_extradata_cat(const uint32_t *clut,
+                                     const size_t clut_size,
+                                     AVCodecParameters *par)
+{
+    AVBPrint bp;
+
+    if (clut_size != FF_DVDCLUT_CLUT_SIZE)
+        return AVERROR(EINVAL);
+
+    av_bprint_init(&bp, 0, FF_DVDCLUT_EXTRADATA_SIZE);
+
+    av_bprintf(&bp, "palette: ");
+
+    for (int i = 0; i < FF_DVDCLUT_CLUT_LEN; i++)
+        av_bprintf(&bp, "%06"PRIx32"%s", clut[i],
+                   i != (FF_DVDCLUT_CLUT_LEN - 1) ? ", " : "");
+
+    av_bprintf(&bp, "\n");
+
+    return ff_bprint_to_codecpar_extradata(par, &bp);
+}
+
+int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size)
+{
+    int y, cb, cr;
+    uint8_t r, g, b;
+    int r_add, g_add, b_add;
+
+    if (clut_size != FF_DVDCLUT_CLUT_SIZE)
+        return AVERROR(EINVAL);
+
+    for (int i = 0; i < FF_DVDCLUT_CLUT_LEN; i++) {
+        y  = (clut[i] >> 16) & 0xFF;
+        cr = (clut[i] >> 8)  & 0xFF;
+        cb = clut[i]         & 0xFF;
+
+        YUV_TO_RGB1_CCIR(cb, cr);
+
+        y = (y - 16) * FIX(255.0 / 219.0);
+        r = av_clip_uint8((y + r_add - 1024) >> SCALEBITS);
+        g = av_clip_uint8((y + g_add - 1024) >> SCALEBITS);
+        b = av_clip_uint8((y + b_add - 1024) >> SCALEBITS);
+
+        clut[i] = (r << 16) | (g << 8) | b;
+    }
+
+    return 0;
+}
diff --git a/libavformat/dvdclut.h b/libavformat/dvdclut.h
new file mode 100644
index 0000000000..41cea7e2c9
--- /dev/null
+++ b/libavformat/dvdclut.h
@@ -0,0 +1,37 @@ 
+/*
+ * DVD-Video subpicture CLUT (Color Lookup Table) utilities
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFORMAT_DVDCLUT_H
+#define AVFORMAT_DVDCLUT_H
+
+#include "libavcodec/codec_par.h"
+
+/* ("palette: ") + ("rrggbb, "*15) + ("rrggbb") + \n + \0 */
+#define FF_DVDCLUT_EXTRADATA_SIZE        (9 + (8 * 15) + 6 + 1 + 1)
+#define FF_DVDCLUT_CLUT_LEN              16
+#define FF_DVDCLUT_CLUT_SIZE             FF_DVDCLUT_CLUT_LEN * sizeof(uint32_t)
+
+int ff_dvdclut_palette_extradata_cat(const uint32_t *clut,
+                                     const size_t clut_size,
+                                     AVCodecParameters *par);
+
+int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size);
+
+#endif /* AVFORMAT_DVDCLUT_H */
diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c
index b83ae0c2a5..3bc76f5c65 100644
--- a/libavformat/dvdvideodec.c
+++ b/libavformat/dvdvideodec.c
@@ -49,6 +49,7 @@ 
 #include "avio_internal.h"
 #include "avlanguage.h"
 #include "demux.h"
+#include "dvdclut.h"
 #include "internal.h"
 #include "url.h"
 
@@ -95,6 +96,7 @@  typedef struct DVDVideoPGCSubtitleStreamEntry {
     int                                 startcode;
     enum DVDVideoSubpictureViewport     viewport;
     int                                 disposition;
+    uint32_t                            clut[FF_DVDCLUT_CLUT_LEN];
     const char                          *lang_iso;
 } DVDVideoPGCSubtitleStreamEntry;
 
@@ -128,6 +130,7 @@  typedef struct DVDVideoDemuxContext {
     int                         opt_angle;          /* the user-provided angle number (1-indexed) */
     int                         opt_chapter_end;    /* the user-provided exit PTT (0 for last) */
     int                         opt_chapter_start;  /* the user-provided entry PTT (1-indexed) */
+    int                         opt_clut_rgb;       /* output subtitle palette (CLUT) as RGB */
     int                         opt_pg;             /* the user-provided PG number (1-indexed) */
     int                         opt_pgc;            /* the user-provided PGC number (1-indexed) */
     int                         opt_preindex;       /* pre-indexing mode (2-pass read) */
@@ -1038,6 +1041,8 @@  break_error:
 static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr,
                                         DVDVideoPGCSubtitleStreamEntry *entry)
 {
+    DVDVideoDemuxContext *c = s->priv_data;
+
     char lang_dvd[3] = {0};
 
     entry->startcode = 0x20 + (offset & 0x1F);
@@ -1045,6 +1050,11 @@  static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, sub
     if (subp_attr.lang_extension == 9)
         entry->disposition |= AV_DISPOSITION_FORCED;
 
+    memcpy(&entry->clut, c->play_state.pgc->palette, FF_DVDCLUT_CLUT_SIZE);
+
+    if (c->opt_clut_rgb)
+        ff_dvdclut_yuv_to_rgb(entry->clut, FF_DVDCLUT_CLUT_SIZE);
+
     AV_WB16(lang_dvd, subp_attr.lang_code);
     entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
 
@@ -1056,6 +1066,7 @@  static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStrea
 {
     AVStream *st;
     FFStream *sti;
+    int ret;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -1065,6 +1076,9 @@  static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStrea
     st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
     st->codecpar->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
 
+    if ((ret = ff_dvdclut_palette_extradata_cat(entry->clut, FF_DVDCLUT_CLUT_SIZE, st->codecpar)) < 0)
+        return ret;
+
     if (entry->lang_iso)
         av_dict_set(&st->metadata, "language", entry->lang_iso, 0);
 
@@ -1373,6 +1387,7 @@  static const AVOption dvdvideo_options[] = {
     {"angle",           "playback angle number",                                    OFFSET(opt_angle),          AV_OPT_TYPE_INT,    { .i64=1 },     1,          9,         AV_OPT_FLAG_DECODING_PARAM },
     {"chapter_end",     "exit chapter (PTT) number (0=end)",                        OFFSET(opt_chapter_end),    AV_OPT_TYPE_INT,    { .i64=0 },     0,          99,        AV_OPT_FLAG_DECODING_PARAM },
     {"chapter_start",   "entry chapter (PTT) number",                               OFFSET(opt_chapter_start),  AV_OPT_TYPE_INT,    { .i64=1 },     1,          99,        AV_OPT_FLAG_DECODING_PARAM },
+    {"clut_rgb",        "output subtitle palette (CLUT) as RGB",                    OFFSET(opt_clut_rgb),       AV_OPT_TYPE_BOOL,   { .i64=1 },     0,          1,         AV_OPT_FLAG_DECODING_PARAM },
     {"pg",              "entry PG number (0=auto)",                                 OFFSET(opt_pg),             AV_OPT_TYPE_INT,    { .i64=0 },     0,          255,       AV_OPT_FLAG_DECODING_PARAM },
     {"pgc",             "entry PGC number (0=auto)",                                OFFSET(opt_pgc),            AV_OPT_TYPE_INT,    { .i64=0 },     0,          999,       AV_OPT_FLAG_DECODING_PARAM },
     {"preindex",        "enable for accurate chapter markers, slow (2-pass read)",  OFFSET(opt_preindex),       AV_OPT_TYPE_BOOL,   { .i64=0 },     0,          1,         AV_OPT_FLAG_DECODING_PARAM },