From 0fe8295e4a7a7cc2535e9bbbfa32c76056952ccf Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 23 Mar 2018 11:27:00 +0100 Subject: ccextractor: Use GstFlowCombiner for aggregated flow return Ensures that if ever there's an issue from downstream that needs to be propagated upstream it is. Also handle a couple more error cases with GST_FLOW_NOT_NEGOTIATED --- gst/closedcaption/gstccextractor.c | 47 ++++++++++++++++++++++++++++++++------ gst/closedcaption/gstccextractor.h | 3 +++ 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 +#include #include G_BEGIN_DECLS @@ -45,6 +46,8 @@ struct _GstCCExtractor GstPad *sinkpad, *srcpad, *captionpad; GstVideoCaptionType caption_type; + + GstFlowCombiner *combiner; }; struct _GstCCExtractorClass -- cgit v1.2.3