LCOV - code coverage report
Current view: top level - gst/mpegdemux - gstmpegtsdemux.c (source / functions) Hit Total Coverage
Test: GStreamer Bad Plug-ins 0.10.21.1 Lines: 90 1311 6.9 %
Date: 2011-03-25 Functions: 8 34 23.5 %
Branches: 15 1281 1.2 %

           Branch data     Line data    Source code
       1                 :            :  /*
       2                 :            :   * This library is licensed under 2 different licenses and you
       3                 :            :   * can choose to use it under the terms of either one of them. The
       4                 :            :   * two licenses are the MPL 1.1 and the LGPL.
       5                 :            :   *
       6                 :            :   * MPL:
       7                 :            :   *
       8                 :            :   * The contents of this file are subject to the Mozilla Public License
       9                 :            :   * Version 1.1 (the "License"); you may not use this file except in
      10                 :            :   * compliance with the License. You may obtain a copy of the License at
      11                 :            :   * http://www.mozilla.org/MPL/.
      12                 :            :   *
      13                 :            :   * Software distributed under the License is distributed on an "AS IS"
      14                 :            :   * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
      15                 :            :   * License for the specific language governing rights and limitations
      16                 :            :   * under the License.
      17                 :            :   *
      18                 :            :   * LGPL:
      19                 :            :   *
      20                 :            :   * This library is free software; you can redistribute it and/or
      21                 :            :   * modify it under the terms of the GNU Library General Public
      22                 :            :   * License as published by the Free Software Foundation; either
      23                 :            :   * version 2 of the License, or (at your option) any later version.
      24                 :            :   *
      25                 :            :   * This library is distributed in the hope that it will be useful,
      26                 :            :   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      27                 :            :   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      28                 :            :   * Library General Public License for more details.
      29                 :            :   *
      30                 :            :   * You should have received a copy of the GNU Library General Public
      31                 :            :   * License along with this library; if not, write to the
      32                 :            :   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      33                 :            :   * Boston, MA 02111-1307, USA.
      34                 :            :   *
      35                 :            :   * The Original Code is Fluendo MPEG Demuxer plugin.
      36                 :            :   *
      37                 :            :   * The Initial Developer of the Original Code is Fluendo, S.A.
      38                 :            :   * Portions created by Fluendo, S.L. are Copyright (C) 2005,2006,2007,2008,2009
      39                 :            :   * Fluendo, S.A. All Rights Reserved.
      40                 :            :   *
      41                 :            :   * Contributor(s): Wim Taymans <wim@fluendo.com>
      42                 :            :   */
      43                 :            : 
      44                 :            : #ifdef HAVE_CONFIG_H
      45                 :            : #include "config.h"
      46                 :            : #endif
      47                 :            : 
      48                 :            : #include <string.h>
      49                 :            : #include <stdlib.h>
      50                 :            : 
      51                 :            : #include <gst/tag/tag.h>
      52                 :            : 
      53                 :            : #include "gstmpegdefs.h"
      54                 :            : #include "gstmpegtsdemux.h"
      55                 :            : #include "flutspatinfo.h"
      56                 :            : #include "flutspmtinfo.h"
      57                 :            : 
      58                 :            : GST_DEBUG_CATEGORY_STATIC (gstmpegtsdemux_debug);
      59                 :            : #define GST_CAT_DEFAULT (gstmpegtsdemux_debug)
      60                 :            : 
      61                 :            : /* elementfactory information */
      62                 :            : 
      63                 :            : #ifndef __always_inline
      64                 :            : #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
      65                 :            : #define __always_inline inline __attribute__((always_inline))
      66                 :            : #else
      67                 :            : #define __always_inline inline
      68                 :            : #endif
      69                 :            : #endif
      70                 :            : 
      71                 :            : #ifndef DISABLE_INLINE
      72                 :            : #define FORCE_INLINE __always_inline
      73                 :            : #else
      74                 :            : #define FORCE_INLINE
      75                 :            : #endif
      76                 :            : 
      77                 :            : /* MPEG2Demux signals and args */
      78                 :            : enum
      79                 :            : {
      80                 :            :   /* FILL ME */
      81                 :            :   LAST_SIGNAL
      82                 :            : };
      83                 :            : 
      84                 :            : #define DEFAULT_PROP_ES_PIDS        ""
      85                 :            : #define DEFAULT_PROP_CHECK_CRC      TRUE
      86                 :            : #define DEFAULT_PROP_PROGRAM_NUMBER -1
      87                 :            : 
      88                 :            : /* latency in mseconds */
      89                 :            : #define TS_LATENCY 700
      90                 :            : 
      91                 :            : enum
      92                 :            : {
      93                 :            :   PROP_0,
      94                 :            :   PROP_ES_PIDS,
      95                 :            :   PROP_CHECK_CRC,
      96                 :            :   PROP_PROGRAM_NUMBER,
      97                 :            :   PROP_PAT_INFO,
      98                 :            :   PROP_PMT_INFO,
      99                 :            : };
     100                 :            : 
     101                 :            : #define GSTTIME_TO_BYTES(time) \
     102                 :            :   ((time != -1) ? gst_util_uint64_scale (MAX(0,(gint64) ((time))), \
     103                 :            :   demux->bitrate, GST_SECOND) : -1)
     104                 :            : #define BYTES_TO_GSTTIME(bytes) \
     105                 :            :   ((bytes != -1) ? (gst_util_uint64_scale (bytes, GST_SECOND, \
     106                 :            :   demux->bitrate)) : -1)
     107                 :            : 
     108                 :            : #define VIDEO_CAPS \
     109                 :            :   GST_STATIC_CAPS (\
     110                 :            :     "video/mpeg, " \
     111                 :            :       "mpegversion = (int) { 1, 2, 4 }, " \
     112                 :            :       "systemstream = (boolean) FALSE; " \
     113                 :            :     "video/x-h264;" \
     114                 :            :     "video/x-dirac;" \
     115                 :            :     "video/x-wmv," \
     116                 :            :       "wmvversion = (int) 3, " \
     117                 :            :       "format = (fourcc) WVC1" \
     118                 :            :   )
     119                 :            : 
     120                 :            : #define AUDIO_CAPS \
     121                 :            :   GST_STATIC_CAPS ( \
     122                 :            :     "audio/mpeg, " \
     123                 :            :       "mpegversion = (int) { 1, 4 };" \
     124                 :            :     "audio/x-lpcm, " \
     125                 :            :       "width = (int) { 16, 20, 24 }, " \
     126                 :            :       "rate = (int) { 48000, 96000 }, " \
     127                 :            :       "channels = (int) [ 1, 8 ], " \
     128                 :            :       "dynamic_range = (int) [ 0, 255 ], " \
     129                 :            :       "emphasis = (boolean) { FALSE, TRUE }, " \
     130                 :            :       "mute = (boolean) { FALSE, TRUE }; " \
     131                 :            :     "audio/x-ac3; audio/x-eac3;" \
     132                 :            :     "audio/x-dts;" \
     133                 :            :     "audio/x-private-ts-lpcm" \
     134                 :            :   )
     135                 :            : 
     136                 :            : /* Can also use the subpicture pads for text subtitles? */
     137                 :            : #define SUBPICTURE_CAPS \
     138                 :            :     GST_STATIC_CAPS ("subpicture/x-pgs; video/x-dvd-subpicture")
     139                 :            : 
     140                 :            : static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     141                 :            :     GST_PAD_SINK,
     142                 :            :     GST_PAD_ALWAYS,
     143                 :            :     GST_STATIC_CAPS ("video/mpegts")
     144                 :            :     );
     145                 :            : 
     146                 :            : static GstStaticPadTemplate video_template =
     147                 :            : GST_STATIC_PAD_TEMPLATE ("video_%04x",
     148                 :            :     GST_PAD_SRC,
     149                 :            :     GST_PAD_SOMETIMES,
     150                 :            :     VIDEO_CAPS);
     151                 :            : 
     152                 :            : static GstStaticPadTemplate audio_template =
     153                 :            : GST_STATIC_PAD_TEMPLATE ("audio_%04x",
     154                 :            :     GST_PAD_SRC,
     155                 :            :     GST_PAD_SOMETIMES,
     156                 :            :     AUDIO_CAPS);
     157                 :            : 
     158                 :            : static GstStaticPadTemplate subpicture_template =
     159                 :            : GST_STATIC_PAD_TEMPLATE ("subpicture_%04x",
     160                 :            :     GST_PAD_SRC,
     161                 :            :     GST_PAD_SOMETIMES,
     162                 :            :     SUBPICTURE_CAPS);
     163                 :            : 
     164                 :            : static GstStaticPadTemplate private_template =
     165                 :            : GST_STATIC_PAD_TEMPLATE ("private_%04x",
     166                 :            :     GST_PAD_SRC,
     167                 :            :     GST_PAD_SOMETIMES,
     168                 :            :     GST_STATIC_CAPS_ANY);
     169                 :            : 
     170                 :            : static void gst_mpegts_demux_base_init (GstMpegTSDemuxClass * klass);
     171                 :            : static void gst_mpegts_demux_class_init (GstMpegTSDemuxClass * klass);
     172                 :            : static void gst_mpegts_demux_init (GstMpegTSDemux * demux);
     173                 :            : static void gst_mpegts_demux_finalize (GstMpegTSDemux * demux);
     174                 :            : static void gst_mpegts_demux_reset (GstMpegTSDemux * demux);
     175                 :            : 
     176                 :            : //static void gst_mpegts_demux_remove_pads (GstMpegTSDemux * demux);
     177                 :            : static void gst_mpegts_demux_set_property (GObject * object, guint prop_id,
     178                 :            :     const GValue * value, GParamSpec * pspec);
     179                 :            : static void gst_mpegts_demux_get_property (GObject * object, guint prop_id,
     180                 :            :     GValue * value, GParamSpec * pspec);
     181                 :            : 
     182                 :            : static gboolean gst_mpegts_demux_is_PMT (GstMpegTSDemux * demux, guint16 PID);
     183                 :            : 
     184                 :            : static gboolean gst_mpegts_demux_sink_event (GstPad * pad, GstEvent * event);
     185                 :            : static gboolean gst_mpegts_demux_src_event (GstPad * pad, GstEvent * event);
     186                 :            : static GstFlowReturn gst_mpegts_demux_chain (GstPad * pad, GstBuffer * buffer);
     187                 :            : static gboolean gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps);
     188                 :            : 
     189                 :            : static GstClock *gst_mpegts_demux_provide_clock (GstElement * element);
     190                 :            : static gboolean gst_mpegts_demux_src_pad_query (GstPad * pad, GstQuery * query);
     191                 :            : static const GstQueryType *gst_mpegts_demux_src_pad_query_type (GstPad * pad);
     192                 :            : 
     193                 :            : static GstStateChangeReturn gst_mpegts_demux_change_state (GstElement * element,
     194                 :            :     GstStateChange transition);
     195                 :            : 
     196                 :            : static MpegTsPmtInfo *mpegts_demux_build_pmt_info (GstMpegTSDemux * demux,
     197                 :            :     guint16 pmt_pid);
     198                 :            : 
     199                 :            : static GstElementClass *parent_class = NULL;
     200                 :            : 
     201                 :            : /*static guint gst_mpegts_demux_signals[LAST_SIGNAL] = { 0 };*/
     202                 :            : 
     203                 :            : GType
     204                 :         40 : gst_mpegts_demux_get_type (void)
     205                 :            : {
     206                 :            :   static GType mpegts_demux_type = 0;
     207                 :            : 
     208         [ +  + ]:         40 :   if (G_UNLIKELY (!mpegts_demux_type)) {
     209                 :            :     static const GTypeInfo mpegts_demux_info = {
     210                 :            :       sizeof (GstMpegTSDemuxClass),
     211                 :            :       (GBaseInitFunc) gst_mpegts_demux_base_init,
     212                 :            :       NULL,
     213                 :            :       (GClassInitFunc) gst_mpegts_demux_class_init,
     214                 :            :       NULL,
     215                 :            :       NULL,
     216                 :            :       sizeof (GstMpegTSDemux),
     217                 :            :       0,
     218                 :            :       (GInstanceInitFunc) gst_mpegts_demux_init,
     219                 :            :     };
     220                 :            : 
     221                 :          6 :     mpegts_demux_type =
     222                 :          6 :         g_type_register_static (GST_TYPE_ELEMENT, "GstMpegTSDemux",
     223                 :            :         &mpegts_demux_info, 0);
     224                 :            : 
     225         [ +  - ]:          6 :     GST_DEBUG_CATEGORY_INIT (gstmpegtsdemux_debug, "mpegtsdemux", 0,
     226                 :            :         "MPEG program stream demultiplexer element");
     227                 :            :   }
     228                 :            : 
     229                 :         40 :   return mpegts_demux_type;
     230                 :            : }
     231                 :            : 
     232                 :            : static void
     233                 :          6 : gst_mpegts_demux_base_init (GstMpegTSDemuxClass * klass)
     234                 :            : {
     235                 :          6 :   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
     236                 :            : 
     237                 :          6 :   klass->sink_template = gst_static_pad_template_get (&sink_template);
     238                 :          6 :   klass->video_template = gst_static_pad_template_get (&video_template);
     239                 :          6 :   klass->audio_template = gst_static_pad_template_get (&audio_template);
     240                 :          6 :   klass->subpicture_template =
     241                 :          6 :       gst_static_pad_template_get (&subpicture_template);
     242                 :          6 :   klass->private_template = gst_static_pad_template_get (&private_template);
     243                 :            : 
     244                 :          6 :   gst_element_class_add_pad_template (element_class, klass->video_template);
     245                 :          6 :   gst_element_class_add_pad_template (element_class, klass->audio_template);
     246                 :          6 :   gst_element_class_add_pad_template (element_class,
     247                 :            :       klass->subpicture_template);
     248                 :          6 :   gst_element_class_add_pad_template (element_class, klass->private_template);
     249                 :          6 :   gst_element_class_add_pad_template (element_class, klass->sink_template);
     250                 :            : 
     251                 :          6 :   gst_element_class_set_details_simple (element_class,
     252                 :            :       "The Fluendo MPEG Transport stream demuxer", "Codec/Demuxer",
     253                 :            :       "Demultiplexes MPEG2 Transport Streams", "Wim Taymans <wim@fluendo.com>");
     254                 :          6 : }
     255                 :            : 
     256                 :            : static void
     257                 :          6 : gst_mpegts_demux_class_init (GstMpegTSDemuxClass * klass)
     258                 :            : {
     259                 :            :   GObjectClass *gobject_class;
     260                 :            :   GstElementClass *gstelement_class;
     261                 :            : 
     262                 :          6 :   parent_class = g_type_class_peek_parent (klass);
     263                 :            : 
     264                 :          6 :   gobject_class = (GObjectClass *) klass;
     265                 :          6 :   gstelement_class = (GstElementClass *) klass;
     266                 :            : 
     267                 :          6 :   gobject_class->finalize = (GObjectFinalizeFunc) gst_mpegts_demux_finalize;
     268                 :          6 :   gobject_class->set_property = gst_mpegts_demux_set_property;
     269                 :          6 :   gobject_class->get_property = gst_mpegts_demux_get_property;
     270                 :            : 
     271                 :          6 :   g_object_class_install_property (gobject_class, PROP_ES_PIDS,
     272                 :            :       g_param_spec_string ("es-pids",
     273                 :            :           "Colon separated list of PIDs containing Elementary Streams",
     274                 :            :           "PIDs to treat as Elementary Streams in the absence of a PMT, "
     275                 :            :           "eg 0x10:0x11:0x20", DEFAULT_PROP_ES_PIDS,
     276                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     277                 :          6 :   g_object_class_install_property (gobject_class, PROP_CHECK_CRC,
     278                 :            :       g_param_spec_boolean ("check-crc", "Check CRC",
     279                 :            :           "Enable CRC checking", DEFAULT_PROP_CHECK_CRC,
     280                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     281                 :          6 :   g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBER,
     282                 :            :       g_param_spec_int ("program-number", "Program Number",
     283                 :            :           "Program number to demux for (-1 to ignore)", -1, G_MAXINT,
     284                 :            :           DEFAULT_PROP_PROGRAM_NUMBER,
     285                 :            :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     286                 :            : 
     287                 :          6 :   g_object_class_install_property (gobject_class, PROP_PAT_INFO,
     288                 :            :       g_param_spec_value_array ("pat-info",
     289                 :            :           "GValueArray containing GObjects with properties",
     290                 :            :           "Array of GObjects containing information from the TS PAT "
     291                 :            :           "about all programs listed in the current Program Association "
     292                 :            :           "Table (PAT)",
     293                 :            :           g_param_spec_object ("flu-pat-streaminfo", "FluPATStreamInfo",
     294                 :            :               "Fluendo TS Demuxer PAT Stream info object",
     295                 :            :               MPEGTS_TYPE_PAT_INFO, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS),
     296                 :            :           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
     297                 :            : 
     298                 :          6 :   g_object_class_install_property (gobject_class, PROP_PMT_INFO,
     299                 :            :       g_param_spec_object ("pmt-info",
     300                 :            :           "Information about the current program",
     301                 :            :           "GObject with properties containing information from the TS PMT "
     302                 :            :           "about the currently selected program and its streams",
     303                 :            :           MPEGTS_TYPE_PMT_INFO, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
     304                 :            : 
     305                 :          6 :   gstelement_class->change_state = gst_mpegts_demux_change_state;
     306                 :          6 :   gstelement_class->provide_clock = gst_mpegts_demux_provide_clock;
     307                 :          6 : }
     308                 :            : 
     309                 :            : static void
     310                 :          3 : gst_mpegts_demux_init (GstMpegTSDemux * demux)
     311                 :            : {
     312                 :          3 :   GstMpegTSDemuxClass *klass = GST_MPEGTS_DEMUX_GET_CLASS (demux);
     313                 :            : 
     314                 :          3 :   demux->streams =
     315                 :          3 :       g_malloc0 (sizeof (GstMpegTSStream *) * (MPEGTS_MAX_PID + 1));
     316                 :          3 :   demux->sinkpad = gst_pad_new_from_template (klass->sink_template, "sink");
     317                 :          3 :   gst_pad_set_chain_function (demux->sinkpad, gst_mpegts_demux_chain);
     318                 :          3 :   gst_pad_set_event_function (demux->sinkpad, gst_mpegts_demux_sink_event);
     319                 :          3 :   gst_pad_set_setcaps_function (demux->sinkpad, gst_mpegts_demux_sink_setcaps);
     320                 :          3 :   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
     321                 :            : 
     322                 :          3 :   demux->elementary_pids = NULL;
     323                 :          3 :   demux->nb_elementary_pids = 0;
     324                 :          3 :   demux->check_crc = DEFAULT_PROP_CHECK_CRC;
     325                 :          3 :   demux->program_number = DEFAULT_PROP_PROGRAM_NUMBER;
     326                 :          3 :   demux->sync_lut = NULL;
     327                 :          3 :   demux->sync_lut_len = 0;
     328                 :          3 :   demux->bitrate = -1;
     329                 :          3 :   demux->num_packets = 0;
     330                 :          3 :   demux->pcr[0] = -1;
     331                 :          3 :   demux->pcr[1] = -1;
     332                 :          3 :   demux->cache_duration = GST_CLOCK_TIME_NONE;
     333                 :          3 :   demux->base_pts = GST_CLOCK_TIME_NONE;
     334                 :          3 : }
     335                 :            : 
     336                 :            : static void
     337                 :          3 : gst_mpegts_demux_finalize (GstMpegTSDemux * demux)
     338                 :            : {
     339                 :          3 :   gst_mpegts_demux_reset (demux);
     340                 :          3 :   g_free (demux->streams);
     341                 :            : 
     342                 :          3 :   G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (demux));
     343                 :          3 : }
     344                 :            : 
     345                 :            : static void
     346                 :         10 : gst_mpegts_demux_reset (GstMpegTSDemux * demux)
     347                 :            : {
     348                 :            :   /* Clean up the streams and pads we allocated */
     349                 :            :   gint i;
     350                 :            : 
     351         [ +  + ]:      81930 :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
     352                 :      81920 :     GstMpegTSStream *stream = demux->streams[i];
     353                 :            : 
     354         [ -  + ]:      81920 :     if (stream != NULL) {
     355         [ #  # ]:          0 :       if (stream->pad)
     356                 :          0 :         gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
     357         [ #  # ]:          0 :       if (stream->ES_info)
     358                 :          0 :         gst_mpeg_descriptor_free (stream->ES_info);
     359                 :            : 
     360         [ #  # ]:          0 :       if (stream->PMT.entries)
     361                 :          0 :         g_array_free (stream->PMT.entries, TRUE);
     362         [ #  # ]:          0 :       if (stream->PMT.program_info)
     363                 :          0 :         gst_mpeg_descriptor_free (stream->PMT.program_info);
     364                 :            : 
     365         [ #  # ]:          0 :       if (stream->PAT.entries)
     366                 :          0 :         g_array_free (stream->PAT.entries, TRUE);
     367                 :            : 
     368                 :          0 :       gst_pes_filter_uninit (&stream->filter);
     369                 :          0 :       gst_section_filter_uninit (&stream->section_filter);
     370                 :            : 
     371         [ #  # ]:          0 :       if (stream->pes_buffer) {
     372                 :          0 :         gst_buffer_unref (stream->pes_buffer);
     373                 :          0 :         stream->pes_buffer = NULL;
     374                 :            :       }
     375                 :          0 :       g_free (stream);
     376                 :          0 :       demux->streams[i] = NULL;
     377                 :            :     }
     378                 :            :   }
     379                 :            : 
     380         [ -  + ]:         10 :   if (demux->clock) {
     381                 :          0 :     g_object_unref (demux->clock);
     382                 :          0 :     demux->clock = NULL;
     383                 :            :   }
     384                 :         10 : }
     385                 :            : 
     386                 :            : #if 0
     387                 :            : static void
     388                 :            : gst_mpegts_demux_remove_pads (GstMpegTSDemux * demux)
     389                 :            : {
     390                 :            :   /* remove pads we added in preparation for adding new ones */
     391                 :            :   /* FIXME: instead of walking all streams, we should retain a list only
     392                 :            :    * of streams that have added pads */
     393                 :            :   gint i;
     394                 :            : 
     395                 :            :   if (demux->need_no_more_pads) {
     396                 :            :     gst_element_no_more_pads ((GstElement *) demux);
     397                 :            :     demux->need_no_more_pads = FALSE;
     398                 :            :   }
     399                 :            : 
     400                 :            :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
     401                 :            :     GstMpegTSStream *stream = demux->streams[i];
     402                 :            : 
     403                 :            :     if (stream != NULL) {
     404                 :            : 
     405                 :            :       if (GST_IS_PAD (stream->pad)) {
     406                 :            :         gst_pad_push_event (stream->pad, gst_event_new_eos ());
     407                 :            :         gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
     408                 :            :       }
     409                 :            :       stream->pad = NULL;
     410                 :            : 
     411                 :            :       if (stream->PID_type == PID_TYPE_ELEMENTARY)
     412                 :            :         gst_pes_filter_drain (&stream->filter);
     413                 :            :     }
     414                 :            :   }
     415                 :            : }
     416                 :            : #endif
     417                 :            : 
     418                 :            : 
     419                 :            : static guint32 crc_tab[256] = {
     420                 :            :   0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
     421                 :            :   0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
     422                 :            :   0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
     423                 :            :   0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
     424                 :            :   0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
     425                 :            :   0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
     426                 :            :   0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
     427                 :            :   0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
     428                 :            :   0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
     429                 :            :   0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
     430                 :            :   0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
     431                 :            :   0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
     432                 :            :   0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
     433                 :            :   0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
     434                 :            :   0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
     435                 :            :   0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
     436                 :            :   0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
     437                 :            :   0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
     438                 :            :   0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
     439                 :            :   0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
     440                 :            :   0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
     441                 :            :   0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
     442                 :            :   0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
     443                 :            :   0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
     444                 :            :   0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
     445                 :            :   0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
     446                 :            :   0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
     447                 :            :   0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
     448                 :            :   0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
     449                 :            :   0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
     450                 :            :   0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
     451                 :            :   0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
     452                 :            :   0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
     453                 :            :   0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
     454                 :            :   0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
     455                 :            :   0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
     456                 :            :   0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
     457                 :            :   0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
     458                 :            :   0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
     459                 :            :   0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
     460                 :            :   0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
     461                 :            :   0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
     462                 :            :   0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
     463                 :            : };
     464                 :            : 
     465                 :            : /*This function fills the value of negotiated packetsize at sinkpad*/
     466                 :            : static gboolean
     467                 :          0 : gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
     468                 :            : {
     469                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
     470                 :          0 :   GstStructure *structure = NULL;
     471                 :            : 
     472                 :          0 :   structure = gst_caps_get_structure (caps, 0);
     473                 :            : 
     474         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "setcaps called with %" GST_PTR_FORMAT, caps);
     475                 :            : 
     476         [ #  # ]:          0 :   if (!gst_structure_get_int (structure, "packetsize", &demux->packetsize)) {
     477         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "packetsize parameter not found in sink caps");
     478                 :            :   }
     479                 :            : 
     480                 :          0 :   gst_object_unref (demux);
     481                 :          0 :   return TRUE;
     482                 :            : }
     483                 :            : 
     484                 :            : static FORCE_INLINE guint32
     485                 :            : gst_mpegts_demux_calc_crc32 (guint8 * data, guint datalen)
     486                 :            : {
     487                 :            :   gint i;
     488                 :          0 :   guint32 crc = 0xffffffff;
     489                 :            : 
     490 [ #  # ][ #  # ]:          0 :   for (i = 0; i < datalen; i++) {
                 [ #  # ]
     491                 :          0 :     crc = (crc << 8) ^ crc_tab[((crc >> 24) ^ *data++) & 0xff];
     492                 :            :   }
     493                 :          0 :   return crc;
     494                 :            : }
     495                 :            : 
     496                 :            : static FORCE_INLINE gboolean
     497                 :            : gst_mpegts_is_dirac_stream (GstMpegTSStream * stream)
     498                 :            : {
     499                 :          0 :   gboolean is_dirac = FALSE;
     500                 :            : 
     501 [ #  # ][ #  # ]:          0 :   if (stream->stream_type != ST_VIDEO_DIRAC)
     502                 :          0 :     return FALSE;
     503                 :            : 
     504 [ #  # ][ #  # ]:          0 :   if (stream->ES_info != NULL) {
     505                 :            :     guint8 *dirac_desc;
     506                 :            : 
     507                 :            :     /* Check for a Registration Descriptor to confirm this is dirac */
     508                 :          0 :     dirac_desc = gst_mpeg_descriptor_find (stream->ES_info, DESC_REGISTRATION);
     509         [ #  # ]:          0 :     if (dirac_desc != NULL && DESC_LENGTH (dirac_desc) >= 4) {
           [ #  #  #  # ]
                 [ #  # ]
     510 [ #  # ][ #  # ]:          0 :       if (DESC_REGISTRATION_format_identifier (dirac_desc) == 0x64726163) {     /* 'drac' in hex */
     511                 :          0 :         is_dirac = TRUE;
     512                 :            :       }
     513                 :            :     } else {
     514                 :            :       /* Check for old mapping as originally specified too */
     515                 :          0 :       dirac_desc = gst_mpeg_descriptor_find (stream->ES_info,
     516                 :            :           DESC_DIRAC_TC_PRIVATE);
     517         [ #  # ]:          0 :       if (dirac_desc != NULL && DESC_LENGTH (dirac_desc) == 0)
           [ #  #  #  # ]
                 [ #  # ]
     518                 :          0 :         is_dirac = TRUE;
     519                 :            :     }
     520                 :            :   }
     521                 :            : 
     522                 :          0 :   return is_dirac;
     523                 :            : }
     524                 :            : 
     525                 :            : static FORCE_INLINE gboolean
     526                 :            : gst_mpegts_stream_is_video (GstMpegTSStream * stream)
     527                 :            : {
     528      [ #  #  # ]:          0 :   switch (stream->stream_type) {
     529                 :            :     case ST_VIDEO_MPEG1:
     530                 :            :     case ST_VIDEO_MPEG2:
     531                 :            :     case ST_VIDEO_MPEG4:
     532                 :            :     case ST_VIDEO_H264:
     533                 :          0 :       return TRUE;
     534                 :            :     case ST_VIDEO_DIRAC:
     535                 :          0 :       return gst_mpegts_is_dirac_stream (stream);
     536                 :            :   }
     537                 :            : 
     538                 :          0 :   return FALSE;
     539                 :            : }
     540                 :            : 
     541                 :            : static gboolean
     542                 :          0 : gst_mpegts_demux_is_reserved_PID (GstMpegTSDemux * demux, guint16 PID)
     543                 :            : {
     544 [ #  # ][ #  # ]:          0 :   return (PID >= PID_RESERVED_FIRST) && (PID < PID_RESERVED_LAST);
     545                 :            : }
     546                 :            : 
     547                 :            : /* This function assumes that provided PID never will be greater than
     548                 :            :  * MPEGTS_MAX_PID (13 bits), this is currently guaranteed as everywhere in
     549                 :            :  * the code recovered PID at maximum is 13 bits long. 
     550                 :            :  */
     551                 :            : static FORCE_INLINE GstMpegTSStream *
     552                 :            : gst_mpegts_demux_get_stream_for_PID (GstMpegTSDemux * demux, guint16 PID)
     553                 :            : {
     554                 :          0 :   GstMpegTSStream *stream = NULL;
     555                 :            : 
     556                 :          0 :   stream = demux->streams[PID];
     557                 :            : 
     558 [ #  # ][ #  # ]:          0 :   if (G_UNLIKELY (stream == NULL)) {
         [ #  # ][ #  # ]
                 [ #  # ]
     559                 :          0 :     stream = g_new0 (GstMpegTSStream, 1);
     560                 :            : 
     561                 :          0 :     stream->demux = demux;
     562                 :          0 :     stream->PID = PID;
     563                 :          0 :     stream->pad = NULL;
     564                 :          0 :     stream->base_PCR = -1;
     565                 :          0 :     stream->last_PCR = -1;
     566                 :          0 :     stream->last_PCR_difference = -1;
     567                 :          0 :     stream->PMT.version_number = -1;
     568                 :          0 :     stream->PAT.version_number = -1;
     569                 :          0 :     stream->PMT_pid = MPEGTS_MAX_PID + 1;
     570                 :          0 :     stream->flags |= MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN;
     571                 :          0 :     stream->pes_buffer_in_sync = FALSE;
     572   [ #  #  #  #  :          0 :     switch (PID) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     573                 :            :         /* check for fixed mapping */
     574                 :            :       case PID_PROGRAM_ASSOCIATION_TABLE:
     575                 :          0 :         stream->PID_type = PID_TYPE_PROGRAM_ASSOCIATION;
     576                 :            :         /* initialise section filter */
     577                 :          0 :         gst_section_filter_init (&stream->section_filter);
     578                 :            :         break;
     579                 :            :       case PID_CONDITIONAL_ACCESS_TABLE:
     580                 :          0 :         stream->PID_type = PID_TYPE_CONDITIONAL_ACCESS;
     581                 :            :         /* initialise section filter */
     582                 :          0 :         gst_section_filter_init (&stream->section_filter);
     583                 :            :         break;
     584                 :            :       case PID_NULL_PACKET:
     585                 :          0 :         stream->PID_type = PID_TYPE_NULL_PACKET;
     586                 :            :         break;
     587                 :            :       default:
     588                 :            :         /* mark reserved PIDs */
     589 [ #  # ][ #  # ]:          0 :         if (gst_mpegts_demux_is_reserved_PID (demux, PID)) {
         [ #  # ][ #  # ]
                 [ #  # ]
     590                 :          0 :           stream->PID_type = PID_TYPE_RESERVED;
     591                 :            :         } else {
     592                 :            :           /* check if PMT found in PAT */
     593 [ #  # ][ #  # ]:          0 :           if (gst_mpegts_demux_is_PMT (demux, PID)) {
         [ #  # ][ #  # ]
                 [ #  # ]
     594                 :          0 :             stream->PID_type = PID_TYPE_PROGRAM_MAP;
     595                 :            :             /* initialise section filter */
     596                 :          0 :             gst_section_filter_init (&stream->section_filter);
     597                 :            :           } else
     598                 :          0 :             stream->PID_type = PID_TYPE_UNKNOWN;
     599                 :            :         }
     600                 :            :         break;
     601                 :            :     }
     602 [ #  # ][ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "creating stream %p for PID 0x%04x, PID_type %d",
         [ #  # ][ #  # ]
                 [ #  # ]
     603                 :            :         stream, PID, stream->PID_type);
     604                 :            : 
     605                 :          0 :     demux->streams[PID] = stream;
     606                 :            :   }
     607                 :            : 
     608                 :          0 :   return stream;
     609                 :            : }
     610                 :            : 
     611                 :            : static gboolean
     612                 :          0 : gst_mpegts_demux_fill_stream (GstMpegTSStream * stream, guint8 id,
     613                 :            :     guint8 stream_type)
     614                 :            : {
     615                 :            :   GstPadTemplate *template;
     616                 :            :   gchar *name;
     617                 :            :   GstMpegTSDemuxClass *klass;
     618                 :            :   GstMpegTSDemux *demux;
     619                 :            :   GstCaps *caps;
     620                 :            : 
     621 [ #  # ][ #  # ]:          0 :   if (stream->stream_type && stream->stream_type != stream_type)
     622                 :          0 :     goto wrong_type;
     623                 :            : 
     624                 :          0 :   demux = stream->demux;
     625                 :          0 :   klass = GST_MPEGTS_DEMUX_GET_CLASS (demux);
     626                 :            : 
     627                 :          0 :   name = NULL;
     628                 :          0 :   template = NULL;
     629                 :          0 :   caps = NULL;
     630                 :            : 
     631   [ #  #  #  #  :          0 :   switch (stream_type) {
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     632                 :            :     case ST_VIDEO_MPEG1:
     633                 :            :     case ST_VIDEO_MPEG2:
     634                 :          0 :       template = klass->video_template;
     635                 :          0 :       name = g_strdup_printf ("video_%04x", stream->PID);
     636         [ #  # ]:          0 :       caps = gst_caps_new_simple ("video/mpeg",
     637                 :            :           "mpegversion", G_TYPE_INT, stream_type == ST_VIDEO_MPEG1 ? 1 : 2,
     638                 :            :           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
     639                 :          0 :       break;
     640                 :            :     case ST_AUDIO_MPEG1:
     641                 :            :     case ST_AUDIO_MPEG2:
     642                 :          0 :       template = klass->audio_template;
     643                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     644                 :          0 :       caps = gst_caps_new_simple ("audio/mpeg",
     645                 :            :           "mpegversion", G_TYPE_INT, 1, NULL);
     646                 :          0 :       break;
     647                 :            :     case ST_PRIVATE_DATA:
     648                 :            :       /* check if there is an AC3 descriptor associated with this stream
     649                 :            :        * from the PMT */
     650         [ #  # ]:          0 :       if (gst_mpeg_descriptor_find (stream->ES_info, DESC_DVB_AC3)) {
     651                 :          0 :         template = klass->audio_template;
     652                 :          0 :         name = g_strdup_printf ("audio_%04x", stream->PID);
     653                 :          0 :         caps = gst_caps_new_simple ("audio/x-ac3", NULL);
     654         [ #  # ]:          0 :       } else if (gst_mpeg_descriptor_find (stream->ES_info,
     655                 :            :               DESC_DVB_ENHANCED_AC3)) {
     656                 :          0 :         template = klass->private_template;
     657                 :          0 :         name = g_strdup_printf ("audio_%04x", stream->PID);
     658                 :          0 :         caps = gst_caps_new_simple ("audio/x-eac3", NULL);
     659         [ #  # ]:          0 :       } else if (gst_mpeg_descriptor_find (stream->ES_info, DESC_DVB_TELETEXT)) {
     660                 :          0 :         template = klass->private_template;
     661                 :          0 :         name = g_strdup_printf ("private_%04x", stream->PID);
     662                 :          0 :         caps = gst_caps_new_simple ("private/teletext", NULL);
     663         [ #  # ]:          0 :       } else if (gst_mpeg_descriptor_find (stream->ES_info,
     664                 :            :               DESC_DVB_SUBTITLING)) {
     665                 :          0 :         template = klass->private_template;
     666                 :          0 :         name = g_strdup_printf ("private_%04x", stream->PID);
     667                 :          0 :         caps = gst_caps_new_simple ("subpicture/x-dvb", NULL);
     668                 :            :       }
     669                 :          0 :       break;
     670                 :            :     case ST_HDV_AUX_V:
     671                 :          0 :       template = klass->private_template;
     672                 :          0 :       name = g_strdup_printf ("private_%04x", stream->PID);
     673                 :          0 :       caps = gst_caps_new_simple ("hdv/aux-v", NULL);
     674                 :          0 :       break;
     675                 :            :     case ST_HDV_AUX_A:
     676                 :          0 :       template = klass->private_template;
     677                 :          0 :       name = g_strdup_printf ("private_%04x", stream->PID);
     678                 :          0 :       caps = gst_caps_new_simple ("hdv/aux-a", NULL);
     679                 :          0 :       break;
     680                 :            :     case ST_PRIVATE_SECTIONS:
     681                 :            :     case ST_MHEG:
     682                 :            :     case ST_DSMCC:
     683                 :          0 :       break;
     684                 :            :     case ST_AUDIO_AAC:
     685                 :          0 :       template = klass->audio_template;
     686                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     687                 :          0 :       caps = gst_caps_new_simple ("audio/mpeg",
     688                 :            :           "mpegversion", G_TYPE_INT, 4, NULL);
     689                 :          0 :       break;
     690                 :            :     case ST_VIDEO_MPEG4:
     691                 :          0 :       template = klass->video_template;
     692                 :          0 :       name = g_strdup_printf ("video_%04x", stream->PID);
     693                 :          0 :       caps = gst_caps_new_simple ("video/mpeg",
     694                 :            :           "mpegversion", G_TYPE_INT, 4,
     695                 :            :           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
     696                 :          0 :       break;
     697                 :            :     case ST_VIDEO_H264:
     698                 :          0 :       template = klass->video_template;
     699                 :          0 :       name = g_strdup_printf ("video_%04x", stream->PID);
     700                 :          0 :       caps = gst_caps_new_simple ("video/x-h264", NULL);
     701                 :          0 :       break;
     702                 :            :     case ST_VIDEO_DIRAC:
     703         [ #  # ]:          0 :       if (gst_mpegts_is_dirac_stream (stream)) {
     704                 :          0 :         template = klass->video_template;
     705                 :          0 :         name = g_strdup_printf ("video_%04x", stream->PID);
     706                 :          0 :         caps = gst_caps_new_simple ("video/x-dirac", NULL);
     707                 :            :       }
     708                 :          0 :       break;
     709                 :            :     case ST_PRIVATE_EA:        /* Try to detect a VC1 stream */
     710                 :            :     {
     711                 :          0 :       guint8 *desc = NULL;
     712                 :            : 
     713         [ #  # ]:          0 :       if (stream->ES_info)
     714                 :          0 :         desc = gst_mpeg_descriptor_find (stream->ES_info, DESC_REGISTRATION);
     715 [ #  # ][ #  # ]:          0 :       if (!(desc && DESC_REGISTRATION_format_identifier (desc) == DRF_ID_VC1)) {
     716         [ #  # ]:          0 :         GST_WARNING ("0xea private stream type found but no descriptor "
     717                 :            :             "for VC1. Assuming plain VC1.");
     718                 :            :       }
     719                 :          0 :       template = klass->video_template;
     720                 :          0 :       name = g_strdup_printf ("video_%04x", stream->PID);
     721                 :          0 :       caps = gst_caps_new_simple ("video/x-wmv",
     722                 :            :           "wmvversion", G_TYPE_INT, 3,
     723                 :            :           "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),
     724                 :            :           NULL);
     725                 :          0 :       break;
     726                 :            :     }
     727                 :            :     case ST_BD_AUDIO_AC3:
     728                 :            :     {
     729                 :          0 :       GstMpegTSStream *PMT_stream =
     730                 :          0 :           gst_mpegts_demux_get_stream_for_PID (stream->demux, stream->PMT_pid);
     731                 :          0 :       GstMPEGDescriptor *program_info = PMT_stream->PMT.program_info;
     732                 :          0 :       guint8 *desc = NULL;
     733                 :            : 
     734         [ #  # ]:          0 :       if (program_info)
     735                 :          0 :         desc = gst_mpeg_descriptor_find (program_info, DESC_REGISTRATION);
     736                 :            : 
     737 [ #  # ][ #  # ]:          0 :       if (desc && DESC_REGISTRATION_format_identifier (desc) == DRF_ID_HDMV) {
     738                 :          0 :         template = klass->audio_template;
     739                 :          0 :         name = g_strdup_printf ("audio_%04x", stream->PID);
     740                 :          0 :         caps = gst_caps_new_simple ("audio/x-eac3", NULL);
     741 [ #  # ][ #  # ]:          0 :       } else if (stream->ES_info && gst_mpeg_descriptor_find (stream->ES_info,
     742                 :            :               DESC_DVB_ENHANCED_AC3)) {
     743                 :          0 :         template = klass->audio_template;
     744                 :          0 :         name = g_strdup_printf ("audio_%04x", stream->PID);
     745                 :          0 :         caps = gst_caps_new_simple ("audio/x-eac3", NULL);
     746                 :            :       } else {
     747   [ #  #  #  # ]:          0 :         if (!stream->ES_info ||
     748                 :          0 :             !gst_mpeg_descriptor_find (stream->ES_info, DESC_DVB_AC3)) {
     749         [ #  # ]:          0 :           GST_WARNING ("AC3 stream type found but no corresponding "
     750                 :            :               "descriptor to differentiate between AC3 and EAC3. "
     751                 :            :               "Assuming plain AC3.");
     752                 :            :         }
     753                 :          0 :         template = klass->audio_template;
     754                 :          0 :         name = g_strdup_printf ("audio_%04x", stream->PID);
     755                 :          0 :         caps = gst_caps_new_simple ("audio/x-ac3", NULL);
     756                 :            :       }
     757                 :          0 :       break;
     758                 :            :     }
     759                 :            :     case ST_BD_AUDIO_EAC3:
     760                 :          0 :       template = klass->audio_template;
     761                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     762                 :          0 :       caps = gst_caps_new_simple ("audio/x-eac3", NULL);
     763                 :          0 :       break;
     764                 :            :     case ST_PS_AUDIO_DTS:
     765                 :            :     case ST_BD_AUDIO_DTS:
     766                 :            :     case ST_BD_AUDIO_DTS_HD:
     767                 :            :     case ST_BD_AUDIO_DTS_HD_MASTER_AUDIO:
     768                 :          0 :       template = klass->audio_template;
     769                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     770                 :          0 :       caps = gst_caps_new_simple ("audio/x-dts", NULL);
     771                 :          0 :       break;
     772                 :            :     case ST_PS_AUDIO_LPCM:
     773                 :          0 :       template = klass->audio_template;
     774                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     775                 :          0 :       caps = gst_caps_new_simple ("audio/x-lpcm", NULL);
     776                 :          0 :       break;
     777                 :            :     case ST_BD_AUDIO_LPCM:
     778                 :          0 :       template = klass->audio_template;
     779                 :          0 :       name = g_strdup_printf ("audio_%04x", stream->PID);
     780                 :          0 :       caps = gst_caps_new_simple ("audio/x-private-ts-lpcm", NULL);
     781                 :          0 :       break;
     782                 :            :     case ST_PS_DVD_SUBPICTURE:
     783                 :          0 :       template = klass->subpicture_template;
     784                 :          0 :       name = g_strdup_printf ("subpicture_%04x", stream->PID);
     785                 :          0 :       caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
     786                 :          0 :       break;
     787                 :            :     case ST_BD_PGS_SUBPICTURE:
     788                 :          0 :       template = klass->subpicture_template;
     789                 :          0 :       name = g_strdup_printf ("subpicture_%04x", stream->PID);
     790                 :          0 :       caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
     791                 :          0 :       break;
     792                 :            :     default:
     793                 :          0 :       break;
     794                 :            :   }
     795 [ #  # ][ #  # ]:          0 :   if (name == NULL || template == NULL || caps == NULL)
                 [ #  # ]
     796                 :          0 :     return FALSE;
     797                 :            : 
     798                 :          0 :   stream->stream_type = stream_type;
     799                 :          0 :   stream->id = id;
     800         [ #  # ]:          0 :   GST_DEBUG ("creating new pad %s", name);
     801                 :          0 :   stream->pad = gst_pad_new_from_template (template, name);
     802                 :          0 :   gst_pad_use_fixed_caps (stream->pad);
     803                 :          0 :   gst_pad_set_caps (stream->pad, caps);
     804                 :          0 :   gst_caps_unref (caps);
     805                 :          0 :   gst_pad_set_query_function (stream->pad,
     806                 :          0 :       GST_DEBUG_FUNCPTR (gst_mpegts_demux_src_pad_query));
     807                 :          0 :   gst_pad_set_query_type_function (stream->pad,
     808                 :          0 :       GST_DEBUG_FUNCPTR (gst_mpegts_demux_src_pad_query_type));
     809                 :          0 :   gst_pad_set_event_function (stream->pad,
     810                 :          0 :       GST_DEBUG_FUNCPTR (gst_mpegts_demux_src_event));
     811                 :          0 :   g_free (name);
     812                 :            : 
     813                 :          0 :   return TRUE;
     814                 :            : 
     815                 :            : wrong_type:
     816                 :            :   {
     817                 :          0 :     return FALSE;
     818                 :            :   }
     819                 :            : }
     820                 :            : 
     821                 :            : static FORCE_INLINE gboolean
     822                 :            : mpegts_is_elem_pid (GstMpegTSDemux * demux, guint16 PID)
     823                 :            : {
     824                 :            :   int i;
     825                 :            : 
     826                 :            :   /* check if it's in our partial ts pid list */
     827 [ #  # ][ #  # ]:          0 :   for (i = 0; i < demux->nb_elementary_pids; i++) {
     828 [ #  # ][ #  # ]:          0 :     if (demux->elementary_pids[i] == PID) {
     829                 :          0 :       return TRUE;
     830                 :            :     }
     831                 :            :   }
     832                 :            : 
     833                 :          0 :   return FALSE;
     834                 :            : }
     835                 :            : 
     836                 :            : static gboolean
     837                 :          0 : gst_mpegts_demux_setup_base_pts (GstMpegTSDemux * demux, gint64 pts)
     838                 :            : {
     839                 :            :   GstMpegTSStream *PCR_stream;
     840                 :            :   GstMpegTSStream *PMT_stream;
     841                 :            :   guint64 base_PCR;
     842                 :            : 
     843                 :            :   /* for the reference start time we need to consult the PCR_PID of the
     844                 :            :    * current PMT */
     845         [ #  # ]:          0 :   if (demux->current_PMT == 0)
     846                 :          0 :     goto no_pmt_stream;
     847                 :            : 
     848                 :          0 :   PMT_stream = demux->streams[demux->current_PMT];
     849         [ #  # ]:          0 :   if (PMT_stream == NULL)
     850                 :          0 :     goto no_pmt_stream;
     851                 :            : 
     852                 :          0 :   PCR_stream = demux->streams[PMT_stream->PMT.PCR_PID];
     853         [ #  # ]:          0 :   if (PCR_stream == NULL)
     854                 :          0 :     goto no_pcr_stream;
     855                 :            : 
     856         [ #  # ]:          0 :   if (PCR_stream->base_PCR == -1) {
     857         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "no base PCR, using last PCR %" G_GUINT64_FORMAT,
     858                 :            :         PCR_stream->last_PCR);
     859                 :          0 :     PCR_stream->base_PCR = PCR_stream->last_PCR;
     860                 :            :   } else {
     861         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "using base PCR %" G_GUINT64_FORMAT,
     862                 :            :         PCR_stream->base_PCR);
     863                 :            :   }
     864         [ #  # ]:          0 :   if (PCR_stream->last_PCR == -1) {
     865         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "no last PCR, using PTS %" G_GUINT64_FORMAT, pts);
     866                 :          0 :     PCR_stream->base_PCR = pts;
     867                 :          0 :     PCR_stream->last_PCR = pts;
     868                 :            :   }
     869                 :          0 :   base_PCR = PCR_stream->base_PCR;
     870                 :            : 
     871                 :          0 :   demux->base_pts = MPEGTIME_TO_GSTTIME (base_PCR);
     872                 :            : 
     873         [ #  # ]:          0 :   if (demux->base_pts == GST_CLOCK_TIME_NONE)
     874                 :          0 :     return FALSE;
     875                 :            : 
     876                 :          0 :   return TRUE;
     877                 :            : 
     878                 :            : no_pmt_stream:
     879                 :            :   {
     880         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "no PMT stream found");
     881                 :          0 :     return FALSE;
     882                 :            :   }
     883                 :            : no_pcr_stream:
     884                 :            :   {
     885         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "no PCR stream found");
     886                 :          0 :     return FALSE;
     887                 :            :   }
     888                 :            : }
     889                 :            : 
     890                 :            : static gboolean
     891                 :          0 : gst_mpegts_demux_send_new_segment (GstMpegTSDemux * demux,
     892                 :            :     GstMpegTSStream * stream, gint64 pts)
     893                 :            : {
     894                 :            :   GstClockTime time;
     895                 :            : 
     896                 :            :   /* base_pts needs to have been set up by a call to
     897                 :            :    * gst_mpegts_demux_setup_base_pts() before calling this function */
     898         [ #  # ]:          0 :   if (demux->base_pts == GST_CLOCK_TIME_NONE)
     899                 :          0 :     goto no_base_time;
     900                 :            : 
     901                 :          0 :   time = demux->base_pts;
     902                 :            : 
     903 [ #  # ][ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "segment PTS to time: %"
         [ #  # ][ #  # ]
                 [ #  # ]
     904                 :            :       GST_TIME_FORMAT, GST_TIME_ARGS (time));
     905                 :            : 
     906 [ #  # ][ #  # ]:          0 :   if (demux->clock && demux->clock_base == GST_CLOCK_TIME_NONE) {
     907                 :          0 :     demux->clock_base = gst_clock_get_time (demux->clock);
     908                 :          0 :     gst_clock_set_calibration (demux->clock,
     909                 :            :         gst_clock_get_internal_time (demux->clock), demux->clock_base, 1, 1);
     910                 :            :   }
     911                 :            : 
     912                 :          0 :   gst_pad_push_event (stream->pad,
     913                 :            :       gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, time, -1, 0));
     914                 :            : 
     915                 :          0 :   return TRUE;
     916                 :            : 
     917                 :            :   /* ERRORS */
     918                 :            : no_base_time:
     919                 :            :   {
     920                 :            :     /* check if it's in our partial ts pid list */
     921         [ #  # ]:          0 :     if (mpegts_is_elem_pid (demux, stream->PID)) {
     922         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux,
     923                 :            :           "Elementary PID, using pts %" G_GUINT64_FORMAT, pts);
     924                 :          0 :       time = MPEGTIME_TO_GSTTIME (pts) + stream->base_time;
     925         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "segment PTS to (%" G_GUINT64_FORMAT ") time: %"
     926                 :            :           G_GUINT64_FORMAT, pts, time);
     927                 :            : 
     928                 :          0 :       gst_pad_push_event (stream->pad,
     929                 :            :           gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, time, -1, 0));
     930                 :          0 :       return TRUE;
     931                 :            :     }
     932                 :            : 
     933                 :            :   }
     934                 :          0 :   return FALSE;
     935                 :            : }
     936                 :            : 
     937                 :            : static void
     938                 :          0 : gst_mpegts_demux_send_tags_for_stream (GstMpegTSDemux * demux,
     939                 :            :     GstMpegTSStream * stream)
     940                 :            : {
     941                 :          0 :   GstTagList *list = NULL;
     942                 :            :   gint i;
     943                 :            : 
     944         [ #  # ]:          0 :   if (stream->ES_info) {
     945                 :            :     static const guint8 lang_descs[] =
     946                 :            :         { DESC_ISO_639_LANGUAGE, DESC_DVB_SUBTITLING };
     947         [ #  # ]:          0 :     for (i = 0; i < G_N_ELEMENTS (lang_descs); i++) {
     948                 :          0 :       guint8 *iso639_languages =
     949                 :          0 :           gst_mpeg_descriptor_find (stream->ES_info, lang_descs[i]);
     950         [ #  # ]:          0 :       if (iso639_languages) {
     951         [ #  # ]:          0 :         if (DESC_ISO_639_LANGUAGE_codes_n (iso639_languages)) {
     952                 :            :           const gchar *lc;
     953                 :            :           gchar lang_code[4];
     954                 :            :           gchar *language_n;
     955                 :            : 
     956                 :          0 :           language_n = (gchar *)
     957                 :            :               DESC_ISO_639_LANGUAGE_language_code_nth (iso639_languages, 0);
     958                 :            : 
     959                 :          0 :           lang_code[0] = language_n[0];
     960                 :          0 :           lang_code[1] = language_n[1];
     961                 :          0 :           lang_code[2] = language_n[2];
     962                 :          0 :           lang_code[3] = 0;
     963                 :            : 
     964         [ #  # ]:          0 :           if (!list)
     965                 :          0 :             list = gst_tag_list_new ();
     966                 :            : 
     967                 :            :           /* descriptor contains ISO 639-2 code, we want the ISO 639-1 code */
     968                 :          0 :           lc = gst_tag_get_language_code (lang_code);
     969         [ #  # ]:          0 :           gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
     970                 :            :               GST_TAG_LANGUAGE_CODE, (lc) ? lc : lang_code, NULL);
     971                 :            :         }
     972                 :            :       }
     973                 :            :     }
     974                 :            :   }
     975                 :            : 
     976         [ #  # ]:          0 :   if (list) {
     977 [ #  # ][ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "Sending tags %p for pad %s:%s",
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     978                 :            :         list, GST_DEBUG_PAD_NAME (stream->pad));
     979                 :          0 :     gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad, list);
     980                 :            :   }
     981                 :          0 : }
     982                 :            : 
     983                 :            : static GstFlowReturn
     984                 :          0 : gst_mpegts_demux_combine_flows (GstMpegTSDemux * demux,
     985                 :            :     GstMpegTSStream * stream, GstFlowReturn ret)
     986                 :            : {
     987                 :            :   gint i;
     988                 :            : 
     989                 :            :   /* store the value */
     990                 :          0 :   stream->last_ret = ret;
     991                 :            : 
     992                 :            :   /* if it's success we can return the value right away */
     993         [ #  # ]:          0 :   if (ret == GST_FLOW_OK)
     994                 :          0 :     goto done;
     995                 :            : 
     996                 :            :   /* any other error that is not-linked can be returned right
     997                 :            :    * away */
     998         [ #  # ]:          0 :   if (ret != GST_FLOW_NOT_LINKED)
     999                 :          0 :     goto done;
    1000                 :            : 
    1001                 :            :   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
    1002         [ #  # ]:          0 :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
    1003         [ #  # ]:          0 :     if (!(stream = demux->streams[i]))
    1004                 :          0 :       continue;
    1005                 :            : 
    1006                 :            :     /* some other return value (must be SUCCESS but we can return
    1007                 :            :      * other values as well) */
    1008                 :          0 :     ret = stream->last_ret;
    1009         [ #  # ]:          0 :     if (ret != GST_FLOW_NOT_LINKED)
    1010                 :          0 :       goto done;
    1011                 :            :   }
    1012                 :            :   /* if we get here, all other pads were unlinked and we return
    1013                 :            :    * NOT_LINKED then */
    1014                 :            : done:
    1015                 :          0 :   return ret;
    1016                 :            : }
    1017                 :            : 
    1018                 :            : 
    1019                 :            : static GstFlowReturn
    1020                 :          0 : gst_mpegts_demux_data_cb (GstPESFilter * filter, gboolean first,
    1021                 :            :     GstBuffer * buffer, GstMpegTSStream * stream)
    1022                 :            : {
    1023                 :            :   GstMpegTSDemux *demux;
    1024                 :            :   GstFlowReturn ret;
    1025                 :            :   GstPad *srcpad;
    1026                 :            :   gint64 pts;
    1027                 :            :   GstClockTime time;
    1028                 :            : 
    1029                 :          0 :   demux = stream->demux;
    1030                 :          0 :   srcpad = stream->pad;
    1031                 :            : 
    1032         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "got data on PID 0x%04x", stream->PID);
    1033                 :            : 
    1034 [ #  # ][ #  # ]:          0 :   if (first && filter->pts != -1) {
    1035                 :          0 :     pts = filter->pts;
    1036                 :          0 :     time = MPEGTIME_TO_GSTTIME (pts) + stream->base_time;
    1037                 :            : 
    1038 [ #  # ][ #  # ]:          0 :     if ((stream->last_time > 0 && stream->last_time < time &&
                 [ #  # ]
    1039                 :          0 :             time - stream->last_time > GST_SECOND * 60 * 10)
    1040         [ #  # ]:          0 :         || (stream->last_time > time
    1041         [ #  # ]:          0 :             && stream->last_time - time > GST_SECOND * 60 * 10)) {
    1042                 :            :       /* check first to see if we're in middle of detecting a discont in PCR.
    1043                 :            :        * if we are we're not sure what timestamp the buffer should have, best
    1044                 :            :        * to drop. */
    1045 [ #  # ][ #  # ]:          0 :       if (stream->PMT_pid <= MPEGTS_MAX_PID && demux->streams[stream->PMT_pid]
    1046         [ #  # ]:          0 :           && demux->streams[demux->streams[stream->PMT_pid]->PMT.PCR_PID]
    1047         [ #  # ]:          0 :           && demux->streams[demux->streams[stream->PMT_pid]->PMT.PCR_PID]->
    1048                 :            :           discont_PCR) {
    1049         [ #  # ]:          0 :         GST_WARNING_OBJECT (demux, "middle of discont, dropping");
    1050                 :          0 :         goto bad_timestamp;
    1051                 :            :       }
    1052                 :            :       /* check for wraparounds */
    1053         [ #  # ]:          0 :       else if (stream->last_time > 0 && time < stream->last_time &&
           [ #  #  #  # ]
    1054                 :          0 :           stream->last_time - time > MPEGTIME_TO_GSTTIME (G_MAXUINT32)) {
    1055                 :            :         /* wrap around occurred */
    1056         [ #  # ]:          0 :         if (stream->base_time + MPEGTIME_TO_GSTTIME ((guint64) (1) << 33) +
    1057                 :          0 :             MPEGTIME_TO_GSTTIME (pts) >
    1058                 :          0 :             stream->last_time + GST_SECOND * 60 * 10) {
    1059         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux,
    1060                 :            :               "looks like we have a corrupt packet because its pts is a lot lower than"
    1061                 :            :               " the previous pts but not a wraparound");
    1062                 :          0 :           goto bad_timestamp;
    1063                 :            :         }
    1064                 :            :         /* wraparound has occured but before we have detected in the pcr,
    1065                 :            :          * so check we're actually getting pcr's...if we are, don't update
    1066                 :            :          * the base time..just set the time and last_time correctly
    1067                 :            :          */
    1068 [ #  # ][ #  # ]:          0 :         if (stream->PMT_pid <= MPEGTS_MAX_PID && demux->streams[stream->PMT_pid]
    1069         [ #  # ]:          0 :             && demux->streams[demux->streams[stream->PMT_pid]->PMT.PCR_PID]
    1070         [ #  # ]:          0 :             && demux->streams[demux->streams[stream->PMT_pid]->PMT.PCR_PID]->
    1071                 :            :             last_PCR > 0) {
    1072         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux, "timestamps wrapped before noticed in PCR");
    1073                 :          0 :           time = MPEGTIME_TO_GSTTIME (pts) + stream->base_time +
    1074                 :          0 :               MPEGTIME_TO_GSTTIME ((guint64) (1) << 33);
    1075                 :          0 :           stream->last_time = time;
    1076                 :            :         } else {
    1077                 :          0 :           stream->base_time = stream->base_time +
    1078                 :          0 :               MPEGTIME_TO_GSTTIME ((guint64) (1) << 33);
    1079                 :          0 :           time = MPEGTIME_TO_GSTTIME (pts) + stream->base_time;
    1080 [ #  # ][ #  # ]:          0 :           GST_DEBUG_OBJECT (demux,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1081                 :            :               "timestamps wrapped around, compensating with new base time: %"
    1082                 :            :               GST_TIME_FORMAT "last time: %" GST_TIME_FORMAT " time: %"
    1083                 :            :               GST_TIME_FORMAT, GST_TIME_ARGS (stream->base_time),
    1084                 :            :               GST_TIME_ARGS (stream->last_time), GST_TIME_ARGS (time));
    1085                 :          0 :           stream->last_time = time;
    1086                 :            :         }
    1087         [ #  # ]:          0 :       } else if (stream->last_time > 0 && time > stream->last_time &&
           [ #  #  #  # ]
    1088         [ #  # ]:          0 :           time - stream->last_time > MPEGTIME_TO_GSTTIME (G_MAXUINT32) &&
    1089                 :          0 :           stream->base_time > 0) {
    1090                 :            :         /* had a previous wrap around */
    1091         [ #  # ]:          0 :         if (time - MPEGTIME_TO_GSTTIME ((guint64) (1) << 33) +
    1092                 :          0 :             GST_SECOND * 60 * 10 < stream->last_time) {
    1093         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux,
    1094                 :            :               "looks like we have a corrupt packet because its pts is a lot higher than"
    1095                 :            :               " the previous pts but not because of a wraparound or pcr discont");
    1096                 :          0 :           goto bad_timestamp;
    1097                 :            :         }
    1098         [ #  # ]:          0 :         if (ABS ((time - MPEGTIME_TO_GSTTIME ((guint64) (1) << 33)) -
    1099                 :          0 :                 stream->last_time) < GST_SECOND) {
    1100 [ #  # ][ #  # ]:          0 :           GST_DEBUG_OBJECT (demux,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1101                 :            :               "timestamps wrapped around earlier but we have an out of pts: %"
    1102                 :            :               G_GUINT64_FORMAT ", as %" GST_TIME_FORMAT " translated to: %"
    1103                 :            :               GST_TIME_FORMAT " and last_time of %" GST_TIME_FORMAT, pts,
    1104                 :            :               GST_TIME_ARGS (time),
    1105                 :            :               GST_TIME_ARGS (time - MPEGTIME_TO_GSTTIME ((guint64) (1) << 33)),
    1106                 :            :               GST_TIME_ARGS (stream->last_time));
    1107                 :          0 :           time = time - MPEGTIME_TO_GSTTIME ((guint64) (1) << 33);
    1108                 :            :         } else {
    1109 [ #  # ][ #  # ]:          0 :           GST_DEBUG_OBJECT (demux,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1110                 :            :               "timestamp may have wrapped around recently but not sure and pts"
    1111                 :            :               " is very different, dropping it timestamp of this packet: %"
    1112                 :            :               GST_TIME_FORMAT " compared to last timestamp: %" GST_TIME_FORMAT,
    1113                 :            :               GST_TIME_ARGS (time -
    1114                 :            :                   MPEGTIME_TO_GSTTIME ((guint64) (1) << (33))),
    1115                 :            :               GST_TIME_ARGS (stream->last_time));
    1116                 :          0 :           goto bad_timestamp;
    1117                 :            :         }
    1118                 :            : 
    1119                 :            :       } else {
    1120                 :            :         /* we must have a corrupt packet */
    1121 [ #  # ][ #  # ]:          0 :         GST_WARNING_OBJECT (demux, "looks like we have a corrupt packet because"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1122                 :            :             " its timestamp is buggered timestamp: %" GST_TIME_FORMAT
    1123                 :            :             " compared to" " last timestamp: %" GST_TIME_FORMAT,
    1124                 :            :             GST_TIME_ARGS (time), GST_TIME_ARGS (stream->last_time));
    1125                 :          0 :         goto bad_timestamp;
    1126                 :            :       }
    1127                 :            :     } else {                    /* do not set last_time if a packet with pts from before wrap
    1128                 :            :                                    around arrived after the wrap around occured */
    1129                 :          0 :       stream->last_time = time;
    1130                 :            :     }
    1131                 :            :   } else {
    1132                 :          0 :     time = GST_CLOCK_TIME_NONE;
    1133                 :          0 :     pts = -1;
    1134                 :            :   }
    1135                 :            : 
    1136 [ #  # ][ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "setting PTS to (%" G_GUINT64_FORMAT ") time: %"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1137                 :            :       GST_TIME_FORMAT " on buffer %p first buffer: %d base_time: %"
    1138                 :            :       GST_TIME_FORMAT, pts, GST_TIME_ARGS (time), buffer, first,
    1139                 :            :       GST_TIME_ARGS (stream->base_time));
    1140                 :            : 
    1141                 :          0 :   GST_BUFFER_TIMESTAMP (buffer) = time;
    1142                 :            : 
    1143                 :            :   /* check if we have a pad already */
    1144         [ #  # ]:          0 :   if (srcpad == NULL) {
    1145                 :            :     /* When adding a stream, require either a valid base PCR, or a valid PTS */
    1146         [ #  # ]:          0 :     if (!gst_mpegts_demux_setup_base_pts (demux, pts))
    1147                 :          0 :       goto bad_timestamp;
    1148                 :            : 
    1149                 :            :     /* fill in the last bits of the stream */
    1150                 :            :     /* if no stream type, then assume it based on the PES start code, 
    1151                 :            :      * needed for partial ts streams without PMT */
    1152         [ #  # ]:          0 :     if (G_UNLIKELY (stream->flags & MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN)) {
    1153         [ #  # ]:          0 :       if ((filter->start_code & 0xFFFFFFF0) == PACKET_VIDEO_START_CODE) {
    1154                 :            :         /* it is mpeg2 video */
    1155                 :          0 :         stream->stream_type = ST_VIDEO_MPEG2;
    1156                 :          0 :         stream->flags &= ~MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN;
    1157                 :          0 :         stream->flags |= MPEGTS_STREAM_FLAG_IS_VIDEO;
    1158         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux, "Found stream 0x%04x without PMT with video "
    1159                 :            :             "start_code. Treating as video", stream->PID);
    1160         [ #  # ]:          0 :       } else if ((filter->start_code & 0xFFFFFFE0) == PACKET_AUDIO_START_CODE) {
    1161                 :            :         /* it is mpeg audio */
    1162                 :          0 :         stream->stream_type = ST_AUDIO_MPEG2;
    1163                 :          0 :         stream->flags &= ~MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN;
    1164         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux, "Found stream 0x%04x without PMT with audio "
    1165                 :            :             "start_code. Treating as audio", stream->PID);
    1166                 :            :       } else {
    1167         [ #  # ]:          0 :         GST_LOG_OBJECT (demux, "Stream start code on pid 0x%04x is: 0x%x",
    1168                 :            :             stream->PID, filter->start_code);
    1169                 :            :       }
    1170                 :            :     }
    1171         [ #  # ]:          0 :     if (!gst_mpegts_demux_fill_stream (stream, filter->id, stream->stream_type))
    1172                 :          0 :       goto unknown_type;
    1173                 :            : 
    1174         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    1175                 :            :         "New stream 0x%04x of type 0x%02x with caps %" GST_PTR_FORMAT,
    1176                 :            :         stream->PID, stream->stream_type, GST_PAD_CAPS (stream->pad));
    1177                 :            : 
    1178                 :          0 :     srcpad = stream->pad;
    1179                 :            : 
    1180                 :            :     /* activate and add */
    1181                 :          0 :     gst_pad_set_active (srcpad, TRUE);
    1182                 :          0 :     gst_element_add_pad (GST_ELEMENT_CAST (demux), srcpad);
    1183                 :          0 :     demux->need_no_more_pads = TRUE;
    1184                 :            : 
    1185                 :          0 :     stream->discont = TRUE;
    1186                 :            : 
    1187                 :            :     /* send new_segment */
    1188                 :          0 :     gst_mpegts_demux_send_new_segment (demux, stream, pts);
    1189                 :            : 
    1190                 :            :     /* send tags */
    1191                 :          0 :     gst_mpegts_demux_send_tags_for_stream (demux, stream);
    1192                 :            :   }
    1193                 :            : 
    1194         [ #  # ]:          0 :   GST_DEBUG_OBJECT (srcpad, "pushing buffer");
    1195                 :          0 :   gst_buffer_set_caps (buffer, GST_PAD_CAPS (srcpad));
    1196         [ #  # ]:          0 :   if (stream->discont) {
    1197                 :          0 :     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
    1198                 :          0 :     stream->discont = FALSE;
    1199                 :            :   }
    1200                 :          0 :   ret = gst_pad_push (srcpad, buffer);
    1201                 :          0 :   ret = gst_mpegts_demux_combine_flows (demux, stream, ret);
    1202                 :            : 
    1203                 :          0 :   return ret;
    1204                 :            : 
    1205                 :            :   /* ERROR */
    1206                 :            : unknown_type:
    1207                 :            :   {
    1208         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "got unknown stream id 0x%02x, type 0x%02x",
    1209                 :            :         filter->id, stream->stream_type);
    1210                 :          0 :     gst_buffer_unref (buffer);
    1211                 :          0 :     return gst_mpegts_demux_combine_flows (demux, stream, GST_FLOW_NOT_LINKED);
    1212                 :            :   }
    1213                 :            : bad_timestamp:
    1214                 :            :   {
    1215                 :          0 :     gst_buffer_unref (buffer);
    1216                 :          0 :     return gst_mpegts_demux_combine_flows (demux, stream, GST_FLOW_OK);
    1217                 :            :   }
    1218                 :            : 
    1219                 :            : }
    1220                 :            : 
    1221                 :            : static void
    1222                 :          0 : gst_mpegts_demux_resync_cb (GstPESFilter * filter, GstMpegTSStream * stream)
    1223                 :            : {
    1224                 :            :   /* does nothing for now */
    1225                 :          0 : }
    1226                 :            : 
    1227                 :            : /*
    1228                 :            :  * CA_section() {
    1229                 :            :  *   table_id                  8 uimsbf   == 0x01
    1230                 :            :  *   section_syntax_indicator  1 bslbf    == 1
    1231                 :            :  *   '0'                       1 bslbf    == 0
    1232                 :            :  *   reserved                  2 bslbf
    1233                 :            :  *   section_length           12 uimsbf   == 00xxxxx...
    1234                 :            :  *   reserved                 18 bslbf
    1235                 :            :  *   version_number            5 uimsbf
    1236                 :            :  *   current_next_indicator    1 bslbf
    1237                 :            :  *   section_number            8 uimsbf
    1238                 :            :  *   last_section_number       8 uimsbf
    1239                 :            :  *   for (i=0; i<N;i++) {
    1240                 :            :  *     descriptor()
    1241                 :            :  *   }
    1242                 :            :  *   CRC_32                   32 rpchof
    1243                 :            :  * }
    1244                 :            :  */
    1245                 :            : static FORCE_INLINE gboolean
    1246                 :            : gst_mpegts_stream_parse_cat (GstMpegTSStream * stream,
    1247                 :            :     guint8 * data, guint datalen)
    1248                 :            : {
    1249                 :            :   GstMpegTSDemux *demux;
    1250                 :            : 
    1251                 :          0 :   demux = stream->demux;
    1252                 :            : 
    1253         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "parsing CA section");
    1254                 :          0 :   return TRUE;
    1255                 :            : }
    1256                 :            : 
    1257                 :            : static void
    1258                 :          0 : gst_mpegts_activate_pmt (GstMpegTSDemux * demux, GstMpegTSStream * stream)
    1259                 :            : {
    1260         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "activating PMT 0x%08x", stream->PID);
    1261                 :            : 
    1262                 :            :   /* gst_mpegts_demux_remove_pads (demux); */
    1263                 :            : 
    1264                 :          0 :   demux->current_PMT = stream->PID;
    1265                 :            : 
    1266                 :            :   /* PMT has been updated, signal the change */
    1267         [ #  # ]:          0 :   if (demux->current_PMT == stream->PID)
    1268                 :          0 :     g_object_notify ((GObject *) (demux), "pmt-info");
    1269                 :          0 : }
    1270                 :            : 
    1271                 :            : /*
    1272                 :            :  * TS_program_map_section() {
    1273                 :            :  *   table_id                          8 uimsbf   == 0x02
    1274                 :            :  *   section_syntax_indicator          1 bslbf    == 1
    1275                 :            :  *   '0'                               1 bslbf    == 0
    1276                 :            :  *   reserved                          2 bslbf
    1277                 :            :  *   section_length                   12 uimsbf   == 00xxxxx...
    1278                 :            :  *   program_number                   16 uimsbf
    1279                 :            :  *   reserved                          2 bslbf
    1280                 :            :  *   version_number                    5 uimsbf
    1281                 :            :  *   current_next_indicator            1 bslbf
    1282                 :            :  *   section_number                    8 uimsbf
    1283                 :            :  *   last_section_number               8 uimsbf
    1284                 :            :  *   reserved                          3 bslbf
    1285                 :            :  *   PCR_PID                          13 uimsbf
    1286                 :            :  *   reserved                          4 bslbf
    1287                 :            :  *   program_info_length              12 uimsbf   == 00xxxxx...
    1288                 :            :  *   for (i=0; i<N; i++) {
    1289                 :            :  *     descriptor()
    1290                 :            :  *   }
    1291                 :            :  *   for (i=0;i<N1;i++) {
    1292                 :            :  *     stream_type                     8 uimsbf
    1293                 :            :  *     reserved                        3 bslbf
    1294                 :            :  *     elementary_PID                 13 uimsnf
    1295                 :            :  *     reserved                        4 bslbf
    1296                 :            :  *     ES_info_length                 12 uimsbf   == 00xxxxx...
    1297                 :            :  *     for (i=0; i<N2; i++) {
    1298                 :            :  *       descriptor()
    1299                 :            :  *     }
    1300                 :            :  *   }
    1301                 :            :  *   CRC_32                           32 rpchof
    1302                 :            :  * }
    1303                 :            :  */
    1304                 :            : static FORCE_INLINE gboolean
    1305                 :            : gst_mpegts_stream_parse_pmt (GstMpegTSStream * stream,
    1306                 :            :     guint8 * data, guint datalen)
    1307                 :            : {
    1308                 :            :   GstMpegTSDemux *demux;
    1309                 :            :   gint entries;
    1310                 :            :   guint32 CRC;
    1311                 :            :   GstMpegTSPMT *PMT;
    1312                 :            :   guint version_number;
    1313                 :            :   guint8 current_next_indicator;
    1314                 :            :   guint16 program_number;
    1315                 :            : 
    1316                 :          0 :   demux = stream->demux;
    1317                 :            : 
    1318         [ #  # ]:          0 :   if (G_UNLIKELY (*data++ != 0x02))
    1319                 :            :     goto wrong_id;
    1320         [ #  # ]:          0 :   if ((data[0] & 0xc0) != 0x80)
    1321                 :            :     goto wrong_sync;
    1322         [ #  # ]:          0 :   if ((data[0] & 0x0c) != 0x00)
    1323                 :            :     goto wrong_seclen;
    1324                 :            : 
    1325                 :          0 :   data += 2;
    1326                 :            : 
    1327         [ #  # ]:          0 :   if (demux->check_crc)
    1328         [ #  # ]:          0 :     if (G_UNLIKELY (gst_mpegts_demux_calc_crc32 (data - 3, datalen) != 0))
    1329                 :            :       goto wrong_crc;
    1330                 :            : 
    1331         [ #  # ]:          0 :   GST_LOG_OBJECT (demux, "PMT section_length: %d", datalen - 3);
    1332                 :            : 
    1333                 :          0 :   PMT = &stream->PMT;
    1334                 :            : 
    1335                 :            :   /* check if version number changed */
    1336                 :          0 :   version_number = (data[2] & 0x3e) >> 1;
    1337         [ #  # ]:          0 :   GST_LOG_OBJECT (demux, "PMT version_number: %d", version_number);
    1338                 :            : 
    1339                 :          0 :   current_next_indicator = (data[2] & 0x01);
    1340         [ #  # ]:          0 :   GST_LOG_OBJECT (demux, "PMT current_next_indicator %d",
    1341                 :            :       current_next_indicator);
    1342         [ #  # ]:          0 :   if (current_next_indicator == 0)
    1343                 :            :     goto not_yet_applicable;
    1344                 :          0 :   program_number = GST_READ_UINT16_BE (data);
    1345                 :            : 
    1346 [ #  # ][ #  # ]:          0 :   if (demux->program_number != -1 && demux->program_number != program_number) {
    1347                 :            :     goto wrong_program_number;
    1348                 :            :   }
    1349         [ #  # ]:          0 :   if (demux->program_number == -1) {
    1350         [ #  # ]:          0 :     GST_INFO_OBJECT (demux, "No program number set, so using first parsed PMT"
    1351                 :            :         "'s program number: %d", program_number);
    1352                 :          0 :     demux->program_number = program_number;
    1353                 :            :   }
    1354                 :            : 
    1355         [ #  # ]:          0 :   if (version_number == PMT->version_number)
    1356                 :            :     goto same_version;
    1357                 :            : 
    1358                 :          0 :   PMT->version_number = version_number;
    1359                 :          0 :   PMT->current_next_indicator = current_next_indicator;
    1360                 :            : 
    1361                 :          0 :   stream->PMT.program_number = program_number;
    1362                 :          0 :   data += 3;
    1363         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT program_number: %d", PMT->program_number);
    1364                 :            : 
    1365                 :          0 :   PMT->section_number = *data++;
    1366         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT section_number: %d", PMT->section_number);
    1367                 :            : 
    1368                 :          0 :   PMT->last_section_number = *data++;
    1369         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT last_section_number: %d",
    1370                 :            :       PMT->last_section_number);
    1371                 :            : 
    1372                 :          0 :   PMT->PCR_PID = GST_READ_UINT16_BE (data);
    1373                 :          0 :   PMT->PCR_PID &= 0x1fff;
    1374                 :          0 :   data += 2;
    1375         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT PCR_PID: 0x%04x", PMT->PCR_PID);
    1376                 :            :   /* create or get stream, not much we can say about it except that when we get
    1377                 :            :    * a data stream and we need a PCR, we can use the stream to get/store the
    1378                 :            :    * base_PCR. */
    1379                 :          0 :   gst_mpegts_demux_get_stream_for_PID (demux, PMT->PCR_PID);
    1380                 :            : 
    1381         [ #  # ]:          0 :   if ((data[0] & 0x0c) != 0x00)
    1382                 :            :     goto wrong_pilen;
    1383                 :            : 
    1384                 :          0 :   PMT->program_info_length = GST_READ_UINT16_BE (data);
    1385                 :          0 :   PMT->program_info_length &= 0x0fff;
    1386                 :            :   /* FIXME: validate value of program_info_length */
    1387                 :          0 :   data += 2;
    1388                 :            : 
    1389                 :            :   /* FIXME: validate value of program_info_length, before using */
    1390                 :            : 
    1391                 :            :   /* parse descriptor */
    1392         [ #  # ]:          0 :   if (G_UNLIKELY (PMT->program_info))
    1393                 :          0 :     gst_mpeg_descriptor_free (PMT->program_info);
    1394                 :          0 :   PMT->program_info =
    1395                 :          0 :       gst_mpeg_descriptor_parse (data, PMT->program_info_length);
    1396                 :            : 
    1397                 :            :   /* skip descriptor */
    1398                 :          0 :   data += PMT->program_info_length;
    1399         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT program_info_length: %d",
    1400                 :            :       PMT->program_info_length);
    1401                 :            : 
    1402                 :          0 :   entries = datalen - 3 - PMT->program_info_length - 9 - 4;
    1403                 :            : 
    1404         [ #  # ]:          0 :   if (G_UNLIKELY (PMT->entries))
    1405                 :          0 :     g_array_free (PMT->entries, TRUE);
    1406                 :          0 :   PMT->entries = g_array_new (FALSE, TRUE, sizeof (GstMpegTSPMTEntry));
    1407                 :            : 
    1408         [ #  # ]:          0 :   while (entries > 0) {
    1409                 :            :     GstMpegTSPMTEntry entry;
    1410                 :            :     GstMpegTSStream *ES_stream;
    1411                 :            :     guint8 stream_type;
    1412                 :            :     guint16 ES_info_length;
    1413                 :            : 
    1414                 :          0 :     stream_type = *data++;
    1415                 :            : 
    1416                 :          0 :     entry.PID = GST_READ_UINT16_BE (data);
    1417                 :          0 :     entry.PID &= 0x1fff;
    1418                 :          0 :     data += 2;
    1419                 :            : 
    1420         [ #  # ]:          0 :     if ((data[0] & 0x0c) != 0x00)
    1421                 :            :       goto wrong_esilen;
    1422                 :            : 
    1423                 :          0 :     ES_info_length = GST_READ_UINT16_BE (data);
    1424                 :          0 :     ES_info_length &= 0x0fff;
    1425                 :          0 :     data += 2;
    1426                 :            : 
    1427                 :            :     /* get/create elementary stream */
    1428                 :          0 :     ES_stream = gst_mpegts_demux_get_stream_for_PID (demux, entry.PID);
    1429                 :            :     /* check if PID unknown */
    1430         [ #  # ]:          0 :     if (ES_stream->PID_type == PID_TYPE_UNKNOWN) {
    1431                 :            :       /* set as elementary */
    1432                 :          0 :       ES_stream->PID_type = PID_TYPE_ELEMENTARY;
    1433                 :            :       /* set stream type */
    1434                 :            :       /* hack for ITV HD (sid 10510, video pid 3401 */
    1435 [ #  # ][ #  # ]:          0 :       if (program_number == 10510 && entry.PID == 3401 &&
                 [ #  # ]
    1436                 :            :           stream_type == ST_PRIVATE_DATA)
    1437                 :          0 :         stream_type = ST_VIDEO_H264;
    1438                 :          0 :       ES_stream->stream_type = stream_type;
    1439                 :          0 :       ES_stream->flags &= ~MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN;
    1440                 :            : 
    1441                 :            :       /* init base and last time */
    1442                 :          0 :       ES_stream->base_time = 0;
    1443                 :          0 :       ES_stream->last_time = 0;
    1444                 :            : 
    1445                 :            :       /* parse descriptor */
    1446                 :          0 :       ES_stream->ES_info = gst_mpeg_descriptor_parse (data, ES_info_length);
    1447                 :            : 
    1448         [ #  # ]:          0 :       if (stream_type == ST_PRIVATE_SECTIONS) {
    1449                 :            :         /* not really an ES, so use section filter not pes filter */
    1450                 :            :         /* initialise section filter */
    1451                 :            :         GstCaps *caps;
    1452                 :            :         gchar name[13];
    1453                 :            : 
    1454                 :          0 :         g_snprintf (name, sizeof (name), "private_%04x", entry.PID);
    1455                 :          0 :         gst_section_filter_init (&ES_stream->section_filter);
    1456                 :          0 :         ES_stream->PID_type = PID_TYPE_PRIVATE_SECTION;
    1457                 :          0 :         ES_stream->pad = gst_pad_new_from_static_template (&private_template,
    1458                 :            :             name);
    1459                 :          0 :         gst_pad_set_active (ES_stream->pad, TRUE);
    1460                 :          0 :         caps = gst_caps_new_simple ("application/x-mpegts-private-section",
    1461                 :            :             NULL);
    1462                 :          0 :         gst_pad_use_fixed_caps (ES_stream->pad);
    1463                 :          0 :         gst_pad_set_caps (ES_stream->pad, caps);
    1464                 :          0 :         gst_caps_unref (caps);
    1465                 :            : 
    1466                 :          0 :         gst_element_add_pad (GST_ELEMENT_CAST (demux), ES_stream->pad);
    1467                 :            :       } else {
    1468                 :            :         /* Recognise video streams based on stream_type */
    1469         [ #  # ]:          0 :         if (gst_mpegts_stream_is_video (ES_stream))
    1470                 :          0 :           ES_stream->flags |= MPEGTS_STREAM_FLAG_IS_VIDEO;
    1471                 :            : 
    1472                 :            :         /* set adaptor */
    1473         [ #  # ]:          0 :         GST_LOG ("Initializing PES filter for PID %u", ES_stream->PID);
    1474                 :          0 :         gst_pes_filter_init (&ES_stream->filter, NULL, NULL);
    1475                 :            : 
    1476         [ #  # ]:          0 :         if (ES_stream->stream_type == ST_PRIVATE_DATA) {
    1477                 :          0 :           guint8 *dvb_sub_desc = gst_mpeg_descriptor_find (ES_stream->ES_info,
    1478                 :            :               DESC_DVB_SUBTITLING);
    1479                 :            : 
    1480                 :            :           /* enable gather PES for DVB subtitles since the dvbsuboverlay
    1481                 :            :            * expects complete PES packets */
    1482         [ #  # ]:          0 :           if (dvb_sub_desc) {
    1483                 :            :             /* FIXME: There's another place where pes filters could get
    1484                 :            :              * initialized. Might need similar temporary hack there as well */
    1485                 :          0 :             ES_stream->filter.gather_pes = TRUE;
    1486                 :            :           }
    1487                 :            :         }
    1488                 :          0 :         gst_pes_filter_set_callbacks (&ES_stream->filter,
    1489                 :            :             (GstPESFilterData) gst_mpegts_demux_data_cb,
    1490                 :            :             (GstPESFilterResync) gst_mpegts_demux_resync_cb, ES_stream);
    1491         [ #  # ]:          0 :         if (ES_stream->flags & MPEGTS_STREAM_FLAG_IS_VIDEO)
    1492                 :          0 :           ES_stream->filter.allow_unbounded = TRUE;
    1493                 :          0 :         ES_stream->PMT_pid = stream->PID;
    1494                 :            :       }
    1495                 :            :     }
    1496                 :            :     /* skip descriptor */
    1497                 :          0 :     data += ES_info_length;
    1498         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    1499                 :            :         "  PMT stream_type: %02x, PID: 0x%04x (ES_info_len %d)", stream_type,
    1500                 :            :         entry.PID, ES_info_length);
    1501                 :            : 
    1502                 :          0 :     g_array_append_val (PMT->entries, entry);
    1503                 :            : 
    1504                 :          0 :     entries -= 5 + ES_info_length;
    1505                 :            :   }
    1506                 :          0 :   CRC = GST_READ_UINT32_BE (data);
    1507         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PMT CRC: 0x%08x", CRC);
    1508                 :            : 
    1509         [ #  # ]:          0 :   if (demux->program_number == -1) {
    1510                 :            :     /* No program specified, take the first PMT */
    1511 [ #  # ][ #  # ]:          0 :     if (demux->current_PMT == 0 || demux->current_PMT == stream->PID)
    1512                 :          0 :       gst_mpegts_activate_pmt (demux, stream);
    1513                 :            :   } else {
    1514                 :            :     /* Program specified, activate this if it matches */
    1515         [ #  # ]:          0 :     if (demux->program_number == PMT->program_number)
    1516                 :          0 :       gst_mpegts_activate_pmt (demux, stream);
    1517                 :            :   }
    1518                 :            : 
    1519                 :          0 :   return TRUE;
    1520                 :            : 
    1521                 :            :   /* ERRORS */
    1522                 :            : wrong_crc:
    1523                 :            :   {
    1524         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "wrong crc");
    1525                 :          0 :     return FALSE;
    1526                 :            :   }
    1527                 :            : same_version:
    1528                 :            :   {
    1529         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "same version as existing PMT");
    1530                 :          0 :     return TRUE;
    1531                 :            :   }
    1532                 :            : wrong_program_number:
    1533                 :            :   {
    1534         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "PMT is for program number we don't care about");
    1535                 :          0 :     return TRUE;
    1536                 :            :   }
    1537                 :            : 
    1538                 :            : not_yet_applicable:
    1539                 :            :   {
    1540         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "Ignoring PMT with current_next_indicator = 0");
    1541                 :          0 :     return TRUE;
    1542                 :            :   }
    1543                 :            : wrong_id:
    1544                 :            :   {
    1545         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "expected table_id == 0, got 0x%02x", data[0]);
    1546                 :          0 :     return FALSE;
    1547                 :            :   }
    1548                 :            : wrong_sync:
    1549                 :            :   {
    1550         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "expected sync 10, got %02x", data[0]);
    1551                 :          0 :     return FALSE;
    1552                 :            :   }
    1553                 :            : wrong_seclen:
    1554                 :            :   {
    1555         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    1556                 :            :         "first two bits of section length must be 0, got %02x", data[0]);
    1557                 :          0 :     return FALSE;
    1558                 :            :   }
    1559                 :            : wrong_pilen:
    1560                 :            :   {
    1561         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    1562                 :            :         "first two bits of program_info length must be 0, got %02x", data[0]);
    1563                 :          0 :     return FALSE;
    1564                 :            :   }
    1565                 :            : wrong_esilen:
    1566                 :            :   {
    1567         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    1568                 :            :         "first two bits of ES_info length must be 0, got %02x", data[0]);
    1569                 :          0 :     g_array_free (stream->PMT.entries, TRUE);
    1570                 :          0 :     stream->PMT.entries = NULL;
    1571                 :          0 :     gst_mpeg_descriptor_free (stream->PMT.program_info);
    1572                 :          0 :     stream->PMT.program_info = NULL;
    1573                 :          0 :     return FALSE;
    1574                 :            :   }
    1575                 :            : }
    1576                 :            : 
    1577                 :            : /*
    1578                 :            :  * private_section() {
    1579                 :            :  *   table_id                                       8 uimsbf
    1580                 :            :  *   section_syntax_indicator                       1 bslbf
    1581                 :            :  *   private_indicator                              1 bslbf
    1582                 :            :  *   reserved                                       2 bslbf
    1583                 :            :  *   private_section_length                        12 uimsbf
    1584                 :            :  *   if (section_syntax_indicator == '0') {
    1585                 :            :  *     for ( i=0;i<N;i++) {
    1586                 :            :  *       private_data_byte                          8 bslbf
    1587                 :            :  *     }
    1588                 :            :  *   }
    1589                 :            :  *   else {
    1590                 :            :  *     table_id_extension                          16 uimsbf
    1591                 :            :  *     reserved                                     2 bslbf
    1592                 :            :  *     version_number                               5 uimsbf
    1593                 :            :  *     current_next_indicator                       1 bslbf
    1594                 :            :  *     section_number                               8 uimsbf
    1595                 :            :  *     last_section_number                          8 uimsbf
    1596                 :            :  *     for ( i=0;i<private_section_length-9;i++) {
    1597                 :            :  *       private_data_byte                          8 bslbf
    1598                 :            :  *     }
    1599                 :            :  *     CRC_32                                      32 rpchof
    1600                 :            :  *   }
    1601                 :            :  * }
    1602                 :            :  */
    1603                 :            : static FORCE_INLINE gboolean
    1604                 :            : gst_mpegts_stream_parse_private_section (GstMpegTSStream * stream,
    1605                 :            :     guint8 * data, guint datalen)
    1606                 :            : {
    1607                 :            :   GstMpegTSDemux *demux;
    1608                 :            :   GstBuffer *buffer;
    1609                 :          0 :   demux = stream->demux;
    1610                 :            : 
    1611         [ #  # ]:          0 :   if (demux->check_crc)
    1612         [ #  # ]:          0 :     if (gst_mpegts_demux_calc_crc32 (data, datalen) != 0)
    1613                 :            :       goto wrong_crc;
    1614                 :            : 
    1615                 :            :   /* just dump this down the pad */
    1616                 :          0 :   buffer = gst_buffer_new_and_alloc (datalen);
    1617                 :          0 :   memcpy (buffer->data, data, datalen);
    1618                 :          0 :   gst_pad_push (stream->pad, buffer);
    1619                 :            : 
    1620         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "parsing private section");
    1621                 :          0 :   return TRUE;
    1622                 :            : 
    1623                 :            : wrong_crc:
    1624                 :            :   {
    1625         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "wrong crc");
    1626                 :          0 :     return FALSE;
    1627                 :            :   }
    1628                 :            : }
    1629                 :            : 
    1630                 :            : /*
    1631                 :            :  * adaptation_field() {
    1632                 :            :  *   adaptation_field_length                              8 uimsbf
    1633                 :            :  *   if(adaptation_field_length >0) {
    1634                 :            :  *     discontinuity_indicator                            1 bslbf
    1635                 :            :  *     random_access_indicator                            1 bslbf
    1636                 :            :  *     elementary_stream_priority_indicator               1 bslbf
    1637                 :            :  *     PCR_flag                                           1 bslbf
    1638                 :            :  *     OPCR_flag                                          1 bslbf
    1639                 :            :  *     splicing_point_flag                                1 bslbf
    1640                 :            :  *     transport_private_data_flag                        1 bslbf
    1641                 :            :  *     adaptation_field_extension_flag                    1 bslbf
    1642                 :            :  *     if(PCR_flag == '1') {
    1643                 :            :  *       program_clock_reference_base                    33 uimsbf
    1644                 :            :  *       reserved                                         6 bslbf
    1645                 :            :  *       program_clock_reference_extension                9 uimsbf
    1646                 :            :  *     }
    1647                 :            :  *     if(OPCR_flag == '1') {
    1648                 :            :  *       original_program_clock_reference_base           33 uimsbf
    1649                 :            :  *       reserved                                         6 bslbf
    1650                 :            :  *       original_program_clock_reference_extension       9 uimsbf
    1651                 :            :  *     }
    1652                 :            :  *     if (splicing_point_flag == '1') {
    1653                 :            :  *       splice_countdown                                 8 tcimsbf
    1654                 :            :  *     }
    1655                 :            :  *     if(transport_private_data_flag == '1') {
    1656                 :            :  *       transport_private_data_length                    8 uimsbf
    1657                 :            :  *       for (i=0; i<transport_private_data_length;i++){
    1658                 :            :  *         private_data_byte                              8 bslbf
    1659                 :            :  *       }
    1660                 :            :  *     }
    1661                 :            :  *     if (adaptation_field_extension_flag == '1' ) {
    1662                 :            :  *       adaptation_field_extension_length                8 uimsbf
    1663                 :            :  *       ltw_flag                                         1 bslbf
    1664                 :            :  *       piecewise_rate_flag                              1 bslbf
    1665                 :            :  *       seamless_splice_flag                             1 bslbf
    1666                 :            :  *       reserved                                         5 bslbf
    1667                 :            :  *       if (ltw_flag == '1') {
    1668                 :            :  *         ltw_valid_flag                                 1 bslbf
    1669                 :            :  *         ltw_offset                                    15 uimsbf
    1670                 :            :  *       }
    1671                 :            :  *       if (piecewise_rate_flag == '1') {
    1672                 :            :  *         reserved                                       2 bslbf
    1673                 :            :  *         piecewise_rate                                22 uimsbf
    1674                 :            :  *       }
    1675                 :            :  *       if (seamless_splice_flag == '1'){
    1676                 :            :  *         splice_type                                    4 bslbf
    1677                 :            :  *         DTS_next_AU[32..30]                            3 bslbf
    1678                 :            :  *         marker_bit                                     1 bslbf
    1679                 :            :  *         DTS_next_AU[29..15]                           15 bslbf
    1680                 :            :  *         marker_bit                                     1 bslbf
    1681                 :            :  *         DTS_next_AU[14..0]                            15 bslbf
    1682                 :            :  *         marker_bit                                     1 bslbf
    1683                 :            :  *       }
    1684                 :            :  *       for ( i=0;i<N;i++) {
    1685                 :            :  *         reserved                                       8 bslbf
    1686                 :            :  *       }
    1687                 :            :  *     }
    1688                 :            :  *     for (i=0;i<N;i++){
    1689                 :            :  *       stuffing_byte                                    8 bslbf
    1690                 :            :  *     }
    1691                 :            :  *   }
    1692                 :            :  * }
    1693                 :            :  */
    1694                 :            : static FORCE_INLINE gboolean
    1695                 :            : gst_mpegts_demux_parse_adaptation_field (GstMpegTSStream * stream,
    1696                 :            :     const guint8 * data, guint data_len, guint * consumed)
    1697                 :            : {
    1698                 :            :   GstMpegTSDemux *demux;
    1699                 :            :   guint8 length;
    1700                 :            :   guint8 *data_end;
    1701                 :            :   gint i;
    1702                 :            :   GstMpegTSStream *pmt_stream;
    1703                 :            : 
    1704                 :          0 :   demux = stream->demux;
    1705                 :            : 
    1706                 :          0 :   data_end = ((guint8 *) data) + data_len;
    1707                 :            : 
    1708                 :          0 :   length = *data++;
    1709         [ #  # ]:          0 :   if (G_UNLIKELY (length > data_len))
    1710                 :            :     goto wrong_length;
    1711                 :            : 
    1712         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "parsing adaptation field, length %d", length);
    1713                 :            : 
    1714         [ #  # ]:          0 :   if (length > 0) {
    1715                 :          0 :     guint8 flags = *data++;
    1716                 :            : 
    1717         [ #  # ]:          0 :     GST_LOG_OBJECT (demux, "flags 0x%02x", flags);
    1718                 :            :     /* discontinuity flag */
    1719         [ #  # ]:          0 :     if (flags & 0x80) {
    1720         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "discontinuity flag set");
    1721                 :            :     }
    1722                 :            :     /* PCR_flag */
    1723         [ #  # ]:          0 :     if (flags & 0x10) {
    1724                 :            :       guint32 pcr1;
    1725                 :            :       guint16 pcr2;
    1726                 :            :       guint64 pcr, pcr_ext;
    1727                 :          0 :       gboolean valid_pcr = TRUE;
    1728                 :            : 
    1729                 :          0 :       pcr1 = GST_READ_UINT32_BE (data);
    1730                 :          0 :       pcr2 = GST_READ_UINT16_BE (data + 4);
    1731                 :          0 :       pcr = ((guint64) pcr1) << 1;
    1732                 :          0 :       pcr |= (pcr2 & 0x8000) >> 15;
    1733                 :          0 :       pcr_ext = (pcr2 & 0x01ff);
    1734         [ #  # ]:          0 :       if (pcr_ext)
    1735                 :          0 :         pcr = (pcr * 300 + pcr_ext % 300) / 300;
    1736 [ #  # ][ #  # ]:          0 :       GST_DEBUG_OBJECT (demux,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1737                 :            :           "have PCR %" G_GUINT64_FORMAT "(%" GST_TIME_FORMAT ") on PID 0x%04x "
    1738                 :            :           "and last pcr is %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")", pcr,
    1739                 :            :           GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (pcr)), stream->PID,
    1740                 :            :           stream->last_PCR,
    1741                 :            :           GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (stream->last_PCR)));
    1742                 :            :       /* pcr has been converted into units of 90Khz ticks 
    1743                 :            :        * so assume discont if last pcr was > 900000 (10 second) lower */
    1744 [ #  # ][ #  # ]:          0 :       if (stream->last_PCR != -1 &&
    1745         [ #  # ]:          0 :           (pcr - stream->last_PCR > 900000 || pcr < stream->last_PCR)) {
    1746                 :            :         GstClockTimeDiff base_time_difference;
    1747                 :            : 
    1748         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux,
    1749                 :            :             "looks like we have a discont, this pcr should really be approx: %"
    1750                 :            :             G_GUINT64_FORMAT, stream->last_PCR + stream->last_PCR_difference);
    1751         [ #  # ]:          0 :         if (stream->discont_PCR == FALSE) {
    1752         [ #  # ]:          0 :           if (pcr > stream->last_PCR) {
    1753                 :          0 :             base_time_difference = -MPEGTIME_TO_GSTTIME ((pcr -
    1754                 :            :                     (stream->last_PCR + stream->last_PCR_difference)));
    1755                 :            :           } else {
    1756                 :          0 :             base_time_difference = MPEGTIME_TO_GSTTIME ((stream->last_PCR +
    1757                 :            :                     stream->last_PCR_difference) - pcr);
    1758                 :            :           }
    1759                 :          0 :           stream->discont_PCR = TRUE;
    1760                 :          0 :           stream->discont_difference = base_time_difference;
    1761                 :          0 :           valid_pcr = FALSE;
    1762                 :            :         } else {
    1763                 :            :           GstClockTimeDiff base_time_difference;
    1764                 :            : 
    1765                 :            :           /* need to update all pmt streams in case this pcr is pcr 
    1766                 :            :            * for multiple programs */
    1767                 :            :           int j;
    1768                 :          0 :           gboolean *pmts_checked = (gboolean *) & demux->pmts_checked;
    1769                 :          0 :           memset (pmts_checked, 0, sizeof (gboolean) * (MPEGTS_MAX_PID + 1));
    1770                 :            : 
    1771         [ #  # ]:          0 :           for (j = 0; j < MPEGTS_MAX_PID + 1; j++) {
    1772         [ #  # ]:          0 :             if (demux->streams[j]
    1773         [ #  # ]:          0 :                 && demux->streams[j]->PMT_pid <= MPEGTS_MAX_PID) {
    1774         [ #  # ]:          0 :               if (!pmts_checked[demux->streams[j]->PMT_pid]) {
    1775                 :            :                 /* check if this is correct pcr for pmt */
    1776 [ #  # ][ #  # ]:          0 :                 if (demux->streams[demux->streams[j]->PMT_pid] &&
    1777                 :          0 :                     stream->PID ==
    1778                 :          0 :                     demux->streams[demux->streams[j]->PMT_pid]->PMT.PCR_PID) {
    1779                 :            :                   /* checking the pcr discont is similar this second time
    1780                 :            :                    * if similar, update the es pids
    1781                 :            :                    * if not, assume it's a false discont due to corruption
    1782                 :            :                    * or other */
    1783         [ #  # ]:          0 :                   if (pcr > stream->last_PCR) {
    1784                 :          0 :                     base_time_difference = -MPEGTIME_TO_GSTTIME ((pcr -
    1785                 :            :                             (stream->last_PCR + stream->last_PCR_difference)));
    1786                 :            :                   } else {
    1787                 :          0 :                     base_time_difference =
    1788                 :          0 :                         MPEGTIME_TO_GSTTIME ((stream->last_PCR +
    1789                 :            :                             stream->last_PCR_difference) - pcr);
    1790                 :            :                   }
    1791 [ #  # ][ #  # ]:          0 :                   if ((base_time_difference - stream->discont_difference > 0 &&
    1792                 :          0 :                           base_time_difference - stream->discont_difference <
    1793         [ #  # ]:          0 :                           GST_SECOND * 10) ||
    1794         [ #  # ]:          0 :                       (stream->discont_difference - base_time_difference > 0 &&
    1795                 :          0 :                           stream->discont_difference - base_time_difference <
    1796                 :            :                           GST_SECOND * 10)) {
    1797                 :          0 :                     pmt_stream = demux->streams[demux->streams[j]->PMT_pid];
    1798         [ #  # ]:          0 :                     GST_DEBUG_OBJECT (demux, "Updating base_time on all es "
    1799                 :            :                         "pids belonging to PMT 0x%02x", stream->PMT_pid);
    1800         [ #  # ]:          0 :                     for (i = 0; i < pmt_stream->PMT.entries->len; i++) {
    1801                 :          0 :                       GstMpegTSPMTEntry *cur_entry =
    1802                 :          0 :                           &g_array_index (pmt_stream->PMT.entries,
    1803                 :            :                           GstMpegTSPMTEntry, i);
    1804         [ #  # ]:          0 :                       GST_DEBUG_OBJECT (demux,
    1805                 :            :                           "Updating base time on " "pid 0x%02x by %"
    1806                 :            :                           G_GINT64_FORMAT, cur_entry->PID,
    1807                 :            :                           stream->discont_difference);
    1808         [ #  # ]:          0 :                       if (cur_entry->PID <= MPEGTS_MAX_PID
    1809         [ #  # ]:          0 :                           && demux->streams[cur_entry->PID]) {
    1810                 :          0 :                         demux->streams[cur_entry->PID]->base_time +=
    1811                 :          0 :                             stream->discont_difference;
    1812                 :            :                       }
    1813                 :            :                     }
    1814                 :            :                   } else {
    1815         [ #  # ]:          0 :                     GST_DEBUG_OBJECT (demux, "last PCR discont looked to be "
    1816                 :            :                         "bogus: previous discont difference %" G_GINT64_FORMAT
    1817                 :            :                         " now %" G_GINT64_FORMAT, stream->discont_difference,
    1818                 :            :                         base_time_difference);
    1819                 :          0 :                     valid_pcr = FALSE;
    1820                 :            :                   }
    1821                 :            :                 }
    1822                 :            :               }
    1823                 :          0 :               pmts_checked[demux->streams[j]->PMT_pid] = TRUE;
    1824                 :            :             }
    1825                 :            :           }
    1826                 :            : 
    1827                 :          0 :           stream->discont_PCR = FALSE;
    1828                 :          0 :           stream->discont_difference = 0;
    1829                 :            :         }
    1830         [ #  # ]:          0 :       } else if (stream->last_PCR != -1) {
    1831         [ #  # ]:          0 :         if (stream->discont_PCR) {
    1832         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux, "last PCR discont looked to be bogus");
    1833                 :          0 :           stream->discont_PCR = FALSE;
    1834                 :          0 :           stream->discont_difference = 0;
    1835                 :            :         }
    1836                 :          0 :         stream->last_PCR_difference = pcr - stream->last_PCR;
    1837                 :            :       }
    1838                 :            : 
    1839         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux,
    1840                 :            :           "valid pcr: %d last PCR difference: %" G_GUINT64_FORMAT, valid_pcr,
    1841                 :            :           stream->last_PCR_difference);
    1842         [ #  # ]:          0 :       if (valid_pcr) {
    1843                 :          0 :         GstMpegTSStream *PMT_stream = demux->streams[demux->current_PMT];
    1844                 :            : 
    1845 [ #  # ][ #  # ]:          0 :         if (PMT_stream && PMT_stream->PMT.PCR_PID == stream->PID) {
    1846         [ #  # ]:          0 :           if (demux->pcr[0] == -1) {
    1847         [ #  # ]:          0 :             GST_DEBUG ("RECORDING pcr[0]:%" G_GUINT64_FORMAT, pcr);
    1848                 :          0 :             demux->pcr[0] = pcr;
    1849                 :          0 :             demux->num_packets = 0;
    1850                 :            :           } /* Considering a difference of 1 sec ie 90000 ticks */
    1851 [ #  # ][ #  # ]:          0 :           else if (G_UNLIKELY (demux->pcr[1] == -1
    1852                 :            :                   && ((pcr - demux->pcr[0]) >= 90000))) {
    1853         [ #  # ]:          0 :             GST_DEBUG ("RECORDING pcr[1]:%" G_GUINT64_FORMAT, pcr);
    1854                 :          0 :             demux->pcr[1] = pcr;
    1855                 :            :           }
    1856                 :            :         }
    1857                 :          0 :         stream->last_PCR = pcr;
    1858                 :            : 
    1859 [ #  # ][ #  # ]:          0 :         if (demux->clock && demux->clock_base != GST_CLOCK_TIME_NONE) {
    1860                 :            :           gdouble r_squared;
    1861                 :            :           GstMpegTSStream *PMT_stream;
    1862                 :            : 
    1863                 :            :           /* for the reference start time we need to consult the PCR_PID of the
    1864                 :            :            * current PMT */
    1865                 :          0 :           PMT_stream = demux->streams[demux->current_PMT];
    1866         [ #  # ]:          0 :           if (PMT_stream->PMT.PCR_PID == stream->PID) {
    1867 [ #  # ][ #  # ]:          0 :             GST_LOG_OBJECT (demux,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1868                 :            :                 "internal %" GST_TIME_FORMAT " observation %" GST_TIME_FORMAT
    1869                 :            :                 " pcr: %" G_GUINT64_FORMAT " base_pcr: %" G_GUINT64_FORMAT
    1870                 :            :                 "pid: %d",
    1871                 :            :                 GST_TIME_ARGS (gst_clock_get_internal_time (demux->clock)),
    1872                 :            :                 GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (pcr) -
    1873                 :            :                     MPEGTIME_TO_GSTTIME (stream->base_PCR) + stream->base_time +
    1874                 :            :                     demux->clock_base), pcr, stream->base_PCR, stream->PID);
    1875                 :          0 :             gst_clock_add_observation (demux->clock,
    1876                 :            :                 gst_clock_get_internal_time (demux->clock),
    1877                 :          0 :                 demux->clock_base + stream->base_time +
    1878                 :          0 :                 MPEGTIME_TO_GSTTIME (pcr) -
    1879                 :          0 :                 MPEGTIME_TO_GSTTIME (stream->base_PCR), &r_squared);
    1880                 :            :           }
    1881                 :            :         }
    1882                 :            :       }
    1883                 :          0 :       data += 6;
    1884                 :            :     }
    1885                 :            :     /* OPCR_flag */
    1886         [ #  # ]:          0 :     if (flags & 0x08) {
    1887                 :            :       guint32 opcr1;
    1888                 :            :       guint16 opcr2;
    1889                 :            :       guint64 opcr, opcr_ext;
    1890                 :            : 
    1891                 :          0 :       opcr1 = GST_READ_UINT32_BE (data);
    1892                 :          0 :       opcr2 = GST_READ_UINT16_BE (data + 4);
    1893                 :          0 :       opcr = ((guint64) opcr1) << 1;
    1894                 :          0 :       opcr |= (opcr2 & 0x8000) >> 15;
    1895                 :          0 :       opcr_ext = (opcr2 & 0x01ff);
    1896         [ #  # ]:          0 :       if (opcr_ext)
    1897                 :          0 :         opcr = (opcr * 300 + opcr_ext % 300) / 300;
    1898         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "have OPCR %" G_GUINT64_FORMAT " on PID 0x%04x",
    1899                 :            :           opcr, stream->PID);
    1900                 :          0 :       stream->last_OPCR = opcr;
    1901                 :          0 :       data += 6;
    1902                 :            :     }
    1903                 :            :     /* splicing_point_flag */
    1904         [ #  # ]:          0 :     if (flags & 0x04) {
    1905                 :            :       guint8 splice_countdown;
    1906                 :            : 
    1907                 :          0 :       splice_countdown = *data++;
    1908         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "have splicing point, countdown %d",
    1909                 :            :           splice_countdown);
    1910                 :            :     }
    1911                 :            :     /* transport_private_data_flag */
    1912         [ #  # ]:          0 :     if (flags & 0x02) {
    1913                 :          0 :       guint8 plength = *data++;
    1914                 :            : 
    1915         [ #  # ]:          0 :       if (data + plength > data_end)
    1916                 :            :         goto private_data_too_large;
    1917                 :            : 
    1918         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "have private data, length: %d", plength);
    1919                 :          0 :       data += plength;
    1920                 :            :     }
    1921                 :            :     /* adaptation_field_extension_flag */
    1922         [ #  # ]:          0 :     if (flags & 0x01) {
    1923         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "have field extension");
    1924                 :            :     }
    1925                 :            :   }
    1926                 :            : 
    1927                 :          0 :   *consumed = length + 1;
    1928                 :          0 :   return TRUE;
    1929                 :            : 
    1930                 :            :   /* ERRORS */
    1931                 :            : wrong_length:
    1932                 :            :   {
    1933         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "length %d > %d", length, data_len);
    1934                 :          0 :     return FALSE;
    1935                 :            :   }
    1936                 :            : private_data_too_large:
    1937                 :            :   {
    1938         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "have too large a private data length");
    1939                 :          0 :     return FALSE;
    1940                 :            :   }
    1941                 :            : }
    1942                 :            : 
    1943                 :            : /*
    1944                 :            :  * program_association_section() {
    1945                 :            :  *   table_id                               8 uimsbf   == 0x00
    1946                 :            :  *   section_syntax_indicator               1 bslbf    == 1
    1947                 :            :  *   '0'                                    1 bslbf    == 0
    1948                 :            :  *   reserved                               2 bslbf
    1949                 :            :  *   section_length                        12 uimsbf   == 00xxxxx...
    1950                 :            :  *   transport_stream_id                   16 uimsbf
    1951                 :            :  *   reserved                               2 bslbf
    1952                 :            :  *   version_number                         5 uimsbf
    1953                 :            :  *   current_next_indicator                 1 bslbf
    1954                 :            :  *   section_number                         8 uimsbf
    1955                 :            :  *   last_section_number                    8 uimsbf
    1956                 :            :  *   for (i=0; i<N;i++) {
    1957                 :            :  *     program_number                      16 uimsbf
    1958                 :            :  *     reserved                             3 bslbf
    1959                 :            :  *     if(program_number == '0') {
    1960                 :            :  *       network_PID                       13 uimsbf
    1961                 :            :  *     }
    1962                 :            :  *     else {
    1963                 :            :  *       program_map_PID                   13 uimsbf
    1964                 :            :  *     }
    1965                 :            :  *   }
    1966                 :            :  *   CRC_32                                32 rpchof
    1967                 :            :  * }
    1968                 :            :  */
    1969                 :            : static FORCE_INLINE gboolean
    1970                 :            : gst_mpegts_stream_parse_pat (GstMpegTSStream * stream,
    1971                 :            :     guint8 * data, guint datalen)
    1972                 :            : {
    1973                 :            :   GstMpegTSDemux *demux;
    1974                 :            :   gint entries;
    1975                 :            :   guint32 CRC;
    1976                 :            :   guint version_number;
    1977                 :            :   guint8 current_next_indicator;
    1978                 :            :   GstMpegTSPAT *PAT;
    1979                 :            : 
    1980                 :          0 :   demux = stream->demux;
    1981                 :            : 
    1982         [ #  # ]:          0 :   if (datalen < 8)
    1983                 :          0 :     return FALSE;
    1984                 :            : 
    1985         [ #  # ]:          0 :   if (*data++ != 0x00)
    1986                 :            :     goto wrong_id;
    1987         [ #  # ]:          0 :   if ((data[0] & 0xc0) != 0x80)
    1988                 :            :     goto wrong_sync;
    1989         [ #  # ]:          0 :   if (G_UNLIKELY ((data[0] & 0x0c) != 0x00))
    1990                 :            :     goto wrong_seclen;
    1991                 :            : 
    1992                 :          0 :   data += 2;
    1993         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT section_length: %d", datalen - 3);
    1994                 :            : 
    1995         [ #  # ]:          0 :   if (demux->check_crc)
    1996         [ #  # ]:          0 :     if (gst_mpegts_demux_calc_crc32 (data - 3, datalen) != 0)
    1997                 :            :       goto wrong_crc;
    1998                 :            : 
    1999                 :          0 :   PAT = &stream->PAT;
    2000                 :            : 
    2001                 :          0 :   version_number = (data[2] & 0x3e) >> 1;
    2002         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT version_number: %d", version_number);
    2003         [ #  # ]:          0 :   if (G_UNLIKELY (version_number == PAT->version_number))
    2004                 :            :     goto same_version;
    2005                 :            : 
    2006                 :          0 :   current_next_indicator = (data[2] & 0x01);
    2007         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT current_next_indicator %d",
    2008                 :            :       current_next_indicator);
    2009         [ #  # ]:          0 :   if (current_next_indicator == 0)
    2010                 :            :     goto not_yet_applicable;
    2011                 :            : 
    2012                 :          0 :   PAT->version_number = version_number;
    2013                 :          0 :   PAT->current_next_indicator = current_next_indicator;
    2014                 :            : 
    2015                 :          0 :   PAT->transport_stream_id = GST_READ_UINT16_BE (data);
    2016                 :          0 :   data += 3;
    2017         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT stream_id: %d", PAT->transport_stream_id);
    2018                 :            : 
    2019                 :          0 :   PAT->section_number = *data++;
    2020                 :          0 :   PAT->last_section_number = *data++;
    2021                 :            : 
    2022         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT current_next_indicator: %d",
    2023                 :            :       PAT->current_next_indicator);
    2024         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT section_number: %d", PAT->section_number);
    2025         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT last_section_number: %d",
    2026                 :            :       PAT->last_section_number);
    2027                 :            : 
    2028                 :            :   /* 5 bytes after section length and a 4 bytes CRC, 
    2029                 :            :    * the rest is 4 byte entries */
    2030                 :          0 :   entries = (datalen - 3 - 9) / 4;
    2031                 :            : 
    2032         [ #  # ]:          0 :   if (PAT->entries)
    2033                 :          0 :     g_array_free (PAT->entries, TRUE);
    2034                 :          0 :   PAT->entries =
    2035                 :          0 :       g_array_sized_new (FALSE, TRUE, sizeof (GstMpegTSPATEntry), entries);
    2036                 :            : 
    2037         [ #  # ]:          0 :   while (entries--) {
    2038                 :            :     GstMpegTSPATEntry entry;
    2039                 :            :     GstMpegTSStream *PMT_stream;
    2040                 :            : 
    2041                 :          0 :     entry.program_number = GST_READ_UINT16_BE (data);
    2042                 :          0 :     data += 2;
    2043                 :          0 :     entry.PID = GST_READ_UINT16_BE (data);
    2044                 :          0 :     entry.PID &= 0x1fff;
    2045                 :          0 :     data += 2;
    2046                 :            : 
    2047                 :            :     /* get/create stream for PMT */
    2048                 :          0 :     PMT_stream = gst_mpegts_demux_get_stream_for_PID (demux, entry.PID);
    2049         [ #  # ]:          0 :     if (PMT_stream->PID_type != PID_TYPE_PROGRAM_MAP) {
    2050                 :            :       /* set as program map */
    2051                 :          0 :       PMT_stream->PID_type = PID_TYPE_PROGRAM_MAP;
    2052                 :            :       /* initialise section filter */
    2053                 :          0 :       gst_section_filter_init (&PMT_stream->section_filter);
    2054                 :            :     }
    2055                 :            : 
    2056                 :          0 :     g_array_append_val (PAT->entries, entry);
    2057                 :            : 
    2058         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "  PAT program: %d, PID 0x%04x",
    2059                 :            :         entry.program_number, entry.PID);
    2060                 :            :   }
    2061                 :          0 :   CRC = GST_READ_UINT32_BE (data);
    2062         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "PAT CRC: 0x%08x", CRC);
    2063                 :            : 
    2064                 :            :   /* PAT has been updated, signal the change */
    2065                 :          0 :   g_object_notify ((GObject *) (demux), "pat-info");
    2066                 :            : 
    2067                 :          0 :   return TRUE;
    2068                 :            : 
    2069                 :            :   /* ERRORS */
    2070                 :            : wrong_crc:
    2071                 :            :   {
    2072         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "wrong crc");
    2073                 :          0 :     return FALSE;
    2074                 :            :   }
    2075                 :            : same_version:
    2076                 :            :   {
    2077         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "same version as existing PAT");
    2078                 :          0 :     return TRUE;
    2079                 :            :   }
    2080                 :            : not_yet_applicable:
    2081                 :            :   {
    2082         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "Ignoring PAT with current_next_indicator = 0");
    2083                 :          0 :     return TRUE;
    2084                 :            :   }
    2085                 :            : wrong_id:
    2086                 :            :   {
    2087         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "expected table_id == 0, got %02x", data[0]);
    2088                 :          0 :     return FALSE;
    2089                 :            :   }
    2090                 :            : wrong_sync:
    2091                 :            :   {
    2092         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "expected sync 10, got %02x", data[0]);
    2093                 :          0 :     return FALSE;
    2094                 :            :   }
    2095                 :            : wrong_seclen:
    2096                 :            :   {
    2097         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux,
    2098                 :            :         "first two bits of section length must be 0, got %02x", data[0]);
    2099                 :          0 :     return FALSE;
    2100                 :            :   }
    2101                 :            : }
    2102                 :            : 
    2103                 :            : static gboolean
    2104                 :          0 : gst_mpegts_demux_is_PMT (GstMpegTSDemux * demux, guint16 PID)
    2105                 :            : {
    2106                 :            :   GstMpegTSStream *stream;
    2107                 :            :   GstMpegTSPAT *PAT;
    2108                 :            :   gint i;
    2109                 :            : 
    2110                 :            :   /* get the PAT */
    2111                 :          0 :   stream = demux->streams[PID_PROGRAM_ASSOCIATION_TABLE];
    2112 [ #  # ][ #  # ]:          0 :   if (stream == NULL || stream->PAT.entries == NULL)
    2113                 :          0 :     return FALSE;
    2114                 :            : 
    2115                 :          0 :   PAT = &stream->PAT;
    2116                 :            : 
    2117         [ #  # ]:          0 :   for (i = 0; i < PAT->entries->len; i++) {
    2118                 :            :     GstMpegTSPATEntry *entry;
    2119                 :            : 
    2120                 :          0 :     entry = &g_array_index (PAT->entries, GstMpegTSPATEntry, i);
    2121         [ #  # ]:          0 :     if (!entry)
    2122                 :          0 :       continue;
    2123                 :            : 
    2124         [ #  # ]:          0 :     if (entry->PID == PID)
    2125                 :          0 :       return TRUE;
    2126                 :            :   }
    2127                 :          0 :   return FALSE;
    2128                 :            : }
    2129                 :            : 
    2130                 :            : static FORCE_INLINE GstFlowReturn
    2131                 :            : gst_mpegts_stream_pes_buffer_flush (GstMpegTSStream * stream, gboolean discard)
    2132                 :            : {
    2133                 :          0 :   GstFlowReturn ret = GST_FLOW_OK;
    2134                 :            : 
    2135 [ #  # ][ #  # ]:          0 :   if (stream->pes_buffer) {
                 [ #  # ]
    2136 [ #  # ][ #  # ]:          0 :     if (discard) {
                 [ #  # ]
    2137                 :          0 :       gst_buffer_unref (stream->pes_buffer);
    2138                 :          0 :       stream->pes_buffer_in_sync = FALSE;
    2139                 :            :     } else {
    2140                 :          0 :       GST_BUFFER_SIZE (stream->pes_buffer) = stream->pes_buffer_used;
    2141                 :          0 :       ret = gst_pes_filter_push (&stream->filter, stream->pes_buffer);
    2142   [ #  #  #  #  :          0 :       if (ret == GST_FLOW_LOST_SYNC)
                   #  # ]
    2143                 :          0 :         stream->pes_buffer_in_sync = FALSE;
    2144                 :            :     }
    2145                 :          0 :     stream->pes_buffer = NULL;
    2146                 :            :   }
    2147                 :          0 :   return ret;
    2148                 :            : }
    2149                 :            : 
    2150                 :            : static FORCE_INLINE GstFlowReturn
    2151                 :            : gst_mpegts_stream_pes_buffer_push (GstMpegTSStream * stream,
    2152                 :            :     const guint8 * in_data, guint in_size)
    2153                 :            : {
    2154                 :          0 :   GstFlowReturn ret = GST_FLOW_OK;
    2155                 :            :   guint8 *out_data;
    2156                 :            : 
    2157 [ #  # ][ #  # ]:          0 :   if (G_UNLIKELY (stream->pes_buffer
    2158                 :            :           && stream->pes_buffer_used + in_size > stream->pes_buffer_size)) {
    2159         [ #  # ]:          0 :     GST_DEBUG ("stream with PID 0x%04x have PES buffer full at %u bytes."
    2160                 :            :         " Flushing and growing the buffer",
    2161                 :            :         stream->PID, stream->pes_buffer_size);
    2162                 :          0 :     stream->pes_buffer_overflow = TRUE;
    2163         [ #  # ]:          0 :     if (stream->pes_buffer_size < (MPEGTS_MAX_PES_BUFFER_SIZE >> 1))
    2164                 :          0 :       stream->pes_buffer_size <<= 1;
    2165                 :            : 
    2166                 :          0 :     ret = gst_mpegts_stream_pes_buffer_flush (stream, FALSE);
    2167         [ #  # ]:          0 :     if (ret == GST_FLOW_LOST_SYNC)
    2168                 :            :       goto done;
    2169                 :            :   }
    2170                 :            : 
    2171         [ #  # ]:          0 :   if (G_UNLIKELY (!stream->pes_buffer)) {
    2172                 :            :     /* set initial size of PES buffer */
    2173         [ #  # ]:          0 :     if (G_UNLIKELY (stream->pes_buffer_size == 0))
    2174                 :          0 :       stream->pes_buffer_size = MPEGTS_MIN_PES_BUFFER_SIZE;
    2175                 :            : 
    2176                 :          0 :     stream->pes_buffer = gst_buffer_new_and_alloc (stream->pes_buffer_size);
    2177                 :          0 :     stream->pes_buffer_used = 0;
    2178                 :            :   }
    2179                 :          0 :   out_data = GST_BUFFER_DATA (stream->pes_buffer) + stream->pes_buffer_used;
    2180                 :          0 :   memcpy (out_data, in_data, in_size);
    2181                 :          0 :   stream->pes_buffer_used += in_size;
    2182                 :            : done:
    2183                 :          0 :   return ret;
    2184                 :            : }
    2185                 :            : 
    2186                 :            : static FORCE_INLINE GstFlowReturn
    2187                 :            : gst_mpegts_demux_pes_buffer_flush (GstMpegTSDemux * demux, gboolean discard)
    2188                 :            : {
    2189                 :            :   gint i;
    2190                 :          0 :   GstFlowReturn ret = GST_FLOW_OK;
    2191                 :            : 
    2192         [ #  # ]:          0 :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
    2193                 :          0 :     GstMpegTSStream *stream = demux->streams[i];
    2194 [ #  # ][ #  # ]:          0 :     if (stream && stream->pad) {
    2195                 :            :       gst_mpegts_stream_pes_buffer_flush (stream, discard);
    2196                 :          0 :       stream->pes_buffer_in_sync = FALSE;
    2197                 :            :     }
    2198                 :            :   }
    2199                 :          0 :   return ret;
    2200                 :            : }
    2201                 :            : 
    2202                 :            : static FORCE_INLINE GstFlowReturn
    2203                 :            : gst_mpegts_demux_push_fragment (GstMpegTSStream * stream,
    2204                 :            :     const guint8 * in_data, guint in_size)
    2205                 :            : {
    2206                 :            :   GstFlowReturn ret;
    2207                 :          0 :   GstBuffer *es_buf = gst_buffer_new_and_alloc (in_size);
    2208                 :          0 :   memcpy (GST_BUFFER_DATA (es_buf), in_data, in_size);
    2209                 :          0 :   ret = gst_pes_filter_push (&stream->filter, es_buf);
    2210                 :            : 
    2211                 :            :   /* If PES filter return ok then PES fragment buffering 
    2212                 :            :    * can be enabled */
    2213   [ #  #  #  # ]:          0 :   if (ret == GST_FLOW_OK)
    2214                 :          0 :     stream->pes_buffer_in_sync = TRUE;
    2215 [ #  # ][ #  # ]:          0 :   else if (ret == GST_FLOW_LOST_SYNC)
    2216                 :          0 :     stream->pes_buffer_in_sync = FALSE;
    2217                 :          0 :   return ret;
    2218                 :            : }
    2219                 :            : 
    2220                 :            : /*
    2221                 :            :  * transport_packet(){
    2222                 :            :  *   sync_byte                                                               8 bslbf == 0x47
    2223                 :            :  *   transport_error_indicator                                               1 bslbf
    2224                 :            :  *   payload_unit_start_indicator                                            1 bslbf
    2225                 :            :  *   transport _priority                                                     1 bslbf
    2226                 :            :  *   PID                                                                    13 uimsbf
    2227                 :            :  *   transport_scrambling_control                                            2 bslbf
    2228                 :            :  *   adaptation_field_control                                                2 bslbf
    2229                 :            :  *   continuity_counter                                                      4 uimsbf
    2230                 :            :  *   if(adaptation_field_control=='10' || adaptation_field_control=='11'){
    2231                 :            :  *     adaptation_field()
    2232                 :            :  *   }
    2233                 :            :  *   if(adaptation_field_control=='01' || adaptation_field_control=='11') {
    2234                 :            :  *     for (i=0;i<N;i++){
    2235                 :            :  *       data_byte                                                           8 bslbf
    2236                 :            :  *     }
    2237                 :            :  *   }
    2238                 :            :  * }
    2239                 :            :  */
    2240                 :            : static FORCE_INLINE GstFlowReturn
    2241                 :            : gst_mpegts_demux_parse_stream (GstMpegTSDemux * demux, GstMpegTSStream * stream,
    2242                 :            :     const guint8 * in_data, guint in_size)
    2243                 :            : {
    2244                 :            :   GstFlowReturn ret;
    2245                 :            :   gboolean transport_error_indicator;
    2246                 :            :   gboolean payload_unit_start_indicator;
    2247                 :            :   gboolean transport_priority;
    2248                 :            :   guint16 PID;
    2249                 :            :   guint8 transport_scrambling_control;
    2250                 :            :   guint8 adaptation_field_control;
    2251                 :            :   guint8 continuity_counter;
    2252                 :          0 :   const guint8 *data = in_data;
    2253                 :          0 :   guint datalen = in_size;
    2254                 :            : 
    2255                 :          0 :   transport_error_indicator = (data[0] & 0x80) == 0x80;
    2256                 :          0 :   payload_unit_start_indicator = (data[0] & 0x40) == 0x40;
    2257                 :          0 :   transport_priority = (data[0] & 0x20) == 0x20;
    2258                 :          0 :   PID = stream->PID;
    2259                 :          0 :   transport_scrambling_control = (data[2] & 0xc0) >> 6;
    2260                 :          0 :   adaptation_field_control = (data[2] & 0x30) >> 4;
    2261                 :          0 :   continuity_counter = data[2] & 0x0f;
    2262                 :            : 
    2263                 :          0 :   data += 3;
    2264                 :          0 :   datalen -= 3;
    2265                 :            : 
    2266         [ #  # ]:          0 :   GST_LOG_OBJECT (demux, "afc 0x%x, pusi %d, PID 0x%04x datalen %u",
    2267                 :            :       adaptation_field_control, payload_unit_start_indicator, PID, datalen);
    2268                 :            : 
    2269                 :          0 :   ret = GST_FLOW_OK;
    2270                 :            : 
    2271                 :            :   /* packets with adaptation_field_control == 0 must be skipped */
    2272         [ #  # ]:          0 :   if (adaptation_field_control == 0)
    2273                 :            :     goto skip;
    2274                 :            : 
    2275                 :            :   /* parse adaption field if any */
    2276         [ #  # ]:          0 :   if (adaptation_field_control & 0x2) {
    2277                 :            :     guint consumed;
    2278                 :            : 
    2279         [ #  # ]:          0 :     if (!gst_mpegts_demux_parse_adaptation_field (stream, data,
    2280                 :            :             datalen, &consumed))
    2281                 :            :       goto done;
    2282                 :            : 
    2283         [ #  # ]:          0 :     if (datalen <= consumed)
    2284                 :            :       goto too_small;
    2285                 :            : 
    2286                 :          0 :     data += consumed;
    2287                 :          0 :     datalen -= consumed;
    2288         [ #  # ]:          0 :     GST_LOG_OBJECT (demux, "consumed: %u datalen: %u", consumed, datalen);
    2289                 :            :   }
    2290                 :            : 
    2291                 :            :   /* If this packet has a payload, handle it */
    2292         [ #  # ]:          0 :   if (adaptation_field_control & 0x1) {
    2293         [ #  # ]:          0 :     GST_LOG_OBJECT (demux, "Packet payload %d bytes, PID 0x%04x", datalen, PID);
    2294                 :            : 
    2295                 :            :     /* For unknown streams, check if the PID is in the partial PIDs
    2296                 :            :      * list as an elementary stream and override the type if so 
    2297                 :            :      */
    2298         [ #  # ]:          0 :     if (G_UNLIKELY (stream->PID_type == PID_TYPE_UNKNOWN)) {
    2299         [ #  # ]:          0 :       if (mpegts_is_elem_pid (demux, PID)) {
    2300         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux,
    2301                 :            :             "PID 0x%04x is an elementary stream in the PID list", PID);
    2302                 :          0 :         stream->PID_type = PID_TYPE_ELEMENTARY;
    2303                 :          0 :         stream->flags |= MPEGTS_STREAM_FLAG_STREAM_TYPE_UNKNOWN;
    2304                 :          0 :         stream->base_time = 0;
    2305                 :          0 :         stream->last_time = 0;
    2306                 :            : 
    2307                 :            :         /* Clear any existing descriptor */
    2308         [ #  # ]:          0 :         if (stream->ES_info) {
    2309                 :          0 :           gst_mpeg_descriptor_free (stream->ES_info);
    2310                 :          0 :           stream->ES_info = NULL;
    2311                 :            :         }
    2312                 :            : 
    2313                 :            :         /* Initialise our PES filter */
    2314         [ #  # ]:          0 :         GST_LOG ("Initializing PES filter for PID %u", stream->PID);
    2315                 :          0 :         gst_pes_filter_init (&stream->filter, NULL, NULL);
    2316                 :          0 :         gst_pes_filter_set_callbacks (&stream->filter,
    2317                 :            :             (GstPESFilterData) gst_mpegts_demux_data_cb,
    2318                 :            :             (GstPESFilterResync) gst_mpegts_demux_resync_cb, stream);
    2319                 :            :       }
    2320                 :            :     }
    2321                 :            : 
    2322                 :            :     /* now parse based on the stream type */
    2323   [ #  #  #  #  :          0 :     switch (stream->PID_type) {
                      # ]
    2324                 :            :       case PID_TYPE_PROGRAM_ASSOCIATION:
    2325                 :            :       case PID_TYPE_CONDITIONAL_ACCESS:
    2326                 :            :       case PID_TYPE_PROGRAM_MAP:
    2327                 :            :       case PID_TYPE_PRIVATE_SECTION:
    2328                 :            :       {
    2329                 :            :         GstBuffer *sec_buf;
    2330                 :            :         guint8 *section_data;
    2331                 :            :         guint16 section_length;
    2332                 :            :         guint8 pointer;
    2333                 :            : 
    2334                 :            :         /* do stuff with our section */
    2335         [ #  # ]:          0 :         if (payload_unit_start_indicator) {
    2336                 :          0 :           pointer = *data++;
    2337                 :          0 :           datalen -= 1;
    2338         [ #  # ]:          0 :           if (pointer >= datalen) {
    2339         [ #  # ]:          0 :             GST_DEBUG_OBJECT (demux, "pointer: 0x%02x too large", pointer);
    2340                 :          0 :             return GST_FLOW_OK;
    2341                 :            :           }
    2342                 :          0 :           data += pointer;
    2343                 :          0 :           datalen -= pointer;
    2344                 :            :         }
    2345                 :            : 
    2346                 :            :         /* FIXME: try to use data directly instead of creating a buffer and
    2347                 :            :            pushing in into adapter at section filter */
    2348                 :          0 :         sec_buf = gst_buffer_new_and_alloc (datalen);
    2349                 :          0 :         memcpy (GST_BUFFER_DATA (sec_buf), data, datalen);
    2350         [ #  # ]:          0 :         if (gst_section_filter_push (&stream->section_filter,
    2351                 :            :                 payload_unit_start_indicator, continuity_counter, sec_buf)) {
    2352         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux, "section finished");
    2353                 :            :           /* section ready */
    2354                 :          0 :           section_length = stream->section_filter.section_length;
    2355                 :          0 :           section_data =
    2356                 :          0 :               (guint8 *) gst_adapter_peek (stream->section_filter.adapter,
    2357                 :          0 :               section_length + 3);
    2358                 :            : 
    2359   [ #  #  #  #  :          0 :           switch (stream->PID_type) {
                      # ]
    2360                 :            :             case PID_TYPE_PROGRAM_ASSOCIATION:
    2361                 :          0 :               gst_mpegts_stream_parse_pat (stream, section_data,
    2362                 :          0 :                   section_length + 3);
    2363                 :            :               break;
    2364                 :            :             case PID_TYPE_CONDITIONAL_ACCESS:
    2365                 :          0 :               gst_mpegts_stream_parse_cat (stream, section_data,
    2366                 :          0 :                   section_length + 3);
    2367                 :            :               break;
    2368                 :            :             case PID_TYPE_PROGRAM_MAP:
    2369                 :          0 :               gst_mpegts_stream_parse_pmt (stream, section_data,
    2370                 :          0 :                   section_length + 3);
    2371                 :            :               break;
    2372                 :            :             case PID_TYPE_PRIVATE_SECTION:
    2373                 :          0 :               gst_mpegts_stream_parse_private_section (stream, section_data,
    2374                 :          0 :                   section_length + 3);
    2375                 :            :               break;
    2376                 :            :           }
    2377                 :            : 
    2378                 :          0 :           gst_section_filter_clear (&stream->section_filter);
    2379                 :            : 
    2380                 :            :         } else {
    2381                 :            :           /* section still going, don't parse left */
    2382         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux, "section still going for PID 0x%04x", PID);
    2383                 :            :         }
    2384                 :            :         break;
    2385                 :            :       }
    2386                 :            :       case PID_TYPE_NULL_PACKET:
    2387         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux,
    2388                 :            :             "skipping PID 0x%04x, type 0x%04x (NULL packet)", PID,
    2389                 :            :             stream->PID_type);
    2390                 :            :         break;
    2391                 :            :       case PID_TYPE_UNKNOWN:
    2392         [ #  # ]:          0 :         GST_DEBUG_OBJECT (demux, "skipping unknown PID 0x%04x, type 0x%04x",
    2393                 :            :             PID, stream->PID_type);
    2394                 :            :         break;
    2395                 :            :       case PID_TYPE_ELEMENTARY:
    2396                 :            :       {
    2397         [ #  # ]:          0 :         if (payload_unit_start_indicator) {
    2398         [ #  # ]:          0 :           GST_DEBUG_OBJECT (demux, "new PES start for PID 0x%04x, used %u "
    2399                 :            :               "bytes of %u bytes in the PES buffer",
    2400                 :            :               PID, stream->pes_buffer_used, stream->pes_buffer_size);
    2401                 :            :           /* Flush buffered PES data */
    2402                 :            :           gst_mpegts_stream_pes_buffer_flush (stream, FALSE);
    2403                 :          0 :           gst_pes_filter_drain (&stream->filter);
    2404                 :            :           /* Resize the buffer to half if no overflow detected and
    2405                 :            :            * had been used less than half of it */
    2406         [ #  # ]:          0 :           if (stream->pes_buffer_overflow == FALSE
    2407         [ #  # ]:          0 :               && stream->pes_buffer_used < (stream->pes_buffer_size >> 1)) {
    2408                 :          0 :             stream->pes_buffer_size >>= 1;
    2409         [ #  # ]:          0 :             if (stream->pes_buffer_size < MPEGTS_MIN_PES_BUFFER_SIZE)
    2410                 :          0 :               stream->pes_buffer_size = MPEGTS_MIN_PES_BUFFER_SIZE;
    2411         [ #  # ]:          0 :             GST_DEBUG_OBJECT (demux, "PES buffer size reduced to %u bytes",
    2412                 :            :                 stream->pes_buffer_size);
    2413                 :            :           }
    2414                 :            :           /* mark the stream not in sync to give a chance on PES filter to 
    2415                 :            :            * detect lost sync */
    2416                 :          0 :           stream->pes_buffer_in_sync = FALSE;
    2417                 :          0 :           stream->pes_buffer_overflow = FALSE;
    2418                 :            :         }
    2419         [ #  # ]:          0 :         GST_LOG_OBJECT (demux, "Elementary packet of size %u for PID 0x%04x",
    2420                 :            :             datalen, PID);
    2421                 :            : 
    2422         [ #  # ]:          0 :         if (datalen > 0) {
    2423         [ #  # ]:          0 :           if (!stream->pes_buffer_in_sync) {
    2424                 :            :             /* Push the first fragment to PES filter to have a chance to
    2425                 :            :              * detect GST_FLOW_LOST_SYNC.
    2426                 :            :              */
    2427         [ #  # ]:          0 :             GST_LOG_OBJECT (demux, "fragment directly pushed to PES filter");
    2428                 :          0 :             ret = gst_mpegts_demux_push_fragment (stream, data, datalen);
    2429                 :            :           } else {
    2430                 :            :             /* Otherwhise we buffer the PES fragment */
    2431                 :          0 :             ret = gst_mpegts_stream_pes_buffer_push (stream, data, datalen);
    2432                 :            :             /* If sync is lost here is due a pes_buffer_flush and we can try
    2433                 :            :              * to resync in the PES filter with the current fragment
    2434                 :            :              */
    2435         [ #  # ]:          0 :             if (ret == GST_FLOW_LOST_SYNC) {
    2436         [ #  # ]:          0 :               GST_LOG_OBJECT (demux, "resync, fragment pushed to PES filter");
    2437                 :          0 :               ret = gst_mpegts_demux_push_fragment (stream, data, datalen);
    2438                 :            :             }
    2439                 :            :           }
    2440                 :            : 
    2441                 :            :           break;
    2442                 :            :         } else {
    2443         [ #  # ]:          0 :           GST_WARNING_OBJECT (demux, "overflow of datalen: %u so skipping",
    2444                 :            :               datalen);
    2445                 :          0 :           return GST_FLOW_OK;
    2446                 :            :         }
    2447                 :            : 
    2448                 :            :       }
    2449                 :            :     }
    2450                 :            :   }
    2451                 :            : 
    2452                 :            : done:
    2453                 :          0 :   return ret;
    2454                 :            : 
    2455                 :            : skip:
    2456                 :            :   {
    2457         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "skipping, adaptation_field_control == 0");
    2458                 :          0 :     return GST_FLOW_OK;
    2459                 :            :   }
    2460                 :            : too_small:
    2461                 :            :   {
    2462         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "skipping, adaptation_field consumed all data");
    2463                 :          0 :     return GST_FLOW_OK;
    2464                 :            :   }
    2465                 :            : }
    2466                 :            : 
    2467                 :            : static FORCE_INLINE GstFlowReturn
    2468                 :            : gst_mpegts_demux_parse_transport_packet (GstMpegTSDemux * demux,
    2469                 :            :     const guint8 * data)
    2470                 :            : {
    2471                 :          0 :   GstFlowReturn ret = GST_FLOW_OK;
    2472                 :            :   guint16 PID;
    2473                 :            :   GstMpegTSStream *stream;
    2474                 :            : 
    2475                 :            :   /* skip sync byte */
    2476                 :          0 :   data++;
    2477                 :            : 
    2478                 :            :   /* get PID */
    2479                 :          0 :   PID = ((data[0] & 0x1f) << 8) | data[1];
    2480                 :            : 
    2481                 :            :   /* Skip NULL packets */
    2482         [ #  # ]:          0 :   if (G_UNLIKELY (PID == 0x1fff))
    2483                 :            :     goto beach;
    2484                 :            : 
    2485                 :            :   /* get the stream. */
    2486                 :          0 :   stream = gst_mpegts_demux_get_stream_for_PID (demux, PID);
    2487                 :            : 
    2488                 :            :   /* parse the stream */
    2489                 :          0 :   ret = gst_mpegts_demux_parse_stream (demux, stream, data,
    2490                 :            :       MPEGTS_NORMAL_TS_PACKETSIZE - 1);
    2491                 :            : 
    2492 [ #  # ][ #  # ]:          0 :   if (demux->pcr[1] != -1 && demux->bitrate == -1) {
    2493                 :            :     guint64 bitrate;
    2494         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "pcr[0]:%" G_GUINT64_FORMAT, demux->pcr[0]);
    2495         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "pcr[1]:%" G_GUINT64_FORMAT, demux->pcr[1]);
    2496 [ #  # ][ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "diff in time %" GST_TIME_FORMAT,
         [ #  # ][ #  # ]
                 [ #  # ]
    2497                 :            :         GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->pcr[1] - demux->pcr[0])));
    2498         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "stream->last_PCR_difference: %" G_GUINT64_FORMAT
    2499                 :            :         ", demux->num_packets %" G_GUINT64_FORMAT,
    2500                 :            :         demux->pcr[1] - demux->pcr[0], demux->num_packets);
    2501                 :          0 :     bitrate = gst_util_uint64_scale (GST_SECOND,
    2502                 :          0 :         MPEGTS_NORMAL_TS_PACKETSIZE * demux->num_packets,
    2503                 :          0 :         MPEGTIME_TO_GSTTIME (demux->pcr[1] - demux->pcr[0]));
    2504                 :            :     /* somehow... I doubt a bitrate below one packet per second is valid */
    2505         [ #  # ]:          0 :     if (bitrate > MPEGTS_NORMAL_TS_PACKETSIZE - 1) {
    2506                 :          0 :       demux->bitrate = bitrate;
    2507         [ #  # ]:          0 :       GST_DEBUG_OBJECT (demux, "bitrate is %" G_GINT64_FORMAT
    2508                 :            :           " bytes per second", demux->bitrate);
    2509                 :            :     } else {
    2510         [ #  # ]:          0 :       GST_WARNING_OBJECT (demux, "Couldn't compute valid bitrate, recomputing");
    2511                 :          0 :       demux->pcr[0] = demux->pcr[1] = -1;
    2512                 :          0 :       demux->num_packets = -1;
    2513                 :            :     }
    2514                 :            :   }
    2515                 :            : 
    2516                 :            : beach:
    2517                 :          0 :   demux->num_packets++;
    2518                 :          0 :   return ret;
    2519                 :            : 
    2520                 :            :   /* ERRORS */
    2521                 :            : }
    2522                 :            : 
    2523                 :            : static gboolean
    2524                 :          0 : gst_mpegts_demux_handle_seek_push (GstMpegTSDemux * demux, GstEvent * event)
    2525                 :            : {
    2526                 :          0 :   gboolean res = FALSE;
    2527                 :            :   gdouble rate;
    2528                 :            :   GstFormat format;
    2529                 :            :   GstSeekFlags flags;
    2530                 :            :   GstSeekType start_type, stop_type;
    2531                 :            :   gint64 start, stop, bstart, bstop;
    2532                 :            :   GstEvent *bevent;
    2533                 :            : 
    2534                 :          0 :   gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
    2535                 :            :       &stop_type, &stop);
    2536                 :            : 
    2537 [ #  # ][ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2538                 :            :       " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
    2539                 :            :       GST_TIME_ARGS (stop));
    2540                 :            : 
    2541         [ #  # ]:          0 :   if (format == GST_FORMAT_BYTES) {
    2542         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
    2543                 :          0 :     goto beach;
    2544                 :            :   }
    2545                 :            : 
    2546         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "seek - trying directly upstream first");
    2547                 :            : 
    2548                 :            :   /* first try original format seek */
    2549                 :          0 :   res = gst_pad_push_event (demux->sinkpad, gst_event_ref (event));
    2550         [ #  # ]:          0 :   if (res == TRUE)
    2551                 :          0 :     goto beach;
    2552         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "seek - no upstream");
    2553                 :            : 
    2554         [ #  # ]:          0 :   if (format != GST_FORMAT_TIME) {
    2555                 :            :     /* From here down, we only support time based seeks */
    2556         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
    2557                 :          0 :     goto beach;
    2558                 :            :   }
    2559                 :            : 
    2560                 :            :   /* We need to convert to byte based seek and we need a scr_rate for that. */
    2561         [ #  # ]:          0 :   if (demux->bitrate == -1) {
    2562         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "seek not possible, no bitrate");
    2563                 :          0 :     goto beach;
    2564                 :            :   }
    2565                 :            : 
    2566         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "try with bitrate");
    2567                 :            : 
    2568         [ #  # ]:          0 :   bstart = GSTTIME_TO_BYTES (start);
    2569         [ #  # ]:          0 :   bstop = GSTTIME_TO_BYTES (stop);
    2570                 :            : 
    2571         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "in bytes bstart %" G_GINT64_FORMAT " bstop %"
    2572                 :            :       G_GINT64_FORMAT, bstart, bstop);
    2573                 :          0 :   bevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, start_type,
    2574                 :            :       bstart, stop_type, bstop);
    2575                 :            : 
    2576                 :          0 :   res = gst_pad_push_event (demux->sinkpad, bevent);
    2577                 :            : 
    2578                 :            : beach:
    2579                 :          0 :   gst_event_unref (event);
    2580                 :          0 :   return res;
    2581                 :            : }
    2582                 :            : 
    2583                 :            : static gboolean
    2584                 :          0 : gst_mpegts_demux_src_event (GstPad * pad, GstEvent * event)
    2585                 :            : {
    2586                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
    2587                 :          0 :   gboolean res = FALSE;
    2588                 :            : 
    2589         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "got event %s",
    2590                 :            :       gst_event_type_get_name (GST_EVENT_TYPE (event)));
    2591                 :            : 
    2592         [ #  # ]:          0 :   switch (GST_EVENT_TYPE (event)) {
    2593                 :            :     case GST_EVENT_SEEK:
    2594                 :          0 :       res = gst_mpegts_demux_handle_seek_push (demux, event);
    2595                 :          0 :       break;
    2596                 :            :     default:
    2597                 :          0 :       res = gst_pad_push_event (demux->sinkpad, event);
    2598                 :          0 :       break;
    2599                 :            :   }
    2600                 :            : 
    2601                 :          0 :   gst_object_unref (demux);
    2602                 :            : 
    2603                 :          0 :   return res;
    2604                 :            : }
    2605                 :            : 
    2606                 :            : static void
    2607                 :          0 : gst_mpegts_demux_flush (GstMpegTSDemux * demux, gboolean discard)
    2608                 :            : {
    2609                 :            :   gint i;
    2610                 :            :   GstMpegTSStream *PCR_stream;
    2611                 :            :   GstMpegTSStream *PMT_stream;
    2612                 :            : 
    2613         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "flushing MPEG TS demuxer (discard %d)", discard);
    2614                 :            : 
    2615                 :            :   /* Start by flushing internal buffers */
    2616                 :            :   gst_mpegts_demux_pes_buffer_flush (demux, discard);
    2617                 :            : 
    2618                 :            :   /* Clear adapter */
    2619                 :          0 :   gst_adapter_clear (demux->adapter);
    2620                 :            : 
    2621                 :            :   /* Try resetting the last_PCR value as we will have a discont */
    2622         [ #  # ]:          0 :   if (demux->current_PMT == 0)
    2623                 :          0 :     goto beach;
    2624                 :            : 
    2625                 :          0 :   PMT_stream = demux->streams[demux->current_PMT];
    2626         [ #  # ]:          0 :   if (PMT_stream == NULL)
    2627                 :          0 :     goto beach;
    2628                 :            : 
    2629                 :          0 :   PCR_stream = demux->streams[PMT_stream->PMT.PCR_PID];
    2630         [ #  # ]:          0 :   if (PCR_stream == NULL)
    2631                 :          0 :     goto beach;
    2632                 :            : 
    2633                 :          0 :   PCR_stream->last_PCR = -1;
    2634                 :            : 
    2635                 :            :   /* Reset last time of all streams */
    2636         [ #  # ]:          0 :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
    2637                 :          0 :     GstMpegTSStream *stream = demux->streams[i];
    2638                 :            : 
    2639         [ #  # ]:          0 :     if (stream) {
    2640                 :          0 :       stream->last_time = 0;
    2641                 :          0 :       stream->discont = TRUE;
    2642                 :            :     }
    2643                 :            :   }
    2644                 :            : 
    2645                 :            : 
    2646                 :            : beach:
    2647                 :          0 :   return;
    2648                 :            : }
    2649                 :            : 
    2650                 :            : static gboolean
    2651                 :          0 : gst_mpegts_demux_send_event (GstMpegTSDemux * demux, GstEvent * event)
    2652                 :            : {
    2653                 :            :   gint i;
    2654                 :          0 :   gboolean have_stream = FALSE, res = TRUE;
    2655                 :            : 
    2656         [ #  # ]:          0 :   for (i = 0; i < MPEGTS_MAX_PID + 1; i++) {
    2657                 :          0 :     GstMpegTSStream *stream = demux->streams[i];
    2658                 :            : 
    2659 [ #  # ][ #  # ]:          0 :     if (stream && stream->pad) {
    2660                 :          0 :       res &= gst_pad_push_event (stream->pad, gst_event_ref (event));
    2661                 :          0 :       have_stream = TRUE;
    2662                 :            :     }
    2663                 :            :   }
    2664                 :          0 :   gst_event_unref (event);
    2665                 :            : 
    2666                 :          0 :   return have_stream;
    2667                 :            : }
    2668                 :            : 
    2669                 :            : static gboolean
    2670                 :          0 : gst_mpegts_demux_sink_event (GstPad * pad, GstEvent * event)
    2671                 :            : {
    2672                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
    2673                 :          0 :   gboolean res = FALSE;
    2674                 :            : 
    2675         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "got event %s",
    2676                 :            :       gst_event_type_get_name (GST_EVENT_TYPE (event)));
    2677                 :            : 
    2678   [ #  #  #  #  :          0 :   switch (GST_EVENT_TYPE (event)) {
                      # ]
    2679                 :            :     case GST_EVENT_FLUSH_START:
    2680                 :          0 :       res = gst_mpegts_demux_send_event (demux, event);
    2681                 :          0 :       break;
    2682                 :            :     case GST_EVENT_FLUSH_STOP:
    2683                 :          0 :       gst_adapter_clear (demux->adapter);
    2684                 :          0 :       gst_mpegts_demux_flush (demux, TRUE);
    2685                 :          0 :       res = gst_mpegts_demux_send_event (demux, event);
    2686                 :          0 :       break;
    2687                 :            :     case GST_EVENT_EOS:
    2688                 :          0 :       gst_mpegts_demux_flush (demux, FALSE);
    2689                 :            :       /* Send the EOS event on each stream */
    2690         [ #  # ]:          0 :       if (!(res = gst_mpegts_demux_send_event (demux, event))) {
    2691                 :            :         /* we have no streams */
    2692 [ #  # ][ #  # ]:          0 :         GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND,
         [ #  # ][ #  # ]
    2693                 :            :             (NULL), ("No valid streams found at EOS"));
    2694                 :            :       }
    2695                 :          0 :       break;
    2696                 :            :     case GST_EVENT_NEWSEGMENT:
    2697                 :            :     {
    2698                 :            :       gboolean update;
    2699                 :            :       gdouble rate;
    2700                 :            :       GstFormat format;
    2701                 :            :       gint64 start, stop, time;
    2702                 :            : 
    2703                 :          0 :       gst_event_parse_new_segment (event, &update, &rate, &format,
    2704                 :            :           &start, &stop, &time);
    2705                 :            : 
    2706                 :          0 :       gst_event_unref (event);
    2707         [ #  # ]:          0 :       GST_INFO_OBJECT (demux, "received new segment: rate %g "
    2708                 :            :           "format %d, start: %" G_GINT64_FORMAT ", stop: %" G_GINT64_FORMAT
    2709                 :            :           ", time: %" G_GINT64_FORMAT, rate, format, start, stop, time);
    2710 [ #  # ][ #  # ]:          0 :       if (format == GST_FORMAT_BYTES && demux->bitrate != -1) {
    2711                 :          0 :         gint64 tstart = 0, tstop = 0, pos = 0;
    2712                 :            : 
    2713         [ #  # ]:          0 :         if (demux->base_pts != GST_CLOCK_TIME_NONE) {
    2714                 :          0 :           tstart = tstop = demux->base_pts;
    2715                 :            :         }
    2716         [ #  # ]:          0 :         tstart += BYTES_TO_GSTTIME (start);
    2717         [ #  # ]:          0 :         tstop += BYTES_TO_GSTTIME (stop);
    2718         [ #  # ]:          0 :         pos = BYTES_TO_GSTTIME (time);
    2719                 :            : 
    2720                 :          0 :         event = gst_event_new_new_segment (update, rate,
    2721                 :            :             GST_FORMAT_TIME, tstart, tstop, pos);
    2722 [ #  # ][ #  # ]:          0 :         GST_DEBUG_OBJECT (demux, "pushing time newsegment from %"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2723                 :            :             GST_TIME_FORMAT " to %" GST_TIME_FORMAT " pos %" GST_TIME_FORMAT,
    2724                 :            :             GST_TIME_ARGS (tstart), GST_TIME_ARGS (tstop), GST_TIME_ARGS (pos));
    2725                 :            : 
    2726                 :          0 :         res = gst_mpegts_demux_send_event (demux, event);
    2727                 :            :       }
    2728                 :          0 :       break;
    2729                 :            :     }
    2730                 :            :     default:
    2731                 :          0 :       res = gst_mpegts_demux_send_event (demux, event);
    2732                 :          0 :       break;
    2733                 :            :   }
    2734                 :          0 :   gst_object_unref (demux);
    2735                 :            : 
    2736                 :          0 :   return res;
    2737                 :            : }
    2738                 :            : 
    2739                 :            : static gboolean
    2740                 :          0 : gst_mpegts_demux_provides_clock (GstElement * element)
    2741                 :            : {
    2742                 :            :   GstMpegTSDemux *demux;
    2743                 :            :   GstQuery *query;
    2744                 :          0 :   gboolean is_live = FALSE;
    2745                 :            :   GstPad *peer;
    2746                 :            : 
    2747                 :          0 :   demux = GST_MPEGTS_DEMUX (element);
    2748                 :          0 :   query = gst_query_new_latency ();
    2749                 :          0 :   peer = gst_pad_get_peer (demux->sinkpad);
    2750                 :            : 
    2751         [ #  # ]:          0 :   if (peer) {
    2752         [ #  # ]:          0 :     if (gst_pad_query (peer, query))
    2753                 :          0 :       gst_query_parse_latency (query, &is_live, NULL, NULL);
    2754                 :          0 :     gst_object_unref (peer);
    2755                 :            :   }
    2756                 :          0 :   gst_query_unref (query);
    2757                 :            : 
    2758                 :          0 :   return is_live;
    2759                 :            : }
    2760                 :            : 
    2761                 :            : static GstClock *
    2762                 :          0 : gst_mpegts_demux_provide_clock (GstElement * element)
    2763                 :            : {
    2764                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (element);
    2765                 :            : 
    2766         [ #  # ]:          0 :   if (gst_mpegts_demux_provides_clock (element)) {
    2767         [ #  # ]:          0 :     if (demux->clock == NULL) {
    2768                 :          0 :       demux->clock = g_object_new (GST_TYPE_SYSTEM_CLOCK, "name",
    2769                 :            :           "MpegTSClock", NULL);
    2770                 :          0 :       demux->clock_base = GST_CLOCK_TIME_NONE;
    2771                 :            :     }
    2772                 :          0 :     return gst_object_ref (demux->clock);
    2773                 :            :   }
    2774                 :            : 
    2775                 :          0 :   return NULL;
    2776                 :            : }
    2777                 :            : 
    2778                 :            : static const GstQueryType *
    2779                 :          0 : gst_mpegts_demux_src_pad_query_type (GstPad * pad)
    2780                 :            : {
    2781                 :            :   static const GstQueryType types[] = {
    2782                 :            :     GST_QUERY_LATENCY,
    2783                 :            :     GST_QUERY_DURATION,
    2784                 :            :     GST_QUERY_SEEKING,
    2785                 :            :     0
    2786                 :            :   };
    2787                 :            : 
    2788                 :          0 :   return types;
    2789                 :            : }
    2790                 :            : 
    2791                 :            : static gboolean
    2792                 :          0 : gst_mpegts_demux_src_pad_query (GstPad * pad, GstQuery * query)
    2793                 :            : {
    2794                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
    2795                 :          0 :   gboolean res = FALSE;
    2796                 :            :   GstPad *peer;
    2797                 :            : 
    2798   [ #  #  #  # ]:          0 :   switch (GST_QUERY_TYPE (query)) {
    2799                 :            :     case GST_QUERY_LATENCY:
    2800                 :            :     {
    2801                 :          0 :       peer = gst_pad_get_peer (demux->sinkpad);
    2802         [ #  # ]:          0 :       if (peer) {
    2803                 :          0 :         res = gst_pad_query (peer, query);
    2804         [ #  # ]:          0 :         if (res) {
    2805                 :            :           gboolean is_live;
    2806                 :            :           GstClockTime min_latency, max_latency;
    2807                 :            : 
    2808                 :          0 :           gst_query_parse_latency (query, &is_live, &min_latency, &max_latency);
    2809         [ #  # ]:          0 :           if (is_live) {
    2810                 :          0 :             min_latency += TS_LATENCY * GST_MSECOND;
    2811         [ #  # ]:          0 :             if (max_latency != GST_CLOCK_TIME_NONE)
    2812                 :          0 :               max_latency += TS_LATENCY * GST_MSECOND;
    2813                 :            :           }
    2814                 :            : 
    2815                 :          0 :           gst_query_set_latency (query, is_live, min_latency, max_latency);
    2816                 :            :         }
    2817                 :          0 :         gst_object_unref (peer);
    2818                 :            :       }
    2819                 :          0 :       break;
    2820                 :            :     }
    2821                 :            :     case GST_QUERY_DURATION:
    2822                 :            :     {
    2823                 :            :       GstFormat format;
    2824                 :            :       GstPad *peer;
    2825                 :            : 
    2826                 :          0 :       gst_query_parse_duration (query, &format, NULL);
    2827                 :            : 
    2828                 :            :       /* Try query upstream first */
    2829                 :          0 :       peer = gst_pad_get_peer (demux->sinkpad);
    2830         [ #  # ]:          0 :       if (peer) {
    2831                 :          0 :         res = gst_pad_query (peer, query);
    2832                 :            :         /* Try doing something with that query if it failed */
    2833 [ #  # ][ #  # ]:          0 :         if (!res && format == GST_FORMAT_TIME && demux->bitrate != -1) {
                 [ #  # ]
    2834                 :            :           /* Try using cache first */
    2835         [ #  # ]:          0 :           if (GST_CLOCK_TIME_IS_VALID (demux->cache_duration)) {
    2836 [ #  # ][ #  # ]:          0 :             GST_LOG_OBJECT (demux, "replying duration query from cache %"
         [ #  # ][ #  # ]
                 [ #  # ]
    2837                 :            :                 GST_TIME_FORMAT, GST_TIME_ARGS (demux->cache_duration));
    2838                 :          0 :             gst_query_set_duration (query, GST_FORMAT_TIME,
    2839                 :          0 :                 demux->cache_duration);
    2840                 :          0 :             res = TRUE;
    2841                 :            :           } else {              /* Query upstream and approximate */
    2842                 :          0 :             GstQuery *bquery = gst_query_new_duration (GST_FORMAT_BYTES);
    2843                 :          0 :             gint64 duration = 0;
    2844                 :            : 
    2845                 :            :             /* Query peer for duration in bytes */
    2846                 :          0 :             res = gst_pad_query (peer, bquery);
    2847         [ #  # ]:          0 :             if (res) {
    2848                 :            :               /* Convert to time format */
    2849                 :          0 :               gst_query_parse_duration (bquery, &format, &duration);
    2850         [ #  # ]:          0 :               GST_DEBUG_OBJECT (demux, "query on peer pad reported bytes %"
    2851                 :            :                   G_GUINT64_FORMAT, duration);
    2852         [ #  # ]:          0 :               demux->cache_duration = BYTES_TO_GSTTIME (duration);
    2853 [ #  # ][ #  # ]:          0 :               GST_DEBUG_OBJECT (demux, "converted to time %" GST_TIME_FORMAT,
         [ #  # ][ #  # ]
                 [ #  # ]
    2854                 :            :                   GST_TIME_ARGS (demux->cache_duration));
    2855                 :          0 :               gst_query_set_duration (query, GST_FORMAT_TIME,
    2856                 :          0 :                   demux->cache_duration);
    2857                 :            :             }
    2858                 :          0 :             gst_query_unref (bquery);
    2859                 :            :           }
    2860                 :            :         } else {
    2861         [ #  # ]:          0 :           GST_WARNING_OBJECT (demux, "unsupported query format or no bitrate "
    2862                 :            :               "yet to approximate duration from bytes");
    2863                 :            :         }
    2864                 :          0 :         gst_object_unref (peer);
    2865                 :            :       }
    2866                 :          0 :       break;
    2867                 :            :     }
    2868                 :            :     case GST_QUERY_SEEKING:{
    2869                 :            :       GstFormat fmt;
    2870                 :            : 
    2871                 :          0 :       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
    2872         [ #  # ]:          0 :       if (fmt == GST_FORMAT_BYTES) {
    2873                 :            :         /* Seeking in BYTES format not supported at all */
    2874                 :          0 :         gst_query_set_seeking (query, fmt, FALSE, -1, -1);
    2875                 :            :       } else {
    2876                 :            :         GstQuery *peerquery;
    2877                 :            :         gboolean seekable;
    2878                 :            : 
    2879                 :            :         /* Then ask upstream */
    2880                 :          0 :         res = gst_pad_peer_query (demux->sinkpad, query);
    2881         [ #  # ]:          0 :         if (res) {
    2882                 :            :           /* If upstream can handle seeks we're done, if it
    2883                 :            :            * can't we still have our TIME->BYTES conversion seek
    2884                 :            :            */
    2885                 :          0 :           gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
    2886 [ #  # ][ #  # ]:          0 :           if (seekable || fmt != GST_FORMAT_TIME)
    2887                 :            :             goto beach;
    2888                 :            :         }
    2889                 :            : 
    2890                 :            :         /* We can't say anything about seekability if we didn't
    2891                 :            :          * have a second PCR yet because the bitrate is calculated
    2892                 :            :          * from this
    2893                 :            :          */
    2894 [ #  # ][ #  # ]:          0 :         if (demux->bitrate == -1 && demux->pcr[1] == -1)
    2895                 :          0 :           goto beach;
    2896                 :            : 
    2897                 :            :         /* We can seek if upstream supports BYTES seeks and we
    2898                 :            :          * have a bitrate
    2899                 :            :          */
    2900                 :          0 :         peerquery = gst_query_new_seeking (GST_FORMAT_BYTES);
    2901                 :          0 :         res = gst_pad_peer_query (demux->sinkpad, peerquery);
    2902 [ #  # ][ #  # ]:          0 :         if (!res || demux->bitrate == -1) {
    2903                 :          0 :           gst_query_set_seeking (query, fmt, FALSE, -1, -1);
    2904                 :            :         } else {
    2905                 :          0 :           gst_query_parse_seeking (peerquery, NULL, &seekable, NULL, NULL);
    2906         [ #  # ]:          0 :           if (seekable)
    2907                 :          0 :             gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
    2908                 :            :           else
    2909                 :          0 :             gst_query_set_seeking (query, fmt, FALSE, -1, -1);
    2910                 :            :         }
    2911                 :            : 
    2912                 :          0 :         gst_query_unref (peerquery);
    2913                 :          0 :         res = TRUE;
    2914                 :            :       }
    2915                 :          0 :       break;
    2916                 :            :     }
    2917                 :            :     default:
    2918                 :          0 :       res = gst_pad_query_default (pad, query);
    2919                 :          0 :       break;
    2920                 :            :   }
    2921                 :            : 
    2922                 :            : beach:
    2923                 :          0 :   gst_object_unref (demux);
    2924                 :            : 
    2925                 :          0 :   return res;
    2926                 :            : }
    2927                 :            : 
    2928                 :            : static FORCE_INLINE gint
    2929                 :            : is_mpegts_sync (const guint8 * in_data, const guint8 * end_data,
    2930                 :            :     guint packetsize)
    2931                 :            : {
    2932                 :          0 :   guint ret = 0;
    2933 [ #  # ][ #  # ]:          0 :   if (G_LIKELY (IS_MPEGTS_SYNC (in_data)))
                 [ #  # ]
    2934                 :          0 :     return 100;
    2935                 :            : 
    2936         [ #  # ]:          0 :   if (in_data + packetsize < end_data - 5) {
    2937 [ #  # ][ #  # ]:          0 :     if (G_LIKELY (IS_MPEGTS_SYNC (in_data + packetsize)))
                 [ #  # ]
    2938                 :          0 :       ret += 50;
    2939                 :            :   }
    2940                 :            : 
    2941         [ #  # ]:          0 :   if (in_data[0] == 0x47) {
    2942                 :          0 :     ret += 25;
    2943                 :            : 
    2944         [ #  # ]:          0 :     if ((in_data[1] & 0x80) == 0x00)
    2945                 :          0 :       ret += 10;
    2946                 :            : 
    2947         [ #  # ]:          0 :     if ((in_data[3] & 0x10) == 0x10)
    2948                 :          0 :       ret += 5;
    2949                 :            :   }
    2950                 :          0 :   return ret;
    2951                 :            : }
    2952                 :            : 
    2953                 :            : static inline void
    2954                 :          0 : gst_mpegts_demux_detect_packet_size (GstMpegTSDemux * demux, guint len)
    2955                 :            : {
    2956                 :          0 :   guint i, packetsize = 0;
    2957                 :            : 
    2958         [ #  # ]:          0 :   for (i = 1; i < len; i++) {
    2959                 :          0 :     packetsize = demux->sync_lut[i] - demux->sync_lut[i - 1];
    2960 [ #  # ][ #  # ]:          0 :     if (packetsize == MPEGTS_NORMAL_TS_PACKETSIZE ||
    2961         [ #  # ]:          0 :         packetsize == MPEGTS_M2TS_TS_PACKETSIZE ||
    2962         [ #  # ]:          0 :         packetsize == MPEGTS_DVB_ASI_TS_PACKETSIZE ||
    2963                 :            :         packetsize == MPEGTS_ATSC_TS_PACKETSIZE)
    2964                 :            :       goto done;
    2965                 :            :     else
    2966                 :          0 :       packetsize = 0;
    2967                 :            :   }
    2968                 :            : 
    2969                 :            : done:
    2970         [ #  # ]:          0 :   demux->packetsize = (packetsize ? packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
    2971         [ #  # ]:          0 :   GST_DEBUG_OBJECT (demux, "packet_size set to %d bytes", demux->packetsize);
    2972                 :          0 : }
    2973                 :            : 
    2974                 :            : static FORCE_INLINE guint
    2975                 :            : gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
    2976                 :            :     guint size, guint * flush)
    2977                 :            : {
    2978                 :          0 :   guint sync_count = 0;
    2979                 :          0 :   const guint8 *end_scan = in_data + size - demux->packetsize;
    2980                 :          0 :   guint8 *ptr_data = (guint8 *) in_data;
    2981         [ #  # ]:          0 :   guint packetsize =
    2982                 :          0 :       (demux->packetsize ? demux->packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
    2983                 :            : 
    2984                 :            :   /* Check if the LUT table is big enough */
    2985         [ #  # ]:          0 :   if (G_UNLIKELY (demux->sync_lut_len < (size / packetsize))) {
    2986                 :          0 :     demux->sync_lut_len = size / packetsize;
    2987         [ #  # ]:          0 :     if (demux->sync_lut)
    2988                 :          0 :       g_free (demux->sync_lut);
    2989                 :          0 :     demux->sync_lut = g_new0 (guint8 *, demux->sync_lut_len);
    2990         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "created sync LUT table with %u entries",
    2991                 :            :         demux->sync_lut_len);
    2992                 :            :   }
    2993                 :            : 
    2994 [ #  # ][ #  # ]:          0 :   while (ptr_data <= end_scan && sync_count < demux->sync_lut_len) {
    2995                 :            :     /* if sync code is found try to store it in the LUT */
    2996                 :          0 :     guint chance = is_mpegts_sync (ptr_data, end_scan, packetsize);
    2997         [ #  # ]:          0 :     if (G_LIKELY (chance > 50)) {
    2998                 :            :       /* skip paketsize bytes and try find next */
    2999                 :          0 :       guint8 *next_sync = ptr_data + packetsize;
    3000         [ #  # ]:          0 :       if (next_sync < end_scan) {
    3001                 :          0 :         demux->sync_lut[sync_count] = ptr_data;
    3002                 :          0 :         sync_count++;
    3003                 :          0 :         ptr_data += packetsize;
    3004                 :            :       } else
    3005                 :            :         goto done;
    3006                 :            :     } else {
    3007                 :          0 :       ptr_data++;
    3008                 :            :     }
    3009                 :            :   }
    3010                 :            : done:
    3011         [ #  # ]:          0 :   if (G_UNLIKELY (!demux->packetsize))
    3012                 :          0 :     gst_mpegts_demux_detect_packet_size (demux, sync_count);
    3013                 :            : 
    3014                 :          0 :   *flush = MIN (ptr_data - in_data, size);
    3015                 :            : 
    3016                 :          0 :   return sync_count;
    3017                 :            : }
    3018                 :            : 
    3019                 :            : static GstFlowReturn
    3020                 :          0 : gst_mpegts_demux_chain (GstPad * pad, GstBuffer * buffer)
    3021                 :            : {
    3022                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
    3023                 :          0 :   GstFlowReturn ret = GST_FLOW_OK;
    3024                 :            :   const guint8 *data;
    3025                 :            :   guint avail;
    3026                 :          0 :   guint flush = 0;
    3027                 :            :   gint i;
    3028                 :            :   guint sync_count;
    3029                 :            : 
    3030         [ #  # ]:          0 :   if (GST_BUFFER_IS_DISCONT (buffer)) {
    3031                 :          0 :     gst_mpegts_demux_flush (demux, FALSE);
    3032                 :            :   }
    3033                 :            :   /* first push the new buffer into the adapter */
    3034                 :          0 :   gst_adapter_push (demux->adapter, buffer);
    3035                 :            : 
    3036                 :            :   /* check if there's enough data to parse a packet */
    3037                 :          0 :   avail = gst_adapter_available (demux->adapter);
    3038         [ #  # ]:          0 :   if (G_UNLIKELY (avail < demux->packetsize))
    3039                 :          0 :     goto done;
    3040                 :            : 
    3041                 :            :   /* recover all data from adapter */
    3042                 :          0 :   data = gst_adapter_peek (demux->adapter, avail);
    3043                 :            : 
    3044                 :            :   /* scan for sync codes */
    3045                 :          0 :   sync_count = gst_mpegts_demux_sync_scan (demux, data, avail, &flush);
    3046                 :            : 
    3047                 :            :   /* process all packets */
    3048         [ #  # ]:          0 :   for (i = 0; i < sync_count; i++) {
    3049                 :          0 :     ret = gst_mpegts_demux_parse_transport_packet (demux, demux->sync_lut[i]);
    3050 [ #  # ][ #  # ]:          0 :     if (G_UNLIKELY (ret == GST_FLOW_LOST_SYNC
    3051                 :            :             || ret == GST_FLOW_NEED_MORE_DATA)) {
    3052                 :          0 :       ret = GST_FLOW_OK;
    3053                 :          0 :       continue;
    3054                 :            :     }
    3055         [ #  # ]:          0 :     if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    3056                 :          0 :       flush = demux->sync_lut[i] - data + demux->packetsize;
    3057                 :          0 :       flush = MIN (avail, flush);
    3058                 :          0 :       goto done;
    3059                 :            :     }
    3060                 :            :   }
    3061                 :            : 
    3062                 :            : done:
    3063                 :            :   /* flush processed data */
    3064         [ #  # ]:          0 :   if (flush) {
    3065         [ #  # ]:          0 :     GST_DEBUG_OBJECT (demux, "flushing %d/%d", flush, avail);
    3066                 :          0 :     gst_adapter_flush (demux->adapter, flush);
    3067                 :            :   }
    3068                 :            : 
    3069                 :          0 :   gst_object_unref (demux);
    3070                 :            : 
    3071                 :          0 :   return ret;
    3072                 :            : }
    3073                 :            : 
    3074                 :            : static GstStateChangeReturn
    3075                 :         34 : gst_mpegts_demux_change_state (GstElement * element, GstStateChange transition)
    3076                 :            : {
    3077                 :         34 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (element);
    3078                 :            :   GstStateChangeReturn result;
    3079                 :            : 
    3080                 :            : 
    3081      [ +  +  + ]:         34 :   switch (transition) {
    3082                 :            :     case GST_STATE_CHANGE_NULL_TO_READY:
    3083                 :          4 :       demux->adapter = gst_adapter_new ();
    3084                 :          4 :       break;
    3085                 :            :     case GST_STATE_CHANGE_READY_TO_PAUSED:
    3086                 :          7 :       break;
    3087                 :            :     default:
    3088                 :         23 :       break;
    3089                 :            :   }
    3090                 :            : 
    3091                 :         34 :   result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
    3092                 :            : 
    3093      [ +  +  + ]:         34 :   switch (transition) {
    3094                 :            :     case GST_STATE_CHANGE_PAUSED_TO_READY:
    3095                 :          7 :       gst_mpegts_demux_reset (demux);
    3096                 :          7 :       break;
    3097                 :            :     case GST_STATE_CHANGE_READY_TO_NULL:
    3098                 :          4 :       g_object_unref (demux->adapter);
    3099         [ -  + ]:          4 :       if (demux->sync_lut)
    3100                 :          0 :         g_free (demux->sync_lut);
    3101                 :          4 :       demux->sync_lut = NULL;
    3102                 :          4 :       demux->sync_lut_len = 0;
    3103                 :          4 :       break;
    3104                 :            :     default:
    3105                 :         23 :       break;
    3106                 :            :   }
    3107                 :            : 
    3108                 :         34 :   return result;
    3109                 :            : }
    3110                 :            : 
    3111                 :            : static GValueArray *
    3112                 :          0 : mpegts_demux_build_pat_info (GstMpegTSDemux * demux)
    3113                 :            : {
    3114                 :          0 :   GValueArray *vals = NULL;
    3115                 :            :   GstMpegTSPAT *PAT;
    3116                 :            :   gint i;
    3117                 :            : 
    3118         [ #  # ]:          0 :   g_return_val_if_fail (demux->streams[0] != NULL, NULL);
    3119         [ #  # ]:          0 :   g_return_val_if_fail (demux->streams[0]->PID_type ==
    3120                 :            :       PID_TYPE_PROGRAM_ASSOCIATION, NULL);
    3121                 :            : 
    3122                 :          0 :   PAT = &(demux->streams[0]->PAT);
    3123                 :          0 :   vals = g_value_array_new (PAT->entries->len);
    3124                 :            : 
    3125         [ #  # ]:          0 :   for (i = 0; i < PAT->entries->len; i++) {
    3126                 :          0 :     GstMpegTSPATEntry *cur_entry =
    3127                 :          0 :         &g_array_index (PAT->entries, GstMpegTSPATEntry, i);
    3128                 :          0 :     GValue v = { 0, };
    3129                 :            :     MpegTsPatInfo *info_obj;
    3130                 :            : 
    3131                 :          0 :     info_obj = mpegts_pat_info_new (cur_entry->program_number, cur_entry->PID);
    3132                 :            : 
    3133                 :          0 :     g_value_init (&v, G_TYPE_OBJECT);
    3134                 :          0 :     g_value_take_object (&v, info_obj);
    3135                 :          0 :     g_value_array_append (vals, &v);
    3136                 :          0 :     g_value_unset (&v);
    3137                 :            :   }
    3138                 :          0 :   return vals;
    3139                 :            : }
    3140                 :            : 
    3141                 :            : static MpegTsPmtInfo *
    3142                 :          0 : mpegts_demux_build_pmt_info (GstMpegTSDemux * demux, guint16 pmt_pid)
    3143                 :            : {
    3144                 :            :   MpegTsPmtInfo *info_obj;
    3145                 :            :   GstMpegTSPMT *PMT;
    3146                 :            :   gint i;
    3147                 :            : 
    3148         [ #  # ]:          0 :   g_return_val_if_fail (demux->streams[pmt_pid] != NULL, NULL);
    3149         [ #  # ]:          0 :   g_return_val_if_fail (demux->streams[pmt_pid]->PID_type ==
    3150                 :            :       PID_TYPE_PROGRAM_MAP, NULL);
    3151                 :            : 
    3152                 :          0 :   PMT = &(demux->streams[pmt_pid]->PMT);
    3153                 :            : 
    3154                 :          0 :   info_obj = mpegts_pmt_info_new (PMT->program_number, PMT->PCR_PID,
    3155                 :          0 :       PMT->version_number);
    3156                 :            : 
    3157         [ #  # ]:          0 :   for (i = 0; i < PMT->entries->len; i++) {
    3158                 :            :     GstMpegTSStream *stream;
    3159                 :            :     MpegTsPmtStreamInfo *stream_info;
    3160                 :          0 :     GstMpegTSPMTEntry *cur_entry =
    3161                 :          0 :         &g_array_index (PMT->entries, GstMpegTSPMTEntry, i);
    3162                 :            : 
    3163                 :          0 :     stream = demux->streams[cur_entry->PID];
    3164                 :          0 :     stream_info =
    3165                 :          0 :         mpegts_pmt_stream_info_new (cur_entry->PID, stream->stream_type);
    3166                 :            : 
    3167         [ #  # ]:          0 :     if (stream->ES_info) {
    3168                 :            :       int i;
    3169                 :            : 
    3170                 :            :       /* add languages */
    3171                 :          0 :       guint8 *iso639_languages =
    3172                 :          0 :           gst_mpeg_descriptor_find (stream->ES_info, DESC_ISO_639_LANGUAGE);
    3173         [ #  # ]:          0 :       if (iso639_languages) {
    3174         [ #  # ]:          0 :         for (i = 0; i < DESC_ISO_639_LANGUAGE_codes_n (iso639_languages); i++) {
    3175                 :          0 :           gchar *language_n = (gchar *)
    3176                 :          0 :               DESC_ISO_639_LANGUAGE_language_code_nth (iso639_languages, i);
    3177                 :          0 :           mpegts_pmt_stream_info_add_language (stream_info,
    3178                 :            :               g_strndup (language_n, 3));
    3179                 :            :         }
    3180                 :            :       }
    3181                 :            : 
    3182         [ #  # ]:          0 :       for (i = 0; i < gst_mpeg_descriptor_n_desc (stream->ES_info); ++i) {
    3183                 :          0 :         guint8 *desc = gst_mpeg_descriptor_nth (stream->ES_info, i);
    3184                 :            : 
    3185                 :            :         /* add the whole descriptor, tag + length + DESC_LENGTH bytes */
    3186                 :          0 :         mpegts_pmt_stream_info_add_descriptor (stream_info,
    3187                 :          0 :             (gchar *) desc, 2 + DESC_LENGTH (desc));
    3188                 :            :       }
    3189                 :            :     }
    3190                 :          0 :     mpegts_pmt_info_add_stream (info_obj, stream_info);
    3191                 :            :   }
    3192                 :          0 :   return info_obj;
    3193                 :            : }
    3194                 :            : 
    3195                 :            : static void
    3196                 :          0 : gst_mpegts_demux_set_property (GObject * object, guint prop_id,
    3197                 :            :     const GValue * value, GParamSpec * pspec)
    3198                 :            : {
    3199                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (object);
    3200                 :            :   gchar **pids;
    3201                 :            :   guint num_pids;
    3202                 :            :   int i;
    3203                 :            : 
    3204   [ #  #  #  # ]:          0 :   switch (prop_id) {
    3205                 :            :     case PROP_ES_PIDS:
    3206                 :          0 :       pids = g_strsplit (g_value_get_string (value), ":", -1);
    3207                 :          0 :       num_pids = g_strv_length (pids);
    3208         [ #  # ]:          0 :       if (num_pids > 0) {
    3209                 :          0 :         demux->elementary_pids = g_new0 (guint16, num_pids);
    3210                 :          0 :         demux->nb_elementary_pids = num_pids;
    3211         [ #  # ]:          0 :         for (i = 0; i < num_pids; i++) {
    3212                 :          0 :           demux->elementary_pids[i] = strtol (pids[i], NULL, 0);
    3213         [ #  # ]:          0 :           GST_INFO ("partial TS ES pid %d", demux->elementary_pids[i]);
    3214                 :            :         }
    3215                 :            :       }
    3216                 :          0 :       g_strfreev (pids);
    3217                 :          0 :       break;
    3218                 :            :     case PROP_CHECK_CRC:
    3219                 :          0 :       demux->check_crc = g_value_get_boolean (value);
    3220                 :          0 :       break;
    3221                 :            :     case PROP_PROGRAM_NUMBER:
    3222                 :          0 :       demux->program_number = g_value_get_int (value);
    3223                 :          0 :       break;
    3224                 :            :     default:
    3225                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    3226                 :          0 :       break;
    3227                 :            :   }
    3228                 :          0 : }
    3229                 :            : 
    3230                 :            : static void
    3231                 :          0 : gst_mpegts_demux_get_property (GObject * object, guint prop_id,
    3232                 :            :     GValue * value, GParamSpec * pspec)
    3233                 :            : {
    3234                 :          0 :   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (object);
    3235                 :            :   int i;
    3236                 :            : 
    3237   [ #  #  #  #  :          0 :   switch (prop_id) {
                   #  # ]
    3238                 :            :     case PROP_ES_PIDS:
    3239         [ #  # ]:          0 :       if (demux->nb_elementary_pids == 0) {
    3240                 :          0 :         g_value_set_static_string (value, "");
    3241                 :            :       } else {
    3242                 :            :         GString *ts_pids;
    3243                 :            : 
    3244                 :          0 :         ts_pids = g_string_sized_new (32);
    3245                 :            :         /* FIXME: align with property description which uses hex numbers? */
    3246                 :          0 :         g_string_append_printf (ts_pids, "%d", demux->elementary_pids[0]);
    3247         [ #  # ]:          0 :         for (i = 1; i < demux->nb_elementary_pids; i++) {
    3248                 :          0 :           g_string_append_printf (ts_pids, ":%d", demux->elementary_pids[i]);
    3249                 :            :         }
    3250                 :          0 :         g_value_take_string (value, g_string_free (ts_pids, FALSE));
    3251                 :            :       }
    3252                 :          0 :       break;
    3253                 :            :     case PROP_CHECK_CRC:
    3254                 :          0 :       g_value_set_boolean (value, demux->check_crc);
    3255                 :          0 :       break;
    3256                 :            :     case PROP_PROGRAM_NUMBER:
    3257                 :          0 :       g_value_set_int (value, demux->program_number);
    3258                 :          0 :       break;
    3259                 :            :     case PROP_PAT_INFO:
    3260                 :            :     {
    3261         [ #  # ]:          0 :       if (demux->streams[0] != NULL) {
    3262                 :          0 :         g_value_take_boxed (value, mpegts_demux_build_pat_info (demux));
    3263                 :            :       }
    3264                 :          0 :       break;
    3265                 :            :     }
    3266                 :            :     case PROP_PMT_INFO:
    3267                 :            :     {
    3268 [ #  # ][ #  # ]:          0 :       if (demux->current_PMT != 0 && demux->streams[demux->current_PMT] != NULL) {
    3269                 :          0 :         g_value_take_object (value, mpegts_demux_build_pmt_info (demux,
    3270                 :          0 :                 demux->current_PMT));
    3271                 :            :       }
    3272                 :          0 :       break;
    3273                 :            :     }
    3274                 :            :     default:
    3275                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    3276                 :          0 :       break;
    3277                 :            :   }
    3278                 :          0 : }
    3279                 :            : 
    3280                 :            : gboolean
    3281                 :          6 : gst_mpegts_demux_plugin_init (GstPlugin * plugin)
    3282                 :            : {
    3283         [ -  + ]:          6 :   if (!gst_element_register (plugin, "mpegtsdemux",
    3284                 :            :           GST_RANK_PRIMARY, GST_TYPE_MPEGTS_DEMUX))
    3285                 :          0 :     return FALSE;
    3286                 :            : 
    3287                 :          6 :   return TRUE;
    3288                 :            : }

Generated by: LCOV version 1.9