コード例 #1
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static GstStateChangeReturn
mpegts_base_change_state (GstElement * element, GstStateChange transition)
{
  MpegTSBase *base;
  GstStateChangeReturn ret;

  base = GST_MPEGTS_BASE (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      mpegts_base_reset (base);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      mpegts_base_reset (base);
      if (base->mode != BASE_MODE_PUSHING)
        base->mode = BASE_MODE_SCANNING;
      break;
    default:
      break;
  }

  return ret;
}
コード例 #2
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static gboolean
mpegts_base_sink_activate_mode (GstPad * pad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;
  MpegTSBase *base = GST_MPEGTS_BASE (parent);

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      base->mode = BASE_MODE_PUSHING;
      res = TRUE;
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        base->mode = BASE_MODE_SCANNING;
        /* When working pull-based, we always use offsets for estimation */
        base->packetizer->calculate_offset = TRUE;
        base->packetizer->calculate_skew = FALSE;
        gst_segment_init (&base->segment, GST_FORMAT_BYTES);
        res =
            gst_pad_start_task (pad, (GstTaskFunction) mpegts_base_loop, base,
            NULL);
      } else
        res = gst_pad_stop_task (pad);
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}
コード例 #3
0
ファイル: tsdemux.c プロジェクト: ChinnaSuhas/ossbuild
static void
gst_ts_demux_init (GstTSDemux * demux, GstTSDemuxClass * klass)
{
  demux->need_newsegment = TRUE;
  demux->program_number = -1;
  demux->duration = GST_CLOCK_TIME_NONE;
  GST_MPEGTS_BASE (demux)->stream_size = sizeof (TSDemuxStream);
}
コード例 #4
0
static void
mpegts_parse_init (MpegTSParse2 * parse, MpegTSParse2Class * klass)
{
  parse->need_sync_program_pads = FALSE;
  parse->program_numbers = g_strdup ("");
  parse->pads_to_add = NULL;
  parse->pads_to_remove = NULL;
  GST_MPEGTS_BASE (parse)->program_size = sizeof (MpegTSParseProgram);
}
コード例 #5
0
ファイル: mpegtsbase.c プロジェクト: Lachann/gst-plugins-bad
static gboolean
mpegts_base_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = TRUE;
  gboolean hard;
  MpegTSBase *base = GST_MPEGTS_BASE (parent);

  GST_DEBUG_OBJECT (base, "Got event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      gst_event_copy_segment (event, &base->segment);
      GST_DEBUG_OBJECT (base, "Received segment %" GST_SEGMENT_FORMAT,
          &base->segment);
      /* Check if we need to switch PCR/PTS handling */
      if (base->segment.format == GST_FORMAT_TIME) {
        base->packetizer->calculate_offset = FALSE;
        base->packetizer->calculate_skew = TRUE;
      } else {
        base->packetizer->calculate_offset = TRUE;
        base->packetizer->calculate_skew = FALSE;
      }
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      break;
    case GST_EVENT_STREAM_START:
      gst_event_unref (event);
      break;
    case GST_EVENT_EOS:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      res = gst_mpegts_base_handle_eos (base);
      break;
    case GST_EVENT_CAPS:
      /* FIXME, do something */
      gst_event_unref (event);
      break;
    case GST_EVENT_FLUSH_STOP:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
      hard = (base->mode != BASE_MODE_SEEKING);
      mpegts_packetizer_flush (base->packetizer, hard);
      mpegts_base_flush (base, hard);
      gst_segment_init (&base->segment, GST_FORMAT_UNDEFINED);
      base->seen_pat = FALSE;
      break;
    default:
      res = GST_MPEGTS_BASE_GET_CLASS (base)->push_event (base, event);
  }

  /* Always return TRUE for sticky events */
  if (GST_EVENT_IS_STICKY (event))
    res = TRUE;

  return res;
}
コード例 #6
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static void
mpegts_base_finalize (GObject * object)
{
  MpegTSBase *base = GST_MPEGTS_BASE (object);

  if (base->pat) {
    g_ptr_array_unref (base->pat);
    base->pat = NULL;
  }
  g_hash_table_destroy (base->programs);

  if (G_OBJECT_CLASS (parent_class)->finalize)
    G_OBJECT_CLASS (parent_class)->finalize (object);
}
コード例 #7
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static void
mpegts_base_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  MpegTSBase *base = GST_MPEGTS_BASE (object);

  switch (prop_id) {
    case PROP_PARSE_PRIVATE_SECTIONS:
      g_value_set_boolean (value, base->parse_private_sections);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}
コード例 #8
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static void
mpegts_base_dispose (GObject * object)
{
  MpegTSBase *base = GST_MPEGTS_BASE (object);

  if (!base->disposed) {
    g_object_unref (base->packetizer);
    base->disposed = TRUE;
    g_free (base->known_psi);
    g_free (base->is_pes);
  }

  if (G_OBJECT_CLASS (parent_class)->dispose)
    G_OBJECT_CLASS (parent_class)->dispose (object);
}
コード例 #9
0
ファイル: mpegtsparse.c プロジェクト: ego5710/gst-plugins-bad
static void
mpegts_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  MpegTSParse2 *parse = (MpegTSParse2 *) object;

  switch (prop_id) {
    case PROP_SET_TIMESTAMPS:
      parse->set_timestamps = g_value_get_boolean (value);
      break;
    case PROP_SMOOTHING_LATENCY:
      parse->smoothing_latency = GST_USECOND * g_value_get_uint (value);
      mpegts_packetizer_set_pcr_discont_threshold (GST_MPEGTS_BASE
          (parse)->packetizer, parse->smoothing_latency);
      break;
    case PROP_PCR_PID:
      parse->pcr_pid = parse->user_pcr_pid = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}
コード例 #10
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static GstFlowReturn
mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn res = GST_FLOW_OK;
  MpegTSBase *base;
  MpegTSPacketizerPacketReturn pret;
  MpegTSPacketizer2 *packetizer;
  MpegTSPacketizerPacket packet;
  MpegTSBaseClass *klass;

  base = GST_MPEGTS_BASE (parent);
  klass = GST_MPEGTS_BASE_GET_CLASS (base);

  packetizer = base->packetizer;

  if (klass->input_done)
    gst_buffer_ref (buf);

  if (GST_BUFFER_IS_DISCONT (buf)) {
    GST_DEBUG_OBJECT (base, "Got DISCONT buffer, flushing");
    res = mpegts_base_drain (base);
    if (G_UNLIKELY (res != GST_FLOW_OK))
      return res;

    mpegts_base_flush (base, FALSE);
    /* In the case of discontinuities in push-mode with TIME segment
     * we want to drop all previous observations (hard:TRUE) from
     * the packetizer */
    if (base->mode == BASE_MODE_PUSHING
        && base->segment.format == GST_FORMAT_TIME)
      mpegts_packetizer_flush (base->packetizer, TRUE);
    else
      mpegts_packetizer_flush (base->packetizer, FALSE);
  }

  mpegts_packetizer_push (base->packetizer, buf);

  while (res == GST_FLOW_OK) {
    pret = mpegts_packetizer_next_packet (base->packetizer, &packet);

    /* If we don't have enough data, return */
    if (G_UNLIKELY (pret == PACKET_NEED_MORE))
      break;

    if (G_UNLIKELY (pret == PACKET_BAD)) {
      /* bad header, skip the packet */
      GST_DEBUG_OBJECT (base, "bad packet, skipping");
      goto next;
    }

    if (klass->inspect_packet)
      klass->inspect_packet (base, &packet);

    /* If it's a known PES, push it */
    if (MPEGTS_BIT_IS_SET (base->is_pes, packet.pid)) {
      /* push the packet downstream */
      if (base->push_data)
        res = klass->push (base, &packet, NULL);
    } else if (packet.payload
        && MPEGTS_BIT_IS_SET (base->known_psi, packet.pid)) {
      /* base PSI data */
      GList *others, *tmp;
      GstMpegtsSection *section;

      section = mpegts_packetizer_push_section (packetizer, &packet, &others);
      if (section)
        mpegts_base_handle_psi (base, section);
      if (G_UNLIKELY (others)) {
        for (tmp = others; tmp; tmp = tmp->next)
          mpegts_base_handle_psi (base, (GstMpegtsSection *) tmp->data);
        g_list_free (others);
      }

      /* we need to push section packet downstream */
      if (base->push_section)
        res = klass->push (base, &packet, section);

    } else if (packet.payload && packet.pid != 0x1fff)
      GST_LOG ("PID 0x%04x Saw packet on a pid we don't handle", packet.pid);

  next:
    mpegts_packetizer_clear_packet (base->packetizer, &packet);
  }

  if (klass->input_done) {
    if (res == GST_FLOW_OK)
      res = klass->input_done (base, buf);
    else
      gst_buffer_unref (buf);
  }

  return res;
}
コード例 #11
0
ファイル: mpegtsparse.c プロジェクト: ego5710/gst-plugins-bad
  g_return_val_if_fail (template != NULL, NULL);
  g_return_val_if_fail (GST_IS_MPEGTS_PARSE (element), NULL);
  g_return_val_if_fail (padname != NULL, NULL);

  sscanf (padname + 8, "%d", &program_num);

  GST_DEBUG_OBJECT (element, "padname:%s, program:%d", padname, program_num);

  parse = GST_MPEGTS_PARSE (element);

  tspad = mpegts_parse_create_tspad (parse, padname);
  tspad->program_number = program_num;

  /* Find if the program is already active */
  parseprogram =
      (MpegTSParseProgram *) mpegts_base_get_program (GST_MPEGTS_BASE (parse),
      program_num);
  if (parseprogram) {
    tspad->program = parseprogram;
    parseprogram->tspad = tspad;
  }

  pad = tspad->pad;
  parse->srcpads = g_list_append (parse->srcpads, pad);
  base->push_data = TRUE;
  base->push_section = TRUE;

  gst_pad_set_active (pad, TRUE);

  stream_id = gst_pad_create_stream_id (pad, element, padname + 8);
コード例 #12
0
ファイル: mpegtsbase.c プロジェクト: PeterXu/gst-mobile
static GstFlowReturn
mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn res = GST_FLOW_OK;
  MpegTSBase *base;
  MpegTSPacketizerPacketReturn pret;
  MpegTSPacketizer2 *packetizer;
  MpegTSPacketizerPacket packet;
  MpegTSBaseClass *klass;

  base = GST_MPEGTS_BASE (parent);
  klass = GST_MPEGTS_BASE_GET_CLASS (base);

  packetizer = base->packetizer;

  if (G_UNLIKELY (base->queried_latency == FALSE)) {
    query_upstream_latency (base);
  }

  if (klass->input_done)
    gst_buffer_ref (buf);

  mpegts_packetizer_push (base->packetizer, buf);

  while (res == GST_FLOW_OK) {
    pret = mpegts_packetizer_next_packet (base->packetizer, &packet);

    /* If we don't have enough data, return */
    if (G_UNLIKELY (pret == PACKET_NEED_MORE))
      break;

    if (G_UNLIKELY (pret == PACKET_BAD)) {
      /* bad header, skip the packet */
      GST_DEBUG_OBJECT (base, "bad packet, skipping");
      goto next;
    }

    /* If it's a known PES, push it */
    if (MPEGTS_BIT_IS_SET (base->is_pes, packet.pid)) {
      /* push the packet downstream */
      if (base->push_data)
        res = klass->push (base, &packet, NULL);
    } else if (packet.payload
        && MPEGTS_BIT_IS_SET (base->known_psi, packet.pid)) {
      /* base PSI data */
      GList *others, *tmp;
      GstMpegTsSection *section;

      section = mpegts_packetizer_push_section (packetizer, &packet, &others);
      if (section)
        mpegts_base_handle_psi (base, section);
      if (G_UNLIKELY (others)) {
        for (tmp = others; tmp; tmp = tmp->next)
          mpegts_base_handle_psi (base, (GstMpegTsSection *) tmp->data);
        g_list_free (others);
      }

      /* we need to push section packet downstream */
      if (base->push_section)
        res = klass->push (base, &packet, section);

    } else if (packet.payload && packet.pid != 0x1fff)
      GST_LOG ("PID 0x%04x Saw packet on a pid we don't handle", packet.pid);

  next:
    mpegts_packetizer_clear_packet (base->packetizer, &packet);
  }

  if (klass->input_done) {
    if (res == GST_FLOW_OK)
      res = klass->input_done (base, buf);
    else
      gst_buffer_unref (buf);
  }

  return res;
}