gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r10626: Fixing bug #25670 (Gst/MP4 c


From: Bastiaan Jacques
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10626: Fixing bug #25670 (Gst/MP4 contained AAC audio doesn't play):
Date: Wed, 25 Feb 2009 21:43:02 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10626
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Wed 2009-02-25 21:43:02 +0100
message:
  Fixing bug #25670 (Gst/MP4 contained AAC audio doesn't play):
  
  * libmedia/gst/MediaParserGst.cpp: Only search for a parsing element if
  the GstCaps indicate that the demuxer has done no parsing or framing.
  * libmedia/gst/swfdec_codec_gst.{c,h}: Allow sink pad connection method
  to be called with either a GstPad or a GstElement. 
modified:
  libmedia/gst/MediaParserGst.cpp
  libmedia/gst/swfdec_codec_gst.c
  libmedia/gst/swfdec_codec_gst.h
=== modified file 'libmedia/gst/MediaParserGst.cpp'
--- a/libmedia/gst/MediaParserGst.cpp   2009-02-25 20:25:28 +0000
+++ b/libmedia/gst/MediaParserGst.cpp   2009-02-25 20:43:02 +0000
@@ -377,60 +377,95 @@
     MediaParserGst* parser = static_cast<MediaParserGst*>(data);
 
     GstCaps* caps = gst_pad_get_caps(new_pad);    
-    print_caps(caps);
-
-    GstElementFactory* parserfactory = swfdec_gst_get_parser_factory (caps);
-
-    if (!parserfactory) {
-        log_error(_("MediaParserGst: Failed to find a parser."));
-        parser->link_to_fakesink(new_pad);
-        return;
-    }
-        
-    GstElement* parserel = gst_element_factory_create (parserfactory, NULL);
-    gst_object_unref (parserfactory);
-    if (!parserel) {
-        log_error(_("MediaParserGst: Failed to find a parser. We'll continue, "
-                    "but either audio or video will not work!"));
-        parser->link_to_fakesink(new_pad);
-        return;
-    }
-                 
-    gboolean success = gst_bin_add(GST_BIN(parser->_bin), parserel);
-    if (!success) {
-        gst_object_unref(parserel);
-        log_error(_("MediaParserGst: couldn't add parser."));
-        return;
-    }    
-    
-    GstPad* sinkpad = gst_element_get_static_pad (parserel, "sink");
-    assert(sinkpad);
-    
-    GstPadLinkReturn ret = gst_pad_link(new_pad, sinkpad);
-    
-    gst_object_unref(GST_OBJECT(sinkpad));
-
-    if (!GST_PAD_LINK_SUCCESSFUL(ret)) {
-        log_error(_("MediaParserGst: couldn't link parser."));
-        return;
-    }
+    print_caps(caps);    
     
     GstStructure* str = gst_caps_get_structure (caps, 0);
     if (!str) {
         log_error(_("MediaParserGst: couldn't get structure name."));
+        parser->link_to_fakesink(new_pad);
         return;    
-    }
-    
-    const gchar* structure_name = gst_structure_get_name (str);
-
-    if (g_strrstr (structure_name, "audio")) {
+    } 
+    
+    const gchar* caps_name = gst_structure_get_name (str);
+    
+    bool media_type_audio;
+
+    if (std::equal(caps_name, caps_name+5, "audio")) {
+        media_type_audio = true;
+    } else if (std::equal(caps_name, caps_name+5, "video")) {
+        media_type_audio = false;
+    } else {
+        log_error(_("MediaParserGst: ignoring stream of type %s."),
+                  caps_name);
+        parser->link_to_fakesink(new_pad);
+        return;
+    }    
+    
+    gboolean parsed = false;
+    gboolean framed = false;
+    
+    gst_structure_get_boolean(str, "parsed", &parsed);
+    gst_structure_get_boolean(str, "framed", &framed);
+    
+    bool already_parsed = parsed || framed;
+    
+    GstPad* final_pad = 0;
+    
+    if (already_parsed) {
+        final_pad = new_pad;
+    } else {
+        // We'll try to find a parser, so that we will eventually receive
+        // timestamped buffers, on which the MediaParser system relies.
+        GstElementFactory* parserfactory = swfdec_gst_get_parser_factory 
(caps);
+
+        if (!parserfactory) {
+            log_error(_("MediaParserGst: Failed to find a parser (media: 
%s)."),
+                      caps_name);
+            parser->link_to_fakesink(new_pad);
+            return;
+        }
+
+        GstElement* parserel = gst_element_factory_create (parserfactory, 
NULL);
+        gst_object_unref (parserfactory);
+        if (!parserel) {
+            log_error(_("MediaParserGst: Failed to find a parser. We'll 
continue, "
+                        "but either audio or video will not work!"));
+            parser->link_to_fakesink(new_pad);
+            return;
+        }
+                     
+        gboolean success = gst_bin_add(GST_BIN(parser->_bin), parserel);
+        if (!success) {
+            gst_object_unref(parserel);
+            log_error(_("MediaParserGst: couldn't add parser."));
+            parser->link_to_fakesink(new_pad);
+            return;
+        }
+        
+        GstPad* sinkpad = gst_element_get_static_pad (parserel, "sink");
+        assert(sinkpad);
+        
+        GstPadLinkReturn ret = gst_pad_link(new_pad, sinkpad);
+        
+        gst_object_unref(GST_OBJECT(sinkpad));
+
+        if (!GST_PAD_LINK_SUCCESSFUL(ret)) {
+            log_error(_("MediaParserGst: couldn't link parser."));
+            parser->link_to_fakesink(new_pad);
+            return;
+        }
+        
+        final_pad = gst_element_get_static_pad (parserel, "src");
+    } 
+
+    if (media_type_audio) {
       
-        parser->_audiosink = swfdec_gst_connect_sinkpad (parserel, caps);
+        parser->_audiosink = swfdec_gst_connect_sinkpad_by_pad (final_pad, 
caps);
         if (!parser->_audiosink) {
             log_error(_("MediaParserGst: couldn't link \"fake\" sink."));
             return;        
         }
-        
+
         gst_pad_set_chain_function (parser->_audiosink, 
MediaParserGst::cb_chain_func_audio);
         
         g_object_set_data (G_OBJECT (parser->_audiosink), "mediaparser-obj", 
parser);
@@ -442,10 +477,10 @@
         audioinfo->extra.reset(new ExtraInfoGst(caps));
 
         parser->_audioInfo.reset(audioinfo);
+        log_debug(_("MediaParserGst: Linked audio source (type: %s)"), 
caps_name); 
 
-    } else if (g_strrstr (structure_name, "video")) {
-    
-        parser->_videosink = swfdec_gst_connect_sinkpad (parserel, caps);
+    } else {
+        parser->_videosink = swfdec_gst_connect_sinkpad_by_pad (final_pad, 
caps);
         if (!parser->_videosink) {
             log_error(_("MediaParserGst: couldn't link \"fake\" sink."));
             return;        
@@ -459,12 +494,13 @@
         videoinfo->extra.reset(new ExtraInfoGst(caps));
 
         parser->_videoInfo.reset(videoinfo);
-
-    } else {
-        log_error(_("AudioDecoderGst can't handle streams of type %s."),
-                  structure_name);
-        parser->link_to_fakesink(new_pad);
-    }    
+        
+        log_debug(_("MediaParserGst: Linked video source (type: %s)"), 
caps_name); 
+    }
+    
+    if (!already_parsed) {
+        gst_object_unref(GST_OBJECT(final_pad));
+    } 
     
     if (!gst_element_set_state (parser->_bin, GST_STATE_PLAYING) == 
GST_STATE_CHANGE_SUCCESS) {
         throw GnashException(_("MediaParserGst could not change element 
state"));
@@ -541,7 +577,7 @@
     frame->extradata.reset(new EncodedExtraGstData(buffer));
     
 #ifdef GNASH_DEBUG_DATAFLOW
-    log_debug("remembering video buffer with timestamp %d.", frame->timestamp);
+    log_debug("remembering audio buffer with timestamp %d.", frame->timestamp);
 #endif
 
     parser->rememberAudioFrame(frame);

=== modified file 'libmedia/gst/swfdec_codec_gst.c'
--- a/libmedia/gst/swfdec_codec_gst.c   2009-02-25 02:00:44 +0000
+++ b/libmedia/gst/swfdec_codec_gst.c   2009-02-25 20:43:02 +0000
@@ -195,32 +195,43 @@
 }
 
 /*static*/ GstPad *
-swfdec_gst_connect_sinkpad (GstElement *element, GstCaps *caps)
+swfdec_gst_connect_sinkpad_by_pad (GstPad *srcpad, GstCaps *caps)
 {
   GstPadTemplate *tmpl;
-  GstPad *srcpad, *sinkpad;
+  GstPad *sinkpad;
 
-  srcpad = gst_element_get_pad (element, "src");
-  if (srcpad == NULL)
-    return NULL;
   gst_caps_ref (caps);
   tmpl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
   sinkpad = gst_pad_new_from_template (tmpl, "sink");
   g_object_unref (tmpl);
   if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)
     goto error;
-  
-  gst_object_unref (srcpad);
+
   gst_pad_set_active (sinkpad, TRUE);
   return sinkpad;
 
 error:
   SWFDEC_ERROR ("failed to create or link sinkpad");
-  gst_object_unref (srcpad);
   gst_object_unref (sinkpad);
   return NULL;
 }
 
+/*static*/ GstPad *
+swfdec_gst_connect_sinkpad (GstElement *element, GstCaps *caps)
+{
+  GstPad* srcpad;
+  srcpad = gst_element_get_pad (element, "src");
+
+  if (srcpad == NULL)
+    return NULL;
+
+  GstPad* sinkpad = swfdec_gst_connect_sinkpad_by_pad (srcpad, caps);
+  
+  gst_object_unref (srcpad);
+  
+  return sinkpad;
+}
+
 /*** DECODER ***/
 
 static GstFlowReturn

=== modified file 'libmedia/gst/swfdec_codec_gst.h'
--- a/libmedia/gst/swfdec_codec_gst.h   2009-02-25 02:00:44 +0000
+++ b/libmedia/gst/swfdec_codec_gst.h   2009-02-25 20:43:02 +0000
@@ -59,6 +59,7 @@
 GstPad *       swfdec_gst_connect_srcpad (GstElement *element, GstCaps *caps);
 
 GstPad *       swfdec_gst_connect_sinkpad (GstElement *element, GstCaps *caps);
+GstPad *    swfdec_gst_connect_sinkpad_by_pad (GstPad *srcpad, GstCaps *caps);
 
 G_END_DECLS
 #endif


reply via email to

[Prev in Thread] Current Thread [Next in Thread]