예제 #1
0
/* decode a clip tag
 * this callback is registered with dec->parser. It is called whenever a
 * clip is parsed.
 */
static void
gst_cmml_dec_parse_clip (GstCmmlDec * dec, GstCmmlTagClip * clip)
{
  GstCmmlTagClip *prev_clip;

  dec->flow_return = GST_FLOW_OK;

  if (clip->empty)
    GST_INFO_OBJECT (dec, "parsing empty clip");
  else
    GST_INFO_OBJECT (dec, "parsing clip (id: %s)", clip->id);

  clip->start_time = dec->timestamp;
  if (clip->start_time == GST_CLOCK_TIME_NONE) {
    GST_ELEMENT_ERROR (dec, STREAM, DECODE,
        (NULL), ("invalid clip start time"));

    dec->flow_return = GST_FLOW_ERROR;
    return;
  }

  /* get the last clip in the current track */
  prev_clip = gst_cmml_track_list_get_track_last_clip (dec->tracks,
      (gchar *) clip->track);
  if (prev_clip) {
    /* output the previous clip */
    if (clip->empty)
      /* the current clip marks the end of the previous one */
      prev_clip->end_time = clip->start_time;

    gst_cmml_dec_push_clip (dec, prev_clip);
  }

  if (dec->wait_clip_end) {
    /* now it's time to send the tag for the previous clip */
    if (prev_clip) {
      prev_clip->end_time = clip->start_time;
      gst_cmml_dec_send_clip_tag (dec, prev_clip);
    }
  } else if (!clip->empty) {
    /* send the tag for the current clip */
    gst_cmml_dec_send_clip_tag (dec, clip);
  }

  if (prev_clip)
    gst_cmml_track_list_del_clip (dec->tracks, prev_clip);

  if (!clip->empty)
    if (!gst_cmml_track_list_has_clip (dec->tracks, clip))
      gst_cmml_track_list_add_clip (dec->tracks, clip);
}
예제 #2
0
static gboolean
gst_cmml_dec_sink_event (GstPad * pad, GstEvent * event)
{
  GstCmmlDec *dec = GST_CMML_DEC (GST_PAD_PARENT (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      GstBuffer *buffer;
      GstCmmlTagClip *clip;
      GList *clips, *walk;

      GST_INFO_OBJECT (dec, "got EOS, flushing clips");

      /* since we output a clip when the next one in the same track is found, on
       * EOS we need to output the last clip (if any) of every track
       */
      clips = gst_cmml_track_list_get_clips (dec->tracks);
      for (walk = clips; walk; walk = g_list_next (walk)) {
        clip = GST_CMML_TAG_CLIP (walk->data);
        gst_cmml_dec_push_clip (dec, clip);
        if (dec->wait_clip_end) {
          clip->end_time = dec->timestamp;
          gst_cmml_dec_send_clip_tag (dec, clip);
        }
      }
      g_list_free (clips);

      /* send the cmml end tag */
      dec->flow_return = gst_cmml_dec_new_buffer (dec,
          (guchar *) "</cmml>", strlen ("</cmml>"), &buffer);

      if (dec->flow_return == GST_FLOW_OK)
        dec->flow_return = gst_pad_push (dec->srcpad, buffer);
      if (dec->flow_return == GST_FLOW_NOT_LINKED)
        dec->flow_return = GST_FLOW_OK; /* Ignore NOT_LINKED */

      break;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, event);
}