gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r23993 - Extractor/src/plugins


From: gnunet
Subject: [GNUnet-SVN] r23993 - Extractor/src/plugins
Date: Tue, 25 Sep 2012 15:57:45 +0200

Author: grothoff
Date: 2012-09-25 15:57:45 +0200 (Tue, 25 Sep 2012)
New Revision: 23993

Modified:
   Extractor/src/plugins/gstreamer_extractor.c
Log:
documenting the code a bit

Modified: Extractor/src/plugins/gstreamer_extractor.c
===================================================================
--- Extractor/src/plugins/gstreamer_extractor.c 2012-09-25 13:20:16 UTC (rev 
23992)
+++ Extractor/src/plugins/gstreamer_extractor.c 2012-09-25 13:57:45 UTC (rev 
23993)
@@ -757,61 +757,181 @@
   };
 
 
+/**
+ *
+ */
 enum CurrentStreamType
 {
+  /**
+   *
+   */
   STREAM_TYPE_NONE = 0,
+
+  /**
+   *
+   */
   STREAM_TYPE_AUDIO = 1,
+
+  /**
+   *
+   */
   STREAM_TYPE_VIDEO = 2,
+
+  /**
+   *
+   */
   STREAM_TYPE_SUBTITLE = 3,
+
+  /**
+   *
+   */
   STREAM_TYPE_CONTAINER = 4,
+
+  /**
+   *
+   */
   STREAM_TYPE_IMAGE = 5
 };
 
 
+/**
+ * Closure we pass when processing a request.
+ */
 struct PrivStruct
 {
+  /**
+   * Tracks the time from the last IO request so that we can decide
+   * to terminate processing if GStreamer just takes far too long.
+   * Values are based on 'g_get_monotonic_time()', in milliseconds.
+   */
+  gint64 last_data_request_time;
+
+  /**
+   * Current read-offset in the 'ec' context (based on our read/seek calls).
+   */
+  guint64 offset;
+
+  /**
+   * Overall size of the file we're processing, UINT64_MAX if unknown.
+   */
+  uint64_t length;
+
+  /**
+   *
+   */
   GstElement *source;
+
+  /**
+   * Extraction context for IO on the underlying data.
+   */
   struct EXTRACTOR_ExtractContext *ec;
-  long length;
-  guint64 offset;
-  int toc_depth;
+
+  /**
+   * Glib main loop.
+   */
+  GMainLoop *loop;
+
+  /**
+   * Discoverer object we are using.
+   */
+  GstDiscoverer *dc;
+
+  /**
+   * Location for building the XML 'table of contents' 
(EXTRACTOR_METATYPE_TOC) for
+   * the input.  Used only during 'send_info'.
+   */
+  gchar *toc;
+
+  /**
+   * Length of the 'toc' string.
+   */
   size_t toc_length;
+
+  /**
+   * Current position (used when creating the 'toc' string).
+   */
   size_t toc_pos;
-  gchar *toc;
+
+  /**
+   *
+   */
+  guint timeout_id;
+
+  /**
+   * Counter used to determine our current depth in the TOC hierarchy.
+   */
+  int toc_depth;
+
+  /**
+   *
+   */
+  enum CurrentStreamType st;
+
+  /**
+   * Last return value from the meta data processor.  Set to
+   * 1 to abort, 0 to continue extracting.
+   */
+  int time_to_leave;
+
+  /**
+   * TOC generation is executed in two phases.  First phase determines
+   * the size of the string and the second phase actually does the
+   * 'printing' (string construction).  This bit is TRUE if we are
+   * in the 'printing' phase.
+   */
   gboolean toc_print_phase;
-  unsigned char time_to_leave;
-  enum CurrentStreamType st;
-  GMainLoop *loop;
-  GstDiscoverer *dc;
-  guint timeout_id;
-  gint64 last_data_request_time;
+
 };
 
 
+/**
+ *
+ */
 static GQuark *audio_quarks;
 
+/**
+ *
+ */
 static GQuark *video_quarks;
 
+/**
+ *
+ */
 static GQuark *subtitle_quarks;
 
+/**
+ *
+ */
 static GQuark duration_quark;
 
 
+/**
+ * Implementation of GstElement's "need-data" callback.  Reads data from
+ * the extraction context and passes it to GStreamer.
+ *
+ * @param appsrc the GstElement for which we are implementing "need-data"
+ * @param size number of bytes requested
+ * @param ps our execution context
+ */
 static void
-feed_data (GstElement * appsrc, guint size, struct PrivStruct * ps)
+feed_data (GstElement * appsrc, 
+          guint size, 
+          struct PrivStruct * ps)
 {
-  long data_len;
+  ssize_t data_len;
   uint8_t *le_data;
   guint accumulated;
   GstMemory *mem;
   GstMapInfo mi;
+  GstBuffer *buffer;
 
   GST_DEBUG ("Request %u bytes", size);
 
   /* Update it now, in case we bail out due to error */
   ps->last_data_request_time = g_get_monotonic_time ();
 
-  if (ps->length > 0 && ps->offset >= ps->length) {
+  if ( (ps->length > 0) && (ps->offset >= ps->length) )
+  {
     /* we are at the EOS, send end-of-stream */
     gst_app_src_end_of_stream (GST_APP_SRC (ps->source));
     return;
@@ -831,7 +951,7 @@
 
   accumulated = 0;
   data_len = 1;
-  while (accumulated < size && data_len > 0)
+  while ( (accumulated < size) && (data_len > 0) )
   {
     data_len = ps->ec->read (ps->ec->cls, (void **) &le_data, size - 
accumulated);
     if (data_len > 0)
@@ -841,9 +961,8 @@
     }
   }
   gst_memory_unmap (mem, &mi);
-  if (data_len > 0)
+  if (size == accumulated)
   {
-    GstBuffer *buffer;
     buffer = gst_buffer_new ();
     gst_buffer_append_memory (buffer, mem);
 
@@ -851,8 +970,8 @@
     GST_BUFFER_OFFSET (buffer) = ps->offset;
     GST_BUFFER_OFFSET_END (buffer) = ps->offset + size;
 
-    GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer,
-        ps->offset, size);
+    GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", 
+              buffer, ps->offset, size);
     gst_app_src_push_buffer (GST_APP_SRC (ps->source), buffer);
     ps->offset += size;
   }
@@ -860,34 +979,44 @@
   {
     gst_memory_unref (mem);
     gst_app_src_end_of_stream (GST_APP_SRC (ps->source));
+    ps->offset = UINT64_MAX; /* set to invalid value */
   }
 
   /* Update it again to account for time we spent fulfilling the request */
   ps->last_data_request_time = g_get_monotonic_time ();
-  return;
 }
 
 
+/**
+ * Implementation of GstElement's "seek-data" callback.  Seeks to a new
+ * position in the extraction context.
+ *
+ * @param appsrc the GstElement for which we are implementing "need-data"
+ * @param position new desired absolute position in the file
+ * @param ps our execution context
+ * @return TRUE if seeking succeeded, FALSE if not
+ */
 static gboolean
-seek_data (GstElement * appsrc, guint64 position, struct PrivStruct * ps)
+seek_data (GstElement * appsrc, 
+          guint64 position, 
+          struct PrivStruct * ps)
 {
   GST_DEBUG ("seek to offset %" G_GUINT64_FORMAT, position);
   ps->offset = ps->ec->seek (ps->ec->cls, position, SEEK_SET);
-
   ps->last_data_request_time = g_get_monotonic_time ();
-  return ps->offset >= 0;
+  return ps->offset == position;
 }
 
 
+/**
+ * FIXME
+ * 
+ * @param field_id FIXME
+ * @param value FIXME
+ * @param user_data our 'struct PrivStruct'
+ * @return TRUE to continue processing, FALSE to abort
+ */
 static gboolean
-_run_async (struct PrivStruct * ps)
-{
-  gst_discoverer_discover_uri_async (ps->dc, "appsrc://");
-  return FALSE;
-}
-
-
-static gboolean
 send_structure_foreach (GQuark field_id, 
                        const GValue *value,
                        gpointer user_data)
@@ -922,7 +1051,6 @@
     break;
   }
 
-
   switch (G_VALUE_TYPE (value))
   {
   case G_TYPE_STRING:
@@ -948,7 +1076,7 @@
     str = NULL;
     break;
   }
-  if (NULL != str)
+  if (NULL != str) 
   {
     unsigned int i;
 
@@ -969,16 +1097,24 @@
     gchar *senddata = g_strdup_printf ("%s=%s", field_name, str);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
                                      EXTRACTOR_METATYPE_UNKNOWN, 
EXTRACTOR_METAFORMAT_UTF8, "text/plain",
-                                     (const char *) senddata, strlen 
(senddata) + 1);
+                                     (const char *) senddata, 
+                                     strlen (senddata) + 1);
     g_free (senddata);
   }
   g_free (str);
 
-  return !ps->time_to_leave;
+  return ! ps->time_to_leave;
 }
 
 
-static int
+/**
+ * FIXME
+ * 
+ * @param info FIXME
+ * @param ps processing context
+ * @return FALSE to continue processing, TRUE to abort
+ */
+static gboolean
 send_audio_info (GstDiscovererAudioInfo *info, 
                 struct PrivStruct *ps)
 {
@@ -1059,15 +1195,24 @@
 }
 
 
+/**
+ * FIXME
+ * 
+ * @param info FIXME
+ * @param ps processing context
+ * @return FALSE to continue processing, TRUE to abort
+ */
 static int
-send_video_info (GstDiscovererVideoInfo *info, struct PrivStruct *ps)
+send_video_info (GstDiscovererVideoInfo *info, 
+                struct PrivStruct *ps)
 {
   gchar *tmp;
-  guint u, u2;
+  guint u;
+  guint u2;
 
   u = gst_discoverer_video_info_get_width (info);
   u2 = gst_discoverer_video_info_get_height (info);
-  if (u > 0 && u2 > 0)
+  if ( (u > 0) && (u2 > 0) )
   {
     tmp = g_strdup_printf ("%ux%u", u, u2);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
@@ -1092,7 +1237,7 @@
 
   u = gst_discoverer_video_info_get_framerate_num (info);
   u2 = gst_discoverer_video_info_get_framerate_denom (info);
-  if (u > 0 && u2 > 0)
+  if ( (u > 0) && (u2 > 0) )
   {
     tmp = g_strdup_printf ("%u/%u", u, u2);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
@@ -1105,7 +1250,7 @@
 
   u = gst_discoverer_video_info_get_par_num (info);
   u2 = gst_discoverer_video_info_get_par_denom (info);
-  if (u > 0 && u2 > 0)
+  if ( (u > 0) && (u2 > 0) )
   {
     tmp = g_strdup_printf ("%u/%u", u, u2);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
@@ -1119,7 +1264,7 @@
   /* gst_discoverer_video_info_is_interlaced (info) I don't trust it... */
 
   u = gst_discoverer_video_info_get_bitrate (info);
-  if (u > 0 && u2 > 0)
+  if (u > 0)
   {
     tmp = g_strdup_printf ("%u", u);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
@@ -1131,7 +1276,7 @@
   }
 
   u = gst_discoverer_video_info_get_max_bitrate (info);
-  if (u > 0 && u2 > 0)
+  if (u > 0)
   {
     tmp = g_strdup_printf ("%u", u);
     ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
@@ -1146,18 +1291,27 @@
 }
 
 
+/**
+ * FIXME
+ * 
+ * @param info FIXME
+ * @param ps processing context
+ * @return FALSE to continue processing, TRUE to abort
+ */
 static int
-send_subtitle_info (GstDiscovererSubtitleInfo *info, struct PrivStruct *ps)
+send_subtitle_info (GstDiscovererSubtitleInfo *info, 
+                   struct PrivStruct *ps)
 {
   const gchar *ctmp;
 
   ctmp = gst_discoverer_subtitle_info_get_language (info);
-  if (ctmp)
-    if ((ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
-        EXTRACTOR_METATYPE_SUBTITLE_LANGUAGE, EXTRACTOR_METAFORMAT_UTF8, 
"text/plain",
-        (const char *) ctmp, strlen (ctmp) + 1)))
-      return TRUE;
-
+  if ( (NULL != ctmp) &&
+       (0 != (ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
+                                               
EXTRACTOR_METATYPE_SUBTITLE_LANGUAGE,
+                                               EXTRACTOR_METAFORMAT_UTF8,
+                                               "text/plain",
+                                               (const char *) ctmp, strlen 
(ctmp) + 1))) )
+    return TRUE;
   return FALSE;
 }
 
@@ -1167,11 +1321,11 @@
                  const gchar * tag,
                  gpointer user_data)
 {
+  static struct KnownTag unknown_tag = {NULL, EXTRACTOR_METATYPE_UNKNOWN};
   struct PrivStruct *ps = user_data;
   size_t i;
   size_t tagl = sizeof (__known_tags) / sizeof (struct KnownTag);
-  struct KnownTag *kt = NULL;
-  struct KnownTag unknown_tag = {NULL, EXTRACTOR_METATYPE_UNKNOWN};
+  const struct KnownTag *kt = NULL;
   GQuark tag_quark;
   guint vallen;
   GstSample *sample;
@@ -1517,12 +1671,13 @@
 
 
 static void
-send_streams (GstDiscovererStreamInfo *info, struct PrivStruct *ps)
+send_streams (GstDiscovererStreamInfo *info, 
+             struct PrivStruct *ps)
 {
+  GstDiscovererStreamInfo *next;
+
   while ( (NULL != info) && (! ps->time_to_leave) )
   {
-    GstDiscovererStreamInfo *next;
-
     send_stream_info (info, ps);
     next = gst_discoverer_stream_info_get_next (info);
     gst_discoverer_stream_info_unref (info);
@@ -1531,6 +1686,13 @@
 }
 
 
+/**
+ * Callback used to construct the XML 'toc'.
+ *
+ * @param tags  FIXME
+ * @param tag FIXME 
+ * @param user_data the 'struct PrivStruct' with the 'toc' string we are 
assembling
+ */
 static void
 send_toc_tags_foreach (const GstTagList * tags,
                       const gchar * tag,
@@ -1588,6 +1750,12 @@
 }
 
 
+/**
+ * Top-level callback used to construct the XML 'toc'.
+ *
+ * @param data the GstTocEntry we're processing
+ * @param user_data the 'struct PrivStruct' with the 'toc' string we are 
assembling
+ */
 static void
 send_toc_foreach (gpointer data, gpointer user_data)
 {
@@ -1595,68 +1763,72 @@
   struct PrivStruct *ps = user_data;
   GstTagList *tags;
   GList *subentries;
-  gint64 start, stop;
+  gint64 start;
+  gint64 stop;
   GstTocEntryType entype;
+  gchar *s;
 
   entype = gst_toc_entry_get_entry_type (entry);
-  if (GST_TOC_ENTRY_TYPE_INVALID != entype)
-  {
-    char *s;
-
-    gst_toc_entry_get_start_stop_times (entry, &start, &stop);
-    s = g_strdup_printf ("%*.*s<%s start=\"%" GST_TIME_FORMAT "\" stop=\"%"
-      GST_TIME_FORMAT"\">\n", ps->toc_depth * 2, ps->toc_depth * 2, " ",
-      gst_toc_entry_type_get_nick (entype), GST_TIME_ARGS (start),
-      GST_TIME_ARGS (stop));
-    if (ps->toc_print_phase)
-      ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos, "%s", s);
-    else
-      ps->toc_length += strlen (s);
-    g_free (s);
-    ps->toc_depth++;
-    tags = gst_toc_entry_get_tags (entry);
-    if (tags)
+  if (GST_TOC_ENTRY_TYPE_INVALID == entype)
+    return;
+  gst_toc_entry_get_start_stop_times (entry, &start, &stop);
+  s = g_strdup_printf ("%*.*s<%s start=\"%" GST_TIME_FORMAT "\" stop=\"%"
+                      GST_TIME_FORMAT"\">\n", ps->toc_depth * 2, ps->toc_depth 
* 2, " ",
+                      gst_toc_entry_type_get_nick (entype), GST_TIME_ARGS 
(start),
+                      GST_TIME_ARGS (stop));
+  if (ps->toc_print_phase)
+    ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos, "%s", s);
+  else
+    ps->toc_length += strlen (s);
+  g_free (s);
+  ps->toc_depth++;
+  tags = gst_toc_entry_get_tags (entry);
+  if (tags)
     {
       if (ps->toc_print_phase)
         ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos,
-        "%*.*s<tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ");
+                                  "%*.*s<tags>\n", ps->toc_depth * 2, 
ps->toc_depth * 2, " ");
       else
         ps->toc_length += strlen ("<tags>\n") + ps->toc_depth * 2;
       ps->toc_depth++;
-      gst_tag_list_foreach (tags, send_toc_tags_foreach, ps);
+      gst_tag_list_foreach (tags, &send_toc_tags_foreach, ps);
       ps->toc_depth--;
       if (ps->toc_print_phase)
         ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos,
-        "%*.*s</tags>\n", ps->toc_depth * 2, ps->toc_depth * 2, " ");
+                                  "%*.*s</tags>\n", ps->toc_depth * 2, 
ps->toc_depth * 2, " ");
       else
         ps->toc_length += strlen ("</tags>\n") + ps->toc_depth * 2;
     }
-
-    subentries = gst_toc_entry_get_sub_entries (entry);
-    g_list_foreach (subentries, send_toc_foreach, ps);
-    ps->toc_depth--;
-
-    s = g_strdup_printf ("%*.*s</%s>\n", ps->toc_depth * 2, ps->toc_depth * 2, 
" ",
-      gst_toc_entry_type_get_nick (entype));
-    if (ps->toc_print_phase)
-      ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos, "%s", s);
-    else
-      ps->toc_length += strlen (s);
-    g_free (s);
-  }
+  
+  subentries = gst_toc_entry_get_sub_entries (entry);
+  g_list_foreach (subentries, send_toc_foreach, ps);
+  ps->toc_depth--;
+  
+  s = g_strdup_printf ("%*.*s</%s>\n", ps->toc_depth * 2, ps->toc_depth * 2, " 
",
+                      gst_toc_entry_type_get_nick (entype));
+  if (ps->toc_print_phase)
+    ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos, "%s", s);
+  else
+    ps->toc_length += strlen (s);
+  g_free (s);
 }
 
 
+/**
+ * XML header for the table-of-contents meta data.
+ */
 #define TOC_XML_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
 
 
 static void
-send_info (GstDiscovererInfo * info, struct PrivStruct *ps)
+send_info (GstDiscovererInfo * info, 
+          struct PrivStruct *ps)
 {
   const GstToc *toc;
   gchar *s;
   GstDiscovererStreamInfo *sinfo;
   GstClockTime duration;
+  GList *entries;
 
   duration = gst_discoverer_info_get_duration (info);
   if ((GST_CLOCK_TIME_IS_VALID (duration)) && (duration > 0))
@@ -1684,12 +1856,10 @@
 
   if ((toc = gst_discoverer_info_get_toc (info)))
   {
-    GList *entries;
-
     entries = gst_toc_get_entries (toc);
     ps->toc_print_phase = FALSE;
     ps->toc_length = 0;
-    g_list_foreach (entries, send_toc_foreach, ps);
+    g_list_foreach (entries, &send_toc_foreach, ps);
 
     if (ps->toc_length > 0)
     {
@@ -1697,18 +1867,24 @@
       ps->toc_length += 1 + strlen (TOC_XML_HEADER);
       ps->toc = g_malloc (ps->toc_length);
       ps->toc_pos = 0;
-      ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], ps->toc_length - 
ps->toc_pos, "%s", TOC_XML_HEADER);
-      g_list_foreach (entries, send_toc_foreach, ps);
+      ps->toc_pos += g_snprintf (&ps->toc[ps->toc_pos], 
+                                ps->toc_length - ps->toc_pos, 
+                                "%s", 
+                                TOC_XML_HEADER);
+      g_list_foreach (entries, &send_toc_foreach, ps);
       ps->toc[ps->toc_length - 1] = '\0';
       ps->time_to_leave = ps->ec->proc (ps->ec->cls, "gstreamer",
-          EXTRACTOR_METATYPE_TOC, EXTRACTOR_METAFORMAT_C_STRING, 
"application/xml",
-          (const char *) ps->toc, ps->toc_length);
+                                       EXTRACTOR_METATYPE_TOC, 
+                                       EXTRACTOR_METAFORMAT_C_STRING, 
+                                       "application/xml",
+                                       (const char *) ps->toc,
+                                       ps->toc_length);
       g_free (ps->toc);
       ps->toc = NULL;
     }
   }
 
-  if (ps->time_to_leave)
+  if (0 != ps->time_to_leave)
     return;
 
   sinfo = gst_discoverer_info_get_stream_info (info);
@@ -1717,7 +1893,8 @@
 
 
 static void
-send_discovered_info (GstDiscovererInfo * info, struct PrivStruct * ps)
+send_discovered_info (GstDiscovererInfo * info, 
+                     struct PrivStruct * ps)
 {
   GstDiscovererResult result;
 
@@ -1765,6 +1942,7 @@
   g_main_loop_quit (ps->loop);
 }
 
+
 static gboolean
 _data_timeout (struct PrivStruct *ps)
 {
@@ -1780,11 +1958,17 @@
   return TRUE;
 }
 
+
 /**
  * This callback is called when discoverer has constructed a source object to
  * read from. Since we provided the appsrc:// uri to discoverer, this will be
  * the appsrc that we must handle. We set up some signals - one to push data
- * into appsrc and one to perform a seek. */
+ * into appsrc and one to perform a seek. 
+ *
+ * @param dc
+ * @param source
+ * @param ps 
+ */
 static void
 _source_setup (GstDiscoverer * dc, 
               GstElement * source,
@@ -1816,6 +2000,20 @@
 
 
 /**
+ * Task run from the main loop to call 'gst_discoverer_uri_async'.
+ *
+ * @param ps our execution context
+ * @return FALSE (always)
+ */
+static gboolean
+_run_async (struct PrivStruct * ps)
+{
+  gst_discoverer_discover_uri_async (ps->dc, "appsrc://");
+  return FALSE;
+}
+
+
+/**
  * This will be the main method of your plugin.
  * Describe a bit what it does here.
  *




reply via email to

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