Commit 347505bc authored by Wim Taymans's avatar Wim Taymans

- major API breakage (one of the last, I promise...)

Original commit message from CVS:
- major API breakage (one of the last, I promise...)
- GST_PAD_QUERY -> GST_QUERY
- GstPadQuery -> GstQuery
- Move query definitions to gstquery.h to allow for future dynamic
query types.
- remove _pad_handles_* in favour of extra format/event functions to
make the same checks.
- fix elements
- Implemented missing query/event/formats functions in gstelement
parent 8854eac1
......@@ -131,6 +131,7 @@ gst_headers = \
gstprobe.h \
gstprops.h \
gstqueue.h \
gstquery.h \
gstscheduler.h \
gstsystemclock.h \
gstthread.h \
......
......@@ -319,34 +319,34 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
return srcpad;
}
GST_FORMATS_FUNCTION (gst_fakesrc_get_formats,
GST_PAD_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
GST_QUERY_TOTAL,
GST_QUERY_POSITION,
GST_QUERY_START,
GST_QUERY_SEGMENT_END
)
static gboolean
gst_fakesrc_query (GstPad *pad, GstPadQueryType type,
gst_fakesrc_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
{
GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad));
switch (type) {
case GST_PAD_QUERY_TOTAL:
case GST_QUERY_TOTAL:
*value = src->num_buffers;
break;
case GST_PAD_QUERY_POSITION:
case GST_QUERY_POSITION:
*value = src->buffer_count;
break;
case GST_PAD_QUERY_START:
case GST_QUERY_START:
*value = src->segment_start;
break;
case GST_PAD_QUERY_SEGMENT_END:
case GST_QUERY_SEGMENT_END:
*value = src->segment_end;
break;
default:
......@@ -355,7 +355,7 @@ gst_fakesrc_query (GstPad *pad, GstPadQueryType type,
return TRUE;
}
GST_EVENT_MASK_FUNCTION (gst_fakesrc_get_event_mask,
GST_PAD_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 }
......
......@@ -50,7 +50,7 @@ enum {
ARG_MAXFILESIZE,
};
GST_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_END |
......
......@@ -109,7 +109,7 @@ enum {
ARG_TOUCH,
};
GST_EVENT_MASK_FUNCTION (gst_filesrc_get_event_mask,
GST_PAD_EVENT_MASK_FUNCTION (gst_filesrc_get_event_mask,
{ GST_EVENT_SEEK, GST_SEEK_METHOD_CUR |
GST_SEEK_METHOD_SET |
GST_SEEK_METHOD_END |
......@@ -119,11 +119,11 @@ GST_EVENT_MASK_FUNCTION (gst_filesrc_get_event_mask,
)
GST_PAD_QUERY_TYPE_FUNCTION (gst_filesrc_get_query_types,
GST_PAD_QUERY_TOTAL,
GST_PAD_QUERY_POSITION
GST_QUERY_TOTAL,
GST_QUERY_POSITION
)
GST_FORMATS_FUNCTION (gst_filesrc_get_formats,
GST_PAD_FORMATS_FUNCTION (gst_filesrc_get_formats,
GST_FORMAT_BYTES
)
......@@ -138,7 +138,7 @@ static void gst_filesrc_get_property (GObject *object, guint prop_id,
static GstBuffer * gst_filesrc_get (GstPad *pad);
static gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event);
static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstPadQueryType type,
static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value);
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
......@@ -732,19 +732,19 @@ gst_filesrc_change_state (GstElement *element)
}
static gboolean
gst_filesrc_srcpad_query (GstPad *pad, GstPadQueryType type,
gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
GstFormat *format, gint64 *value)
{
GstFileSrc *src = GST_FILESRC (GST_PAD_PARENT (pad));
switch (type) {
case GST_PAD_QUERY_TOTAL:
case GST_QUERY_TOTAL:
if (*format != GST_FORMAT_BYTES) {
return FALSE;
}
*value = src->filelen;
break;
case GST_PAD_QUERY_POSITION:
case GST_QUERY_POSITION:
switch (*format) {
case GST_FORMAT_BYTES:
*value = src->curoffset;
......
......@@ -60,10 +60,6 @@ static void gst_element_real_get_property (GObject *object, guint prop_id, GVa
static void gst_element_dispose (GObject *object);
static gboolean gst_element_send_event_default (GstElement *element, GstEvent *event);
static gboolean gst_element_query_default (GstElement *element, GstPadQueryType type,
GstFormat *format, gint64 *value);
static GstElementStateReturn gst_element_change_state (GstElement *element);
static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
......@@ -149,8 +145,8 @@ gst_element_class_init (GstElementClass *klass)
klass->elementfactory = NULL;
klass->padtemplates = NULL;
klass->numpadtemplates = 0;
klass->send_event = GST_DEBUG_FUNCPTR (gst_element_send_event_default);
klass->query = GST_DEBUG_FUNCPTR (gst_element_query_default);
klass->send_event = NULL;
klass->query = NULL;
}
static void
......@@ -1762,24 +1758,52 @@ gst_element_error_func (GstElement* element, GstElement *source,
}
}
static gboolean
gst_element_send_event_default (GstElement *element, GstEvent *event)
static GstPad*
gst_element_get_random_pad (GstElement *element, GstPadDirection dir)
{
GList *pads = element->pads;
gboolean res = FALSE;
while (pads) {
GstPad *pad = GST_PAD_CAST (pads->data);
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
if (GST_PAD_DIRECTION (pad) == dir) {
if (GST_PAD_IS_USABLE (pad)) {
res = gst_pad_send_event (GST_PAD_PEER (pad), event);
break;
return pad;
}
}
pads = g_list_next (pads);
}
return res;
return NULL;
}
/**
* gst_element_get_event_masks:
* @element: a #GstElement to query
*
* Get an array of event masks from the element.
* If the element doesn't
* implement an event masks function, the query will be forwarded
* to a random sink pad.
*
* Returns: An array of #GstEventMask elements.
*/
const GstEventMask*
gst_element_get_event_masks (GstElement *element)
{
GstElementClass *oclass;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_event_masks)
return oclass->get_event_masks (element);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_get_event_masks (GST_PAD_PEER (pad));
}
return FALSE;
}
/**
......@@ -1805,35 +1829,50 @@ gst_element_send_event (GstElement *element, GstEvent *event)
if (oclass->send_event)
return oclass->send_event (element, event);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_send_event (GST_PAD_PEER (pad), event);
}
return FALSE;
}
static gboolean
gst_element_query_default (GstElement *element, GstPadQueryType type,
GstFormat *format, gint64 *value)
/**
* gst_element_get_query_types:
* @element: a #GstElement to query
*
* Get an array of query types from the element.
* If the element doesn't
* implement a query types function, the query will be forwarded
* to a random sink pad.
*
* Returns: An array of #GstQueryType elements.
*/
const GstQueryType*
gst_element_get_query_types (GstElement *element)
{
GList *pads = element->pads;
gboolean res = FALSE;
GstElementClass *oclass;
while (pads) {
GstPad *pad = GST_PAD_CAST (pads->data);
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
if (GST_PAD_IS_USABLE (pad)) {
res = gst_pad_query (GST_PAD_PEER (pad), type, format, value);
break;
}
}
pads = g_list_next (pads);
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_query_types)
return oclass->get_query_types (element);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_get_query_types (GST_PAD_PEER (pad));
}
return res;
return FALSE;
}
/**
* gst_element_query:
* @element: a #GstElement to perform the query on.
* @type: the #GstPadQueryType.
* @type: the #GstQueryType.
* @format: the #GstFormat pointer to hold the format of the result.
* @value: the pointer to the value of the result.
*
......@@ -1841,12 +1880,12 @@ gst_element_query_default (GstElement *element, GstPadQueryType type,
* to GST_FORMAT_DEFAULT and this function returns TRUE, the
* format pointer will hold the default format.
* For element that don't implement a query handler, this function
* forwards the query to a random connected sinkpad of this element.
* forwards the query to a random usable sinkpad of this element.
*
* Returns: TRUE if the query could be performed.
*/
gboolean
gst_element_query (GstElement *element, GstPadQueryType type,
gst_element_query (GstElement *element, GstQueryType type,
GstFormat *format, gint64 *value)
{
GstElementClass *oclass;
......@@ -1859,6 +1898,90 @@ gst_element_query (GstElement *element, GstPadQueryType type,
if (oclass->query)
return oclass->query (element, type, format, value);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
}
return FALSE;
}
/**
* gst_element_get_formats:
* @element: a #GstElement to query
*
* Get an array of formst from the element.
* If the element doesn't
* implement a formats function, the query will be forwarded
* to a random sink pad.
*
* Returns: An array of #GstFormat elements.
*/
const GstFormat*
gst_element_get_formats (GstElement *element)
{
GstElementClass *oclass;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_formats)
return oclass->get_formats (element);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_get_formats (GST_PAD_PEER (pad));
}
return FALSE;
}
/**
* gst_element_convert:
* @element: a #GstElement to invoke the converter on.
* @src_format: the source #GstFormat.
* @src_value: the source value.
* @dest_format: a pointer to the destination #GstFormat.
* @dest_value: a pointer to the destination value.
*
* Invokes a conversion on the element.
* If the element doesn't
* implement a convert function, the query will be forwarded
* to a random sink pad.
*
* Returns: TRUE if the conversion could be performed.
*/
gboolean
gst_element_convert (GstElement *element,
GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value)
{
GstElementClass *oclass;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (src_format == *dest_format) {
*dest_value = src_value;
return TRUE;
}
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->convert)
return oclass->convert (element,
src_format, src_value,
dest_format, dest_value);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_convert (GST_PAD_PEER (pad),
src_format, src_value,
dest_format, dest_value);
}
return FALSE;
}
......
......@@ -69,6 +69,23 @@ extern GType _gst_element_type;
# define GST_ELEMENT_CLASS GST_ELEMENT_CLASS_CAST
#endif
/* convenience functions */
#ifdef G_HAVE_ISO_VARARGS
#define GST_ELEMENT_QUERY_TYPE_FUNCTION(functionname, ...) \
GST_QUERY_TYPE_FUNCTION (GstElement*, functionname, __VA_ARGS__);
#define GST_ELEMENT_FORMATS_FUNCTION(functionname, ...) \
GST_FORMATS_FUNCTION (GstElement*, functionname, __VA_ARGS__);
#define GST_ELEMENT_EVENT_MASK_FUNCTION(functionname, ...) \
GST_EVENT_MASK_FUNCTION (GstElement*, functionname, __VA_ARGS__);
#elif defined(G_HAVE_GNUC_VARARGS)
#define GST_ELEMENT_QUERY_TYPE_FUNCTION(functionname, a...) \
GST_QUERY_TYPE_FUNCTION (GstElement*, functionname, a);
#define GST_ELEMENT_FORMATS_FUNCTION(functionname, a...) \
GST_FORMATS_FUNCTION (GstElement*, functionname, a);
#define GST_ELEMENT_EVENT_MASK_FUNCTION(functionname, a...) \
GST_EVENT_MASK_FUNCTION (GstElement*, functionname, a);
#endif
typedef enum {
/* element is complex (for some def.) and generally require a cothread */
GST_ELEMENT_COMPLEX = GST_OBJECT_FLAG_LAST,
......@@ -168,21 +185,34 @@ struct _GstElementClass {
/* vtable*/
gboolean (*release_locks) (GstElement *element);
/* query/convert/events functions */
const GstEventMask* (*get_event_masks) (GstElement *element);
gboolean (*send_event) (GstElement *element, GstEvent *event);
gboolean (*query) (GstElement *element, GstPadQueryType type,
const GstFormat* (*get_formats) (GstElement *element);
gboolean (*convert) (GstElement *element,
GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
const GstQueryType* (*get_query_types) (GstElement *element);
gboolean (*query) (GstElement *element, GstQueryType type,
GstFormat *format, gint64 *value);
/* change the element state */
GstElementStateReturn (*change_state) (GstElement *element);
/* request a new pad */
/* request/release pads */
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name);
void (*release_pad) (GstElement *element, GstPad *pad);
/* set/get clocks */
GstClock* (*get_clock) (GstElement *element);
void (*set_clock) (GstElement *element, GstClock *clock);
/* index */
GstIndex* (*get_index) (GstElement *element);
void (*set_index) (GstElement *element, GstIndex *index);
/* padding */
gpointer dummy[8];
};
......@@ -255,10 +285,6 @@ const GList* gst_element_get_pad_list (GstElement *element);
GstPad* gst_element_get_compatible_pad (GstElement *element, GstPad *pad);
GstPad* gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
GstCaps *filtercaps);
/* unimplemented
GstPad* gst_element_get_compatible_request_pad (GstElement *element, GstPadTemplate *templ);
GstPad* gst_element_get_compatible_static_pad (GstElement *element, GstPadTemplate *templ);
*/
GstPadTemplate* gst_element_get_pad_template (GstElement *element, const gchar *name);
GList* gst_element_get_pad_template_list (GstElement *element);
......@@ -279,9 +305,15 @@ gboolean gst_element_connect_pads_filtered (GstElement *src, const gchar *srcpa
void gst_element_disconnect_pads (GstElement *src, const gchar *srcpadname,
GstElement *dest, const gchar *destpadname);
const GstEventMask* gst_element_get_event_masks (GstElement *element);
gboolean gst_element_send_event (GstElement *element, GstEvent *event);
gboolean gst_element_query (GstElement *element, GstPadQueryType type,
const GstQueryType* gst_element_get_query_types (GstElement *element);
gboolean gst_element_query (GstElement *element, GstQueryType type,
GstFormat *format, gint64 *value);
const GstFormat* gst_element_get_formats (GstElement *element);
gboolean gst_element_convert (GstElement *element,
GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
void gst_element_set_eos (GstElement *element);
......
......@@ -88,6 +88,34 @@ _gst_event_free (GstEvent* event)
g_free (event);
}
/**
* gst_event_masks_contains:
* @masks: The eventmask array to search
* @mask: the event mask to find
*
* See if the given eventmask is inside the eventmask array.
*
* Returns: TRUE if the eventmask is found inside the array
*/
gboolean
gst_event_masks_contains (const GstEventMask *masks, GstEventMask *mask)
{
g_return_val_if_fail (mask != NULL, FALSE);
if (!masks)
return FALSE;
while (masks->type) {
if (masks->type == mask->type &&
(masks->flags & mask->flags) == mask->flags)
return TRUE;
masks++;
}
return FALSE;
}
/**
* gst_event_new:
* @type: The type of the new event
......
......@@ -79,9 +79,9 @@ typedef struct
} GstEventMask;
#ifdef G_HAVE_ISO_VARARGS
#define GST_EVENT_MASK_FUNCTION(functionname, ...) \
#define GST_EVENT_MASK_FUNCTION(type,functionname, ...) \
static const GstEventMask* \
functionname (GstPad *pad) \
functionname (type pad) \
{ \
static const GstEventMask masks[] = { \
__VA_ARGS__, \
......@@ -90,9 +90,9 @@ functionname (GstPad *pad) \
return masks; \
}
#elif defined(G_HAVE_GNUC_VARARGS)
#define GST_EVENT_MASK_FUNCTION(functionname, a...) \
#define GST_EVENT_MASK_FUNCTION(type,functionname, a...) \
static const GstEventMask* \
functionname (GstPad *pad) \
functionname (type pad) \
{ \
static const GstEventMask masks[] = { \
a, \
......@@ -189,6 +189,8 @@ GstEvent* gst_event_new (GstEventType type);
/* copy buffer */
#define gst_event_copy(ev) GST_EVENT (gst_data_copy (GST_DATA (ev)))
gboolean gst_event_masks_contains (const GstEventMask *masks, GstEventMask *mask);
/* seek event */
GstEvent* gst_event_new_seek (GstSeekType type, gint64 offset);
......
......@@ -54,26 +54,26 @@ struct _GstFormatDefinition
};
#ifdef G_HAVE_ISO_VARARGS
#define GST_FORMATS_FUNCTION(functionname, ...) \
static const GstFormat* \
functionname (GstPad *pad) \
{ \
static const GstFormat formats[] = { \
__VA_ARGS__, \
0 \
}; \
return formats; \
#define GST_FORMATS_FUNCTION(type, functionname, ...) \
static const GstFormat* \
functionname (type object) \
{ \
static const GstFormat formats[] = { \
__VA_ARGS__, \
0 \
}; \
return formats; \
}
#elif defined(G_HAVE_GNUC_VARARGS)
#define GST_FORMATS_FUNCTION(functionname, a...) \
static const GstFormat* \
functionname (GstPad *pad) \
{ \
static const GstFormat formats[] = { \
a, \
0 \
}; \
return formats; \
#define GST_FORMATS_FUNCTION(type, functionname, a...) \
static const GstFormat* \
functionname (type object) \
{ \
static const GstFormat formats[] = { \
a, \
0 \
}; \
return formats; \
}
#endif
......
......@@ -547,6 +547,7 @@ gst_index_compare_func (gconstpointer a,
* @index: the index to search
* @id: the id of the index writer
* @method: The lookup method to use
* @flags: Flags for the entry
* @format: the format of the value
* @value: the value to find
*
......@@ -571,6 +572,7 @@ gst_index_get_assoc_entry (GstIndex *index, gint id,
* @index: the index to search
* @id: the id of the index writer
* @method: The lookup method to use
* @flags: Flags for the entry
* @format: the format of the value
* @value: the value to find
* @func: the function used to compare entries
......
......@@ -580,38 +580,6 @@ gst_pad_get_event_masks_default (GstPad *pad)
return result;
}
/**
* gst_pad_handles_event:
* @pad: a #GstPad to check
* @mask: the mask to check
*
* Checks if the pad can handle the given eventmask.
*
* Returns: TRUE if the pad can handle the given eventmask
*/
gboolean
gst_pad_handles_event (GstPad *pad, GstEventMask *mask)
{
const GstEventMask *masks;
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (mask != NULL, FALSE);
masks = gst_pad_get_event_masks (pad);
if (!masks)
return FALSE;
while (masks->type) {
if (masks->type == mask->type &&
(masks->flags & mask->flags) == mask->flags)
return TRUE;
masks++;
}
return FALSE;
}
/**
* gst_pad_set_convert_function:
* @pad: a #GstPad to set the convert function for.
......@@ -679,7 +647,7 @@ gst_pad_set_query_type_function (GstPad *pad, GstPadQueryTypeFunction type_func)
*
* Returns: an array of querytypes anded with 0.
*/
const GstPadQueryType*
const GstQueryType*
gst_pad_get_query_types (GstPad *pad)
{
GstRealPad *rpad;
......@@ -698,7 +666,7 @@ gst_pad_get_query_types (GstPad *pad)
}