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; }
/* outputs the cmml head element and send TITLE and CMML_HEAD tags. * This callback is registered with dec->parser. It is called when the * head element is parsed. */ static void gst_cmml_dec_parse_head (GstCmmlDec * dec, GstCmmlTagHead * head) { GstTagList *tags; GValue str_val = { 0 }, title_val = { 0}; guchar *head_str; GstBuffer *buffer; GST_DEBUG_OBJECT (dec, "found CMML head (title: %s base: %s)", head->title, head->base); /* create the GST_TAG_TITLE tag */ g_value_init (&str_val, G_TYPE_STRING); g_value_init (&title_val, gst_tag_get_type (GST_TAG_TITLE)); g_value_set_string (&str_val, (gchar *) head->title); g_value_transform (&str_val, &title_val); tags = gst_tag_list_new (); gst_tag_list_add_values (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, &title_val, NULL); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_CMML_HEAD, head, NULL); gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags); g_value_unset (&str_val); g_value_unset (&title_val); head_str = gst_cmml_parser_tag_head_to_string (dec->parser, head); dec->flow_return = gst_cmml_dec_new_buffer (dec, head_str, strlen ((gchar *) head_str), &buffer); g_free (head_str); 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 */ }
/* encode the CMML head tag and push the CMML headers */ static void gst_cmml_enc_parse_tag_head (GstCmmlEnc * enc, GstCmmlTagHead * head) { GList *headers = NULL; GList *walk; guchar *head_string; GstCaps *caps; GstBuffer *ident_buf, *preamble_buf, *head_buf; GstBuffer *buffer; if (enc->preamble == NULL) goto flow_unexpected; GST_INFO_OBJECT (enc, "parsing head tag"); enc->flow_return = gst_cmml_enc_new_ident_header (enc, &ident_buf); if (enc->flow_return != GST_FLOW_OK) goto alloc_error; headers = g_list_append (headers, ident_buf); enc->flow_return = gst_cmml_enc_new_buffer (enc, enc->preamble, strlen ((gchar *) enc->preamble), &preamble_buf); if (enc->flow_return != GST_FLOW_OK) goto alloc_error; headers = g_list_append (headers, preamble_buf); head_string = gst_cmml_parser_tag_head_to_string (enc->parser, head); enc->flow_return = gst_cmml_enc_new_buffer (enc, head_string, strlen ((gchar *) head_string), &head_buf); g_free (head_string); if (enc->flow_return != GST_FLOW_OK) goto alloc_error; headers = g_list_append (headers, head_buf); caps = gst_pad_get_caps (enc->srcpad); caps = gst_cmml_enc_set_header_on_caps (enc, caps, ident_buf, preamble_buf, head_buf); while (headers) { buffer = GST_BUFFER (headers->data); /* set granulepos 0 on headers */ GST_BUFFER_OFFSET_END (buffer) = 0; gst_buffer_set_caps (buffer, caps); enc->flow_return = gst_cmml_enc_push (enc, buffer); headers = g_list_delete_link (headers, headers); if (GST_FLOW_IS_FATAL (enc->flow_return)) goto push_error; } gst_caps_unref (caps); enc->sent_headers = TRUE; return; flow_unexpected: GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("got head tag before preamble")); enc->flow_return = GST_FLOW_ERROR; return; push_error: gst_caps_unref (caps); /* fallthrough */ alloc_error: for (walk = headers; walk; walk = walk->next) gst_buffer_unref (GST_BUFFER (walk->data)); g_list_free (headers); return; }