dv1394src: Fix element for live usage... which has been broken for 2 years :(

This is a live source, therefore:
* Use GST_FORMAT_TIME as the default format
* set_timestamp to True
* properly implement query latency.

This allows expected live usage like : playbin2 uri=dv://
This commit is contained in:
Edward Hervey 2009-07-03 14:04:13 +02:00
parent 3fd4cdcc43
commit d522f94f98

View file

@ -142,12 +142,7 @@ 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);
static gboolean gst_dv1394src_convert (GstPad * pad, static gboolean gst_dv1394src_query (GstBaseSrc * src, GstQuery * query);
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value);
static const GstQueryType *gst_dv1394src_get_query_types (GstPad * pad);
static gboolean gst_dv1394src_query (GstPad * pad, GstQuery * query);
static void gst_dv1394src_update_device_name (GstDV1394Src * src); static void gst_dv1394src_update_device_name (GstDV1394Src * src);
static void static void
@ -244,6 +239,7 @@ gst_dv1394src_class_init (GstDV1394SrcClass * klass)
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; gstbasesrc_class->unlock = gst_dv1394src_unlock;
gstbasesrc_class->query = gst_dv1394src_query;
gstpushsrc_class->create = gst_dv1394src_create; gstpushsrc_class->create = gst_dv1394src_create;
} }
@ -254,11 +250,10 @@ gst_dv1394src_init (GstDV1394Src * dv1394src, GstDV1394SrcClass * klass)
GstPad *srcpad = GST_BASE_SRC_PAD (dv1394src); GstPad *srcpad = GST_BASE_SRC_PAD (dv1394src);
gst_base_src_set_live (GST_BASE_SRC (dv1394src), TRUE); gst_base_src_set_live (GST_BASE_SRC (dv1394src), TRUE);
gst_base_src_set_format (GST_BASE_SRC (dv1394src), GST_FORMAT_TIME);
gst_base_src_set_do_timestamp (GST_BASE_SRC (dv1394src), TRUE);
gst_pad_use_fixed_caps (srcpad); gst_pad_use_fixed_caps (srcpad);
gst_pad_set_query_function (srcpad, gst_dv1394src_query);
gst_pad_set_query_type_function (srcpad, gst_dv1394src_get_query_types);
dv1394src->port = DEFAULT_PORT; dv1394src->port = DEFAULT_PORT;
dv1394src->channel = DEFAULT_CHANNEL; dv1394src->channel = DEFAULT_CHANNEL;
@ -423,22 +418,12 @@ gst_dv1394src_iec61883_receive (unsigned char *data, int len,
if (G_LIKELY ((dv1394src->frame_sequence + 1) % (dv1394src->skip + if (G_LIKELY ((dv1394src->frame_sequence + 1) % (dv1394src->skip +
dv1394src->consecutive) < dv1394src->consecutive)) { dv1394src->consecutive) < dv1394src->consecutive)) {
if (complete && len == dv1394src->frame_size) { if (complete && len == dv1394src->frame_size) {
gint64 i64;
guint8 *bufdata; guint8 *bufdata;
GstBuffer *buf; GstBuffer *buf;
GstFormat format;
buf = gst_buffer_new_and_alloc (dv1394src->frame_size); buf = gst_buffer_new_and_alloc (dv1394src->frame_size);
/* fill in offset, duration, timestamp */
GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence; GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence;
format = GST_FORMAT_TIME;
gst_dv1394src_convert (GST_BASE_SRC_PAD (dv1394src), GST_FORMAT_DEFAULT,
GST_BUFFER_OFFSET (buf), &format, &i64);
GST_BUFFER_TIMESTAMP (buf) = i64;
gst_dv1394src_convert (GST_BASE_SRC_PAD (dv1394src), GST_FORMAT_DEFAULT,
1, &format, &i64);
GST_BUFFER_DURATION (buf) = i64;
bufdata = GST_BUFFER_DATA (buf); bufdata = GST_BUFFER_DATA (buf);
memcpy (bufdata, data, len); memcpy (bufdata, data, len);
dv1394src->buf = buf; dv1394src->buf = buf;
@ -510,7 +495,6 @@ gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
} }
if ((dv1394src->frame_sequence + 1) % (dv1394src->skip + if ((dv1394src->frame_sequence + 1) % (dv1394src->skip +
dv1394src->consecutive) < dv1394src->consecutive) { dv1394src->consecutive) < dv1394src->consecutive) {
GstFormat format;
GstBuffer *buf; GstBuffer *buf;
gint64 i64; gint64 i64;
@ -518,14 +502,6 @@ gst_dv1394src_iso_receive (raw1394handle_t handle, int channel, size_t len,
/* fill in offset, duration, timestamp */ /* fill in offset, duration, timestamp */
GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence; GST_BUFFER_OFFSET (buf) = dv1394src->frame_sequence;
format = GST_FORMAT_TIME;
gst_dv1394src_convert (GST_BASE_SRC_PAD (dv1394src), GST_FORMAT_DEFAULT,
GST_BUFFER_OFFSET (buf), &format, &i64);
GST_BUFFER_TIMESTAMP (buf) = i64;
gst_dv1394src_convert (GST_BASE_SRC_PAD (dv1394src), GST_FORMAT_DEFAULT,
1, &format, &i64);
GST_BUFFER_DURATION (buf) = i64;
dv1394src->frame = buf; dv1394src->frame = buf;
} }
dv1394src->frame_sequence++; dv1394src->frame_sequence++;
@ -643,7 +619,7 @@ gst_dv1394src_create (GstPushSrc * psrc, GstBuffer ** buf)
pollfds[1].fd = READ_SOCKET (dv1394src); pollfds[1].fd = READ_SOCKET (dv1394src);
pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI; pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
if (dv1394src->buf) { if (G_UNLIKELY (dv1394src->buf)) {
/* maybe we had an error before, and there's a stale buffer? */ /* maybe we had an error before, and there's a stale buffer? */
gst_buffer_unref (dv1394src->buf); gst_buffer_unref (dv1394src->buf);
dv1394src->buf = NULL; dv1394src->buf = NULL;
@ -967,120 +943,22 @@ gst_dv1394src_unlock (GstBaseSrc * bsrc)
} }
static gboolean static gboolean
gst_dv1394src_convert (GstPad * pad, gst_dv1394src_query (GstBaseSrc * basesrc, GstQuery * query)
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value)
{ {
GstDV1394Src *src;
src = GST_DV1394SRC (gst_pad_get_parent (pad));
switch (src_format) {
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
src_value *= src->frame_size;
case GST_FORMAT_DEFAULT:
*dest_value =
gst_util_uint64_scale_int (src_value, src->frame_rate,
GST_SECOND);
break;
default:
goto not_supported;
}
break;
case GST_FORMAT_BYTES:
src_value /= src->frame_size;
case GST_FORMAT_DEFAULT:
switch (*dest_format) {
case GST_FORMAT_BYTES:
*dest_value = src_value * src->frame_size;
break;
case GST_FORMAT_TIME:
if (src->frame_rate != 0)
*dest_value =
gst_util_uint64_scale_int (src_value, GST_SECOND,
src->frame_rate);
else
goto not_supported;
break;
default:
goto not_supported;
}
break;
default:
goto not_supported;
}
gst_object_unref (src);
return TRUE;
not_supported:
{
GST_DEBUG_OBJECT (src, "unsupported conversion");
gst_object_unref (src);
return FALSE;
}
}
static const GstQueryType *
gst_dv1394src_get_query_types (GstPad * pad)
{
static const GstQueryType src_query_types[] = {
GST_QUERY_CONVERT,
GST_QUERY_POSITION,
0
};
return src_query_types;
}
static gboolean
gst_dv1394src_query (GstPad * pad, GstQuery * query)
{
GstDV1394Src *src;
src = GST_DV1394SRC (gst_pad_get_parent (pad));
switch (GST_QUERY_TYPE (query)) { switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION: case GST_QUERY_LATENCY:
{ {
GstFormat format; gst_query_set_latency (query, TRUE, GST_SECOND / 25, GST_CLOCK_TIME_NONE);
gint64 current;
gst_query_parse_position (query, &format, NULL);
/* bring our current frame to the requested format */
gst_pad_query_convert (pad,
GST_FORMAT_DEFAULT, src->frame_sequence, &format, &current);
gst_query_set_position (query, format, current);
break;
} }
case GST_QUERY_CONVERT:
{
GstFormat src_fmt, dest_fmt;
gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
if (!(gst_dv1394src_convert (pad, src_fmt, src_val, &dest_fmt,
&dest_val)))
goto not_supported;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
break; break;
}
default: default:
goto not_supported; goto not_supported;
} }
gst_object_unref (src);
return TRUE; return TRUE;
not_supported: not_supported:
{ return GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
gst_object_unref (src);
return FALSE;
}
} }
static void static void