diff mbox series

[FFmpeg-devel] libavformat/dvdvideo: enable subtitle palette support

Message ID 20240129055343.432489-1-marth64@proxyid.net
State New
Headers show
Series [FFmpeg-devel] libavformat/dvdvideo: enable subtitle palette support | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Marth64 Jan. 29, 2024, 5:53 a.m. UTC
If DVD demuxer and CLUT utilities patches are merged, then this
enables RGB palette support for demuxed DVD subtitles and in turn
makes them playable/usable with nearly all compatible players
(which do not support YUV palettes).

Signed-off-by: Marth64 <marth64@proxyid.net>
---
 doc/demuxers.texi         |  5 +++++
 libavformat/Makefile      |  2 +-
 libavformat/dvdvideodec.c | 16 +++++++++++++++-
 3 files changed, 21 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index f7f9e6769a..7f0af820ae 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -412,6 +412,11 @@  for a uniform output from many discs which insert AC3 delay or filler frames
 at the start of the PGC.
 Default is 1, true.
 
+@item clut_rgb
+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
 
 @section ea
diff --git a/libavformat/Makefile b/libavformat/Makefile
index f0b42188a2..8cbbea8356 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -192,7 +192,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/dvdvideodec.c b/libavformat/dvdvideodec.c
index b9ec3acaaf..68ddf73bd4 100644
--- a/libavformat/dvdvideodec.c
+++ b/libavformat/dvdvideodec.c
@@ -51,6 +51,7 @@ 
 #include "avio_internal.h"
 #include "avlanguage.h"
 #include "demux.h"
+#include "dvdclut.h"
 #include "internal.h"
 #include "url.h"
 
@@ -92,6 +93,7 @@  typedef struct DVDVideoPGCAudioStreamEntry {
 
 typedef struct DVDVideoPGCSubtitleStreamEntry {
     int startcode;
+    uint32_t *clut;
     int disposition;
     char *lang_iso;
     enum DVDVideoSubpictureViewport viewport;
@@ -133,6 +135,7 @@  typedef struct DVDVideoDemuxContext {
     int                         opt_preindex;       /* pre-indexing mode (2-pass read) */
     int                         opt_trim;           /* trim padding cells at beginning and end */
     int                         opt_wait_for_audio; /* wait for audio streams to start, if any */
+    int                         opt_clut_rgb;       /* output subtitle palette (CLUT) as RGB */
 
     /* subdemux */
     const AVInputFormat         *mpeg_fmt;          /* inner MPEG-PS (VOB) demuxer */
@@ -1031,6 +1034,8 @@  break_free_and_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);
@@ -1038,6 +1043,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 = (char *) ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL);
 
@@ -1059,7 +1069,8 @@  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;
 
-    /* XXX: palette support will be inserted here in upcoming patch */
+    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);
@@ -1088,6 +1099,7 @@  static int dvdvideo_subp_stream_add_internal(AVFormatContext *s, uint32_t offset
     int ret = 0;
 
     entry = av_mallocz(sizeof(DVDVideoPGCSubtitleStreamEntry));
+    entry->clut = av_mallocz(FF_DVDCLUT_CLUT_SIZE);
     entry->viewport = viewport;
 
     if ((ret = dvdvideo_subp_stream_analyze(s, offset, subp_attr, entry)) < 0)
@@ -1107,6 +1119,7 @@  end_free_error:
     av_log(s, AV_LOG_ERROR, "Unable to allocate subtitle stream\n");
 
 end_free:
+    av_free(entry->clut);
     av_freep(&entry);
 
     return ret;
@@ -1386,6 +1399,7 @@  static const AVOption dvdvideo_options[] = {
     {"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 },
     {"trim",            "trim padding cells from start",                            OFFSET(opt_trim),           AV_OPT_TYPE_BOOL,   { .i64=1 },     0,          1,         AV_OPT_FLAG_DECODING_PARAM },
     {"wait_for_audio",  "wait for audio keyframe at start, if any",                 OFFSET(opt_wait_for_audio), AV_OPT_TYPE_BOOL,   { .i64=1 },     0,          1,         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 },
     {NULL}
 };