Beispiel #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);
}
Beispiel #2
0
/* encode a CMML clip tag
 * remove the start and end attributes (GstCmmlParser does this itself) and
 * push the tag with the timestamp of its start attribute. If the tag has the
 * end attribute, create a new empty clip and encode it.
 */
static void
gst_cmml_enc_parse_tag_clip (GstCmmlEnc * enc, GstCmmlTagClip * clip)
{
  GstCmmlTagClip *prev_clip;
  GstClockTime prev_clip_time = GST_CLOCK_TIME_NONE;

  /* this can happen if there's a programming error (eg user forgets to set
   * the start-time property) or if one of the gst_cmml_clock_time_from_*
   * overflows in GstCmmlParser */
  if (clip->start_time == GST_CLOCK_TIME_NONE) {
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE,
        (NULL), ("invalid start time for clip (%s)", clip->id));
    enc->flow_return = GST_FLOW_ERROR;

    return;
  }

  /* get the previous clip's start time to encode the current granulepos */
  prev_clip = gst_cmml_track_list_get_track_last_clip (enc->tracks,
      (gchar *) clip->track);
  if (prev_clip) {
    prev_clip_time = prev_clip->start_time;
    if (prev_clip_time > clip->start_time) {
      GST_ELEMENT_ERROR (enc, STREAM, ENCODE,
          (NULL), ("previous clip start time > current clip (%s) start time",
              clip->id));
      enc->flow_return = GST_FLOW_ERROR;
      return;
    }

    /* we don't need the prev clip anymore */
    gst_cmml_track_list_del_clip (enc->tracks, prev_clip);
  }

  /* add the current clip to the tracklist */
  gst_cmml_track_list_add_clip (enc->tracks, clip);

  enc->flow_return = gst_cmml_enc_push_clip (enc, clip, prev_clip_time);
}