summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/closedcaption/gstccextractor.c47
-rw-r--r--gst/closedcaption/gstccextractor.h3
2 files changed, 43 insertions, 7 deletions
diff --git a/gst/closedcaption/gstccextractor.c b/gst/closedcaption/gstccextractor.c
index c38754a55..5a83aa2ec 100644
--- a/gst/closedcaption/gstccextractor.c
+++ b/gst/closedcaption/gstccextractor.c
@@ -136,6 +136,15 @@ static void
gst_cc_extractor_reset (GstCCExtractor * filter)
{
filter->caption_type = GST_VIDEO_CAPTION_TYPE_UNKNOWN;
+ gst_flow_combiner_reset (filter->combiner);
+ gst_flow_combiner_add_pad (filter->combiner, filter->srcpad);
+
+ if (filter->captionpad) {
+ gst_flow_combiner_remove_pad (filter->combiner, filter->captionpad);
+ gst_pad_set_active (filter->captionpad, FALSE);
+ gst_element_remove_pad ((GstElement *) filter, filter->captionpad);
+ filter->captionpad = NULL;
+ }
}
static void
@@ -162,6 +171,8 @@ gst_cc_extractor_init (GstCCExtractor * filter)
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
+ filter->combiner = gst_flow_combiner_new ();
+
gst_cc_extractor_reset (filter);
}
@@ -213,13 +224,14 @@ gst_cc_extractor_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
return gst_pad_event_default (pad, parent, event);
}
-static void
+static GstFlowReturn
gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf,
GstVideoCaptionMeta * meta)
{
GstBuffer *outbuf = NULL;
GstEvent *event;
gchar *captionid;
+ GstFlowReturn flow;
GST_DEBUG_OBJECT (filter, "Handling meta");
@@ -227,7 +239,8 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf,
if (filter->captionpad != NULL && meta->caption_type != filter->caption_type) {
GST_ERROR_OBJECT (filter,
"GstVideoCaptionMeta type changed, Not handled currently");
- return;
+ flow = GST_FLOW_NOT_NEGOTIATED;
+ goto out;
}
if (filter->captionpad == NULL) {
@@ -259,7 +272,7 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf,
}
if (caption_caps == NULL) {
GST_ERROR_OBJECT (filter, "Unknown/invalid caption type");
- return;
+ return GST_FLOW_NOT_NEGOTIATED;
}
/* Create the caption pad and set the caps */
@@ -269,6 +282,7 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf,
GST_DEBUG_FUNCPTR (gst_cc_extractor_iterate_internal_links));
gst_pad_set_active (filter->captionpad, TRUE);
gst_element_add_pad (GST_ELEMENT (filter), filter->captionpad);
+ gst_flow_combiner_add_pad (filter->combiner, filter->captionpad);
captionid =
gst_pad_create_stream_id (filter->captionpad, (GstElement *) filter,
@@ -310,29 +324,43 @@ gst_cc_extractor_handle_meta (GstCCExtractor * filter, GstBuffer * buf,
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
/* We don't really care about the flow return */
- gst_pad_push (filter->captionpad, outbuf);
+ flow = gst_pad_push (filter->captionpad, outbuf);
+
+out:
+ /* Set flow return on pad and return combined value */
+ return gst_flow_combiner_update_pad_flow (filter->combiner,
+ filter->captionpad, flow);
}
static GstFlowReturn
gst_cc_extractor_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
GstCCExtractor *filter = (GstCCExtractor *) parent;
+ GstFlowReturn flow = GST_FLOW_OK;
GstVideoCaptionMeta *cc_meta;
cc_meta = gst_buffer_get_video_caption_meta (buf);
if (cc_meta)
- gst_cc_extractor_handle_meta (filter, buf, cc_meta);
+ flow = gst_cc_extractor_handle_meta (filter, buf, cc_meta);
else
GST_DEBUG_OBJECT (filter, "No CC meta on buffer");
- return gst_pad_push (filter->srcpad, buf);
+ /* If there's an issue handling the CC, return immediately */
+ if (flow != GST_FLOW_OK) {
+ gst_buffer_unref (buf);
+ return flow;
+ }
+
+ /* Push the buffer downstream and return the combined flow return */
+ return gst_flow_combiner_update_pad_flow (filter->combiner, filter->srcpad,
+ gst_pad_push (filter->srcpad, buf));
}
static GstStateChangeReturn
gst_cc_extractor_change_state (GstElement * element, GstStateChange transition)
{
GstStateChangeReturn ret;
- /* GstCCExtractor *filter = GST_CCEXTRACTOR (element); */
+ GstCCExtractor *filter = GST_CCEXTRACTOR (element);
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
@@ -353,6 +381,7 @@ gst_cc_extractor_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_cc_extractor_reset (filter);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
default:
@@ -365,5 +394,9 @@ gst_cc_extractor_change_state (GstElement * element, GstStateChange transition)
static void
gst_cc_extractor_finalize (GObject * object)
{
+ GstCCExtractor *filter = GST_CCEXTRACTOR (object);
+
+ gst_flow_combiner_free (filter->combiner);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
diff --git a/gst/closedcaption/gstccextractor.h b/gst/closedcaption/gstccextractor.h
index 728072ada..2ad8bd394 100644
--- a/gst/closedcaption/gstccextractor.h
+++ b/gst/closedcaption/gstccextractor.h
@@ -22,6 +22,7 @@
#define __GST_CCEXTRACTOR_H__
#include <gst/gst.h>
+#include <gst/base/gstflowcombiner.h>
#include <gst/video/video-anc.h>
G_BEGIN_DECLS
@@ -45,6 +46,8 @@ struct _GstCCExtractor
GstPad *sinkpad, *srcpad, *captionpad;
GstVideoCaptionType caption_type;
+
+ GstFlowCombiner *combiner;
};
struct _GstCCExtractorClass