From b148c22cec70f4cd97836ea42ef2882589fe9adf Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 12 Nov 2013 18:36:04 -0300 Subject: [PATCH] mpegtsmux: Properly add subtitle descriptor for DVb subpicture subtitles We were adding an empty descriptor for them and it was not possible to actually use them on muxed streams. --- gst/mpegtsmux/Makefile.am | 1 + gst/mpegtsmux/mpegtsmux.c | 37 ++++++++++++++++++++++++++++++++++++- gst/mpegtsmux/mpegtsmux.h | 2 ++ gst/mpegtsmux/tsmux/tsmux.c | 8 +++++++- gst/mpegtsmux/tsmux/tsmux.h | 2 +- gst/mpegtsmux/tsmux/tsmuxstream.c | 28 +++++++++++++++++++++------- gst/mpegtsmux/tsmux/tsmuxstream.h | 3 +++ 7 files changed, 71 insertions(+), 10 deletions(-) diff --git a/gst/mpegtsmux/Makefile.am b/gst/mpegtsmux/Makefile.am index 845419b..8dd002c 100644 --- a/gst/mpegtsmux/Makefile.am +++ b/gst/mpegtsmux/Makefile.am @@ -9,6 +9,7 @@ libgstmpegtsmux_la_SOURCES = \ libgstmpegtsmux_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) libgstmpegtsmux_la_LIBADD = $(top_builddir)/gst/mpegtsmux/tsmux/libtsmux.la \ + -lgsttag-@GST_API_VERSION@ \ $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_BASE_LIBS) $(GST_LIBS) libgstmpegtsmux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstmpegtsmux_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) diff --git a/gst/mpegtsmux/mpegtsmux.c b/gst/mpegtsmux/mpegtsmux.c index aebe23a..2bf6174 100644 --- a/gst/mpegtsmux/mpegtsmux.c +++ b/gst/mpegtsmux/mpegtsmux.c @@ -92,6 +92,7 @@ * with newer GLib versions (>= 2.31.0) */ #define GLIB_DISABLE_DEPRECATION_WARNINGS +#include #include #include "mpegtsmux.h" @@ -340,6 +341,12 @@ mpegtsmux_pad_reset (MpegTsPadData * pad_data) /* reference owned elsewhere */ pad_data->stream = NULL; pad_data->prog = NULL; + + if (pad_data->language) { + g_free (pad_data->language); + pad_data->language = NULL; + } + } static void @@ -646,7 +653,8 @@ mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data) } if (st != TSMUX_ST_RESERVED) { - ts_data->stream = tsmux_create_stream (mux->tsmux, st, ts_data->pid); + ts_data->stream = tsmux_create_stream (mux->tsmux, st, ts_data->pid, + ts_data->language); } else { GST_DEBUG_OBJECT (pad, "Failed to determine stream type"); } @@ -781,6 +789,7 @@ mpegtsmux_sink_event (GstCollectPads * pads, GstCollectData * data, gboolean forward = TRUE; #ifndef GST_DISABLE_GST_DEBUG GstPad *pad; + MpegTsPadData *pad_data = (MpegTsPadData *) data; pad = data->pad; #endif @@ -818,6 +827,32 @@ mpegtsmux_sink_event (GstCollectPads * pads, GstCollectData * data, gst_event_replace (&mux->force_key_unit_event, event); break; } + case GST_EVENT_TAG:{ + GstTagList *list; + gchar *lang = NULL; + + GST_DEBUG_OBJECT (mux, "received tag event"); + gst_event_parse_tag (event, &list); + + /* Matroska wants ISO 639-2B code, taglist most likely contains 639-1 */ + if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) { + const gchar *lang_code; + + lang_code = gst_tag_get_language_code_iso_639_2B (lang); + if (lang_code) { + GST_DEBUG_OBJECT (pad, "Setting language to '%s'", lang_code); + pad_data->language = g_strdup (lang_code); + } else { + GST_WARNING_OBJECT (pad, "Did not get language code for '%s'", lang); + } + g_free (lang); + } + + /* handled this, don't want collectpads to forward it downstream */ + res = TRUE; + forward = FALSE; + break; + } default: break; } diff --git a/gst/mpegtsmux/mpegtsmux.h b/gst/mpegtsmux/mpegtsmux.h index afdbc12..52b291e 100644 --- a/gst/mpegtsmux/mpegtsmux.h +++ b/gst/mpegtsmux/mpegtsmux.h @@ -208,6 +208,8 @@ struct MpegTsPadData { gint prog_id; /* program this stream belongs to == mux->programs[prog_id] */ TsMuxProgram *prog; + + gchar *language; }; GType mpegtsmux_get_type (void); diff --git a/gst/mpegtsmux/tsmux/tsmux.c b/gst/mpegtsmux/tsmux/tsmux.c index e7edf57..7835940 100644 --- a/gst/mpegtsmux/tsmux/tsmux.c +++ b/gst/mpegtsmux/tsmux/tsmux.c @@ -419,7 +419,8 @@ tsmux_get_new_pid (TsMux * mux) * Returns: a new #TsMuxStream. */ TsMuxStream * -tsmux_create_stream (TsMux * mux, TsMuxStreamType stream_type, guint16 pid) +tsmux_create_stream (TsMux * mux, TsMuxStreamType stream_type, guint16 pid, + gchar * language) { TsMuxStream *stream; guint16 new_pid; @@ -441,6 +442,11 @@ tsmux_create_stream (TsMux * mux, TsMuxStreamType stream_type, guint16 pid) mux->streams = g_list_prepend (mux->streams, stream); mux->nb_streams++; + if (language) + g_strlcat (stream->language, language, 3 * sizeof (gchar)); + else + g_strlcat (stream->language, "eng", 3 * sizeof (gchar)); + return stream; } diff --git a/gst/mpegtsmux/tsmux/tsmux.h b/gst/mpegtsmux/tsmux/tsmux.h index 160b6bd..acebcb5 100644 --- a/gst/mpegtsmux/tsmux/tsmux.h +++ b/gst/mpegtsmux/tsmux/tsmux.h @@ -189,7 +189,7 @@ void tsmux_set_pmt_interval (TsMuxProgram *program, guint interval); guint tsmux_get_pmt_interval (TsMuxProgram *program); /* stream management */ -TsMuxStream * tsmux_create_stream (TsMux *mux, TsMuxStreamType stream_type, guint16 pid); +TsMuxStream * tsmux_create_stream (TsMux *mux, TsMuxStreamType stream_type, guint16 pid, gchar *language); TsMuxStream * tsmux_find_stream (TsMux *mux, guint16 pid); void tsmux_program_add_stream (TsMuxProgram *program, TsMuxStream *stream); diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.c b/gst/mpegtsmux/tsmux/tsmuxstream.c index 20378b5..a03977a 100644 --- a/gst/mpegtsmux/tsmux/tsmuxstream.c +++ b/gst/mpegtsmux/tsmux/tsmuxstream.c @@ -181,6 +181,7 @@ tsmux_stream_new (guint16 pid, TsMuxStreamType stream_type) case TSMUX_ST_PS_DVB_SUBPICTURE: /* private stream 1 */ stream->id = 0xBD; + stream->is_dvb_sub = TRUE; stream->stream_type = TSMUX_ST_PRIVATE_DATA; stream->pi.flags |= TSMUX_PACKET_FLAG_PES_FULL_HEADER | @@ -877,13 +878,6 @@ tsmux_stream_get_es_descrs (TsMuxStream * stream, guint8 * buf, guint16 * len) case TSMUX_ST_PS_AUDIO_LPCM: /* FIXME */ break; - case TSMUX_ST_PS_DVB_SUBPICTURE: - /* tag */ - *pos++ = 0x59; - /* FIXME empty descriptor for now; - * should be provided by upstream in event or so ? */ - *pos = 0; - break; case TSMUX_ST_PS_TELETEXT: /* tag */ *pos++ = 0x56; @@ -891,6 +885,26 @@ tsmux_stream_get_es_descrs (TsMuxStream * stream, guint8 * buf, guint16 * len) * should be provided by upstream in event or so ? */ *pos = 0; break; + case TSMUX_ST_PS_DVB_SUBPICTURE: + /* falltrough ... + * that should never happen anyway as + * dvb subtitles are private data */ + case TSMUX_ST_PRIVATE_DATA: + if (stream->is_dvb_sub) { + GST_DEBUG ("Stream language %s", stream->language); + *pos++ = 0x59; /* dvb subtitles */ + *pos++ = 0x08; /* descriptor length */ + *pos++ = stream->language[0]; /* Language */ + *pos++ = stream->language[1]; + *pos++ = stream->language[2]; + *pos++ = 0x10; /* Simple DVB subtitles with no monitor aspect ratio critical + FIXME, how do we make it settable? */ + *pos++ = 0x00; /* Default composition page ID */ + *pos++ = 0x01; + *pos++ = 0x01; /* Default ancillary_page_id */ + *pos++ = 0x52; + break; + } default: break; } diff --git a/gst/mpegtsmux/tsmux/tsmuxstream.h b/gst/mpegtsmux/tsmux/tsmuxstream.h index 27c0e79..8bff394 100644 --- a/gst/mpegtsmux/tsmux/tsmuxstream.h +++ b/gst/mpegtsmux/tsmux/tsmuxstream.h @@ -203,6 +203,9 @@ struct TsMuxStream { gint audio_sampling; gint audio_channels; gint audio_bitrate; + + gboolean is_dvb_sub; + gchar language[4]; }; /* stream management */ -- 2.7.4