static GstFlowReturn gst_kate_parse_push_headers (GstKateParse * parse) { /* mark and put on caps */ GstCaps *caps; GstBuffer *outbuf; kate_packet packet; GList *headers, *outbuf_list = NULL; int ret; gboolean res; /* get the headers into the caps, passing them to kate as we go */ caps = gst_kate_util_set_header_on_caps (&parse->element, gst_pad_get_current_caps (parse->sinkpad), parse->streamheader); if (G_UNLIKELY (!caps)) { GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), ("Failed to set headers on caps")); return GST_FLOW_ERROR; } GST_DEBUG_OBJECT (parse, "here are the caps: %" GST_PTR_FORMAT, caps); res = gst_pad_set_caps (parse->srcpad, caps); gst_caps_unref (caps); if (G_UNLIKELY (!res)) { GST_WARNING_OBJECT (parse->srcpad, "Failed to set caps on source pad"); return GST_FLOW_NOT_NEGOTIATED; } headers = parse->streamheader; while (headers) { GstMapInfo info; outbuf = GST_BUFFER_CAST (headers->data); if (!gst_buffer_map (outbuf, &info, GST_MAP_READ)) { GST_WARNING_OBJECT (outbuf, "Failed to map buffer"); continue; } kate_packet_wrap (&packet, info.size, info.data); ret = kate_decode_headerin (&parse->ki, &parse->kc, &packet); if (G_UNLIKELY (ret < 0)) { GST_WARNING_OBJECT (parse, "Failed to decode header: %s", gst_kate_util_get_error_message (ret)); } gst_buffer_unmap (outbuf, &info); /* takes ownership of outbuf, which was previously in parse->streamheader */ GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_HEADER); outbuf_list = g_list_append (outbuf_list, outbuf); headers = headers->next; } /* first process queued events */ gst_kate_parse_drain_event_queue (parse); /* push out buffers, ignoring return value... */ headers = outbuf_list; while (headers) { outbuf = GST_BUFFER_CAST (headers->data); gst_pad_push (parse->srcpad, outbuf); headers = headers->next; } g_list_free (outbuf_list); g_list_free (parse->streamheader); parse->streamheader = NULL; parse->streamheader_sent = TRUE; return GST_FLOW_OK; }
static GstFlowReturn gst_kate_enc_send_headers (GstKateEnc * ke) { GstFlowReturn rflow = GST_FLOW_OK; GstCaps *caps; GList *headers = NULL, *item; if (G_UNLIKELY (ke->category == NULL || *ke->category == '\0')) { /* The error code is a bit of a lie, but seems most appropriate. */ GST_ELEMENT_ERROR (ke, LIBRARY, SETTINGS, (NULL), ("The 'category' property must be set. For subtitles, set it to " "either 'SUB' (text subtitles) or 'K-SPU' (dvd-style subtitles)")); return GST_FLOW_ERROR; } gst_kate_enc_set_metadata (ke); /* encode headers and store them in a list */ while (1) { kate_packet kp; int ret = kate_encode_headers (&ke->k, &ke->kc, &kp); if (ret == 0) { GstBuffer *buffer; buffer = gst_kate_enc_create_buffer (ke, &kp, 0, 0, 0, TRUE); if (!buffer) { GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Failed to create buffer, %u bytes", (guint) kp.nbytes)); rflow = GST_FLOW_ERROR; break; } kate_packet_clear (&kp); GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER); headers = g_list_append (headers, buffer); } else if (ret > 0) { GST_LOG_OBJECT (ke, "Last header encoded"); break; } else { GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL), ("Failed encoding headers: %s", gst_kate_util_get_error_message (ret))); rflow = GST_FLOW_ERROR; break; } } if (rflow == GST_FLOW_OK) { if (gst_kate_enc_is_simple_subtitle_category (ke, ke->category)) { caps = gst_kate_util_set_header_on_caps (&ke->element, gst_caps_from_string ("subtitle/x-kate"), headers); } else { caps = gst_kate_util_set_header_on_caps (&ke->element, gst_caps_from_string ("application/x-kate"), headers); } if (caps) { GST_DEBUG_OBJECT (ke, "here are the caps: %" GST_PTR_FORMAT, caps); gst_pad_set_caps (ke->srcpad, caps); gst_caps_unref (caps); if (ke->pending_segment) gst_pad_push_event (ke->srcpad, ke->pending_segment); ke->pending_segment = NULL; GST_LOG_OBJECT (ke, "pushing headers"); item = headers; while (item) { GstBuffer *buffer = item->data; GST_LOG_OBJECT (ke, "pushing header %p", buffer); gst_kate_enc_push_buffer (ke, buffer); item = item->next; } } else { GST_ERROR_OBJECT (ke, "Failed to set headers on caps"); } } g_list_free (headers); return rflow; }