mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
katedec: handle streamheaders in caps
Properly handle the caps event by configuring the kate decoding lib using the available streamheaders. This makes it possible to decode kate subtitles when the stream is seeked before katedec gets the initial buffers that are usually the streamheaders. https://bugzilla.gnome.org/show_bug.cgi?id=733226
This commit is contained in:
parent
83b672f328
commit
b0e63bbb9b
1 changed files with 171 additions and 102 deletions
|
@ -237,36 +237,11 @@ gst_kate_dec_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
/* GstElement vmethod implementations */
|
||||
|
||||
/* chain function
|
||||
* this function does the actual processing
|
||||
*/
|
||||
|
||||
static GstFlowReturn
|
||||
gst_kate_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||
gst_kate_dec_handle_kate_event (GstKateDec * kd, const kate_event * ev)
|
||||
{
|
||||
GstKateFormat format = GST_KATE_FORMAT_UNDEFINED;
|
||||
GstKateDec *kd = GST_KATE_DEC (parent);
|
||||
const kate_event *ev = NULL;
|
||||
GstFlowReturn rflow = GST_FLOW_OK;
|
||||
|
||||
if (!gst_kate_util_decoder_base_update_segment (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), buf)) {
|
||||
GST_WARNING_OBJECT (kd, "Out of segment!");
|
||||
goto not_in_seg;
|
||||
}
|
||||
|
||||
rflow =
|
||||
gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), pad, buf, kd->srcpad, kd->srcpad, &kd->src_caps,
|
||||
&ev);
|
||||
if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
|
||||
gst_buffer_unref (buf);
|
||||
return rflow;
|
||||
}
|
||||
|
||||
if (ev) {
|
||||
GstKateFormat format = GST_KATE_FORMAT_UNDEFINED;
|
||||
gchar *escaped;
|
||||
GstBuffer *buffer;
|
||||
size_t len;
|
||||
|
@ -367,6 +342,39 @@ gst_kate_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
|||
rflow = GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
return rflow;
|
||||
}
|
||||
|
||||
/* GstElement vmethod implementations */
|
||||
|
||||
/* chain function
|
||||
* this function does the actual processing
|
||||
*/
|
||||
|
||||
static GstFlowReturn
|
||||
gst_kate_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||
{
|
||||
GstKateDec *kd = GST_KATE_DEC (parent);
|
||||
const kate_event *ev = NULL;
|
||||
GstFlowReturn rflow = GST_FLOW_OK;
|
||||
|
||||
if (!gst_kate_util_decoder_base_update_segment (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), buf)) {
|
||||
GST_WARNING_OBJECT (kd, "Out of segment!");
|
||||
goto not_in_seg;
|
||||
}
|
||||
|
||||
rflow =
|
||||
gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), pad, buf, kd->srcpad, kd->srcpad, &kd->src_caps,
|
||||
&ev);
|
||||
if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
|
||||
gst_buffer_unref (buf);
|
||||
return rflow;
|
||||
}
|
||||
|
||||
if (ev) {
|
||||
rflow = gst_kate_dec_handle_kate_event (kd, ev);
|
||||
}
|
||||
|
||||
not_in_seg:
|
||||
|
@ -400,13 +408,74 @@ gst_kate_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_kate_dec_set_caps (GstKateDec * kd, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure = gst_caps_get_structure (caps, 0);
|
||||
GstFlowReturn rflow = GST_FLOW_OK;
|
||||
|
||||
if (gst_structure_has_field (structure, "streamheader")) {
|
||||
const GValue *value;
|
||||
GstBuffer *buf;
|
||||
const kate_event *ev;
|
||||
|
||||
value = gst_structure_get_value (structure, "streamheader");
|
||||
|
||||
if (GST_VALUE_HOLDS_BUFFER (value)) {
|
||||
buf = gst_value_get_buffer (value);
|
||||
|
||||
gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), kd->sinkpad, buf, kd->srcpad, kd->srcpad,
|
||||
&kd->src_caps, &ev);
|
||||
|
||||
if (ev) {
|
||||
rflow = gst_kate_dec_handle_kate_event (kd, ev);
|
||||
}
|
||||
} else if (GST_VALUE_HOLDS_ARRAY (value)) {
|
||||
gint i, size = gst_value_array_get_size (value);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
const GValue *v = gst_value_array_get_value (value, i);
|
||||
|
||||
buf = gst_value_get_buffer (v);
|
||||
gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
|
||||
GST_ELEMENT_CAST (kd), kd->sinkpad, buf, kd->srcpad, kd->srcpad,
|
||||
&kd->src_caps, &ev);
|
||||
|
||||
if (ev) {
|
||||
rflow = gst_kate_dec_handle_kate_event (kd, ev);
|
||||
if (rflow != GST_FLOW_OK && rflow != GST_FLOW_NOT_LINKED)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GST_WARNING_OBJECT (kd, "Unhandled streamheader type: %s",
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
}
|
||||
}
|
||||
|
||||
return rflow == GST_FLOW_OK || rflow == GST_FLOW_NOT_LINKED;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_kate_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
{
|
||||
GstKateDec *kd = GST_KATE_DEC (parent);
|
||||
gboolean res = TRUE;
|
||||
|
||||
GST_LOG_OBJECT (pad, "Event on sink pad: %s", GST_EVENT_TYPE_NAME (event));
|
||||
GST_LOG_OBJECT (pad, "Event on sink pad: %" GST_PTR_FORMAT, event);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CAPS:{
|
||||
GstCaps *caps;
|
||||
|
||||
gst_event_parse_caps (event, &caps);
|
||||
gst_kate_dec_set_caps (kd, caps);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Delay events till we've set caps */
|
||||
if (gst_kate_util_decoder_base_queue_event (&kd->decoder, event,
|
||||
|
|
Loading…
Reference in a new issue