resindvd: fix preroll on titles with no audio track
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Fri, 20 Jan 2012 15:34:27 +0000 (15:34 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Mon, 23 Jan 2012 11:04:26 +0000 (11:04 +0000)
https://bugzilla.gnome.org/show_bug.cgi?id=599469

ext/resindvd/resindvdbin.c
ext/resindvd/rsndec.c

index c73af9a..c1a29eb 100644 (file)
@@ -470,18 +470,16 @@ create_elements (RsnDvdBin * dvdbin)
           RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector"))
     return FALSE;
 
-  if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL,
-          RSN_TYPE_AUDIODEC, "auddec", "audio decoder"))
+  if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL,
+          RSN_TYPE_AUDIOMUNGE, "audioearlymunge", "Audio output filter"))
     return FALSE;
 
-  /* rsnaudiomunge goes after the audio decoding to regulate the stream */
-  if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL,
-          RSN_TYPE_AUDIOMUNGE, "audiomunge", "Audio output filter"))
+  if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL,
+          RSN_TYPE_AUDIODEC, "auddec", "audio decoder"))
     return FALSE;
 
-  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src");
-  sink =
-      gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink");
+  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
+  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink");
   if (src == NULL || sink == NULL)
     goto failed_aud_connect;
   if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
@@ -491,7 +489,8 @@ create_elements (RsnDvdBin * dvdbin)
   src = sink = NULL;
 
   src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src");
-  sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink");
+  sink =
+      gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink");
   if (src == NULL || sink == NULL)
     goto failed_aud_connect;
   if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
@@ -501,7 +500,7 @@ create_elements (RsnDvdBin * dvdbin)
   src = sink = NULL;
 
   /* ghost audio munge output pad onto bin */
-  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
+  src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src");
   if (src == NULL)
     goto failed_aud_ghost;
   src_templ = gst_static_pad_template_get (&audio_src_template);
@@ -701,7 +700,7 @@ demux_pad_added (GstElement * element, GstPad * pad, RsnDvdBin * dvdbin)
         gst_element_get_request_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT],
         "sink%d");
     skip_mq = TRUE;
-  } else if (can_sink_caps (dvdbin->pieces[DVD_ELEM_AUDDEC], caps)) {
+  } else if (can_sink_caps (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], caps)) {
     GST_LOG_OBJECT (dvdbin, "Found audio pad w/ caps %" GST_PTR_FORMAT, caps);
     dest_pad =
         gst_element_get_request_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT],
index 8d7e380..e826640 100644 (file)
@@ -247,14 +247,44 @@ _get_decoder_factories (gpointer arg)
   GstPadTemplate *templ = gst_element_class_get_pad_template (klass,
       "sink");
   RsnDecFactoryFilterCtx ctx = { NULL, };
+  GstCaps *raw;
+  gboolean raw_audio;
 
   ctx.desired_caps = gst_pad_template_get_caps (templ);
+
+  raw = gst_caps_from_string ("audio/x-raw-float");
+  raw_audio = gst_caps_can_intersect (raw, ctx.desired_caps);
+  if (raw_audio) {
+    GstCaps *sub = gst_caps_subtract (ctx.desired_caps, raw);
+    gst_caps_unref (ctx.desired_caps);
+    ctx.desired_caps = sub;
+  }
+  gst_caps_unref (raw);
+
   /* Set decoder caps to empty. Will be filled by the factory_filter */
   ctx.decoder_caps = gst_caps_new_empty ();
+  GST_DEBUG ("Finding factories for caps: %" GST_PTR_FORMAT, ctx.desired_caps);
 
   factories = gst_default_registry_feature_filter (
       (GstPluginFeatureFilter) rsndec_factory_filter, FALSE, &ctx);
 
+  /* If these are audio caps, we add audioconvert, which is not a decoder,
+     but allows raw audio to go through relatively unmolested - this will
+     come handy when we have to send placeholder silence to allow preroll
+     for those DVDs which have titles with no audio track. */
+  if (raw_audio) {
+    GstPluginFeature *feature;
+    GST_DEBUG ("These are audio caps, adding audioconvert");
+    feature =
+        gst_default_registry_find_feature ("audioconvert",
+        GST_TYPE_ELEMENT_FACTORY);
+    if (feature) {
+      factories = g_list_append (factories, feature);
+    } else {
+      GST_WARNING ("Could not find feature audioconvert");
+    }
+  }
+
   factories = g_list_sort (factories, (GCompareFunc) sort_by_ranks);
 
   GST_DEBUG ("Available decoder caps %" GST_PTR_FORMAT, ctx.decoder_caps);
@@ -343,7 +373,7 @@ static GstStaticPadTemplate audio_sink_template =
     GST_STATIC_CAPS ("audio/mpeg,mpegversion=(int)1;"
         "audio/x-private1-lpcm;"
         "audio/x-private1-ac3;" "audio/ac3;" "audio/x-ac3;"
-        "audio/x-private1-dts;")
+        "audio/x-private1-dts; audio/x-raw-float")
     );
 
 static GstStaticPadTemplate audio_src_template = GST_STATIC_PAD_TEMPLATE ("src",