Merge branch 'master' of ssh://git.freedesktop.org/git/gstreamer/gst-plugins-good

This commit is contained in:
Sebastian Dröge 2009-02-27 20:28:27 +01:00
commit d189fe7f26
9 changed files with 352 additions and 48 deletions

View file

@ -619,9 +619,13 @@ gst_avi_demux_handle_src_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
/* handle seeking */
res = gst_avi_demux_handle_seek (avi, pad, event);
gst_event_unref (event);
/* handle seeking only in pull mode */
if (!avi->streaming) {
res = gst_avi_demux_handle_seek (avi, pad, event);
gst_event_unref (event);
} else {
res = gst_pad_event_default (pad, event);
}
break;
case GST_EVENT_QOS:
case GST_EVENT_NAVIGATION:
@ -4246,6 +4250,7 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
if (active) {
avi->segment_running = TRUE;
avi->streaming = FALSE;
return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop,
sinkpad);
} else {
@ -4257,9 +4262,11 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
static gboolean
gst_avi_demux_activate_push (GstPad * pad, gboolean active)
{
GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (pad));
if (active) {
GST_DEBUG ("avi: activating push/chain function");
avi->streaming = TRUE;
} else {
GST_DEBUG ("avi: deactivating push/chain function");
}

View file

@ -5135,9 +5135,6 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
guint rformat;
guint subformat;
gst_util_dump_mem (data, size);
gst_util_dump_mem (data + 0x1a, size - 0x1a);
subformat = GST_READ_UINT32_BE (data + 0x1a);
rformat = GST_READ_UINT32_BE (data + 0x1e);
@ -5503,7 +5500,6 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
guint extra_data_size;
GST_ERROR ("real audio raversion:%d", raversion);
gst_util_dump_mem (data, size);
if (raversion == 8) {
/* COOK */
flavor = GST_READ_UINT16_BE (data + 22);

View file

@ -92,7 +92,7 @@ enum
#define PEAK_FORMAT ".06f"
#define VALID_GAIN(x) ((x) > -60.00 && (x) < 60.00)
#define VALID_PEAK(x) ((x) > 0.)
#define VALID_PEAK(x) ((x) > 0. && (x) < 1.)
/* Same template caps as GstVolume, for I don't like having just ANY caps. */

View file

@ -139,6 +139,11 @@ gst_rtp_vraw_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
goto no_height;
height = atoi (str);
/* optional interlace value but we don't handle interlaced
* formats yet */
if ((str = gst_structure_get_string (structure, "interlace")))
goto interlaced;
if (!(str = gst_structure_get_string (structure, "sampling")))
goto no_sampling;
@ -248,6 +253,11 @@ no_height:
GST_ERROR_OBJECT (depayload, "no height specified");
return FALSE;
}
interlaced:
{
GST_ERROR_OBJECT (depayload, "interlaced formats not supported yet");
return FALSE;
}
no_sampling:
{
GST_ERROR_OBJECT (depayload, "no sampling specified");

View file

@ -211,6 +211,7 @@ gst_rtp_vraw_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
GstVideoFormat sampling;
const gchar *depthstr, *samplingstr, *colorimetrystr;
gchar *wstr, *hstr;
gboolean interlaced;
rtpvrawpay = GST_RTP_VRAW_PAY (payload);
@ -229,6 +230,13 @@ gst_rtp_vraw_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
if (!res)
goto missing_dimension;
/* fail on interlaced video for now */
if (!gst_structure_get_boolean (s, "interlaced", &interlaced))
interlaced = FALSE;
if (interlaced)
goto interlaced;
yp = up = vp = 0;
xinc = yinc = 1;
@ -358,6 +366,11 @@ unknown_fourcc:
GST_ERROR_OBJECT (payload, "invalid or missing fourcc");
return FALSE;
}
interlaced:
{
GST_ERROR_OBJECT (payload, "interlaced video not supported yet");
return FALSE;
}
missing_dimension:
{
GST_ERROR_OBJECT (payload, "missing width or height property");
@ -409,7 +422,7 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
GstBuffer *out;
guint8 *outdata, *headers;
gboolean next_line;
guint length, cont, pixels;
guint length, cont, pixels, fieldid;
/* get the max allowed payload length size, we try to fill the complete MTU */
left = gst_rtp_buffer_calc_payload_len (mtu, 0, 0);
@ -422,6 +435,24 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
GST_LOG_OBJECT (rtpvrawpay, "created buffer of size %u for MTU %u", left,
mtu);
/*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Extended Sequence Number | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |F| Line No |C| Offset |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Length |F| Line No |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |C| Offset | .
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ .
* . .
* . Two (partial) lines of video data .
* . .
* +---------------------------------------------------------------+
*/
/* need 2 bytes for the extended sequence number */
*outdata++ = 0;
*outdata++ = 0;
@ -456,8 +487,12 @@ gst_rtp_vraw_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
/* write length */
*outdata++ = (length >> 8) & 0xff;
*outdata++ = length & 0xff;
/* always 0 for now */
fieldid = 0x00;
/* write line no */
*outdata++ = (line >> 8) & 0x7f;
*outdata++ = ((line >> 8) & 0x7f) | fieldid;
*outdata++ = line & 0xff;
if (next_line) {

View file

@ -146,6 +146,7 @@ enum
#define DEFAULT_LATENCY_MS 3000
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_NAT_METHOD GST_RTSP_NAT_DUMMY
#define DEFAULT_DO_RTCP TRUE
enum
{
@ -159,6 +160,7 @@ enum
PROP_LATENCY,
PROP_CONNECTION_SPEED,
PROP_NAT_METHOD,
PROP_DO_RTCP,
PROP_LAST
};
@ -335,6 +337,19 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
GST_TYPE_RTSP_NAT_METHOD, DEFAULT_NAT_METHOD,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* GstRTSPSrc::do-rtcp
*
* Enable RTCP support. Some old server don't like RTCP and then this property
* needs to be set to FALSE.
*
* Since: 0.10.15
*/
g_object_class_install_property (gobject_class, PROP_DO_RTCP,
g_param_spec_boolean ("do-rtcp", "Do RTCP",
"Don't send RTCP packets",
DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
gstelement_class->change_state = gst_rtspsrc_change_state;
gstbin_class->handle_message = gst_rtspsrc_handle_message;
@ -454,6 +469,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
case PROP_NAT_METHOD:
rtspsrc->nat_method = g_value_get_enum (value);
break;
case PROP_DO_RTCP:
rtspsrc->do_rtcp = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -502,6 +520,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_NAT_METHOD:
g_value_set_enum (value, rtspsrc->nat_method);
break;
case PROP_DO_RTCP:
g_value_set_boolean (value, rtspsrc->do_rtcp);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1942,8 +1963,8 @@ gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream,
}
gst_object_unref (template);
}
/* setup RTCP transport back to the server */
if (src->session) {
/* setup RTCP transport back to the server if we have to. */
if (src->session && src->do_rtcp) {
GstPad *pad;
template = gst_static_pad_template_get (&anysinktemplate);
@ -2162,7 +2183,7 @@ gst_rtspsrc_stream_configure_udp_sinks (GstRTSPSrc * src,
}
/* it's possible that the server does not want us to send RTCP in which case
* the port is -1 */
if (rtcp_port != -1 && src->session != NULL) {
if (rtcp_port != -1 && src->session != NULL && src->do_rtcp) {
GST_DEBUG_OBJECT (src, "configure RTCP UDP sink for %s:%d", destination,
rtcp_port);
@ -3944,7 +3965,7 @@ gst_rtspsrc_setup_streams (GstRTSPSrc * src)
GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream,
stream->setup_url);
retry:
retry:
/* create a string with all the transports */
res = gst_rtspsrc_create_transports_string (src, protocols, &transports);
if (res < 0)

View file

@ -186,6 +186,7 @@ struct _GstRTSPSrc {
guint latency;
guint connection_speed;
GstRTSPNatMethod nat_method;
gboolean do_rtcp;
/* state */
GstRTSPState state;

View file

@ -115,12 +115,17 @@ beach:
int
gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl)
{
socklen_t socklen;
struct sockaddr_storage addr;
int ret = -1;
#if 0
int l = (loop == FALSE) ? 0 : 1;
switch (addr->ss_family) {
socklen = sizeof (addr);
if ((ret = getsockname (sockfd, (struct sockaddr *) &addr, &socklen)) < 0) {
return ret;
}
switch (addr.ss_family) {
case AF_INET:
{
if ((ret =
@ -155,7 +160,6 @@ gst_udp_set_loop_ttl (int sockfd, gboolean loop, int ttl)
errno = EAFNOSUPPORT;
#endif
}
#endif
return ret;
}

View file

@ -77,6 +77,7 @@ static gboolean gst_wavparse_pad_convert (GstPad * pad,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
static GstFlowReturn gst_wavparse_chain (GstPad * pad, GstBuffer * buf);
static gboolean gst_wavparse_sink_event (GstPad * pad, GstEvent * event);
static void gst_wavparse_loop (GstPad * pad);
static gboolean gst_wavparse_srcpad_event (GstPad * pad, GstEvent * event);
@ -193,6 +194,8 @@ gst_wavparse_init (GstWavParse * wavparse, GstWavParseClass * g_class)
GST_DEBUG_FUNCPTR (gst_wavparse_sink_activate_pull));
gst_pad_set_chain_function (wavparse->sinkpad,
GST_DEBUG_FUNCPTR (gst_wavparse_chain));
gst_pad_set_event_function (wavparse->sinkpad,
GST_DEBUG_FUNCPTR (gst_wavparse_sink_event));
gst_element_add_pad (GST_ELEMENT_CAST (wavparse), wavparse->sinkpad);
/* src, will be created later */
@ -725,8 +728,35 @@ gst_wavparse_stream_init (GstWavParse * wav)
return GST_FLOW_OK;
}
/* This function is used to perform seeks on the element in
* pull mode.
static gboolean
gst_wavparse_time_to_bytepos (GstWavParse * wav, gint64 ts, gint64 * bytepos)
{
/* -1 always maps to -1 */
if (ts == -1) {
*bytepos = -1;
return TRUE;
}
/* 0 always maps to 0 */
if (ts == 0) {
*bytepos = 0;
return TRUE;
}
if (wav->bps > 0) {
*bytepos = uint64_ceiling_scale (ts, (guint64) wav->bps, GST_SECOND);
return TRUE;
} else if (wav->fact) {
guint64 bps =
gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact);
*bytepos = uint64_ceiling_scale (ts, bps, GST_SECOND);
return TRUE;
}
return FALSE;
}
/* This function is used to perform seeks on the element.
*
* It also works when event is NULL, in which case it will just
* start from the last configured segment. This technique is
@ -783,6 +813,48 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event)
stop_type = GST_SEEK_TYPE_SET;
}
/* in push mode, we must delegate to upstream */
if (wav->streaming) {
gboolean res = FALSE;
/* if streaming not yet started; only prepare initial newsegment */
if (!event || wav->state != GST_WAVPARSE_DATA) {
if (wav->start_segment)
gst_event_unref (wav->start_segment);
wav->start_segment =
gst_event_new_new_segment (FALSE, wav->segment.rate,
wav->segment.format, wav->segment.last_stop, wav->segment.duration,
wav->segment.last_stop);
res = TRUE;
} else {
/* convert seek positions to byte positions in data sections */
if (format == GST_FORMAT_TIME) {
/* should not fail */
if (!gst_wavparse_time_to_bytepos (wav, cur, &cur))
goto no_position;
if (!gst_wavparse_time_to_bytepos (wav, stop, &stop))
goto no_position;
}
/* mind sample boundary and header */
if (cur >= 0) {
cur -= (cur % wav->bytes_per_sample);
cur += wav->datastart;
}
if (stop >= 0) {
stop -= (stop % wav->bytes_per_sample);
stop += wav->datastart;
}
GST_DEBUG_OBJECT (wav, "Pushing BYTE seek rate %g, "
"start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, cur,
stop);
/* BYTE seek event */
event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, cur,
stop_type, stop);
res = gst_pad_push_event (wav->sinkpad, event);
}
return res;
}
/* get flush flag */
flush = flags & GST_SEEK_FLAG_FLUSH;
@ -832,16 +904,8 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event)
/* bring offset to bytes, if the bps is 0, we have the segment in BYTES and
* we can just copy the last_stop. If not, we use the bps to convert TIME to
* bytes. */
if (wav->bps > 0)
wav->offset =
uint64_ceiling_scale (seeksegment.last_stop, (guint64) wav->bps,
GST_SECOND);
else if (wav->fact) {
guint64 bps =
gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact);
wav->offset =
uint64_ceiling_scale (seeksegment.last_stop, bps, GST_SECOND);
} else
if (!gst_wavparse_time_to_bytepos (wav, seeksegment.last_stop,
(gint64 *) & wav->offset))
wav->offset = seeksegment.last_stop;
GST_LOG_OBJECT (wav, "offset=%" G_GUINT64_FORMAT, wav->offset);
wav->offset -= (wav->offset % wav->bytes_per_sample);
@ -854,14 +918,7 @@ gst_wavparse_perform_seek (GstWavParse * wav, GstEvent * event)
}
if (stop_type != GST_SEEK_TYPE_NONE) {
if (wav->bps > 0)
wav->end_offset =
uint64_ceiling_scale (stop, (guint64) wav->bps, GST_SECOND);
else if (wav->fact) {
guint64 bps =
gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact);
wav->end_offset = uint64_ceiling_scale (stop, bps, GST_SECOND);
} else
if (!gst_wavparse_time_to_bytepos (wav, stop, (gint64 *) & wav->end_offset))
wav->end_offset = stop;
GST_LOG_OBJECT (wav, "end_offset=%" G_GUINT64_FORMAT, wav->end_offset);
wav->end_offset -= (wav->end_offset % wav->bytes_per_sample);
@ -962,6 +1019,12 @@ no_format:
GST_DEBUG_OBJECT (wav, "unsupported format given, seek aborted.");
return FALSE;
}
no_position:
{
GST_DEBUG_OBJECT (wav,
"Could not determine byte position for desired time");
return FALSE;
}
}
/*
@ -1678,6 +1741,32 @@ iterate_adapter:
if (wav->streaming) {
guint avail = gst_adapter_available (wav->adapter);
guint extra;
/* flush some bytes if evil upstream sends segment that starts
* before data or does is not send sample aligned segment */
if (G_LIKELY (wav->offset >= wav->datastart)) {
extra = (wav->offset - wav->datastart) % wav->bytes_per_sample;
} else {
extra = wav->datastart - wav->offset;
}
if (G_UNLIKELY (extra)) {
extra = wav->bytes_per_sample - extra;
if (extra <= avail) {
GST_DEBUG_OBJECT (wav, "flushing %d bytes to sample boundary", extra);
gst_adapter_flush (wav->adapter, extra);
wav->offset += extra;
wav->dataleft -= extra;
goto iterate_adapter;
} else {
GST_DEBUG_OBJECT (wav, "flushing %d bytes", avail);
gst_adapter_clear (wav->adapter);
wav->offset += avail;
wav->dataleft -= avail;
return GST_FLOW_OK;
}
}
if (avail < desired) {
GST_LOG_OBJECT (wav, "Got only %d bytes of data from the sinkpad", avail);
@ -1927,6 +2016,8 @@ gst_wavparse_chain (GstPad * pad, GstBuffer * buf)
/* fall-through */
case GST_WAVPARSE_DATA:
if (buf && GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))
wav->discont = TRUE;
if ((ret = gst_wavparse_stream_data (wav)) != GST_FLOW_OK)
goto done;
break;
@ -1937,6 +2028,132 @@ done:
return ret;
}
static GstFlowReturn
gst_wavparse_flush_data (GstWavParse * wav)
{
GstFlowReturn ret = GST_FLOW_OK;
guint av;
if ((av = gst_adapter_available (wav->adapter)) > 0) {
wav->dataleft = av;
wav->end_offset = wav->offset + av;
ret = gst_wavparse_stream_data (wav);
}
return ret;
}
static gboolean
gst_wavparse_sink_event (GstPad * pad, GstEvent * event)
{
GstWavParse *wav = GST_WAVPARSE (GST_PAD_PARENT (pad));
gboolean ret = TRUE;
GST_LOG_OBJECT (wav, "handling %s event", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
{
GstFormat format;
gdouble rate, arate;
gint64 start, stop, time, offset = 0, end_offset = -1;
gboolean update;
GstSegment segment;
/* some debug output */
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);
GST_DEBUG_OBJECT (wav,
"received format %d newsegment %" GST_SEGMENT_FORMAT, format,
&segment);
if (wav->state != GST_WAVPARSE_DATA) {
GST_DEBUG_OBJECT (wav, "still starting, eating event");
goto exit;
}
/* now we are either committed to TIME or BYTE format,
* and we only expect a BYTE segment, e.g. following a seek */
if (format == GST_FORMAT_BYTES) {
if (start > 0) {
offset = start;
start -= wav->datastart;
start = MAX (start, 0);
}
if (stop > 0) {
end_offset = stop;
stop -= wav->datastart;
stop = MAX (stop, 0);
}
if (wav->segment.format == GST_FORMAT_TIME) {
guint64 bps = wav->bps;
/* operating in format TIME, so we can convert */
if (!bps && wav->fact)
bps =
gst_util_uint64_scale_int (wav->datasize, wav->rate, wav->fact);
if (bps) {
if (start >= 0)
start =
uint64_ceiling_scale (start, GST_SECOND, (guint64) wav->bps);
if (stop >= 0)
stop =
uint64_ceiling_scale (stop, GST_SECOND, (guint64) wav->bps);
}
}
} else {
GST_DEBUG_OBJECT (wav, "unsupported segment format, ignoring");
goto exit;
}
/* accept upstream's notion of segment and distribute along */
gst_segment_set_newsegment_full (&wav->segment, update, rate, arate,
wav->segment.format, start, stop, start);
/* also store the newsegment event for the streaming thread */
if (wav->start_segment)
gst_event_unref (wav->start_segment);
wav->start_segment =
gst_event_new_new_segment_full (update, rate, arate,
wav->segment.format, start, stop, start);
GST_DEBUG_OBJECT (wav, "Pushing newseg update %d, rate %g, "
"applied rate %g, format %d, start %" G_GINT64_FORMAT ", "
"stop %" G_GINT64_FORMAT, update, rate, arate, wav->segment.format,
start, stop);
/* stream leftover data in current segment */
gst_wavparse_flush_data (wav);
/* and set up streaming thread for next one */
wav->offset = offset;
wav->end_offset = end_offset;
if (wav->end_offset > 0) {
wav->dataleft = wav->end_offset - wav->offset;
} else {
/* infinity; upstream will EOS when done */
wav->dataleft = G_MAXUINT64;
}
exit:
gst_event_unref (event);
break;
}
case GST_EVENT_EOS:
/* stream leftover data in current segment */
gst_wavparse_flush_data (wav);
/* fall-through */
case GST_EVENT_FLUSH_STOP:
gst_adapter_clear (wav->adapter);
wav->discont = TRUE;
/* fall-through */
default:
ret = gst_pad_event_default (wav->sinkpad, event);
break;
}
return ret;
}
#if 0
/* convert and query stuff */
static const GstFormat *
@ -2089,6 +2306,8 @@ gst_wavparse_pad_query (GstPad * pad, GstQuery * query)
return FALSE;
}
GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
{
@ -2152,19 +2371,30 @@ gst_wavparse_pad_query (GstPad * pad, GstQuery * query)
}
case GST_QUERY_SEEKING:{
GstFormat fmt;
gboolean seekable = FALSE;
gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
if (fmt == GST_FORMAT_TIME) {
gboolean seekable = TRUE;
if ((wav->bps == 0) && !wav->fact) {
seekable = FALSE;
} else if (!gst_wavparse_calculate_duration (wav)) {
seekable = FALSE;
}
gst_query_set_seeking (query, GST_FORMAT_TIME, seekable,
0, wav->duration);
if (fmt == wav->segment.format) {
res = TRUE;
if (wav->streaming) {
GstQuery *q;
q = gst_query_new_seeking (GST_FORMAT_BYTES);
if ((res = gst_pad_peer_query (wav->sinkpad, q))) {
gst_query_parse_seeking (q, &fmt, &seekable, NULL, NULL);
GST_LOG_OBJECT (wav, "upstream BYTE seekable %d", seekable);
}
gst_query_unref (q);
} else {
GST_LOG_OBJECT (wav, "looping => seekable");
seekable = TRUE;
res = TRUE;
}
} else if (fmt == GST_FORMAT_TIME) {
res = TRUE;
}
if (res) {
gst_query_set_seeking (query, fmt, seekable, 0, wav->segment.duration);
}
break;
}