aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-09-04 12:31:32 +0000
committerChristian Grothoff <christian@grothoff.org>2012-09-04 12:31:32 +0000
commitf81422c103c166b7389ba1e5d98ceaaca5417039 (patch)
tree4984ac84fa26760a5b0a927b6806112da35d98c7
parent2ceacf7a1ed5fc789297272bd1db4aa8b1376fe3 (diff)
downloadlibextractor-f81422c103c166b7389ba1e5d98ceaaca5417039.tar.gz
libextractor-f81422c103c166b7389ba1e5d98ceaaca5417039.zip
refactoring initialization code to use constructor for non-mutable statics and using fresh gstreamer object for each file
-rw-r--r--src/plugins/gstreamer_extractor.c160
1 files changed, 76 insertions, 84 deletions
diff --git a/src/plugins/gstreamer_extractor.c b/src/plugins/gstreamer_extractor.c
index 867fdfe..bb00746 100644
--- a/src/plugins/gstreamer_extractor.c
+++ b/src/plugins/gstreamer_extractor.c
@@ -768,14 +768,8 @@ struct PrivStruct
768 gboolean toc_print_phase; 768 gboolean toc_print_phase;
769 unsigned char time_to_leave; 769 unsigned char time_to_leave;
770 enum CurrentStreamType st; 770 enum CurrentStreamType st;
771};
772
773
774struct InitData
775{
776 GMainLoop *loop; 771 GMainLoop *loop;
777 GstDiscoverer *dc; 772 GstDiscoverer *dc;
778 struct PrivStruct *ps;
779}; 773};
780 774
781 775
@@ -865,9 +859,9 @@ seek_data (GstElement * appsrc, guint64 position, struct PrivStruct * ps)
865 859
866 860
867static gboolean 861static gboolean
868_run_async (struct InitData * id) 862_run_async (struct PrivStruct * ps)
869{ 863{
870 gst_discoverer_discover_uri_async (id->dc, "appsrc://"); 864 gst_discoverer_discover_uri_async (ps->dc, "appsrc://");
871 return FALSE; 865 return FALSE;
872} 866}
873 867
@@ -1599,7 +1593,7 @@ send_toc_foreach (gpointer data, gpointer user_data)
1599 else 1593 else
1600 ps->toc_length += strlen (s); 1594 ps->toc_length += strlen (s);
1601 g_free (s); 1595 g_free (s);
1602 ps->toc_depth += 1; 1596 ps->toc_depth++;
1603 tags = gst_toc_entry_get_tags (entry); 1597 tags = gst_toc_entry_get_tags (entry);
1604 if (tags) 1598 if (tags)
1605 { 1599 {
@@ -1608,9 +1602,9 @@ send_toc_foreach (gpointer data, gpointer user_data)
1608 "%*.*s<tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " "); 1602 "%*.*s<tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ");
1609 else 1603 else
1610 ps->toc_length += strlen ("<tags>\n") + ps->toc_depth * 2; 1604 ps->toc_length += strlen ("<tags>\n") + ps->toc_depth * 2;
1611 ps->toc_depth += 1; 1605 ps->toc_depth++;
1612 gst_tag_list_foreach (tags, send_toc_tags_foreach, ps); 1606 gst_tag_list_foreach (tags, send_toc_tags_foreach, ps);
1613 ps->toc_depth -= 1; 1607 ps->toc_depth--;
1614 if (ps->toc_print_phase) 1608 if (ps->toc_print_phase)
1615 ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - ps->toc_pos, 1609 ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - ps->toc_pos,
1616 "%*.*s</tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " "); 1610 "%*.*s</tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ");
@@ -1620,7 +1614,7 @@ send_toc_foreach (gpointer data, gpointer user_data)
1620 1614
1621 subentries = gst_toc_entry_get_sub_entries (entry); 1615 subentries = gst_toc_entry_get_sub_entries (entry);
1622 g_list_foreach (subentries, send_toc_foreach, ps); 1616 g_list_foreach (subentries, send_toc_foreach, ps);
1623 ps->toc_depth -= 1; 1617 ps->toc_depth--;
1624 1618
1625 s = g_strdup_printf ("%*.*s</%s>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ", 1619 s = g_strdup_printf ("%*.*s</%s>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ",
1626 gst_toc_entry_type_get_nick (entype)); 1620 gst_toc_entry_type_get_nick (entype));
@@ -1713,35 +1707,38 @@ send_discovered_info (GstDiscovererInfo * info, struct PrivStruct * ps)
1713 result = gst_discoverer_info_get_result (info); 1707 result = gst_discoverer_info_get_result (info);
1714 1708
1715 switch (result) 1709 switch (result)
1716 { 1710 {
1717 case GST_DISCOVERER_OK: 1711 case GST_DISCOVERER_OK:
1718 break; 1712 break;
1719 case GST_DISCOVERER_URI_INVALID: 1713 case GST_DISCOVERER_URI_INVALID:
1720 break; 1714 break;
1721 case GST_DISCOVERER_ERROR: 1715 case GST_DISCOVERER_ERROR:
1722 break; 1716 break;
1723 case GST_DISCOVERER_TIMEOUT: 1717 case GST_DISCOVERER_TIMEOUT:
1724 break; 1718 break;
1725 case GST_DISCOVERER_BUSY: 1719 case GST_DISCOVERER_BUSY:
1726 break; 1720 break;
1727 case GST_DISCOVERER_MISSING_PLUGINS: 1721 case GST_DISCOVERER_MISSING_PLUGINS:
1728 break; 1722 break;
1729 } 1723 }
1730 send_info (info, ps); 1724 send_info (info, ps);
1731} 1725}
1732 1726
1733 1727
1734static void 1728static void
1735_new_discovered_uri (GstDiscoverer * dc, GstDiscovererInfo * info, GError * err, struct PrivStruct * ps) 1729_new_discovered_uri (GstDiscoverer * dc,
1730 GstDiscovererInfo * info,
1731 GError * err,
1732 struct PrivStruct *ps)
1736{ 1733{
1737 send_discovered_info (info, ps); 1734 send_discovered_info (info, ps);
1738} 1735}
1739 1736
1740 1737
1741static void 1738static void
1742_discoverer_finished (GstDiscoverer * dc, struct InitData * id) 1739_discoverer_finished (GstDiscoverer * dc, struct PrivStruct *ps)
1743{ 1740{
1744 g_main_loop_quit (id->loop); 1741 g_main_loop_quit (ps->loop);
1745} 1742}
1746 1743
1747 1744
@@ -1751,7 +1748,9 @@ _discoverer_finished (GstDiscoverer * dc, struct InitData * id)
1751 * the appsrc that we must handle. We set up some signals - one to push data 1748 * the appsrc that we must handle. We set up some signals - one to push data
1752 * into appsrc and one to perform a seek. */ 1749 * into appsrc and one to perform a seek. */
1753static void 1750static void
1754_source_setup (GstDiscoverer * dc, GstElement * source, struct PrivStruct * ps) 1751_source_setup (GstDiscoverer * dc,
1752 GstElement * source,
1753 struct PrivStruct *ps)
1755{ 1754{
1756 if (ps->source) 1755 if (ps->source)
1757 gst_object_unref (GST_OBJECT (ps->source)); 1756 gst_object_unref (GST_OBJECT (ps->source));
@@ -1776,15 +1775,59 @@ _source_setup (GstDiscoverer * dc, GstElement * source, struct PrivStruct * ps)
1776} 1775}
1777 1776
1778 1777
1779static int 1778/**
1780initialize (struct InitData *id, struct PrivStruct *ps) 1779 * This will be the main method of your plugin.
1780 * Describe a bit what it does here.
1781 *
1782 * @param ec extraction context, here you get the API
1783 * for accessing the file data and for returning
1784 * meta data
1785 */
1786void
1787EXTRACTOR_gstreamer_extract_method (struct EXTRACTOR_ExtractContext *ec)
1781{ 1788{
1789 struct PrivStruct ps;
1782 GError *err = NULL; 1790 GError *err = NULL;
1783 gint timeout = 10;
1784 1791
1792 memset (&ps, 0, sizeof (ps));
1793 ps.dc = gst_discoverer_new (10 * GST_SECOND, &err);
1794 if (NULL == ps.dc)
1795 {
1796 g_print ("Error initializing: %s\n", err->message);
1797 if (NULL != err)
1798 g_error_free (err);
1799 return;
1800 }
1801 if (NULL != err)
1802 g_error_free (err);
1803 /* connect signals */
1804 g_signal_connect (ps.dc, "discovered", G_CALLBACK (_new_discovered_uri), &ps);
1805 g_signal_connect (ps.dc, "finished", G_CALLBACK (_discoverer_finished), &ps);
1806 g_signal_connect (ps.dc, "source-setup", G_CALLBACK (_source_setup), &ps);
1807 ps.loop = g_main_loop_new (NULL, TRUE);
1808 ps.ec = ec;
1809 ps.length = ps.ec->get_size (ps.ec->cls);
1810 if (ps.length == UINT_MAX)
1811 ps.length = 0;
1812 gst_discoverer_start (ps.dc);
1813 g_psle_add ((GSourceFunc) &_run_async, &ps);
1814 g_main_loop_run (ps.loop);
1815 gst_discoverer_stop (ps.dc);
1816 g_object_unref (ps.dc);
1817 g_object_unref (ps.loop);
1818}
1819
1820
1821/**
1822 * Initialize glib and globals.
1823 */
1824void __attribute__ ((constructor))
1825gstreamer_init ()
1826{
1785 gst_init (NULL, NULL); 1827 gst_init (NULL, NULL);
1786 GST_DEBUG_CATEGORY_INIT (gstreamer_extractor, "GstExtractor", 1828 GST_DEBUG_CATEGORY_INIT (gstreamer_extractor, "GstExtractor",
1787 0, "GStreamer-based libextractor plugin"); 1829 0, "GStreamer-based libextractor plugin");
1830
1788 audio_quarks = g_new0 (GQuark, 4); 1831 audio_quarks = g_new0 (GQuark, 4);
1789 audio_quarks[0] = g_quark_from_string ("rate"); 1832 audio_quarks[0] = g_quark_from_string ("rate");
1790 audio_quarks[1] = g_quark_from_string ("channels"); 1833 audio_quarks[1] = g_quark_from_string ("channels");
@@ -1804,57 +1847,6 @@ initialize (struct InitData *id, struct PrivStruct *ps)
1804 subtitle_quarks[1] = g_quark_from_string (NULL); 1847 subtitle_quarks[1] = g_quark_from_string (NULL);
1805 1848
1806 duration_quark = g_quark_from_string ("duration"); 1849 duration_quark = g_quark_from_string ("duration");
1807
1808 id->dc = gst_discoverer_new (timeout * GST_SECOND, &err);
1809 if (NULL == id->dc)
1810 {
1811 g_print ("Error initializing: %s\n", err->message);
1812 return FALSE;
1813 }
1814 if (err)
1815 g_error_free (err);
1816 /* connect signals */
1817 g_signal_connect (id->dc, "discovered", G_CALLBACK (_new_discovered_uri), ps);
1818 g_signal_connect (id->dc, "finished", G_CALLBACK (_discoverer_finished), id);
1819 g_signal_connect (id->dc, "source-setup", G_CALLBACK (_source_setup), ps);
1820
1821 id->loop = g_main_loop_new (NULL, TRUE);
1822
1823 id->ps = ps;
1824
1825 return TRUE;
1826}
1827
1828
1829/**
1830 * This will be the main method of your plugin.
1831 * Describe a bit what it does here.
1832 *
1833 * @param ec extraction context, here you get the API
1834 * for accessing the file data and for returning
1835 * meta data
1836 */
1837void
1838EXTRACTOR_gstreamer_extract_method (struct EXTRACTOR_ExtractContext *ec)
1839{
1840 static int initialized = FALSE;
1841 static struct PrivStruct ps;
1842 static struct InitData id;
1843
1844 if ( (! initialized) &&
1845 (! (initialized = initialize (&id, &ps))) )
1846 return;
1847
1848 memset (&ps, 0, sizeof (ps));
1849 ps.ec = ec;
1850 ps.length = ps.ec->get_size (ps.ec->cls);
1851 if (ps.length == UINT_MAX)
1852 ps.length = 0;
1853
1854 gst_discoverer_start (id.dc);
1855 g_idle_add ((GSourceFunc) &_run_async, &id);
1856 g_main_loop_run (id.loop);
1857 gst_discoverer_stop (id.dc);
1858} 1850}
1859 1851
1860 1852