static gboolean gst_au_parse_src_query (GstPad * pad, GstQuery * query);
static gboolean gst_au_parse_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_au_parse_sink_event (GstPad * pad, GstEvent * event);
+static gboolean gst_au_parse_src_convert (GstAuParse * auparse,
+ GstFormat src_format, gint64 srcval, GstFormat dest_format,
+ gint64 * destval);
GST_BOILERPLATE (GstAuParse, gst_au_parse, GstElement, GST_TYPE_ELEMENT);
}
auparse->offset = GST_READ_UINT32_BE (head + 4);
- /* Do not trust size, could be set to -1 : unknown */
+ /* Do not trust size, could be set to -1 : unknown
+ * otherwise: filesize = size + auparse->offset
+ */
size = GST_READ_UINT32_BE (head + 8);
auparse->encoding = GST_READ_UINT32_BE (head + 12);
auparse->samplerate = GST_READ_UINT32_BE (head + 16);
GstFlowReturn ret = GST_FLOW_OK;
GstAuParse *auparse;
gint avail, sendnow = 0;
+ gint64 timestamp;
+ gint64 duration;
+ gint64 offset;
auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
goto out;
gst_pad_push_event (auparse->srcpad,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_DEFAULT,
+ gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
0, GST_CLOCK_TIME_NONE, 0));
}
if (sendnow > 0) {
GstBuffer *outbuf;
const guint8 *data;
+ gint64 pos;
ret = gst_pad_alloc_buffer_and_set_caps (auparse->srcpad,
auparse->buffer_offset, sendnow, GST_PAD_CAPS (auparse->srcpad),
memcpy (GST_BUFFER_DATA (outbuf), data, sendnow);
gst_adapter_flush (auparse->adapter, sendnow);
+ pos = auparse->buffer_offset - auparse->offset;
+ pos = MAX (pos, 0);
+
+ if (auparse->sample_size > 0 && auparse->samplerate > 0) {
+ gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, pos,
+ GST_FORMAT_DEFAULT, &offset);
+ gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, pos,
+ GST_FORMAT_TIME, ×tamp);
+ gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES,
+ sendnow, GST_FORMAT_TIME, &duration);
+
+ GST_BUFFER_OFFSET (outbuf) = offset;
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+ GST_BUFFER_DURATION (outbuf) = duration;
+ }
+
auparse->buffer_offset += sendnow;
ret = gst_pad_push (auparse->srcpad, outbuf);
/* fallthrough */
case GST_FORMAT_DEFAULT:{
switch (dest_format) {
+ case GST_FORMAT_DEFAULT:
+ *destval = srcval;
+ break;
case GST_FORMAT_BYTES:
*destval = srcval * samplesize;
break;
case GST_FORMAT_TIME:{
switch (dest_format) {
case GST_FORMAT_BYTES:
- *destval =
- gst_util_uint64_scale_int (srcval, rate * samplesize, GST_SECOND);
+ *destval = samplesize *
+ gst_util_uint64_scale_int (srcval, rate, GST_SECOND);
break;
case GST_FORMAT_DEFAULT:
*destval = gst_util_uint64_scale_int (srcval, rate, GST_SECOND);
len -= auparse->offset;
GST_OBJECT_UNLOCK (auparse);
- ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, len,
- format, &val);
+ ret = gst_au_parse_src_convert (auparse, bformat, len, format, &val);
if (ret) {
gst_query_set_duration (query, format, val);
}
break;
}
+ case GST_QUERY_SEEKING:{
+ GstFormat format;
+
+ gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
+ /* FIXME: query duration in 'format'
+ gst_query_set_seeking (query, format, TRUE, 0, duration);
+ */
+ gst_query_set_seeking (query, format, TRUE, 0, GST_CLOCK_TIME_NONE);
+ ret = TRUE;
+ break;
+ }
default:
ret = gst_pad_query_default (pad, query);
break;
GstFormat format;
gdouble rate;
gint64 start, stop;
+ gboolean res;
gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
&stop_type, &stop);
return FALSE;
}
- /* FIXME: implement seeking */
- return FALSE;
+ res = gst_au_parse_src_convert (auparse, GST_FORMAT_TIME, start,
+ GST_FORMAT_BYTES, &start);
+
+ if (stop > 0) {
+ res = gst_au_parse_src_convert (auparse, GST_FORMAT_TIME, stop,
+ GST_FORMAT_BYTES, &stop);
+ }
+
+ GST_INFO_OBJECT (auparse,
+ "seeking: %" G_GINT64_FORMAT " ... %" G_GINT64_FORMAT, start, stop);
+
+ event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, start_type, start,
+ stop_type, stop);
+ res = gst_pad_push_event (auparse->sinkpad, event);
+ return res;
}
static gboolean
gst_au_parse_sink_event (GstPad * pad, GstEvent * event)
{
GstAuParse *auparse;
- gboolean ret;
+ gboolean ret = TRUE;
auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:
+ {
+ GstFormat format;
+ gdouble rate, arate;
+ gint64 start, stop, time, offset = 0;
+ gboolean update;
+ GstSegment segment;
+ GstEvent *new_event = NULL;
+
+ gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
+ gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
+ &start, &stop, &time);
+ gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
+ start, stop, time);
+
+ if (auparse->sample_size > 0) {
+ if (start > 0) {
+ offset = start;
+ start -= auparse->offset;
+ start = MAX (start, 0);
+ }
+ if (stop > 0) {
+ stop -= auparse->offset;
+ stop = MAX (stop, 0);
+ }
+ gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, start,
+ GST_FORMAT_TIME, &start);
+ gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, stop,
+ GST_FORMAT_TIME, &stop);
+ }
+
+ if (auparse->srcpad) {
+ GST_INFO_OBJECT (auparse,
+ "new segment: %" GST_TIME_FORMAT " ... %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
+
+ new_event = gst_event_new_new_segment_full (update, rate, arate,
+ GST_FORMAT_TIME, start, stop, start);
+
+ ret = gst_pad_push_event (auparse->srcpad, new_event);
+ }
+
+ auparse->buffer_offset = offset;
+
+ gst_event_unref (event);
+ break;
+ }
default:
ret = gst_pad_event_default (pad, event);
break;