summaryrefslogtreecommitdiffstats
path: root/ext/dv
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2006-06-02 11:33:18 +0000
committerEdward Hervey <bilboed@bilboed.com>2006-06-02 11:33:18 +0000
commitb91d63fb3b709b100ea67a561d1e5861acc725e8 (patch)
tree540ded53af6eba6be94fd2ab0325cda0a85d383a /ext/dv
parent7174c10edff8a9fcd5e3c54e3c2f36e21b40a4ef (diff)
ext/dv/gstdvdec.*: Added GstSegment handling, now implements dropping/clipping.
Original commit message from CVS: * ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_sink_event), (gst_dvdec_chain), (gst_dvdec_change_state): * ext/dv/gstdvdec.h: Added GstSegment handling, now implements dropping/clipping.
Diffstat (limited to 'ext/dv')
-rw-r--r--ext/dv/gstdvdec.c62
-rw-r--r--ext/dv/gstdvdec.h2
2 files changed, 63 insertions, 1 deletions
diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c
index c7ab3690..42b98488 100644
--- a/ext/dv/gstdvdec.c
+++ b/ext/dv/gstdvdec.c
@@ -143,6 +143,7 @@ GST_BOILERPLATE (GstDVDec, gst_dvdec, GstElement, GST_TYPE_ELEMENT);
static gboolean gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps);
static GstFlowReturn gst_dvdec_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_dvdec_sink_event (GstPad * pad, GstEvent * event);
static GstStateChangeReturn gst_dvdec_change_state (GstElement * element,
GstStateChange transition);
@@ -207,6 +208,7 @@ gst_dvdec_init (GstDVDec * dvdec, GstDVDecClass * g_class)
gst_pad_set_setcaps_function (dvdec->sinkpad,
GST_DEBUG_FUNCPTR (gst_dvdec_sink_setcaps));
gst_pad_set_chain_function (dvdec->sinkpad, gst_dvdec_chain);
+ gst_pad_set_event_function (dvdec->sinkpad, gst_dvdec_sink_event);
gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->sinkpad);
dvdec->srcpad =
@@ -282,6 +284,41 @@ error:
}
}
+static gboolean
+gst_dvdec_sink_event (GstPad * pad, GstEvent * event)
+{
+ GstDVDec *dvdec;
+ gboolean res = TRUE;
+
+ dvdec = GST_DVDEC (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:{
+ gboolean update;
+ gdouble rate;
+ GstFormat format;
+ gint64 start, stop, position;
+
+ /* Once -good depends on core >= 0.10.6, use newsegment_full */
+ gst_event_parse_new_segment (event, &update, &rate, &format,
+ &start, &stop, &position);
+ GST_DEBUG_OBJECT (dvdec, "Got NEWSEGMENT [%" GST_TIME_FORMAT
+ " - %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "]",
+ GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
+ GST_TIME_ARGS (position));
+ gst_segment_set_newsegment (dvdec->segment, update, rate, format,
+ start, stop, position);
+ }
+ break;
+ default:
+ break;
+ }
+
+ res = gst_pad_push_event (dvdec->srcpad, event);
+
+ return res;
+}
+
static GstFlowReturn
gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
{
@@ -293,6 +330,7 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
GstBuffer *outbuf;
GstFlowReturn ret = GST_FLOW_OK;
guint length;
+ gint64 cstart, cstop;
dvdec = GST_DVDEC (gst_pad_get_parent (pad));
inframe = GST_BUFFER_DATA (buf);
@@ -302,6 +340,14 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < NTSC_BUFFER))
goto wrong_size;
+ /* preliminary dropping. unref and return if outside of configured segment */
+ if ((dvdec->segment->format == GST_FORMAT_TIME) &&
+ (!(gst_segment_clip (dvdec->segment, GST_FORMAT_TIME,
+ GST_BUFFER_TIMESTAMP (buf),
+ GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf),
+ &cstart, &cstop))))
+ goto dropping;
+
if (G_UNLIKELY (dv_parse_header (dvdec->decoder, inframe) < 0))
goto parse_header_error;
@@ -341,7 +387,10 @@ gst_dvdec_chain (GstPad * pad, GstBuffer * buf)
dv_decode_full_frame (dvdec->decoder, inframe,
e_dv_color_yuv, outframe_ptrs, outframe_pitches);
- gst_buffer_stamp (outbuf, buf);
+ GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
+ GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_END (buf);
+ GST_BUFFER_TIMESTAMP (outbuf) = cstart;
+ GST_BUFFER_DURATION (outbuf) = cstop - cstart;
ret = gst_pad_push (dvdec->srcpad, outbuf);
@@ -374,6 +423,13 @@ no_buffer:
GST_DEBUG_OBJECT (dvdec, "could not allocate buffer");
goto done;
}
+
+dropping:
+ {
+ GST_DEBUG_OBJECT (dvdec,
+ "dropping buffer since it's out of the configured segment");
+ goto done;
+ }
}
static GstStateChangeReturn
@@ -391,6 +447,8 @@ gst_dvdec_change_state (GstElement * element, GstStateChange transition)
dv_decoder_new (0, dvdec->clamp_luma, dvdec->clamp_chroma);
dvdec->decoder->quality = qualities[dvdec->quality];
dv_set_error_log (dvdec->decoder, NULL);
+ dvdec->segment = gst_segment_new ();
+ gst_segment_init (dvdec->segment, GST_FORMAT_UNDEFINED);
/*
* Enable this function call when libdv2 0.100 or higher is more
* common
@@ -411,6 +469,8 @@ gst_dvdec_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PAUSED_TO_READY:
dv_decoder_free (dvdec->decoder);
dvdec->decoder = NULL;
+ gst_segment_free (dvdec->segment);
+ dvdec->segment = NULL;
break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
diff --git a/ext/dv/gstdvdec.h b/ext/dv/gstdvdec.h
index 90438d65..ffc8a24a 100644
--- a/ext/dv/gstdvdec.h
+++ b/ext/dv/gstdvdec.h
@@ -69,6 +69,8 @@ struct _GstDVDec {
gint video_offset;
gint drop_factor;
+
+ GstSegment *segment;
};
struct _GstDVDecClass {