mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
libs/gst/base/: Add ::unlock_stop to basesrc and basesink. This allows an opportunity for sub-classes to correctly cl...
Original commit message from CVS: * libs/gst/base/gstbasesink.c: (gst_base_sink_set_flushing), (gst_base_sink_change_state): * libs/gst/base/gstbasesink.h: * libs/gst/base/gstbasesrc.c: (gst_base_src_perform_seek), (gst_base_src_default_event), (gst_base_src_unlock_stop), (gst_base_src_deactivate): * libs/gst/base/gstbasesrc.h: Add ::unlock_stop to basesrc and basesink. This allows an opportunity for sub-classes to correctly clear any state they set trying to unlock, such as clearing out unlock commands from a command fd. * plugins/elements/gstfdsink.c: (gst_fd_sink_class_init), (gst_fd_sink_render), (gst_fd_sink_unlock), (gst_fd_sink_unlock_stop): * plugins/elements/gstfdsrc.c: (gst_fd_src_class_init), (gst_fd_src_init), (gst_fd_src_unlock), (gst_fd_src_unlock_stop), (gst_fd_src_create), (gst_fd_src_get_size), (gst_fd_src_do_seek): Implement unlock_stop in fdsrc and fdsink. Implement seeking in fdsrc when a seekable fd is passed, as in gst-launch-0.10 fdsrc ! ... ! xvimagesink < /path/to/file
This commit is contained in:
parent
e447f17955
commit
c248d1dba0
7 changed files with 167 additions and 39 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
2007-03-19 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
|
* libs/gst/base/gstbasesink.c: (gst_base_sink_set_flushing),
|
||||||
|
(gst_base_sink_change_state):
|
||||||
|
* libs/gst/base/gstbasesink.h:
|
||||||
|
* libs/gst/base/gstbasesrc.c: (gst_base_src_perform_seek),
|
||||||
|
(gst_base_src_default_event), (gst_base_src_unlock_stop),
|
||||||
|
(gst_base_src_deactivate):
|
||||||
|
* libs/gst/base/gstbasesrc.h:
|
||||||
|
Add ::unlock_stop to basesrc and basesink. This allows an opportunity
|
||||||
|
for sub-classes to correctly clear any state they set trying to
|
||||||
|
unlock, such as clearing out unlock commands from a command fd.
|
||||||
|
|
||||||
|
* plugins/elements/gstfdsink.c: (gst_fd_sink_class_init),
|
||||||
|
(gst_fd_sink_render), (gst_fd_sink_unlock),
|
||||||
|
(gst_fd_sink_unlock_stop):
|
||||||
|
* plugins/elements/gstfdsrc.c: (gst_fd_src_class_init),
|
||||||
|
(gst_fd_src_init), (gst_fd_src_unlock), (gst_fd_src_unlock_stop),
|
||||||
|
(gst_fd_src_create), (gst_fd_src_get_size), (gst_fd_src_do_seek):
|
||||||
|
|
||||||
|
Implement unlock_stop in fdsrc and fdsink.
|
||||||
|
Implement seeking in fdsrc when a seekable fd is passed, as in
|
||||||
|
gst-launch-0.10 fdsrc ! ... ! xvimagesink < /path/to/file
|
||||||
|
|
||||||
2007-03-19 Wim Taymans <wim@fluendo.com>
|
2007-03-19 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
Patch by: Evan Nemerson <evan at coeus dash group dot com>
|
Patch by: Evan Nemerson <evan at coeus dash group dot com>
|
||||||
|
|
|
@ -2245,12 +2245,11 @@ static gboolean
|
||||||
gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
|
gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
|
||||||
gboolean flushing)
|
gboolean flushing)
|
||||||
{
|
{
|
||||||
|
GstBaseSinkClass *bclass;
|
||||||
|
|
||||||
|
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
||||||
|
|
||||||
if (flushing) {
|
if (flushing) {
|
||||||
GstBaseSinkClass *bclass;
|
|
||||||
|
|
||||||
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
|
||||||
|
|
||||||
/* unlock any subclasses, we need to do this before grabbing the
|
/* unlock any subclasses, we need to do this before grabbing the
|
||||||
* PREROLL_LOCK since we hold this lock before going into ::render. */
|
* PREROLL_LOCK since we hold this lock before going into ::render. */
|
||||||
if (bclass->unlock)
|
if (bclass->unlock)
|
||||||
|
@ -2260,7 +2259,11 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
|
||||||
GST_PAD_PREROLL_LOCK (pad);
|
GST_PAD_PREROLL_LOCK (pad);
|
||||||
basesink->flushing = flushing;
|
basesink->flushing = flushing;
|
||||||
if (flushing) {
|
if (flushing) {
|
||||||
/* step 1, unblock clock sync (if any) or any other blocking thing */
|
/* step 1, now that we have the PREROLL lock, clear our unlock request */
|
||||||
|
if (bclass->unlock_stop)
|
||||||
|
bclass->unlock_stop (basesink);
|
||||||
|
|
||||||
|
/* step 2, unblock clock sync (if any) or any other blocking thing */
|
||||||
basesink->need_preroll = TRUE;
|
basesink->need_preroll = TRUE;
|
||||||
if (basesink->clock_id) {
|
if (basesink->clock_id) {
|
||||||
gst_clock_id_unschedule (basesink->clock_id);
|
gst_clock_id_unschedule (basesink->clock_id);
|
||||||
|
@ -2868,6 +2871,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
bclass->unlock (basesink);
|
bclass->unlock (basesink);
|
||||||
|
|
||||||
GST_PAD_PREROLL_LOCK (basesink->sinkpad);
|
GST_PAD_PREROLL_LOCK (basesink->sinkpad);
|
||||||
|
/* now that we have the PREROLL lock, clear our unlock request */
|
||||||
|
if (bclass->unlock_stop)
|
||||||
|
bclass->unlock_stop (basesink);
|
||||||
|
|
||||||
basesink->need_preroll = TRUE;
|
basesink->need_preroll = TRUE;
|
||||||
if (basesink->clock_id) {
|
if (basesink->clock_id) {
|
||||||
gst_clock_id_unschedule (basesink->clock_id);
|
gst_clock_id_unschedule (basesink->clock_id);
|
||||||
|
|
|
@ -114,6 +114,8 @@ struct _GstBaseSink {
|
||||||
* @stop: Stop processing. Subclasses should use this to close resources.
|
* @stop: Stop processing. Subclasses should use this to close resources.
|
||||||
* @unlock: Unlock any pending access to the resource. Subclasses should
|
* @unlock: Unlock any pending access to the resource. Subclasses should
|
||||||
* unblock any blocked function ASAP
|
* unblock any blocked function ASAP
|
||||||
|
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
|
||||||
|
* any state they set during unlock(), such as clearing command queues.
|
||||||
* @event: Override this to handle events arriving on the sink pad
|
* @event: Override this to handle events arriving on the sink pad
|
||||||
* @preroll: Called to present the preroll buffer if desired
|
* @preroll: Called to present the preroll buffer if desired
|
||||||
* @render: Called when a buffer should be presented or output, at the
|
* @render: Called when a buffer should be presented or output, at the
|
||||||
|
@ -174,8 +176,13 @@ struct _GstBaseSinkClass {
|
||||||
/* fixate sink caps during pull-mode negotiation */
|
/* fixate sink caps during pull-mode negotiation */
|
||||||
void (*fixate) (GstBaseSink *sink, GstCaps *caps);
|
void (*fixate) (GstBaseSink *sink, GstCaps *caps);
|
||||||
|
|
||||||
|
/* Clear a previously indicated unlock request not that unlocking is
|
||||||
|
* complete. Sub-classes should clear any command queue or indicator they
|
||||||
|
* set during unlock */
|
||||||
|
gboolean (*unlock_stop) (GstBaseSink *sink);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING_LARGE-3];
|
gpointer _gst_reserved[GST_PADDING_LARGE-4];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_base_sink_get_type(void);
|
GType gst_base_sink_get_type(void);
|
||||||
|
|
|
@ -290,6 +290,7 @@ static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
|
||||||
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
|
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
|
||||||
|
|
||||||
static gboolean gst_base_src_unlock (GstBaseSrc * basesrc);
|
static gboolean gst_base_src_unlock (GstBaseSrc * basesrc);
|
||||||
|
static gboolean gst_base_src_unlock_stop (GstBaseSrc * basesrc);
|
||||||
static gboolean gst_base_src_start (GstBaseSrc * basesrc);
|
static gboolean gst_base_src_start (GstBaseSrc * basesrc);
|
||||||
static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
|
static gboolean gst_base_src_stop (GstBaseSrc * basesrc);
|
||||||
|
|
||||||
|
@ -910,6 +911,9 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
|
||||||
* because our peer is flushing. */
|
* because our peer is flushing. */
|
||||||
GST_PAD_STREAM_LOCK (src->srcpad);
|
GST_PAD_STREAM_LOCK (src->srcpad);
|
||||||
|
|
||||||
|
if (unlock)
|
||||||
|
gst_base_src_unlock_stop (src);
|
||||||
|
|
||||||
/* make copy into temp structure, we can only update the main one
|
/* make copy into temp structure, we can only update the main one
|
||||||
* when the subclass actually could do the seek. */
|
* when the subclass actually could do the seek. */
|
||||||
memcpy (&seeksegment, &src->segment, sizeof (GstSegment));
|
memcpy (&seeksegment, &src->segment, sizeof (GstSegment));
|
||||||
|
@ -1110,6 +1114,8 @@ gst_base_src_default_event (GstBaseSrc * src, GstEvent * event)
|
||||||
result = gst_base_src_unlock (src);
|
result = gst_base_src_unlock (src);
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
result = gst_base_src_unlock_stop (src);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -1687,6 +1693,28 @@ gst_base_src_unlock (GstBaseSrc * basesrc)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this will always be called between start() and stop(). So you can rely on
|
||||||
|
* resources allocated by start() and freed from stop(). This needs to be added
|
||||||
|
* to the docs at some point. */
|
||||||
|
static gboolean
|
||||||
|
gst_base_src_unlock_stop (GstBaseSrc * basesrc)
|
||||||
|
{
|
||||||
|
GstBaseSrcClass *bclass;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (basesrc, "unlock stop");
|
||||||
|
|
||||||
|
/* Finish a previous unblock request, allowing subclasses to flush command
|
||||||
|
* queues or whatever they need to do */
|
||||||
|
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
|
||||||
|
if (bclass->unlock_stop)
|
||||||
|
result = bclass->unlock_stop (basesrc);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (basesrc, "unlock stop done");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* default negotiation code.
|
/* default negotiation code.
|
||||||
*
|
*
|
||||||
* Take intersection between src and sink pads, take first
|
* Take intersection between src and sink pads, take first
|
||||||
|
@ -1906,6 +1934,9 @@ gst_base_src_deactivate (GstBaseSrc * basesrc, GstPad * pad)
|
||||||
/* step 2, make sure streaming finishes */
|
/* step 2, make sure streaming finishes */
|
||||||
result &= gst_pad_stop_task (pad);
|
result &= gst_pad_stop_task (pad);
|
||||||
|
|
||||||
|
/* step 3, clear the unblock condition */
|
||||||
|
result &= gst_base_src_unlock_stop (basesrc);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ struct _GstBaseSrc {
|
||||||
* @is_seekable: Check if the source can seek
|
* @is_seekable: Check if the source can seek
|
||||||
* @unlock: Unlock any pending access to the resource. Subclasses should
|
* @unlock: Unlock any pending access to the resource. Subclasses should
|
||||||
* unblock any blocked function ASAP
|
* unblock any blocked function ASAP
|
||||||
|
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
|
||||||
|
* any state they set during unlock(), such as clearing command queues.
|
||||||
* @event: Override this to implement custom event handling.
|
* @event: Override this to implement custom event handling.
|
||||||
* @create: Ask the subclass to create a buffer with offset and size.
|
* @create: Ask the subclass to create a buffer with offset and size.
|
||||||
* @do_seek: Perform seeking on the resource to the indicated segment.
|
* @do_seek: Perform seeking on the resource to the indicated segment.
|
||||||
|
@ -208,8 +210,11 @@ struct _GstBaseSrcClass {
|
||||||
/* called if, in negotation, caps need fixating */
|
/* called if, in negotation, caps need fixating */
|
||||||
void (*fixate) (GstBaseSrc *src, GstCaps *caps);
|
void (*fixate) (GstBaseSrc *src, GstCaps *caps);
|
||||||
|
|
||||||
|
/* Clear any pending unlock request, as we succeeded in unlocking */
|
||||||
|
gboolean (*unlock_stop) (GstBaseSrc *src);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING_LARGE - 4];
|
gpointer _gst_reserved[GST_PADDING_LARGE - 5];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_base_src_get_type (void);
|
GType gst_base_src_get_type (void);
|
||||||
|
|
|
@ -141,6 +141,7 @@ static GstFlowReturn gst_fd_sink_render (GstBaseSink * sink,
|
||||||
static gboolean gst_fd_sink_start (GstBaseSink * basesink);
|
static gboolean gst_fd_sink_start (GstBaseSink * basesink);
|
||||||
static gboolean gst_fd_sink_stop (GstBaseSink * basesink);
|
static gboolean gst_fd_sink_stop (GstBaseSink * basesink);
|
||||||
static gboolean gst_fd_sink_unlock (GstBaseSink * basesink);
|
static gboolean gst_fd_sink_unlock (GstBaseSink * basesink);
|
||||||
|
static gboolean gst_fd_sink_unlock_stop (GstBaseSink * basesink);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fd_sink_base_init (gpointer g_class)
|
gst_fd_sink_base_init (gpointer g_class)
|
||||||
|
@ -170,6 +171,7 @@ gst_fd_sink_class_init (GstFdSinkClass * klass)
|
||||||
gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_fd_sink_start);
|
gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_fd_sink_start);
|
||||||
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_fd_sink_stop);
|
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_fd_sink_stop);
|
||||||
gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock);
|
gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock);
|
||||||
|
gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_sink_unlock_stop);
|
||||||
gstbasesink_class->event = NULL;
|
gstbasesink_class->event = NULL;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_FD,
|
g_object_class_install_property (gobject_class, ARG_FD,
|
||||||
|
@ -272,21 +274,8 @@ again:
|
||||||
if (retval == -1)
|
if (retval == -1)
|
||||||
goto select_error;
|
goto select_error;
|
||||||
|
|
||||||
if (FD_ISSET (READ_SOCKET (fdsink), &readfds)) {
|
if (FD_ISSET (READ_SOCKET (fdsink), &readfds))
|
||||||
/* read all stop commands */
|
|
||||||
while (TRUE) {
|
|
||||||
gchar command;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
READ_COMMAND (fdsink, command, res);
|
|
||||||
if (res < 0) {
|
|
||||||
GST_LOG_OBJECT (fdsink, "no more commands");
|
|
||||||
/* no more commands */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto stopped;
|
goto stopped;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (fdsink, "writing %d bytes to file descriptor %d", size,
|
GST_DEBUG_OBJECT (fdsink, "writing %d bytes to file descriptor %d", size,
|
||||||
|
@ -437,11 +426,35 @@ gst_fd_sink_unlock (GstBaseSink * basesink)
|
||||||
{
|
{
|
||||||
GstFdSink *fdsink = GST_FD_SINK (basesink);
|
GstFdSink *fdsink = GST_FD_SINK (basesink);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (fdsink, "Sending unlock command to queue");
|
||||||
SEND_COMMAND (fdsink, CONTROL_STOP);
|
SEND_COMMAND (fdsink, CONTROL_STOP);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_fd_sink_unlock_stop (GstBaseSink * basesink)
|
||||||
|
{
|
||||||
|
GstFdSink *fdsink = GST_FD_SINK (basesink);
|
||||||
|
|
||||||
|
/* read all stop commands */
|
||||||
|
GST_LOG_OBJECT (fdsink, "Clearing unlock command queue");
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
gchar command;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
READ_COMMAND (fdsink, command, res);
|
||||||
|
if (res < 0) {
|
||||||
|
GST_LOG_OBJECT (fdsink, "no more commands");
|
||||||
|
/* no more commands */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_fd_sink_update_fd (GstFdSink * fdsink, int new_fd)
|
gst_fd_sink_update_fd (GstFdSink * fdsink, int new_fd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -119,8 +119,10 @@ static void gst_fd_src_dispose (GObject * obj);
|
||||||
static gboolean gst_fd_src_start (GstBaseSrc * bsrc);
|
static gboolean gst_fd_src_start (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_fd_src_stop (GstBaseSrc * bsrc);
|
static gboolean gst_fd_src_stop (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc);
|
static gboolean gst_fd_src_unlock (GstBaseSrc * bsrc);
|
||||||
|
static gboolean gst_fd_src_unlock_stop (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc);
|
static gboolean gst_fd_src_is_seekable (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size);
|
static gboolean gst_fd_src_get_size (GstBaseSrc * src, guint64 * size);
|
||||||
|
static gboolean gst_fd_src_do_seek (GstBaseSrc * src, GstSegment * segment);
|
||||||
|
|
||||||
static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
|
static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
|
||||||
|
|
||||||
|
@ -160,8 +162,10 @@ gst_fd_src_class_init (GstFdSrcClass * klass)
|
||||||
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start);
|
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start);
|
||||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop);
|
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop);
|
||||||
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock);
|
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock);
|
||||||
|
gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_fd_src_unlock_stop);
|
||||||
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable);
|
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fd_src_is_seekable);
|
||||||
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size);
|
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_fd_src_get_size);
|
||||||
|
gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_fd_src_do_seek);
|
||||||
|
|
||||||
gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create);
|
gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_fd_src_create);
|
||||||
}
|
}
|
||||||
|
@ -169,10 +173,10 @@ gst_fd_src_class_init (GstFdSrcClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
|
gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
|
||||||
{
|
{
|
||||||
fdsrc->fd = 0;
|
fdsrc->fd = -1;
|
||||||
fdsrc->new_fd = 0;
|
fdsrc->new_fd = 0;
|
||||||
fdsrc->seekable_fd = FALSE;
|
fdsrc->seekable_fd = FALSE;
|
||||||
fdsrc->uri = g_strdup_printf ("fd://%d", fdsrc->fd);
|
fdsrc->uri = g_strdup_printf ("fd://0");
|
||||||
fdsrc->curoffset = 0;
|
fdsrc->curoffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,11 +272,37 @@ gst_fd_src_unlock (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
GstFdSrc *src = GST_FD_SRC (bsrc);
|
GstFdSrc *src = GST_FD_SRC (bsrc);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (src, "sending unlock command");
|
||||||
SEND_COMMAND (src, CONTROL_STOP);
|
SEND_COMMAND (src, CONTROL_STOP);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_fd_src_unlock_stop (GstBaseSrc * bsrc)
|
||||||
|
{
|
||||||
|
GstFdSrc *src = GST_FD_SRC (bsrc);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (src, "clearing unlock command queue");
|
||||||
|
|
||||||
|
/* read all stop commands */
|
||||||
|
while (TRUE) {
|
||||||
|
gchar command;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (src, "reading command");
|
||||||
|
|
||||||
|
READ_COMMAND (src, command, res);
|
||||||
|
if (res < 0) {
|
||||||
|
GST_LOG_OBJECT (src, "no more commands");
|
||||||
|
/* no more commands */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_fd_src_set_property (GObject * object, guint prop_id, const GValue * value,
|
gst_fd_src_set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
GParamSpec * pspec)
|
GParamSpec * pspec)
|
||||||
|
@ -343,23 +373,8 @@ gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
||||||
if (retval == -1)
|
if (retval == -1)
|
||||||
goto select_error;
|
goto select_error;
|
||||||
|
|
||||||
if (FD_ISSET (READ_SOCKET (src), &readfds)) {
|
if (FD_ISSET (READ_SOCKET (src), &readfds))
|
||||||
/* read all stop commands */
|
|
||||||
while (TRUE) {
|
|
||||||
gchar command;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (src, "reading command");
|
|
||||||
|
|
||||||
READ_COMMAND (src, command, res);
|
|
||||||
if (res < 0) {
|
|
||||||
GST_LOG_OBJECT (src, "no more commands");
|
|
||||||
/* no more commands */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto stopped;
|
goto stopped;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
blocksize = GST_BASE_SRC (src)->blocksize;
|
blocksize = GST_BASE_SRC (src)->blocksize;
|
||||||
|
@ -453,7 +468,33 @@ could_not_stat:
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_fd_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
|
||||||
|
{
|
||||||
|
gint res;
|
||||||
|
gint64 offset;
|
||||||
|
GstFdSrc *src = GST_FD_SRC (bsrc);
|
||||||
|
|
||||||
|
offset = segment->start;
|
||||||
|
|
||||||
|
/* No need to seek to the current position */
|
||||||
|
if (offset == src->curoffset)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
res = lseek (src->fd, offset, SEEK_SET);
|
||||||
|
if (G_UNLIKELY (res < 0 || res != offset))
|
||||||
|
goto seek_failed;
|
||||||
|
|
||||||
|
segment->last_stop = segment->start;
|
||||||
|
segment->time = segment->start;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
seek_failed:
|
||||||
|
GST_DEBUG_OBJECT (src, "lseek returned %" G_GINT64_FORMAT, offset);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** GSTURIHANDLER INTERFACE *************************************************/
|
/*** GSTURIHANDLER INTERFACE *************************************************/
|
||||||
|
|
Loading…
Reference in a new issue