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.
This commit is contained in:
Jan Schmidt 2009-04-24 14:07:30 +01:00
parent 62db462298
commit eedf313156
2 changed files with 70 additions and 24 deletions

View file

@ -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)) if (!gst_structure_get_int (structure, cur_stream_name, &stream_format))
continue; 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; demux->audio_stream_types[i] = stream_format;
switch (stream_format) { switch (stream_format) {
case 0x0: case 0x0:
/* AC3 */ /* AC3 */
stream_id = 0x80 + i; stream_id += 0x80;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Audio stream %d format %d ID 0x%02x - AC3", i, "Audio stream %d format %d ID 0x%02x - AC3", i,
stream_format, stream_id); stream_format, stream_id);
@ -636,7 +642,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event)
case 0x3: case 0x3:
/* MPEG audio without and with extension stream are /* MPEG audio without and with extension stream are
* treated the same */ * treated the same */
stream_id = 0xC0 + i; stream_id += 0xC0;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Audio stream %d format %d ID 0x%02x - MPEG audio", i, "Audio stream %d format %d ID 0x%02x - MPEG audio", i,
stream_format, stream_id); stream_format, stream_id);
@ -644,7 +650,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event)
break; break;
case 0x4: case 0x4:
/* LPCM */ /* LPCM */
stream_id = 0xA0 + i; stream_id += 0xA0;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Audio stream %d format %d ID 0x%02x - DVD LPCM", i, "Audio stream %d format %d ID 0x%02x - DVD LPCM", i,
stream_format, stream_id); stream_format, stream_id);
@ -653,7 +659,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event)
break; break;
case 0x6: case 0x6:
/* DTS */ /* DTS */
stream_id = 0x88 + i; stream_id += 0x88;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Audio stream %d format %d ID 0x%02x - DTS", i, "Audio stream %d format %d ID 0x%02x - DTS", i,
stream_format, stream_id); stream_format, stream_id);
@ -673,16 +679,23 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event)
/* And subtitle streams */ /* And subtitle streams */
for (i = 0; i < MAX_DVD_SUBPICTURE_STREAMS; i++) { for (i = 0; i < MAX_DVD_SUBPICTURE_STREAMS; i++) {
gint stream_format; gint stream_format;
gint stream_id;
g_snprintf (cur_stream_name, 32, "subpicture-%d-format", i); g_snprintf (cur_stream_name, 32, "subpicture-%d-format", i);
if (!gst_structure_get_int (structure, cur_stream_name, &stream_format)) if (!gst_structure_get_int (structure, cur_stream_name, &stream_format))
continue; 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); GST_DEBUG_OBJECT (demux, "Subpicture stream %d ID 0x%02x", i, 0x20 + i);
/* Retrieve the subpicture stream to force pad creation */ /* 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, " GST_DEBUG_OBJECT (demux, "Created all pads from Language Codes event, "

View file

@ -685,8 +685,8 @@ get_current_pgc (resinDvdSrc * src)
DVDNAV_STATUS_OK) DVDNAV_STATUS_OK)
return NULL; return NULL;
/* To find the right tmap, we need the title number within this VTS (vts_ttn) /* To find the right PGC, we need the title number within this VTS (vts_ttn)
* * from the VMG tt_srpt table... */ * from the VMG tt_srpt table... */
if (title < 1 || title > src->vmg_file->tt_srpt->nr_of_srpts) if (title < 1 || title > src->vmg_file->tt_srpt->nr_of_srpts)
return NULL; return NULL;
@ -864,6 +864,9 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
"CELL change dur now %" GST_TIME_FORMAT " position now %" "CELL change dur now %" GST_TIME_FORMAT " position now %"
GST_TIME_FORMAT, GST_TIME_ARGS (src->pgc_duration), GST_TIME_FORMAT, GST_TIME_ARGS (src->pgc_duration),
GST_TIME_ARGS (src->cur_position)); GST_TIME_ARGS (src->cur_position));
rsn_dvdsrc_prepare_streamsinfo_event (src);
break; break;
} }
case DVDNAV_SPU_CLUT_CHANGE: 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); src->in_menu = !dvdnav_is_domain_vts (src->dvdnav);
if (!dvdnav_is_domain_fp (src->dvdnav))
rsn_dvdsrc_prepare_streamsinfo_event (src);
break; break;
} }
case DVDNAV_AUDIO_STREAM_CHANGE:{ 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 /* Push in-band events now that we've dropped the dvd_lock, before
* we change segment */ * we change segment */
if (streams_event) { 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); gst_pad_push_event (GST_BASE_SRC_PAD (src), streams_event);
} }
if (clut_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_phys_stream = phys_stream;
src->cur_spu_forced_only = forced_only; src->cur_spu_forced_only = forced_only;
GST_DEBUG_OBJECT (src, "Preparing SPU change, phys %d forced %d", GST_DEBUG_OBJECT (src, "Preparing SPU change, log %d phys %d forced %d",
phys_stream, forced_only); logical_stream, phys_stream, forced_only);
s = gst_structure_new ("application/x-gst-dvd", s = gst_structure_new ("application/x-gst-dvd",
"event", G_TYPE_STRING, "dvd-set-subpicture-track", "event", G_TYPE_STRING, "dvd-set-subpicture-track",
@ -1506,6 +1506,7 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src)
gchar *t; gchar *t;
gboolean is_widescreen; gboolean is_widescreen;
gboolean have_audio; gboolean have_audio;
gboolean have_subp;
if (src->vts_attrs == NULL || src->vts_n >= src->vts_attrs->len) { if (src->vts_attrs == NULL || src->vts_n >= src->vts_attrs->len) {
if (src->vts_attrs) if (src->vts_attrs)
@ -1561,6 +1562,16 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src)
have_audio = FALSE; have_audio = FALSE;
for (i = 0; i < n_audio; i++) { for (i = 0; i < n_audio; i++) {
const audio_attr_t *a = a_attrs + 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 #if 1
/* FIXME: Only output A52 streams for now, until the decoder switching /* FIXME: Only output A52 streams for now, until the decoder switching
@ -1573,13 +1584,17 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src)
#endif #endif
have_audio = TRUE; 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); t = g_strdup_printf ("audio-%d-format", i);
gst_structure_set (s, t, G_TYPE_INT, (int) a->audio_format, NULL); gst_structure_set (s, t, G_TYPE_INT, (int) a->audio_format, NULL);
g_free (t); g_free (t);
GST_DEBUG_OBJECT (src, "Audio stream %d is format %d", i,
(int) a->audio_format);
if (a->lang_type) { if (a->lang_type) {
t = g_strdup_printf ("audio-%d-language", i); t = g_strdup_printf ("audio-%d-language", i);
lang_code[0] = (a->lang_code >> 8) & 0xff; lang_code[0] = (a->lang_code >> 8) & 0xff;
@ -1594,17 +1609,29 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src)
if (have_audio == FALSE) { if (have_audio == FALSE) {
/* Always create at least one audio stream */ /* 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 */ /* subpictures */
if (n_subp == 0) { have_subp = FALSE;
/* 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);
}
for (i = 0; i < n_subp; i++) { for (i = 0; i < n_subp; i++) {
const subp_attr_t *u = s_attrs + 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); t = g_strdup_printf ("subpicture-%d-format", i);
gst_structure_set (s, t, G_TYPE_INT, (int) 0, NULL); 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, GST_DEBUG_OBJECT (src, "Subpicture stream %d is language %s", i,
lang_code[0] ? lang_code : "NONE"); 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) if (src->streams_event)
gst_event_unref (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. */ /* Create the DVD event and put the structure into it. */
event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure); 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) if (src->clut_event)
gst_event_unref (src->clut_event); gst_event_unref (src->clut_event);