All pastes #733059 Raw Edit

Something

public text v1 · immutable
·published 2007-10-11 14:25 UTC
rendered paste body
diff -x Makefile -x Makefile.in -u gst/mpegtsparse/mpegtspacketizer.c ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtspacketizer.c
--- gst/mpegtsparse/mpegtspacketizer.c  2007-10-05 16:13:42.000000000 +0200
+++ ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtspacketizer.c 2007-10-05 16:25:10.000000000 +0200
@@ -105,7 +105,8 @@
     packetizer->disposed = TRUE;
   }
 
-  G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose (object);
+  if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose)
+    G_OBJECT_CLASS (mpegts_packetizer_parent_class)->dispose (object);
 }
 
 static gboolean
@@ -128,7 +129,8 @@
       stream_foreach_remove, packetizer);
   g_hash_table_destroy (packetizer->streams);
 
-  G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize (object);
+  if (G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize)
+    G_OBJECT_CLASS (mpegts_packetizer_parent_class)->finalize (object);
 }
 
 static gboolean
@@ -142,20 +144,21 @@
   if (packet->adaptation_field_control == 0x02) {
     /* no payload, adaptation field of 183 bytes */
     if (length != 183) {
-      GST_WARNING ("PID %d afc == 0x%x and length %d != 183",
+      GST_DEBUG ("PID %d afc == 0x%x and length %d != 183",
           packet->pid, packet->adaptation_field_control, length);
     }
   } else if (length > 182) {
-    GST_WARNING ("PID %d afc == 0x%01x and length %d > 182",
+    GST_DEBUG ("PID %d afc == 0x%01x and length %d > 182",
         packet->pid, packet->adaptation_field_control, length);
   }
 
   /* skip the adaptation field body for now */
   if (packet->data + length > packet->data_end) {
-    GST_ERROR ("PID %d afc length overflows the buffer %d",
+    GST_DEBUG ("PID %d afc length overflows the buffer %d",
         packet->pid, length);
     return FALSE;
   }
+  
   packet->data += length;
 
   return TRUE;
@@ -280,7 +283,13 @@
     g_value_unset (&value);
   }
 
-  g_assert (data == end - 4);
+  if (data != end - 4) {
+    /* FIXME: check the CRC before parsing the packet */
+    GST_ERROR ("at the end of PAT data != end - 4");
+    g_value_array_free (pat);
+
+    return NULL;
+  }
 
   return pat;
 }
@@ -307,7 +316,7 @@
         section->pid, section->section_length);
     goto error;
   }
-
+  
   data = GST_BUFFER_DATA (section->buffer);
   end = data + GST_BUFFER_SIZE (section->buffer);
 
diff -x Makefile -x Makefile.in -u gst/mpegtsparse/mpegtsparse.c ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtsparse.c
--- gst/mpegtsparse/mpegtsparse.c       2007-10-05 16:13:42.000000000 +0200
+++ ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtsparse.c      2007-10-05 19:46:01.000000000 +0200
@@ -48,6 +48,7 @@
 {
   gint program_number;
   guint16 pmt_pid;
+  guint16 pcr_pid;
   GObject *pmt_info;
   GHashTable *streams;
   gint patcount;
@@ -83,6 +84,12 @@
     GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
     );
 
+static GstStaticPadTemplate src_template =
+GST_STATIC_PAD_TEMPLATE ("src%d", GST_PAD_SRC,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
+    );
+
 static GstStaticPadTemplate program_template =
 GST_STATIC_PAD_TEMPLATE ("program_%d", GST_PAD_SRC,
     GST_PAD_SOMETIMES,
@@ -123,6 +130,9 @@
     gchar * programs);
 
 static void mpegts_parse_pad_removed (GstElement * element, GstPad * pad);
+static GstPad *mpegts_parse_request_new_pad (GstElement *element,
+    GstPadTemplate *templ, const gchar *name);
+static void mpegts_parse_release_pad (GstElement *element, GstPad *pad);
 static GstFlowReturn mpegts_parse_chain (GstPad * pad, GstBuffer * buf);
 static gboolean mpegts_parse_sink_event (GstPad * pad, GstEvent * event);
 static GstStateChangeReturn mpegts_parse_change_state (GstElement * element,
@@ -140,6 +150,8 @@
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&sink_template));
   gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_template));
+  gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&program_template));
 
   gst_element_class_set_details (element_class, &mpegts_parse_details);
@@ -153,6 +165,8 @@
 
   element_class = GST_ELEMENT_CLASS (klass);
   element_class->pad_removed = mpegts_parse_pad_removed;
+  element_class->request_new_pad = mpegts_parse_request_new_pad;
+  element_class->release_pad = mpegts_parse_release_pad;
   element_class->change_state = mpegts_parse_change_state;
 
   gobject_class = G_OBJECT_CLASS (klass);
@@ -230,7 +244,8 @@
     parse->disposed = TRUE;
   }
 
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  if (G_OBJECT_CLASS (parent_class)->dispose)
+    G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void
@@ -244,7 +259,8 @@
   g_hash_table_destroy (parse->programs);
   g_hash_table_destroy (parse->psi_pids);
 
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
@@ -289,6 +305,7 @@
   program = g_new0 (MpegTSParseProgram, 1);
   program->program_number = program_number;
   program->pmt_pid = pmt_pid;
+  program->pcr_pid = G_MAXUINT16;
   program->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
       NULL, (GDestroyNotify) mpegts_parse_free_stream);
   program->patcount = 1;
@@ -529,6 +546,43 @@
 
   tspad = (MpegTSParsePad *) gst_pad_get_element_private (pad);
   mpegts_parse_destroy_tspad (parse, tspad);
+
+  if (GST_ELEMENT_CLASS (parent_class)->pad_removed)
+    GST_ELEMENT_CLASS (parent_class)->pad_removed (element, pad);
+}
+
+static GstPad *
+mpegts_parse_request_new_pad (GstElement *element, GstPadTemplate *template,
+  const gchar *unused)
+{
+  MpegTSParse *parse;
+  gchar *name;
+  GstPad *pad;
+
+  g_return_val_if_fail (template != NULL, NULL);
+  g_return_val_if_fail (GST_IS_MPEGTS_PARSE (element), NULL);
+
+  parse = GST_MPEGTS_PARSE (element);
+
+  GST_OBJECT_LOCK (element);
+  name = g_strdup_printf ("src%d", parse->req_pads++);
+  GST_OBJECT_UNLOCK (element);
+
+  pad = mpegts_parse_create_tspad (parse, name)->pad;
+  gst_pad_set_active (pad, TRUE);
+  gst_element_add_pad (element, pad);
+
+  return pad;
+}
+
+static void
+mpegts_parse_release_pad (GstElement *element, GstPad *pad)
+{
+  g_return_if_fail (GST_IS_MPEGTS_PARSE (element));
+
+  gst_pad_set_active (pad, FALSE);
+  /* we do the cleanup in GstElement::pad-removed */
+  gst_element_remove_pad (element, pad); 
 }
 
 static GstFlowReturn
@@ -538,11 +592,13 @@
   GstFlowReturn ret = GST_FLOW_NOT_LINKED;
   GHashTable *pad_pids = NULL;
   guint16 pmt_pid = G_MAXUINT16;
+  guint16 pcr_pid = G_MAXUINT16;
 
   if (tspad->program_number != -1) {
     if (tspad->program) {
       pad_pids = tspad->program->streams;
       pmt_pid = tspad->program->pmt_pid;
+      pcr_pid = tspad->program->pcr_pid;
     } else {
       /* there's a program filter on the pad but the PMT for the program has not
        * been parsed yet, ignore the pad until we get a PMT */
@@ -553,13 +609,12 @@
   }
 
   /* FIXME: send all the SI pids not only PAT and PMT */
-  if (pad_pids == NULL || pid == 0 || pid == pmt_pid ||
+  if (pad_pids == NULL || pid == pcr_pid || pid == pmt_pid || pid == 0 ||
       g_hash_table_lookup (pad_pids, GINT_TO_POINTER ((gint) pid)) != NULL) {
     /* push if there's no filter or if the pid is in the filter */
     ret = gst_pad_push (tspad->pad, buffer);
   } else {
     gst_buffer_unref (buffer);
-    /* caps don't include this pid */
     if (gst_pad_is_linked (tspad->pad))
       ret = GST_FLOW_OK;
   }
@@ -586,15 +641,22 @@
   MpegTSParsePad *tspad;
   guint16 pid;
   GstBuffer *buffer;
-  GstFlowReturn ret = GST_FLOW_OK;
+  GstFlowReturn ret;
 
   pid = packet->pid;
   buffer = packet->buffer;
+  /* we have the same caps on all the src pads */
+  gst_buffer_set_caps (buffer,
+    gst_static_pad_template_get_caps (&src_template));
 
   GST_OBJECT_LOCK (parse);
   /* clear tspad->pushed on pads */
   g_list_foreach (GST_ELEMENT_CAST (parse)->srcpads,
       (GFunc) pad_clear_for_push, parse);
+  if (GST_ELEMENT_CAST (parse)->srcpads)
+    ret = GST_FLOW_NOT_LINKED;
+  else
+    ret = GST_FLOW_OK;
   GST_OBJECT_UNLOCK (parse);
 
   iterator = gst_element_iterate_src_pads (GST_ELEMENT_CAST (parse));
@@ -717,6 +779,12 @@
           "program-number", &program_number, "pid", &pid, NULL);
 
       program = mpegts_parse_get_program (parse, program_number);
+      if (program == NULL) {
+        GST_DEBUG_OBJECT (parse, "broken PAT, duplicated entry for program %d",
+          program_number);
+        continue;
+      }
+      
       if (--program->patcount > 0)
         /* the program has been referenced by the new pat, keep it */
         continue;
@@ -790,6 +858,8 @@
   /* activate new pmt */
   program->pmt_info = pmt_info;
   program->pmt_pid = pmt_pid;
+  /* FIXME: check if the pcr pid is changed */
+  program->pcr_pid = pcr_pid;
   mpegts_parse_program_add_stream (parse, program, (guint16) pcr_pid, -1);
 
   for (i = 0; i < new_streams->n_values; ++i) {
@@ -797,6 +867,7 @@
     stream = g_value_get_object (value);
 
     g_object_get (stream, "pid", &pid, "stream-type", &stream_type, NULL);
+    GST_DEBUG_OBJECT (parse, "PMT program %d pid %d", program_number, pid);
     mpegts_parse_program_add_stream (parse, program, (guint16) pid,
         (guint8) stream_type);
   }
diff -x Makefile -x Makefile.in -u gst/mpegtsparse/mpegtsparse.h ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtsparse.h
--- gst/mpegtsparse/mpegtsparse.h       2007-10-01 11:21:19.000000000 +0200
+++ ../gst-plugins-bad-dvb-2/gst/mpegtsparse/mpegtsparse.h      2007-10-11 16:20:30.000000000 +0200
@@ -55,6 +55,7 @@
   GList *pads_to_add;
   GList *pads_to_remove;
   GHashTable *programs;
+  guint req_pads;
 
   GValueArray *pat_info;
   MpegTSPacketizer *packetizer;