diff options
Diffstat (limited to 'src/plugins/gstreamer_extractor.c')
-rw-r--r-- | src/plugins/gstreamer_extractor.c | 160 |
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 | |||
774 | struct 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 | ||
867 | static gboolean | 861 | static 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 | ||
1734 | static void | 1728 | static 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 | ||
1741 | static void | 1738 | static 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. */ |
1753 | static void | 1750 | static 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 | ||
1779 | static int | 1778 | /** |
1780 | initialize (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 | */ | ||
1786 | void | ||
1787 | EXTRACTOR_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 | */ | ||
1824 | void __attribute__ ((constructor)) | ||
1825 | gstreamer_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 | */ | ||
1837 | void | ||
1838 | EXTRACTOR_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 | ||