/* 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); }
/* 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); }