From eedf3131564c59e1c026cba7ab104c31df2fb6db Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 24 Apr 2009 14:07:30 +0100 Subject: resindvd: Map audio and subpicture logical streams to physical. The logical audio and subpicture stream number doesn't always correspond with the physical substream it is coming from. When configuring the demuxer pads, use the mapping table provided in each PGC to get the layout and ensure the demuxer creates the correct pads. --- ext/resindvd/gstmpegdemux.c | 25 ++++++++++++---- ext/resindvd/resindvdsrc.c | 69 +++++++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 24 deletions(-) (limited to 'ext/resindvd') diff --git a/ext/resindvd/gstmpegdemux.c b/ext/resindvd/gstmpegdemux.c index bee7f43f..cc37ec4e 100644 --- a/ext/resindvd/gstmpegdemux.c +++ b/ext/resindvd/gstmpegdemux.c @@ -622,11 +622,17 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) if (!gst_structure_get_int (structure, cur_stream_name, &stream_format)) continue; + g_snprintf (cur_stream_name, 32, "audio-%d-stream", i); + if (!gst_structure_get_int (structure, cur_stream_name, &stream_id)) + continue; + if (stream_id < 0 || stream_id >= MAX_DVD_AUDIO_STREAMS) + continue; + demux->audio_stream_types[i] = stream_format; switch (stream_format) { case 0x0: /* AC3 */ - stream_id = 0x80 + i; + stream_id += 0x80; GST_DEBUG_OBJECT (demux, "Audio stream %d format %d ID 0x%02x - AC3", i, stream_format, stream_id); @@ -636,7 +642,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) case 0x3: /* MPEG audio without and with extension stream are * treated the same */ - stream_id = 0xC0 + i; + stream_id += 0xC0; GST_DEBUG_OBJECT (demux, "Audio stream %d format %d ID 0x%02x - MPEG audio", i, stream_format, stream_id); @@ -644,7 +650,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) break; case 0x4: /* LPCM */ - stream_id = 0xA0 + i; + stream_id += 0xA0; GST_DEBUG_OBJECT (demux, "Audio stream %d format %d ID 0x%02x - DVD LPCM", i, stream_format, stream_id); @@ -653,7 +659,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) break; case 0x6: /* DTS */ - stream_id = 0x88 + i; + stream_id += 0x88; GST_DEBUG_OBJECT (demux, "Audio stream %d format %d ID 0x%02x - DTS", i, stream_format, stream_id); @@ -673,16 +679,23 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) /* And subtitle streams */ for (i = 0; i < MAX_DVD_SUBPICTURE_STREAMS; i++) { gint stream_format; + gint stream_id; g_snprintf (cur_stream_name, 32, "subpicture-%d-format", i); - if (!gst_structure_get_int (structure, cur_stream_name, &stream_format)) continue; + g_snprintf (cur_stream_name, 32, "subpicture-%d-stream", i); + if (!gst_structure_get_int (structure, cur_stream_name, &stream_id)) + continue; + if (stream_id < 0 || stream_id >= MAX_DVD_SUBPICTURE_STREAMS) + continue; + GST_DEBUG_OBJECT (demux, "Subpicture stream %d ID 0x%02x", i, 0x20 + i); /* Retrieve the subpicture stream to force pad creation */ - temp = gst_flups_demux_get_stream (demux, 0x20 + i, ST_PS_DVD_SUBPICTURE); + temp = gst_flups_demux_get_stream (demux, 0x20 + stream_id, + ST_PS_DVD_SUBPICTURE); } GST_DEBUG_OBJECT (demux, "Created all pads from Language Codes event, " diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c index d2e3b25a..2ad11256 100644 --- a/ext/resindvd/resindvdsrc.c +++ b/ext/resindvd/resindvdsrc.c @@ -685,8 +685,8 @@ get_current_pgc (resinDvdSrc * src) DVDNAV_STATUS_OK) return NULL; - /* To find the right tmap, we need the title number within this VTS (vts_ttn) - * * from the VMG tt_srpt table... */ + /* To find the right PGC, we need the title number within this VTS (vts_ttn) + * from the VMG tt_srpt table... */ if (title < 1 || title > src->vmg_file->tt_srpt->nr_of_srpts) return NULL; @@ -864,6 +864,9 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock) "CELL change dur now %" GST_TIME_FORMAT " position now %" GST_TIME_FORMAT, GST_TIME_ARGS (src->pgc_duration), GST_TIME_ARGS (src->cur_position)); + + rsn_dvdsrc_prepare_streamsinfo_event (src); + break; } case DVDNAV_SPU_CLUT_CHANGE: @@ -885,9 +888,6 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock) src->in_menu = !dvdnav_is_domain_vts (src->dvdnav); - if (!dvdnav_is_domain_fp (src->dvdnav)) - rsn_dvdsrc_prepare_streamsinfo_event (src); - break; } case DVDNAV_AUDIO_STREAM_CHANGE:{ @@ -1018,7 +1018,7 @@ rsn_dvdsrc_create (RsnPushSrc * psrc, GstBuffer ** outbuf) /* Push in-band events now that we've dropped the dvd_lock, before * we change segment */ if (streams_event) { - GST_LOG_OBJECT (src, "Pushing stream event"); + GST_LOG_OBJECT (src, "Pushing stream layout event"); gst_pad_push_event (GST_BASE_SRC_PAD (src), streams_event); } if (clut_event) { @@ -1475,8 +1475,8 @@ rsn_dvdsrc_prepare_spu_stream_event (resinDvdSrc * src, guint8 logical_stream, src->cur_spu_phys_stream = phys_stream; src->cur_spu_forced_only = forced_only; - GST_DEBUG_OBJECT (src, "Preparing SPU change, phys %d forced %d", - phys_stream, forced_only); + GST_DEBUG_OBJECT (src, "Preparing SPU change, log %d phys %d forced %d", + logical_stream, phys_stream, forced_only); s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING, "dvd-set-subpicture-track", @@ -1506,6 +1506,7 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) gchar *t; gboolean is_widescreen; gboolean have_audio; + gboolean have_subp; if (src->vts_attrs == NULL || src->vts_n >= src->vts_attrs->len) { if (src->vts_attrs) @@ -1561,6 +1562,16 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) have_audio = FALSE; for (i = 0; i < n_audio; i++) { const audio_attr_t *a = a_attrs + i; + gint phys_id = dvdnav_get_audio_logical_stream (src->dvdnav, (guint) i); + + if (phys_id == -1) { + GST_DEBUG_OBJECT (src, "No substream ID in map for audio %d. Skipping.", + i); + continue; + } + + GST_DEBUG_OBJECT (src, "mapped logical audio %d to MPEG substream %d", + i, phys_id); #if 1 /* FIXME: Only output A52 streams for now, until the decoder switching @@ -1573,13 +1584,17 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) #endif have_audio = TRUE; + GST_DEBUG_OBJECT (src, "Audio stream %d is format %d, substream %d", i, + (int) a->audio_format, phys_id); + + t = g_strdup_printf ("audio-%d-stream", i); + gst_structure_set (s, t, G_TYPE_INT, phys_id, NULL); + g_free (t); + t = g_strdup_printf ("audio-%d-format", i); gst_structure_set (s, t, G_TYPE_INT, (int) a->audio_format, NULL); g_free (t); - GST_DEBUG_OBJECT (src, "Audio stream %d is format %d", i, - (int) a->audio_format); - if (a->lang_type) { t = g_strdup_printf ("audio-%d-language", i); lang_code[0] = (a->lang_code >> 8) & 0xff; @@ -1594,17 +1609,29 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) if (have_audio == FALSE) { /* Always create at least one audio stream */ - gst_structure_set (s, "audio-0-format", G_TYPE_INT, (int) 0, NULL); + gst_structure_set (s, "audio-0-format", G_TYPE_INT, (int) 0, + "audio-0-stream", G_TYPE_INT, (int) 0, NULL); } /* subpictures */ - if (n_subp == 0) { - /* Always create at least one subpicture stream */ - gst_structure_set (s, "subpicture-0-format", G_TYPE_INT, (int) 0, NULL); - gst_structure_set (s, "subpicture-0-language", G_TYPE_STRING, "MENU", NULL); - } + have_subp = FALSE; for (i = 0; i < n_subp; i++) { const subp_attr_t *u = s_attrs + i; + gint phys_id = dvdnav_get_spu_logical_stream (src->dvdnav, (guint) i); + + if (phys_id == -1) { + GST_DEBUG_OBJECT (src, "No substream ID in map for subpicture %d. " + "Skipping", i); + continue; + } + have_subp = TRUE; + + GST_DEBUG_OBJECT (src, "mapped logical subpicture %d to MPEG substream %d", + i, phys_id); + + t = g_strdup_printf ("subpicture-%d-stream", i); + gst_structure_set (s, t, G_TYPE_INT, (int) phys_id, NULL); + g_free (t); t = g_strdup_printf ("subpicture-%d-format", i); gst_structure_set (s, t, G_TYPE_INT, (int) 0, NULL); @@ -1623,6 +1650,12 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) GST_DEBUG_OBJECT (src, "Subpicture stream %d is language %s", i, lang_code[0] ? lang_code : "NONE"); } + if (!have_subp) { + /* Always create at least one subpicture stream */ + gst_structure_set (s, "subpicture-0-format", G_TYPE_INT, (int) 0, + "subpicture-0-language", G_TYPE_STRING, "MENU", + "subpicture-0-stream", G_TYPE_INT, (int) 0, NULL); + } if (src->streams_event) gst_event_unref (src->streams_event); @@ -1655,7 +1688,7 @@ rsn_dvdsrc_prepare_clut_change_event (resinDvdSrc * src, const guint32 * clut) /* Create the DVD event and put the structure into it. */ event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure); - GST_LOG_OBJECT (src, "pushing clut change event %" GST_PTR_FORMAT, event); + GST_LOG_OBJECT (src, "preparing clut change event %" GST_PTR_FORMAT, event); if (src->clut_event) gst_event_unref (src->clut_event); -- cgit v1.2.1