static GstFlowReturn gst_cmml_enc_push_clip (GstCmmlEnc * enc, GstCmmlTagClip * clip, GstClockTime prev_clip_time) { GstFlowReturn res; GstBuffer *buffer; gchar *clip_string; gint64 granulepos; /* encode the clip */ clip_string = (gchar *) gst_cmml_parser_tag_clip_to_string (enc->parser, clip); res = gst_cmml_enc_new_buffer (enc, (guchar *) clip_string, strlen (clip_string), &buffer); g_free (clip_string); if (res != GST_FLOW_OK) goto done; GST_INFO_OBJECT (enc, "encoding clip" "(start-time: %" GST_TIME_FORMAT " end-time: %" GST_TIME_FORMAT, GST_TIME_ARGS (clip->start_time), GST_TIME_ARGS (clip->end_time)); /* set the granulepos */ granulepos = gst_cmml_clock_time_to_granule (prev_clip_time, clip->start_time, enc->granulerate_n, enc->granulerate_d, enc->granuleshift); if (granulepos == -1) { gst_buffer_unref (buffer); goto granule_overflow; } GST_BUFFER_OFFSET (buffer) = clip->start_time; GST_BUFFER_OFFSET_END (buffer) = granulepos; GST_BUFFER_TIMESTAMP (buffer) = clip->start_time; res = gst_cmml_enc_push (enc, buffer); if (GST_FLOW_IS_FATAL (res)) goto done; if (clip->end_time != GST_CLOCK_TIME_NONE) { /* create a new empty clip for the same cmml track starting at end_time */ GObject *end_clip = g_object_new (GST_TYPE_CMML_TAG_CLIP, "start-time", clip->end_time, "track", clip->track, NULL); /* encode the empty end clip */ gst_cmml_enc_push_clip (enc, GST_CMML_TAG_CLIP (end_clip), clip->start_time); g_object_unref (end_clip); } done: return res; granule_overflow: GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("granulepos overflow")); return GST_FLOW_ERROR; }
/* push the string representation of a clip */ static void gst_cmml_dec_push_clip (GstCmmlDec * dec, GstCmmlTagClip * clip) { GstBuffer *buffer; guchar *clip_str; GST_DEBUG_OBJECT (dec, "pushing clip %s", clip->id); clip_str = gst_cmml_parser_tag_clip_to_string (dec->parser, clip); dec->flow_return = gst_cmml_dec_new_buffer (dec, clip_str, strlen ((gchar *) clip_str), &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 */ g_free (clip_str); }
guchar * gst_cmml_parser_tag_object_to_string (GstCmmlParser * parser, GObject * tag) { guchar *tag_string = NULL; GType tag_type = G_OBJECT_TYPE (tag); if (tag_type == GST_TYPE_CMML_TAG_STREAM) tag_string = gst_cmml_parser_tag_stream_to_string (parser, GST_CMML_TAG_STREAM (tag)); else if (tag_type == GST_TYPE_CMML_TAG_HEAD) tag_string = gst_cmml_parser_tag_head_to_string (parser, GST_CMML_TAG_HEAD (tag)); else if (tag_type == GST_TYPE_CMML_TAG_CLIP) tag_string = gst_cmml_parser_tag_clip_to_string (parser, GST_CMML_TAG_CLIP (tag)); else g_warning ("could not convert object to cmml"); return tag_string; }