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