mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
Implemented segment seeking in fakesrc
Original commit message from CVS: Implemented segment seeking in fakesrc
This commit is contained in:
parent
63fd06bda7
commit
1dea23cf36
4 changed files with 170 additions and 108 deletions
|
@ -269,6 +269,8 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
|
|||
gst_fakesrc_update_functions (fakesrc);
|
||||
|
||||
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
||||
fakesrc->segment_start = -1;
|
||||
fakesrc->segment_end = -1;
|
||||
fakesrc->num_buffers = -1;
|
||||
fakesrc->rt_num_buffers = -1;
|
||||
fakesrc->buffer_count = 0;
|
||||
|
@ -312,6 +314,48 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
|
|||
return srcpad;
|
||||
}
|
||||
|
||||
GST_FORMATS_FUNCTION (gst_fakesrc_get_formats,
|
||||
GST_FORMAT_DEFAULT
|
||||
)
|
||||
|
||||
GST_PAD_QUERY_TYPE_FUNCTION (gst_fakesrc_get_query_types,
|
||||
GST_PAD_QUERY_TOTAL,
|
||||
GST_PAD_QUERY_POSITION,
|
||||
GST_PAD_QUERY_START,
|
||||
GST_PAD_QUERY_SEGMENT_END
|
||||
)
|
||||
|
||||
static gboolean
|
||||
gst_fakesrc_query (GstPad *pad, GstPadQueryType type,
|
||||
GstFormat *format, gint64 *value)
|
||||
{
|
||||
GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad));
|
||||
|
||||
switch (type) {
|
||||
case GST_PAD_QUERY_TOTAL:
|
||||
*value = src->num_buffers;
|
||||
break;
|
||||
case GST_PAD_QUERY_POSITION:
|
||||
*value = src->buffer_count;
|
||||
break;
|
||||
case GST_PAD_QUERY_START:
|
||||
*value = src->segment_start;
|
||||
break;
|
||||
case GST_PAD_QUERY_SEGMENT_END:
|
||||
*value = src->segment_end;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_EVENT_MASK_FUNCTION (gst_fakesrc_get_event_mask,
|
||||
{ GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH },
|
||||
{ GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP },
|
||||
{ GST_EVENT_FLUSH, 0 }
|
||||
)
|
||||
|
||||
static gboolean
|
||||
gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
||||
{
|
||||
|
@ -327,6 +371,12 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
|||
break;
|
||||
}
|
||||
/* else we do a flush too */
|
||||
case GST_EVENT_SEEK_SEGMENT:
|
||||
src->segment_start = GST_EVENT_SEEK_OFFSET (event);
|
||||
src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
|
||||
src->buffer_count = src->segment_start;
|
||||
src->segment_loop = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
|
||||
break;
|
||||
case GST_EVENT_FLUSH:
|
||||
src->need_flush = TRUE;
|
||||
break;
|
||||
|
@ -338,18 +388,6 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static const GstEventMask*
|
||||
gst_fakesrc_get_event_mask (GstPad *pad)
|
||||
{
|
||||
static const GstEventMask gst_fakesrc_event_mask[] = {
|
||||
{ GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH },
|
||||
{ GST_EVENT_FLUSH, 0 },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
return gst_fakesrc_event_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesrc_update_functions (GstFakeSrc *src)
|
||||
{
|
||||
|
@ -375,6 +413,9 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
|
|||
|
||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
||||
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
||||
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
}
|
||||
|
@ -687,6 +728,16 @@ gst_fakesrc_get(GstPad *pad)
|
|||
return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
|
||||
}
|
||||
|
||||
if (src->buffer_count == src->segment_end) {
|
||||
if (src->segment_loop) {
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_SEGMENT_DONE));
|
||||
}
|
||||
else {
|
||||
gst_element_set_eos (GST_ELEMENT (src));
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
|
||||
}
|
||||
}
|
||||
|
||||
if (src->rt_num_buffers == 0) {
|
||||
gst_element_set_eos (GST_ELEMENT (src));
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
|
||||
|
@ -745,36 +796,13 @@ gst_fakesrc_loop(GstElement *element)
|
|||
GstPad *pad = GST_PAD (pads->data);
|
||||
GstBuffer *buf;
|
||||
|
||||
if (src->rt_num_buffers == 0) {
|
||||
src->eos = TRUE;
|
||||
}
|
||||
else {
|
||||
if (src->rt_num_buffers > 0)
|
||||
src->rt_num_buffers--;
|
||||
}
|
||||
buf = gst_fakesrc_get (pad);
|
||||
gst_pad_push (pad, buf);
|
||||
|
||||
if (src->eos) {
|
||||
gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS)));
|
||||
return;
|
||||
}
|
||||
|
||||
buf = gst_fakesrc_create_buffer (src);
|
||||
GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
|
||||
|
||||
if (!src->silent) {
|
||||
if (src->last_message)
|
||||
g_free (src->last_message);
|
||||
|
||||
src->last_message = g_strdup_printf ("fakesrc: loop ******* (%s:%s) > (%d bytes, %llu)",
|
||||
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
|
||||
|
||||
g_object_notify (G_OBJECT (src), "last_message");
|
||||
}
|
||||
|
||||
g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
|
||||
buf, pad);
|
||||
gst_pad_push (pad, buf);
|
||||
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,30 +82,33 @@ typedef struct _GstFakeSrc GstFakeSrc;
|
|||
typedef struct _GstFakeSrcClass GstFakeSrcClass;
|
||||
|
||||
struct _GstFakeSrc {
|
||||
GstElement element;
|
||||
GstElement element;
|
||||
|
||||
gboolean loop_based;
|
||||
gboolean eos;
|
||||
gboolean loop_based;
|
||||
gboolean eos;
|
||||
|
||||
GstFakeSrcOutputType output;
|
||||
GstFakeSrcDataType data;
|
||||
GstFakeSrcSizeType sizetype;
|
||||
GstFakeSrcFillType filltype;
|
||||
GstFakeSrcDataType data;
|
||||
GstFakeSrcSizeType sizetype;
|
||||
GstFakeSrcFillType filltype;
|
||||
|
||||
guint sizemin;
|
||||
guint sizemax;
|
||||
guint sizemin;
|
||||
guint sizemax;
|
||||
GstBuffer *parent;
|
||||
guint parentsize;
|
||||
guint parentoffset;
|
||||
guint8 pattern_byte;
|
||||
guint parentsize;
|
||||
guint parentoffset;
|
||||
guint8 pattern_byte;
|
||||
gchar *pattern;
|
||||
GList *patternlist;
|
||||
gint num_buffers;
|
||||
gint rt_num_buffers; /* we are going to change this at runtime */
|
||||
guint64 buffer_count;
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
gint64 segment_start;
|
||||
gint64 segment_end;
|
||||
gboolean segment_loop;
|
||||
gint num_buffers;
|
||||
gint rt_num_buffers; /* we are going to change this at runtime */
|
||||
guint64 buffer_count;
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
GstBufferPool *pool;
|
||||
|
||||
gchar *last_message;
|
||||
|
|
|
@ -269,6 +269,8 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
|
|||
gst_fakesrc_update_functions (fakesrc);
|
||||
|
||||
fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
|
||||
fakesrc->segment_start = -1;
|
||||
fakesrc->segment_end = -1;
|
||||
fakesrc->num_buffers = -1;
|
||||
fakesrc->rt_num_buffers = -1;
|
||||
fakesrc->buffer_count = 0;
|
||||
|
@ -312,6 +314,48 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
|
|||
return srcpad;
|
||||
}
|
||||
|
||||
GST_FORMATS_FUNCTION (gst_fakesrc_get_formats,
|
||||
GST_FORMAT_DEFAULT
|
||||
)
|
||||
|
||||
GST_PAD_QUERY_TYPE_FUNCTION (gst_fakesrc_get_query_types,
|
||||
GST_PAD_QUERY_TOTAL,
|
||||
GST_PAD_QUERY_POSITION,
|
||||
GST_PAD_QUERY_START,
|
||||
GST_PAD_QUERY_SEGMENT_END
|
||||
)
|
||||
|
||||
static gboolean
|
||||
gst_fakesrc_query (GstPad *pad, GstPadQueryType type,
|
||||
GstFormat *format, gint64 *value)
|
||||
{
|
||||
GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad));
|
||||
|
||||
switch (type) {
|
||||
case GST_PAD_QUERY_TOTAL:
|
||||
*value = src->num_buffers;
|
||||
break;
|
||||
case GST_PAD_QUERY_POSITION:
|
||||
*value = src->buffer_count;
|
||||
break;
|
||||
case GST_PAD_QUERY_START:
|
||||
*value = src->segment_start;
|
||||
break;
|
||||
case GST_PAD_QUERY_SEGMENT_END:
|
||||
*value = src->segment_end;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_EVENT_MASK_FUNCTION (gst_fakesrc_get_event_mask,
|
||||
{ GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH },
|
||||
{ GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP },
|
||||
{ GST_EVENT_FLUSH, 0 }
|
||||
)
|
||||
|
||||
static gboolean
|
||||
gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
||||
{
|
||||
|
@ -327,6 +371,12 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
|||
break;
|
||||
}
|
||||
/* else we do a flush too */
|
||||
case GST_EVENT_SEEK_SEGMENT:
|
||||
src->segment_start = GST_EVENT_SEEK_OFFSET (event);
|
||||
src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
|
||||
src->buffer_count = src->segment_start;
|
||||
src->segment_loop = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
|
||||
break;
|
||||
case GST_EVENT_FLUSH:
|
||||
src->need_flush = TRUE;
|
||||
break;
|
||||
|
@ -338,18 +388,6 @@ gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static const GstEventMask*
|
||||
gst_fakesrc_get_event_mask (GstPad *pad)
|
||||
{
|
||||
static const GstEventMask gst_fakesrc_event_mask[] = {
|
||||
{ GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH },
|
||||
{ GST_EVENT_FLUSH, 0 },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
return gst_fakesrc_event_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_fakesrc_update_functions (GstFakeSrc *src)
|
||||
{
|
||||
|
@ -375,6 +413,9 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
|
|||
|
||||
gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
|
||||
gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
|
||||
gst_pad_set_query_function (pad, gst_fakesrc_query);
|
||||
gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
|
||||
gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
}
|
||||
|
@ -687,6 +728,16 @@ gst_fakesrc_get(GstPad *pad)
|
|||
return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
|
||||
}
|
||||
|
||||
if (src->buffer_count == src->segment_end) {
|
||||
if (src->segment_loop) {
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_SEGMENT_DONE));
|
||||
}
|
||||
else {
|
||||
gst_element_set_eos (GST_ELEMENT (src));
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
|
||||
}
|
||||
}
|
||||
|
||||
if (src->rt_num_buffers == 0) {
|
||||
gst_element_set_eos (GST_ELEMENT (src));
|
||||
return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
|
||||
|
@ -745,36 +796,13 @@ gst_fakesrc_loop(GstElement *element)
|
|||
GstPad *pad = GST_PAD (pads->data);
|
||||
GstBuffer *buf;
|
||||
|
||||
if (src->rt_num_buffers == 0) {
|
||||
src->eos = TRUE;
|
||||
}
|
||||
else {
|
||||
if (src->rt_num_buffers > 0)
|
||||
src->rt_num_buffers--;
|
||||
}
|
||||
buf = gst_fakesrc_get (pad);
|
||||
gst_pad_push (pad, buf);
|
||||
|
||||
if (src->eos) {
|
||||
gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS)));
|
||||
return;
|
||||
}
|
||||
|
||||
buf = gst_fakesrc_create_buffer (src);
|
||||
GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
|
||||
|
||||
if (!src->silent) {
|
||||
if (src->last_message)
|
||||
g_free (src->last_message);
|
||||
|
||||
src->last_message = g_strdup_printf ("fakesrc: loop ******* (%s:%s) > (%d bytes, %llu)",
|
||||
GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
|
||||
|
||||
g_object_notify (G_OBJECT (src), "last_message");
|
||||
}
|
||||
|
||||
g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
|
||||
buf, pad);
|
||||
gst_pad_push (pad, buf);
|
||||
|
||||
pads = g_list_next (pads);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,30 +82,33 @@ typedef struct _GstFakeSrc GstFakeSrc;
|
|||
typedef struct _GstFakeSrcClass GstFakeSrcClass;
|
||||
|
||||
struct _GstFakeSrc {
|
||||
GstElement element;
|
||||
GstElement element;
|
||||
|
||||
gboolean loop_based;
|
||||
gboolean eos;
|
||||
gboolean loop_based;
|
||||
gboolean eos;
|
||||
|
||||
GstFakeSrcOutputType output;
|
||||
GstFakeSrcDataType data;
|
||||
GstFakeSrcSizeType sizetype;
|
||||
GstFakeSrcFillType filltype;
|
||||
GstFakeSrcDataType data;
|
||||
GstFakeSrcSizeType sizetype;
|
||||
GstFakeSrcFillType filltype;
|
||||
|
||||
guint sizemin;
|
||||
guint sizemax;
|
||||
guint sizemin;
|
||||
guint sizemax;
|
||||
GstBuffer *parent;
|
||||
guint parentsize;
|
||||
guint parentoffset;
|
||||
guint8 pattern_byte;
|
||||
guint parentsize;
|
||||
guint parentoffset;
|
||||
guint8 pattern_byte;
|
||||
gchar *pattern;
|
||||
GList *patternlist;
|
||||
gint num_buffers;
|
||||
gint rt_num_buffers; /* we are going to change this at runtime */
|
||||
guint64 buffer_count;
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
gint64 segment_start;
|
||||
gint64 segment_end;
|
||||
gboolean segment_loop;
|
||||
gint num_buffers;
|
||||
gint rt_num_buffers; /* we are going to change this at runtime */
|
||||
guint64 buffer_count;
|
||||
gboolean silent;
|
||||
gboolean dump;
|
||||
gboolean need_flush;
|
||||
GstBufferPool *pool;
|
||||
|
||||
gchar *last_message;
|
||||
|
|
Loading…
Reference in a new issue