static gboolean gst_dshowvideodec_sink_event (GstPad * pad, GstEvent * event) { gboolean ret = TRUE; GstDshowVideoDec *vdec = (GstDshowVideoDec *) gst_pad_get_parent (pad); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: gst_dshowvideodec_flush (vdec); ret = gst_pad_event_default (pad, event); break; case GST_EVENT_NEWSEGMENT: { GstFormat format; gdouble rate; gint64 start, stop, time; gboolean update; gst_event_parse_new_segment (event, &update, &rate, &format, &start, &stop, &time); /* save the new segment in our local current segment */ gst_segment_set_newsegment (vdec->segment, update, rate, format, start, stop, time); GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec, "new segment received => start=%" GST_TIME_FORMAT " stop=%" GST_TIME_FORMAT, GST_TIME_ARGS (vdec->segment->start), GST_TIME_ARGS (vdec->segment->stop)); if (update) { GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec, "closing current segment flushing.."); gst_dshowvideodec_flush (vdec); } ret = gst_pad_event_default (pad, event); break; } default: ret = gst_pad_event_default (pad, event); break; } gst_object_unref (vdec); return ret; }
static GstFlowReturn gst_dshowvideodec_chain (GstPad * pad, GstBuffer * buffer) { GstDshowVideoDec *vdec = (GstDshowVideoDec *) gst_pad_get_parent (pad); bool discont = FALSE; GstClockTime stop; if (!vdec->setup) { /* we are not setup */ GST_WARNING_OBJECT (vdec, "Decoder not set up, failing"); vdec->last_ret = GST_FLOW_FLUSHING; goto beach; } if (GST_FLOW_IS_FATAL (vdec->last_ret)) { GST_DEBUG_OBJECT (vdec, "last decoding iteration generated a fatal error " "%s", gst_flow_get_name (vdec->last_ret)); goto beach; } /* check if duration is valid and use duration only when it's valid /* because dshow is not decoding frames having stop smaller than start */ if (GST_BUFFER_DURATION_IS_VALID (buffer)) { stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer); } else { stop = GST_BUFFER_TIMESTAMP (buffer); } GST_CAT_LOG_OBJECT (dshowvideodec_debug, vdec, "chain (size %d)=> pts %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (stop)); /* if the incoming buffer has discont flag set => flush decoder data */ if (buffer && GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec, "this buffer has a DISCONT flag (%" GST_TIME_FORMAT "), flushing", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); gst_dshowvideodec_flush (vdec); discont = TRUE; } /* push the buffer to the directshow decoder */ vdec->fakesrc->GetOutputPin()->PushBuffer( GST_BUFFER_DATA (buffer), GST_BUFFER_TIMESTAMP (buffer), stop, GST_BUFFER_SIZE (buffer), discont); beach: gst_buffer_unref (buffer); gst_object_unref (vdec); return vdec->last_ret; }