static void dxr3videosink_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); Dxr3VideoSink *sink; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); sink = DXR3VIDEOSINK (gst_pad_get_parent (pad)); if (GST_IS_EVENT (buf)) { dxr3videosink_handle_event (pad, GST_EVENT (buf)); return; } /* fprintf (stderr, "^^^^^^ Video block\n"); */ if (sink->cur_buf == NULL) { sink->cur_buf = buf; } else { sink->cur_buf = gst_buffer_append (sink->cur_buf, buf); } sink->last_ts = GST_BUFFER_TIMESTAMP (buf); dxr3videosink_parse_data (sink); }
static void dxr3videosink_set_clock (GstElement * element, GstClock * clock) { Dxr3VideoSink *src = DXR3VIDEOSINK (element); src->clock = clock; }
static gboolean dxr3videosink_set_clock (GstElement * element, GstClock * clock) { Dxr3VideoSink *src = DXR3VIDEOSINK (element); src->clock = clock; return GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock); }
static void dxr3videosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { Dxr3VideoSink *sink; sink = DXR3VIDEOSINK (object); switch (prop_id) { default: break; } }
static void dxr3videosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { Dxr3VideoSink *sink; g_return_if_fail (GST_IS_DXR3VIDEOSINK (object)); sink = DXR3VIDEOSINK (object); switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstStateChangeReturn dxr3videosink_change_state (GstElement * element, GstStateChange transition) { g_return_val_if_fail (GST_IS_DXR3VIDEOSINK (element), GST_STATE_CHANGE_FAILURE); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!GST_OBJECT_FLAG_IS_SET (element, DXR3VIDEOSINK_OPEN)) { if (!dxr3videosink_open (DXR3VIDEOSINK (element))) { return GST_STATE_CHANGE_FAILURE; } } break; case GST_STATE_CHANGE_READY_TO_PAUSED: dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_PAUSE); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_START); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_PAUSE); break; case GST_STATE_CHANGE_PAUSED_TO_READY: dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_STOP); break; case GST_STATE_CHANGE_READY_TO_NULL: if (GST_OBJECT_FLAG_IS_SET (element, DXR3VIDEOSINK_OPEN)) { dxr3videosink_close (DXR3VIDEOSINK (element)); } break; } if (GST_ELEMENT_CLASS (parent_class)->change_state) { return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); } return GST_STATE_CHANGE_SUCCESS; }
static gboolean dxr3videosink_handle_event (GstPad * pad, GstEvent * event) { GstEventType type; Dxr3VideoSink *sink; sink = DXR3VIDEOSINK (gst_pad_get_parent (pad)); type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN; switch (type) { case GST_EVENT_EMPTY: //fprintf (stderr, "++++++ Video empty event\n"); { /* FIXME: Handle this with a discontinuity or something. */ /* Write an MPEG2 sequence end code, to ensure that the card actually displays the last picture. Apparently some DVDs are encoded without proper sequence end codes. */ static const guint8 sec[4] = { 0x00, 0x00, 0x01, 0xb7 }; if (sink->cur_buf != NULL) { dxr3videosink_write_data (sink, 0); } write (sink->video_fd, &sec, 4); } break; case GST_EVENT_DISCONTINUOUS: //fprintf (stderr, "++++++ Video discont event\n"); { gint64 time; gboolean has_time; unsigned cur_scr, mpeg_scr, diff; has_time = gst_event_discont_get_value (event, GST_FORMAT_TIME, &time); if (has_time) { /* fprintf (stderr, "^^^^^^ Discontinuous event has time %.4f\n", */ /* (double) time / GST_SECOND); */ /* If the SCR in the card is way off, fix it. */ ioctl (sink->control_fd, EM8300_IOCTL_SCR_GET, &cur_scr); mpeg_scr = MPEGTIME_TO_DXRTIME (GSTTIME_TO_MPEGTIME (time)); diff = cur_scr > mpeg_scr ? cur_scr - mpeg_scr : mpeg_scr - cur_scr; if (diff > 1800) { unsigned zero = 0; /* fprintf (stderr, "====== Adjusting SCR from video\n"); */ ioctl (sink->control_fd, EM8300_IOCTL_SCR_SET, &zero); ioctl (sink->control_fd, EM8300_IOCTL_SCR_SET, &mpeg_scr); } } else { /* fprintf (stderr, "^^^^^^ Discontinuous event has no time\n"); */ } } break; case GST_EVENT_FLUSH: dxr3videosink_reset_parser (sink); break; default: gst_pad_event_default (pad, event); break; } return TRUE; }