add gst_caps_copy_nth as a more general replacement for copy_1.

Original commit message from CVS:
* docs/design/part-TODO.txt:
* gst/elements/gstfakesink.c: (gst_fakesink_event),
(gst_fakesink_chain):
* gst/elements/gstfakesink.h:
* gst/elements/gstfakesrc.c: (gst_fakesrc_loop),
(gst_fakesrc_activate):
* gst/elements/gstfilesrc.c: (gst_filesrc_getrange),
(gst_filesrc_open_file), (gst_filesrc_loop),
(gst_filesrc_activate), (gst_filesrc_change_state),
(filesrc_find_peek), (gst_filesrc_type_find):
* gst/gstcaps.c: (gst_caps_copy_nth):
* gst/gstcaps.h:
* gst/gstelement.c: (gst_element_add_pad),
(gst_element_remove_pad), (iterate_pad),
(gst_element_get_state_func), (gst_element_commit_state),
(gst_element_set_state), (gst_element_pads_activate),
(gst_element_change_state), (gst_element_dispose):
* gst/gstutils.c: (gst_element_finish_preroll):
* gst/gstutils.h:
* tools/gst-launch.c: (check_intr):
add gst_caps_copy_nth as a more general replacement for
copy_1.
Slightly change the finish_preroll helper function to
include pad flush/active.
Small cleanups in fakesrc.
Add STREAM_LOCK in filesrc.
This commit is contained in:
Wim Taymans 2005-02-16 15:18:18 +00:00
parent 2af759f2b5
commit dc44130c0e
16 changed files with 125 additions and 38 deletions

View file

@ -1,3 +1,32 @@
2005-02-16 Wim Taymans <wim@fluendo.com>
* docs/design/part-TODO.txt:
* gst/elements/gstfakesink.c: (gst_fakesink_event),
(gst_fakesink_chain):
* gst/elements/gstfakesink.h:
* gst/elements/gstfakesrc.c: (gst_fakesrc_loop),
(gst_fakesrc_activate):
* gst/elements/gstfilesrc.c: (gst_filesrc_getrange),
(gst_filesrc_open_file), (gst_filesrc_loop),
(gst_filesrc_activate), (gst_filesrc_change_state),
(filesrc_find_peek), (gst_filesrc_type_find):
* gst/gstcaps.c: (gst_caps_copy_nth):
* gst/gstcaps.h:
* gst/gstelement.c: (gst_element_add_pad),
(gst_element_remove_pad), (iterate_pad),
(gst_element_get_state_func), (gst_element_commit_state),
(gst_element_set_state), (gst_element_pads_activate),
(gst_element_change_state), (gst_element_dispose):
* gst/gstutils.c: (gst_element_finish_preroll):
* gst/gstutils.h:
* tools/gst-launch.c: (check_intr):
add gst_caps_copy_nth as a more general replacement for
copy_1.
Slightly change the finish_preroll helper function to
include pad flush/active.
Small cleanups in fakesrc.
Add STREAM_LOCK in filesrc.
2005-02-11 Thomas Vander Stichele <thomas at apestaart dot org> 2005-02-11 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/gst/Makefile.am: * docs/gst/Makefile.am:

View file

@ -10,3 +10,7 @@
- only emit EOS in PLAYING. - only emit EOS in PLAYING.
- implement state change order on get<->loop-get<->loop elements. - implement state change order on get<->loop-get<->loop elements.
- unlinking pads in the PAUSED state needs to make sure the stream thread is not
executing code. Can this be done with a flush to unlock all downstream chain
functions?

View file

@ -330,8 +330,7 @@ gst_fakesink_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS: case GST_EVENT_EOS:
{ {
gst_element_finish_preroll (GST_ELEMENT (fakesink), gst_element_finish_preroll (GST_ELEMENT (fakesink), pad);
GST_STREAM_GET_LOCK (pad));
gst_element_post_message (GST_ELEMENT (fakesink), gst_element_post_message (GST_ELEMENT (fakesink),
gst_message_new_eos (GST_OBJECT (fakesink))); gst_message_new_eos (GST_OBJECT (fakesink)));
break; break;
@ -367,9 +366,7 @@ gst_fakesink_chain (GstPad * pad, GstBuffer * buffer)
/* grab streaming lock to synchronize with event method */ /* grab streaming lock to synchronize with event method */
GST_STREAM_LOCK (pad); GST_STREAM_LOCK (pad);
result = result = gst_element_finish_preroll (GST_ELEMENT (fakesink), pad);
gst_element_finish_preroll (GST_ELEMENT (fakesink),
GST_STREAM_GET_LOCK (pad));
if (result != GST_FLOW_OK) if (result != GST_FLOW_OK)
goto exit; goto exit;

View file

@ -56,6 +56,8 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink { struct _GstFakeSink {
GstElement element; GstElement element;
GstPad *sinkpad;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;
gboolean sync; gboolean sync;

View file

@ -777,6 +777,7 @@ gst_fakesrc_loop (GstPad * pad)
GstFakeSrc *src; GstFakeSrc *src;
GstBuffer *buf; GstBuffer *buf;
GstClockTime time; GstClockTime time;
GstFlowReturn ret;
src = GST_FAKESRC (GST_OBJECT_PARENT (pad)); src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
@ -791,15 +792,13 @@ gst_fakesrc_loop (GstPad * pad)
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE)); //gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
} else { } else {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} }
} }
if (src->rt_num_buffers == 0) { if (src->rt_num_buffers == 0) {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} else { } else {
if (src->rt_num_buffers > 0) if (src->rt_num_buffers > 0)
src->rt_num_buffers--; src->rt_num_buffers--;
@ -808,8 +807,7 @@ gst_fakesrc_loop (GstPad * pad)
if (src->eos) { if (src->eos) {
GST_INFO ("fakesrc is setting eos on pad"); GST_INFO ("fakesrc is setting eos on pad");
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} }
buf = gst_fakesrc_create_buffer (src); buf = gst_fakesrc_create_buffer (src);
@ -848,10 +846,18 @@ gst_fakesrc_loop (GstPad * pad)
src->bytes_sent += GST_BUFFER_SIZE (buf); src->bytes_sent += GST_BUFFER_SIZE (buf);
gst_pad_push (pad, buf); ret = gst_pad_push (pad, buf);
if (ret != GST_FLOW_OK) {
goto pause;
}
done:
GST_STREAM_UNLOCK (pad); GST_STREAM_UNLOCK (pad);
return;
pause:
gst_task_pause (src->task);
GST_STREAM_UNLOCK (pad);
return;
} }
static gboolean static gboolean

View file

@ -907,15 +907,19 @@ gst_filesrc_loop (GstPad * pad)
filesrc = GST_FILESRC (GST_PAD_PARENT (pad)); filesrc = GST_FILESRC (GST_PAD_PARENT (pad));
GST_STREAM_LOCK (pad);
result = gst_filesrc_get (pad, &buffer); result = gst_filesrc_get (pad, &buffer);
if (result != GST_FLOW_OK) { if (result != GST_FLOW_OK) {
gst_task_pause (GST_RPAD_TASK (pad)); gst_task_pause (GST_RPAD_TASK (pad));
return; goto done;
} }
result = gst_pad_push (pad, buffer); result = gst_pad_push (pad, buffer);
if (result != GST_FLOW_OK) { if (result != GST_FLOW_OK) {
gst_task_pause (GST_RPAD_TASK (pad)); gst_task_pause (GST_RPAD_TASK (pad));
} }
done:
GST_STREAM_UNLOCK (pad);
} }
@ -978,9 +982,9 @@ gst_filesrc_change_state (GstElement * element)
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
src->need_discont = 2; src->need_discont = 2;
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
gst_task_start (GST_RPAD_TASK (src->srcpad));
break; break;
} }
@ -988,6 +992,7 @@ gst_filesrc_change_state (GstElement * element)
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
gst_task_start (GST_RPAD_TASK (src->srcpad));
break; break;
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
if (GST_FLAG_IS_SET (element, GST_FILESRC_OPEN)) if (GST_FLAG_IS_SET (element, GST_FILESRC_OPEN))

View file

@ -530,6 +530,35 @@ gst_caps_get_structure (const GstCaps * caps, int index)
return g_ptr_array_index (caps->structs, index); return g_ptr_array_index (caps->structs, index);
} }
/**
* gst_caps_copy_nth:
* @caps: the @GstCaps to copy
* @nth: the nth structure to copy
*
* Creates a new @GstCaps and appends a copy of the nth structure
* contained in @caps.
*
* Returns: the new @GstCaps
*/
GstCaps *
gst_caps_copy_nth (const GstCaps * caps, gint nth)
{
GstCaps *newcaps;
GstStructure *structure;
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
newcaps = gst_caps_new_empty ();
newcaps->flags = caps->flags;
if (caps->structs->len > nth) {
structure = gst_caps_get_structure (caps, nth);
gst_caps_append_structure (newcaps, gst_structure_copy (structure));
}
return newcaps;
}
/** /**
* gst_caps_set_simple: * gst_caps_set_simple:
* @caps: the @GstCaps to set * @caps: the @GstCaps to set

View file

@ -106,6 +106,7 @@ void gst_caps_append_structure (GstCaps
int gst_caps_get_size (const GstCaps *caps); int gst_caps_get_size (const GstCaps *caps);
GstStructure * gst_caps_get_structure (const GstCaps *caps, GstStructure * gst_caps_get_structure (const GstCaps *caps,
int index); int index);
GstCaps * gst_caps_copy_nth (const GstCaps * caps, gint nth);
void gst_caps_set_simple (GstCaps *caps, void gst_caps_set_simple (GstCaps *caps,
char *field, ...); char *field, ...);
void gst_caps_set_simple_valist (GstCaps *caps, void gst_caps_set_simple_valist (GstCaps *caps,

View file

@ -1731,6 +1731,7 @@ gst_element_commit_state (GstElement * element)
GST_STATE (element) = pending; GST_STATE (element) = pending;
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_STATE_ERROR (element) = FALSE;
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
0, old_state, pending); 0, old_state, pending);

View file

@ -388,7 +388,7 @@ gst_element_abort_preroll (GstElement * element)
/* call with stream lock held */ /* call with stream lock held */
GstFlowReturn GstFlowReturn
gst_element_finish_preroll (GstElement * element, GMutex * streamlock) gst_element_finish_preroll (GstElement * element, GstPad * pad)
{ {
GstFlowReturn result = GST_FLOW_OK; GstFlowReturn result = GST_FLOW_OK;
@ -403,19 +403,20 @@ gst_element_finish_preroll (GstElement * element, GMutex * streamlock)
GST_CAT_DEBUG (GST_CAT_STATES, GST_CAT_DEBUG (GST_CAT_STATES,
"element %s wants to finish preroll", GST_ELEMENT_NAME (element)); "element %s wants to finish preroll", GST_ELEMENT_NAME (element));
/* FIXME, release streaming lock? */
if (streamlock)
g_mutex_unlock (streamlock);
/* here we wait for the next state change */ /* here we wait for the next state change */
while (GST_STATE (element) == GST_STATE_PAUSED) { while (GST_STATE (element) == GST_STATE_PAUSED) {
if (GST_RPAD_IS_FLUSHING (pad) || !GST_RPAD_IS_ACTIVE (pad)) {
GST_CAT_DEBUG (GST_CAT_STATES, "pad is flushing");
result = GST_FLOW_UNEXPECTED;
goto done;
}
GST_CAT_DEBUG (GST_CAT_STATES, "waiting for next state change"); GST_CAT_DEBUG (GST_CAT_STATES, "waiting for next state change");
GST_STATE_WAIT (element); GST_STATE_WAIT (element);
GST_CAT_DEBUG (GST_CAT_STATES, " got state change");
} }
if (streamlock)
g_mutex_lock (streamlock);
/* check if we got playing */ /* check if we got playing */
if (GST_STATE (element) != GST_STATE_PLAYING) { if (GST_STATE (element) != GST_STATE_PLAYING) {
/* not playing, we can't accept the buffer */ /* not playing, we can't accept the buffer */
@ -423,6 +424,7 @@ gst_element_finish_preroll (GstElement * element, GMutex * streamlock)
} }
GST_CAT_DEBUG (GST_CAT_STATES, "done preroll"); GST_CAT_DEBUG (GST_CAT_STATES, "done preroll");
} }
done:
GST_STATE_UNLOCK (element); GST_STATE_UNLOCK (element);
return result; return result;

View file

@ -230,7 +230,7 @@ void gst_object_default_error (GstObject * source,
/* element functions */ /* element functions */
GstFlowReturn gst_element_abort_preroll (GstElement *element); GstFlowReturn gst_element_abort_preroll (GstElement *element);
GstFlowReturn gst_element_finish_preroll (GstElement *element, GMutex *streamlock); GstFlowReturn gst_element_finish_preroll (GstElement *element, GstPad *pad);
GstPad* gst_element_get_compatible_pad (GstElement *element, GstPad *pad); GstPad* gst_element_get_compatible_pad (GstElement *element, GstPad *pad);
GstPad* gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, GstPad* gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,

View file

@ -330,8 +330,7 @@ gst_fakesink_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS: case GST_EVENT_EOS:
{ {
gst_element_finish_preroll (GST_ELEMENT (fakesink), gst_element_finish_preroll (GST_ELEMENT (fakesink), pad);
GST_STREAM_GET_LOCK (pad));
gst_element_post_message (GST_ELEMENT (fakesink), gst_element_post_message (GST_ELEMENT (fakesink),
gst_message_new_eos (GST_OBJECT (fakesink))); gst_message_new_eos (GST_OBJECT (fakesink)));
break; break;
@ -367,9 +366,7 @@ gst_fakesink_chain (GstPad * pad, GstBuffer * buffer)
/* grab streaming lock to synchronize with event method */ /* grab streaming lock to synchronize with event method */
GST_STREAM_LOCK (pad); GST_STREAM_LOCK (pad);
result = result = gst_element_finish_preroll (GST_ELEMENT (fakesink), pad);
gst_element_finish_preroll (GST_ELEMENT (fakesink),
GST_STREAM_GET_LOCK (pad));
if (result != GST_FLOW_OK) if (result != GST_FLOW_OK)
goto exit; goto exit;

View file

@ -56,6 +56,8 @@ typedef struct _GstFakeSinkClass GstFakeSinkClass;
struct _GstFakeSink { struct _GstFakeSink {
GstElement element; GstElement element;
GstPad *sinkpad;
gboolean silent; gboolean silent;
gboolean dump; gboolean dump;
gboolean sync; gboolean sync;

View file

@ -777,6 +777,7 @@ gst_fakesrc_loop (GstPad * pad)
GstFakeSrc *src; GstFakeSrc *src;
GstBuffer *buf; GstBuffer *buf;
GstClockTime time; GstClockTime time;
GstFlowReturn ret;
src = GST_FAKESRC (GST_OBJECT_PARENT (pad)); src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
@ -791,15 +792,13 @@ gst_fakesrc_loop (GstPad * pad)
//gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE)); //gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
} else { } else {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} }
} }
if (src->rt_num_buffers == 0) { if (src->rt_num_buffers == 0) {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} else { } else {
if (src->rt_num_buffers > 0) if (src->rt_num_buffers > 0)
src->rt_num_buffers--; src->rt_num_buffers--;
@ -808,8 +807,7 @@ gst_fakesrc_loop (GstPad * pad)
if (src->eos) { if (src->eos) {
GST_INFO ("fakesrc is setting eos on pad"); GST_INFO ("fakesrc is setting eos on pad");
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS)); gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
gst_task_pause (src->task); goto pause;
goto done;
} }
buf = gst_fakesrc_create_buffer (src); buf = gst_fakesrc_create_buffer (src);
@ -848,10 +846,18 @@ gst_fakesrc_loop (GstPad * pad)
src->bytes_sent += GST_BUFFER_SIZE (buf); src->bytes_sent += GST_BUFFER_SIZE (buf);
gst_pad_push (pad, buf); ret = gst_pad_push (pad, buf);
if (ret != GST_FLOW_OK) {
goto pause;
}
done:
GST_STREAM_UNLOCK (pad); GST_STREAM_UNLOCK (pad);
return;
pause:
gst_task_pause (src->task);
GST_STREAM_UNLOCK (pad);
return;
} }
static gboolean static gboolean

View file

@ -907,15 +907,19 @@ gst_filesrc_loop (GstPad * pad)
filesrc = GST_FILESRC (GST_PAD_PARENT (pad)); filesrc = GST_FILESRC (GST_PAD_PARENT (pad));
GST_STREAM_LOCK (pad);
result = gst_filesrc_get (pad, &buffer); result = gst_filesrc_get (pad, &buffer);
if (result != GST_FLOW_OK) { if (result != GST_FLOW_OK) {
gst_task_pause (GST_RPAD_TASK (pad)); gst_task_pause (GST_RPAD_TASK (pad));
return; goto done;
} }
result = gst_pad_push (pad, buffer); result = gst_pad_push (pad, buffer);
if (result != GST_FLOW_OK) { if (result != GST_FLOW_OK) {
gst_task_pause (GST_RPAD_TASK (pad)); gst_task_pause (GST_RPAD_TASK (pad));
} }
done:
GST_STREAM_UNLOCK (pad);
} }
@ -978,9 +982,9 @@ gst_filesrc_change_state (GstElement * element)
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
src->need_discont = 2; src->need_discont = 2;
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
gst_task_start (GST_RPAD_TASK (src->srcpad));
break; break;
} }
@ -988,6 +992,7 @@ gst_filesrc_change_state (GstElement * element)
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PLAYING_TO_PAUSED: case GST_STATE_PLAYING_TO_PAUSED:
gst_task_start (GST_RPAD_TASK (src->srcpad));
break; break;
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
if (GST_FLAG_IS_SET (element, GST_FILESRC_OPEN)) if (GST_FLAG_IS_SET (element, GST_FILESRC_OPEN))

View file

@ -279,6 +279,7 @@ check_intr (user_data)
} else { } else {
g_print ("Pausing pipeline.\n"); g_print ("Pausing pipeline.\n");
gst_element_set_state (pipeline, GST_STATE_PAUSED); gst_element_set_state (pipeline, GST_STATE_PAUSED);
g_print ("Paused pipeline.\n");
g_main_loop_quit (loop); g_main_loop_quit (loop);
return FALSE; return FALSE;
} }