ext/raw1394/gstdv1394src.c: Make interruptible, so it won't block forever in a read().
Original commit message from CVS: 2005-10-07 Andy Wingo <wingo@pobox.com> * ext/raw1394/gstdv1394src.c: Make interruptible, so it won't block forever in a read().
This commit is contained in:
parent
19712f28f6
commit
aeb4ab082e
@ -1,5 +1,8 @@
|
|||||||
2005-10-07 Andy Wingo <wingo@pobox.com>
|
2005-10-07 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* ext/raw1394/gstdv1394src.c: Make interruptible, so it won't
|
||||||
|
block forever in a read().
|
||||||
|
|
||||||
* ext/raw1394/gstdv1394src.c: Clean up for style before doing some
|
* ext/raw1394/gstdv1394src.c: Clean up for style before doing some
|
||||||
hacking. The only change should be that the state change stuff was
|
hacking. The only change should be that the state change stuff was
|
||||||
put into basesrc's start() and stop() routines, which coalesces
|
put into basesrc's start() and stop() routines, which coalesces
|
||||||
|
@ -144,7 +144,7 @@ static gboolean gst_signal_processor_src_activate_pull (GstPad * pad,
|
|||||||
static gboolean gst_signal_processor_sink_activate_push (GstPad * pad,
|
static gboolean gst_signal_processor_sink_activate_push (GstPad * pad,
|
||||||
gboolean active);
|
gboolean active);
|
||||||
static GstStateChangeReturn gst_signal_processor_change_state (GstElement *
|
static GstStateChangeReturn gst_signal_processor_change_state (GstElement *
|
||||||
element);
|
element, GstStateChange transition);
|
||||||
|
|
||||||
static gboolean gst_signal_processor_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_signal_processor_event (GstPad * pad, GstEvent * event);
|
||||||
static GstFlowReturn gst_signal_processor_getrange (GstPad * pad,
|
static GstFlowReturn gst_signal_processor_getrange (GstPad * pad,
|
||||||
|
@ -23,14 +23,40 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
#include <gst/gst.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <libavc1394/avc1394.h>
|
#include <libavc1394/avc1394.h>
|
||||||
#include <libavc1394/avc1394_vcr.h>
|
#include <libavc1394/avc1394_vcr.h>
|
||||||
#include <libavc1394/rom1394.h>
|
#include <libavc1394/rom1394.h>
|
||||||
|
#include <libraw1394/raw1394.h>
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#include "gstdv1394src.h"
|
#include "gstdv1394src.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CONTROL_STOP 'S' /* stop the select call */
|
||||||
|
#define CONTROL_SOCKETS(src) src->control_sock
|
||||||
|
#define WRITE_SOCKET(src) src->control_sock[1]
|
||||||
|
#define READ_SOCKET(src) src->control_sock[0]
|
||||||
|
|
||||||
|
#define SEND_COMMAND(src, command) \
|
||||||
|
G_STMT_START { \
|
||||||
|
unsigned char c; c = command; \
|
||||||
|
write (WRITE_SOCKET(src), &c, 1); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define READ_COMMAND(src, command, res) \
|
||||||
|
G_STMT_START { \
|
||||||
|
res = read(READ_SOCKET(src), &command, 1); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (dv1394src_debug);
|
GST_DEBUG_CATEGORY_STATIC (dv1394src_debug);
|
||||||
#define GST_CAT_DEFAULT (dv1394src_debug)
|
#define GST_CAT_DEFAULT (dv1394src_debug)
|
||||||
|
|
||||||
@ -91,6 +117,7 @@ static void gst_dv1394src_get_property (GObject * object, guint prop_id,
|
|||||||
|
|
||||||
static gboolean gst_dv1394src_start (GstBaseSrc * bsrc);
|
static gboolean gst_dv1394src_start (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_dv1394src_stop (GstBaseSrc * bsrc);
|
static gboolean gst_dv1394src_stop (GstBaseSrc * bsrc);
|
||||||
|
static gboolean gst_dv1394src_unlock (GstBaseSrc * bsrc);
|
||||||
|
|
||||||
static GstFlowReturn gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf);
|
static GstFlowReturn gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf);
|
||||||
|
|
||||||
@ -181,6 +208,8 @@ gst_dv1394src_class_init (GstDV1394SrcClass * klass)
|
|||||||
gstbasesrc_class->negotiate = NULL;
|
gstbasesrc_class->negotiate = NULL;
|
||||||
gstbasesrc_class->start = gst_dv1394src_start;
|
gstbasesrc_class->start = gst_dv1394src_start;
|
||||||
gstbasesrc_class->stop = gst_dv1394src_stop;
|
gstbasesrc_class->stop = gst_dv1394src_stop;
|
||||||
|
gstbasesrc_class->unlock = gst_dv1394src_unlock;
|
||||||
|
|
||||||
gstpushsrc_class->create = gst_dv1394src_create;
|
gstpushsrc_class->create = gst_dv1394src_create;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +224,6 @@ gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass)
|
|||||||
gst_pad_set_query_function (srcpad, gst_dv1394src_query);
|
gst_pad_set_query_function (srcpad, gst_dv1394src_query);
|
||||||
gst_pad_set_query_type_function (srcpad, gst_dv1394src_get_query_types);
|
gst_pad_set_query_type_function (srcpad, gst_dv1394src_get_query_types);
|
||||||
|
|
||||||
dv1394src->dv_lock = g_mutex_new ();
|
|
||||||
dv1394src->port = DEFAULT_PORT;
|
dv1394src->port = DEFAULT_PORT;
|
||||||
dv1394src->channel = DEFAULT_CHANNEL;
|
dv1394src->channel = DEFAULT_CHANNEL;
|
||||||
|
|
||||||
@ -205,6 +233,9 @@ gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass)
|
|||||||
dv1394src->use_avc = DEFAULT_USE_AVC;
|
dv1394src->use_avc = DEFAULT_USE_AVC;
|
||||||
dv1394src->guid = DEFAULT_GUID;
|
dv1394src->guid = DEFAULT_GUID;
|
||||||
|
|
||||||
|
READ_SOCKET (dv1394src) = -1;
|
||||||
|
WRITE_SOCKET (dv1394src) = -1;
|
||||||
|
|
||||||
/* initialized when first header received */
|
/* initialized when first header received */
|
||||||
dv1394src->frame_size = 0;
|
dv1394src->frame_size = 0;
|
||||||
|
|
||||||
@ -302,7 +333,7 @@ gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (section_type == 0 && dif_sequence == 0) { // dif header
|
if (section_type == 0 && dif_sequence == 0) { // dif header
|
||||||
if (!dv1394src->negotiated) {
|
if (!GST_PAD_CAPS (GST_BASE_SRC_PAD (dv1394src))) {
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
// figure format (NTSC/PAL)
|
// figure format (NTSC/PAL)
|
||||||
@ -326,7 +357,6 @@ gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
|
|||||||
}
|
}
|
||||||
gst_pad_set_caps (GST_BASE_SRC_PAD (dv1394src), caps);
|
gst_pad_set_caps (GST_BASE_SRC_PAD (dv1394src), caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
dv1394src->negotiated = TRUE;
|
|
||||||
}
|
}
|
||||||
// drop last frame when not complete
|
// drop last frame when not complete
|
||||||
if (!dv1394src->drop_incomplete
|
if (!dv1394src->drop_incomplete
|
||||||
@ -417,20 +447,67 @@ gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf)
|
|||||||
{
|
{
|
||||||
GstDV1394Src *dv1394src = GST_DV1394SRC (psrc);
|
GstDV1394Src *dv1394src = GST_DV1394SRC (psrc);
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
struct pollfd pollfds[2];
|
||||||
|
|
||||||
GST_DV_LOCK (dv1394src);
|
pollfds[0].fd = raw1394_get_fd (dv1394src->handle);
|
||||||
|
pollfds[0].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
|
||||||
|
pollfds[1].fd = READ_SOCKET (dv1394src);
|
||||||
|
pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
|
||||||
|
|
||||||
|
if (dv1394src->buf) {
|
||||||
|
/* maybe we had an error before, and there's a stale buffer? */
|
||||||
|
gst_buffer_unref (dv1394src->buf);
|
||||||
dv1394src->buf = NULL;
|
dv1394src->buf = NULL;
|
||||||
while (dv1394src->buf == NULL)
|
}
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
int res = poll (pollfds, 2, -1);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
goto error_while_polling;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pollfds[1].revents) {
|
||||||
|
char command;
|
||||||
|
|
||||||
|
g_print ("told to stop!\n");
|
||||||
|
|
||||||
|
if (pollfds[1].revents & POLLIN)
|
||||||
|
READ_COMMAND (dv1394src, command, res);
|
||||||
|
|
||||||
|
goto told_to_stop;
|
||||||
|
} else if (pollfds[0].revents & POLLIN) {
|
||||||
|
/* shouldn't block in theory */
|
||||||
raw1394_loop_iterate (dv1394src->handle);
|
raw1394_loop_iterate (dv1394src->handle);
|
||||||
|
if (dv1394src->buf)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (dv1394src->buf);
|
||||||
|
|
||||||
caps = gst_pad_get_caps (GST_BASE_SRC_PAD (psrc));
|
caps = gst_pad_get_caps (GST_BASE_SRC_PAD (psrc));
|
||||||
gst_buffer_set_caps (dv1394src->buf, caps);
|
gst_buffer_set_caps (dv1394src->buf, caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
*buf = dv1394src->buf;
|
*buf = dv1394src->buf;
|
||||||
GST_DV_UNLOCK (dv1394src);
|
dv1394src->buf = NULL;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
error_while_polling:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (dv1394src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
|
||||||
|
return GST_FLOW_UNEXPECTED;
|
||||||
|
}
|
||||||
|
told_to_stop:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (dv1394src, "told to stop, shutting down");
|
||||||
|
return GST_FLOW_WRONG_STATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -504,6 +581,16 @@ static gboolean
|
|||||||
gst_dv1394src_start (GstBaseSrc * bsrc)
|
gst_dv1394src_start (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
GstDV1394Src *src = GST_DV1394SRC (bsrc);
|
GstDV1394Src *src = GST_DV1394SRC (bsrc);
|
||||||
|
int control_sock[2];
|
||||||
|
|
||||||
|
if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
|
||||||
|
goto socket_pair;
|
||||||
|
|
||||||
|
READ_SOCKET (src) = control_sock[0];
|
||||||
|
WRITE_SOCKET (src) = control_sock[1];
|
||||||
|
|
||||||
|
fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
|
||||||
|
fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
src->handle = raw1394_new_handle ();
|
src->handle = raw1394_new_handle ();
|
||||||
|
|
||||||
@ -542,6 +629,12 @@ gst_dv1394src_start (GstBaseSrc * bsrc)
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
socket_pair:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
|
||||||
|
GST_ERROR_SYSTEM);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
no_handle:
|
no_handle:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
|
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
|
||||||
@ -573,7 +666,11 @@ gst_dv1394src_stop (GstBaseSrc * bsrc)
|
|||||||
{
|
{
|
||||||
GstDV1394Src *src = GST_DV1394SRC (bsrc);
|
GstDV1394Src *src = GST_DV1394SRC (bsrc);
|
||||||
|
|
||||||
GST_DV_LOCK (src);
|
close (READ_SOCKET (src));
|
||||||
|
close (WRITE_SOCKET (src));
|
||||||
|
READ_SOCKET (src) = -1;
|
||||||
|
WRITE_SOCKET (src) = -1;
|
||||||
|
|
||||||
raw1394_stop_iso_rcv (src->handle, src->channel);
|
raw1394_stop_iso_rcv (src->handle, src->channel);
|
||||||
if (src->use_avc) {
|
if (src->use_avc) {
|
||||||
/* pause the VCR */
|
/* pause the VCR */
|
||||||
@ -582,8 +679,6 @@ gst_dv1394src_stop (GstBaseSrc * bsrc)
|
|||||||
!= AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE))
|
!= AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE))
|
||||||
avc1394_vcr_pause (src->handle, src->avc_node);
|
avc1394_vcr_pause (src->handle, src->avc_node);
|
||||||
}
|
}
|
||||||
GST_DV_UNLOCK (src);
|
|
||||||
src->negotiated = FALSE;
|
|
||||||
|
|
||||||
if (src->use_avc)
|
if (src->use_avc)
|
||||||
/* stop the VCR */
|
/* stop the VCR */
|
||||||
@ -594,6 +689,17 @@ gst_dv1394src_stop (GstBaseSrc * bsrc)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_dv1394src_unlock (GstBaseSrc * bsrc)
|
||||||
|
{
|
||||||
|
GstDV1394Src *src = GST_DV1394SRC (bsrc);
|
||||||
|
|
||||||
|
g_print ("sending command!\n");
|
||||||
|
SEND_COMMAND (src, CONTROL_STOP);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_dv1394src_convert (GstPad * pad,
|
gst_dv1394src_convert (GstPad * pad,
|
||||||
GstFormat src_format, gint64 src_value,
|
GstFormat src_format, gint64 src_value,
|
||||||
|
@ -43,10 +43,6 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _GstDV1394Src GstDV1394Src;
|
typedef struct _GstDV1394Src GstDV1394Src;
|
||||||
typedef struct _GstDV1394SrcClass GstDV1394SrcClass;
|
typedef struct _GstDV1394SrcClass GstDV1394SrcClass;
|
||||||
|
|
||||||
#define GST_DV_GET_LOCK(dv) (GST_DV1394SRC (dv)->dv_lock)
|
|
||||||
#define GST_DV_LOCK(dv) g_mutex_lock(GST_DV_GET_LOCK (dv))
|
|
||||||
#define GST_DV_UNLOCK(dv) g_mutex_unlock(GST_DV_GET_LOCK (dv))
|
|
||||||
|
|
||||||
struct _GstDV1394Src {
|
struct _GstDV1394Src {
|
||||||
GstPushSrc element;
|
GstPushSrc element;
|
||||||
|
|
||||||
@ -55,8 +51,6 @@ struct _GstDV1394Src {
|
|||||||
gint skip;
|
gint skip;
|
||||||
gboolean drop_incomplete;
|
gboolean drop_incomplete;
|
||||||
|
|
||||||
GMutex *dv_lock;
|
|
||||||
|
|
||||||
gint num_ports;
|
gint num_ports;
|
||||||
gint port;
|
gint port;
|
||||||
gint channel;
|
gint channel;
|
||||||
@ -75,7 +69,7 @@ struct _GstDV1394Src {
|
|||||||
guint bytes_in_frame;
|
guint bytes_in_frame;
|
||||||
guint frame_sequence;
|
guint frame_sequence;
|
||||||
|
|
||||||
gboolean negotiated;
|
int control_sock[2];
|
||||||
|
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user