diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/directdraw/gstdirectdrawsink.c | 10 | ||||
-rw-r--r-- | sys/osxvideo/Makefile.am | 2 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2object.c | 4 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2object.h | 1 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2src.c | 70 | ||||
-rw-r--r-- | sys/v4l2/v4l2_calls.c | 8 | ||||
-rw-r--r-- | sys/v4l2/v4l2src_calls.c | 33 |
7 files changed, 119 insertions, 9 deletions
diff --git a/sys/directdraw/gstdirectdrawsink.c b/sys/directdraw/gstdirectdrawsink.c index a128b317..144f6595 100644 --- a/sys/directdraw/gstdirectdrawsink.c +++ b/sys/directdraw/gstdirectdrawsink.c @@ -610,7 +610,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, !gst_directdraw_sink_surface_check (ddrawsink, surface)) ) { gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); surface = NULL; } else { /* We found a suitable surface */ @@ -629,7 +629,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, DDSURFACEDESC2 surface_desc; DDSURFACEDESC2 *sd; - if (!gst_structure_get_int (structure, "depth", &depth)) { + if (!gst_structure_get_int (structure, "depth", (gint *) & depth)) { GST_CAT_DEBUG_OBJECT (directdrawsink_debug, ddrawsink, "Can't get depth from buffer_alloc caps"); return GST_FLOW_ERROR; @@ -663,7 +663,7 @@ gst_directdraw_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, gint bpp, endianness, red_mask, green_mask, blue_mask; /* get new display mode properties */ - gst_structure_get_int (display_structure, "depth", &depth); + gst_structure_get_int (display_structure, "depth", (gint *) & depth); gst_structure_get_int (display_structure, "bpp", &bpp); gst_structure_get_int (display_structure, "endianness", &endianness); gst_structure_get_int (display_structure, "red_mask", &red_mask); @@ -997,7 +997,7 @@ gst_ddrawvideosink_get_format_from_caps (GstDirectDrawSink * ddrawsink, pPixelFormat->dwBBitMask = GUINT32_TO_BE (pPixelFormat->dwBBitMask); } } else if (gst_structure_has_name (structure, "video/x-raw-yuv")) { - gint fourcc; + guint32 fourcc; pPixelFormat->dwFlags = DDPF_FOURCC; ret &= gst_structure_get_fourcc (structure, "format", &fourcc); @@ -1894,7 +1894,7 @@ gst_directdraw_sink_bufferpool_clear (GstDirectDrawSink * ddrawsink) ddrawsink->buffer_pool = g_slist_delete_link (ddrawsink->buffer_pool, ddrawsink->buffer_pool); gst_directdraw_sink_surface_destroy (ddrawsink, surface); - gst_buffer_unref (surface); + gst_buffer_unref (GST_BUFFER_CAST (surface)); } g_mutex_unlock (ddrawsink->pool_lock); } diff --git a/sys/osxvideo/Makefile.am b/sys/osxvideo/Makefile.am index 5e6d4310..71fc6206 100644 --- a/sys/osxvideo/Makefile.am +++ b/sys/osxvideo/Makefile.am @@ -1,5 +1,3 @@ -# FIXME: clean up this crap -OBJC=gcc plugin_LTLIBRARIES = libgstosxvideosink.la diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index ffc1046d..d848ccf3 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -270,6 +270,7 @@ gst_v4l2_object_new (GstElement * element, v4l2object->update_fps_func = update_fps_func; v4l2object->video_fd = -1; + v4l2object->poll = gst_poll_new (TRUE); v4l2object->buffer = NULL; v4l2object->videodev = g_strdup (DEFAULT_PROP_DEVICE); @@ -290,6 +291,9 @@ gst_v4l2_object_destroy (GstV4l2Object * v4l2object) if (v4l2object->videodev) g_free (v4l2object->videodev); + if (v4l2object->poll) + gst_poll_free (v4l2object->poll); + if (v4l2object->channel) g_free (v4l2object->channel); diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index 5eb557ed..c5bc3cb7 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -71,6 +71,7 @@ struct _GstV4l2Object { /* the video-device's file descriptor */ gint video_fd; + GstPoll * poll; /* the video buffer (mmap()'ed) */ guint8 **buffer; diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index a90ddf81..141fb7bb 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -129,6 +129,9 @@ static const guint32 gst_v4l2_formats[] = { #ifdef V4L2_PIX_FMT_PWC2 V4L2_PIX_FMT_PWC2, #endif +#ifdef V4L2_PIX_FMT_YVYU + V4L2_PIX_FMT_YVYU, +#endif }; #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats)) @@ -237,6 +240,10 @@ static void gst_v4l2src_finalize (GstV4l2Src * v4l2src); /* basesrc methods */ static gboolean gst_v4l2src_start (GstBaseSrc * src); +static gboolean gst_v4l2src_unlock (GstBaseSrc * src); + +static gboolean gst_v4l2src_unlock_stop (GstBaseSrc * src); + static gboolean gst_v4l2src_stop (GstBaseSrc * src); static gboolean gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps); @@ -309,6 +316,8 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass) basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps); basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps); basesrc_class->start = GST_DEBUG_FUNCPTR (gst_v4l2src_start); + basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock); + basesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_v4l2src_unlock_stop); basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2src_stop); basesrc_class->query = GST_DEBUG_FUNCPTR (gst_v4l2src_query); basesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_v4l2src_fixate); @@ -688,6 +697,9 @@ gst_v4l2src_v4l2fourcc_to_structure (guint32 fourcc) case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_Y41P: case V4L2_PIX_FMT_YUV422P: +#ifdef V4L2_PIX_FMT_YVYU + case V4L2_PIX_FMT_YVYU: +#endif case V4L2_PIX_FMT_YUV411P:{ guint32 fcc = 0; @@ -725,6 +737,11 @@ gst_v4l2src_v4l2fourcc_to_structure (guint32 fourcc) case V4L2_PIX_FMT_YUV422P: fcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B'); break; +#ifdef V4L2_PIX_FMT_YVYU + case V4L2_PIX_FMT_YVYU: + fcc = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'); + break; +#endif default: g_assert_not_reached (); break; @@ -969,6 +986,12 @@ gst_v4l2_get_caps_info (GstV4l2Src * v4l2src, GstCaps * caps, outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h); outsize += (GST_ROUND_UP_4 (*w) * *h) / 2; break; +#ifdef V4L2_PIX_FMT_YVYU + case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'): + fourcc = V4L2_PIX_FMT_YVYU; + outsize = (GST_ROUND_UP_2 (*w) * 2) * *h; + break; +#endif } } else if (!strcmp (mimetype, "video/x-raw-rgb")) { gint depth, endianness, r_mask; @@ -1159,6 +1182,29 @@ gst_v4l2src_start (GstBaseSrc * src) } static gboolean +gst_v4l2src_unlock (GstBaseSrc * src) +{ + GstV4l2Src *v4l2src = GST_V4L2SRC (src); + + GST_LOG_OBJECT (src, "Flushing"); + gst_poll_set_flushing (v4l2src->v4l2object->poll, TRUE); + + return TRUE; +} + +static gboolean +gst_v4l2src_unlock_stop (GstBaseSrc * src) +{ + GstV4l2Src *v4l2src = GST_V4L2SRC (src); + + GST_LOG_OBJECT (src, "No longer flushing"); + gst_poll_set_flushing (v4l2src->v4l2object->poll, FALSE); + + return TRUE; +} + + +static gboolean gst_v4l2src_stop (GstBaseSrc * src) { GstV4l2Src *v4l2src = GST_V4L2SRC (src); @@ -1186,6 +1232,7 @@ static GstFlowReturn gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) { gint amount; + gint ret; gint buffersize; @@ -1194,6 +1241,18 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) *buf = gst_buffer_new_and_alloc (buffersize); do { + ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE); + if (G_UNLIKELY (ret < 0)) { + if (errno == EBUSY) + goto stopped; +#ifdef G_OS_WIN32 + if (WSAGetLastError () != WSAEINTR) + goto select_error; +#else + if (errno != EAGAIN && errno != EINTR) + goto select_error; +#endif + } amount = v4l2_read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf), buffersize); @@ -1253,6 +1312,17 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf) return GST_FLOW_OK; /* ERRORS */ +select_error: + { + GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL), + ("select error %d: %s (%d)", ret, g_strerror (errno), errno)); + return GST_FLOW_ERROR; + } +stopped: + { + GST_DEBUG ("stop called"); + return GST_FLOW_WRONG_STATE; + } read_error: { GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index a6b4b7dc..b1875a88 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -400,6 +400,7 @@ gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd; + GstPollFD pollfd = GST_POLL_FD_INIT; GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s", v4l2object->videodev); @@ -453,6 +454,10 @@ gst_v4l2_open (GstV4l2Object * v4l2object) "Opened device '%s' (%s) successfully", v4l2object->vcap.card, v4l2object->videodev); + pollfd.fd = v4l2object->video_fd; + gst_poll_add_fd (v4l2object->poll, &pollfd); + gst_poll_fd_ctl_read (v4l2object->poll, &pollfd, TRUE); + return TRUE; /* ERRORS */ @@ -508,6 +513,7 @@ error: gboolean gst_v4l2_close (GstV4l2Object * v4l2object) { + GstPollFD pollfd = GST_POLL_FD_INIT; GST_DEBUG_OBJECT (v4l2object->element, "Trying to close %s", v4l2object->videodev); @@ -516,6 +522,8 @@ gst_v4l2_close (GstV4l2Object * v4l2object) /* close device */ v4l2_close (v4l2object->video_fd); + pollfd.fd = v4l2object->video_fd; + gst_poll_remove_fd (v4l2object->poll, &pollfd); v4l2object->video_fd = -1; /* empty lists */ diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index c247c497..5abfda31 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -771,6 +771,7 @@ unknown_type: } #endif /* defined VIDIOC_ENUM_FRAMEINTERVALS */ +#ifdef VIDIOC_ENUM_FRAMESIZES static gint sort_by_frame_size (GstStructure * s1, GstStructure * s2) { @@ -784,6 +785,7 @@ sort_by_frame_size (GstStructure * s1, GstStructure * s2) /* I think it's safe to assume that this won't overflow for a while */ return ((w2 * h2) - (w1 * h1)); } +#endif GstCaps * gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat, @@ -974,7 +976,7 @@ default_frame_sizes: /****************************************************** * gst_v4l2src_grab_frame (): * grab a frame for capturing - * return value: GST_FLOW_OK or GST_FLOW_ERROR + * return value: GST_FLOW_OK, GST_FLOW_WRONG_STATE or GST_FLOW_ERROR ******************************************************/ GstFlowReturn gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) @@ -985,12 +987,28 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) GstBuffer *pool_buffer; gboolean need_copy; gint index; + gint ret; memset (&buffer, 0x00, sizeof (buffer)); buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; - while (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) < 0) { + for (;;) { + ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE); + if (G_UNLIKELY (ret < 0)) { + if (errno == EBUSY) + goto stopped; +#ifdef G_OS_WIN32 + if (WSAGetLastError () != WSAEINTR) + goto select_error; +#else + if (errno != EAGAIN && errno != EINTR) + goto select_error; +#endif + } + + if (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) >= 0) + break; GST_WARNING_OBJECT (v4l2src, "problem grabbing frame %d (ix=%d), trials=%d, pool-ct=%d, buf.flags=%d", @@ -1133,6 +1151,17 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf) return GST_FLOW_OK; /* ERRORS */ +select_error: + { + GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ, (NULL), + ("select error %d: %s (%d)", ret, g_strerror (errno), errno)); + return GST_FLOW_ERROR; + } +stopped: + { + GST_DEBUG ("stop called"); + return GST_FLOW_WRONG_STATE; + } einval: { GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED, |