mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gst-libs/gst/audio/gstbaseaudiosink.*: Extract rate from the NEWSEGMENT event.
Original commit message from CVS: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_event), (gst_base_audio_sink_render): * gst-libs/gst/audio/gstbaseaudiosink.h: Extract rate from the NEWSEGMENT event. Use commit_full to also take rate adjustment into account when writing samples to the ringbuffer. * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_commit_full), (gst_ring_buffer_commit), (gst_ring_buffer_read): * gst-libs/gst/audio/gstringbuffer.h: Added _commit_full() to also take rate into account. Use simple interpolation algorithm to resample audio. API: gst_ring_buffer_commit_full() * tests/examples/seek/scrubby.c: (speed_cb), (do_seek): * tests/examples/seek/seek.c: (segment_done): Don't try to seek with 0.0 rate, just pause instead. Remove bogus debug line.
This commit is contained in:
parent
453f06075c
commit
1166abbc99
7 changed files with 311 additions and 61 deletions
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
|||
2006-10-18 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||
(gst_base_audio_sink_event), (gst_base_audio_sink_render):
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.h:
|
||||
Extract rate from the NEWSEGMENT event.
|
||||
Use commit_full to also take rate adjustment into account when writing
|
||||
samples to the ringbuffer.
|
||||
|
||||
* gst-libs/gst/audio/gstringbuffer.c:
|
||||
(gst_ring_buffer_commit_full), (gst_ring_buffer_commit),
|
||||
(gst_ring_buffer_read):
|
||||
* gst-libs/gst/audio/gstringbuffer.h:
|
||||
Added _commit_full() to also take rate into account.
|
||||
Use simple interpolation algorithm to resample audio.
|
||||
API: gst_ring_buffer_commit_full()
|
||||
|
||||
* tests/examples/seek/scrubby.c: (speed_cb), (do_seek):
|
||||
* tests/examples/seek/seek.c: (segment_done):
|
||||
Don't try to seek with 0.0 rate, just pause instead.
|
||||
Remove bogus debug line.
|
||||
|
||||
2006-10-18 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst/playback/gstplaybasebin.c: (subbin_startup_sync_msg),
|
||||
|
|
|
@ -441,6 +441,32 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
|
|||
/* now wait till we played everything */
|
||||
gst_base_audio_sink_drain (sink);
|
||||
break;
|
||||
case GST_EVENT_NEWSEGMENT:
|
||||
{
|
||||
gdouble rate;
|
||||
GValue src = { 0 };
|
||||
GValue dst = { 0 };
|
||||
|
||||
/* we only need the rate */
|
||||
gst_event_parse_new_segment_full (event, NULL, &rate, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_value_init (&src, G_TYPE_DOUBLE);
|
||||
g_value_set_double (&src, rate);
|
||||
g_value_init (&dst, GST_TYPE_FRACTION);
|
||||
g_value_transform (&src, &dst);
|
||||
g_value_unset (&src);
|
||||
|
||||
sink->abidata.ABI.rate_num = gst_value_get_fraction_numerator (&dst);
|
||||
sink->abidata.ABI.rate_denom = gst_value_get_fraction_denominator (&dst);
|
||||
sink->abidata.ABI.rate_accum = 0;
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "set rate to %f = %d / %d", rate,
|
||||
sink->abidata.ABI.rate_num, sink->abidata.ABI.rate_denom);
|
||||
|
||||
g_value_unset (&dst);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -513,9 +539,10 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
guint size;
|
||||
guint samples, written;
|
||||
gint bps;
|
||||
gdouble crate = 1.0;
|
||||
GstClockTime crate_num;
|
||||
GstClockTime crate_denom;
|
||||
gint rate_num;
|
||||
gint rate_denom;
|
||||
GstClockTime cinternal, cexternal;
|
||||
GstClock *clock;
|
||||
gboolean sync;
|
||||
|
@ -545,6 +572,9 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
"time %" GST_TIME_FORMAT ", offset %llu, start %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time), in_offset, GST_TIME_ARGS (bsink->segment.start));
|
||||
|
||||
rate_num = sink->abidata.ABI.rate_num;
|
||||
rate_denom = sink->abidata.ABI.rate_denom;
|
||||
|
||||
/* if not valid timestamp or we can't clip or sync, try to play
|
||||
* sample ASAP */
|
||||
if (!GST_CLOCK_TIME_IS_VALID (time)) {
|
||||
|
@ -606,12 +636,17 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
goto no_sync;
|
||||
}
|
||||
|
||||
gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
|
||||
&crate_num, &crate_denom);
|
||||
|
||||
/* bring buffer timestamp to running time */
|
||||
render_time =
|
||||
gst_segment_to_running_time (&bsink->segment, GST_FORMAT_TIME, time);
|
||||
GST_DEBUG_OBJECT (sink, "running time %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (render_time));
|
||||
|
||||
/* get calibration parameters to compensate for speed and offset differences
|
||||
* when we are slaved */
|
||||
gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
|
||||
&crate_num, &crate_denom);
|
||||
|
||||
/* add base time to get absolute clock time */
|
||||
render_time +=
|
||||
(gst_element_get_base_time (GST_ELEMENT_CAST (bsink)) - cexternal) +
|
||||
|
@ -621,7 +656,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
gst_util_uint64_scale_int (render_time, ringbuf->spec.rate, GST_SECOND);
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "render time %" GST_TIME_FORMAT
|
||||
", render offset %llu, samples %u",
|
||||
", render offset %" G_GUINT64_FORMAT ", samples %u",
|
||||
GST_TIME_ARGS (render_time), render_offset, samples);
|
||||
|
||||
/* never try to align samples when we are slaved to another clock, just
|
||||
|
@ -646,7 +681,10 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
}
|
||||
|
||||
/* now try to align the sample to the previous one */
|
||||
diff = ABS ((gint64) render_offset - (gint64) sink->next_sample);
|
||||
if (render_offset >= sink->next_sample)
|
||||
diff = render_offset - sink->next_sample;
|
||||
else
|
||||
diff = sink->next_sample - render_offset;
|
||||
|
||||
/* we tollerate half a second diff before we start resyncing. This
|
||||
* should be enough to compensate for various rounding errors in the timestamp
|
||||
|
@ -659,6 +697,8 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
/* just align with previous sample then */
|
||||
render_offset = sink->next_sample;
|
||||
} else {
|
||||
/* bring sample diff to seconds for error message */
|
||||
diff = gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate);
|
||||
/* timestamps drifted apart from previous samples too much, we need to
|
||||
* resync. We log this as an element warning. */
|
||||
GST_ELEMENT_WARNING (sink, CORE, CLOCK,
|
||||
|
@ -669,23 +709,47 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
}
|
||||
|
||||
no_align:
|
||||
/* crate contains diff against the clock we are using in the pipeline. */
|
||||
crate =
|
||||
gst_guint64_to_gdouble (crate_num) / gst_guint64_to_gdouble (crate_denom);
|
||||
/* check if we have a clock rate adjustment to do */
|
||||
if (crate_num != 1 || crate_num != 1) {
|
||||
gint64 num, denom;
|
||||
|
||||
/* make clock rate fit in int */
|
||||
while ((crate_num | crate_denom) > G_MAXINT) {
|
||||
crate_num /= 2;
|
||||
crate_denom /= 2;
|
||||
}
|
||||
/* full 64bit multiplication */
|
||||
num = ((gint64) crate_denom) * rate_num;
|
||||
denom = ((gint64) crate_num) * rate_denom;
|
||||
|
||||
/* make result fit in int again */
|
||||
while ((num | denom) > G_MAXINT) {
|
||||
num /= 2;
|
||||
denom /= 2;
|
||||
}
|
||||
rate_num = num;
|
||||
rate_denom = denom;
|
||||
|
||||
GST_DEBUG_OBJECT (sink,
|
||||
"internal %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT ", rate %g",
|
||||
cinternal, cexternal, crate);
|
||||
"clock rate: internal %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT
|
||||
" %d/%d", cinternal, cexternal, rate_num, rate_denom);
|
||||
}
|
||||
|
||||
no_sync:
|
||||
/* clip length based on rate */
|
||||
samples = MIN (samples, samples / (crate * bsink->segment.abs_rate));
|
||||
|
||||
/* the next sample should be current sample and its length */
|
||||
sink->next_sample = render_offset + samples;
|
||||
/* the next sample should be current sample and its length, this will be
|
||||
* updated as we write samples to the ringbuffer. */
|
||||
sink->next_sample = render_offset;
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "rendering at %" G_GUINT64_FORMAT, sink->next_sample);
|
||||
|
||||
do {
|
||||
written = gst_ring_buffer_commit (ringbuf, render_offset, data, samples);
|
||||
GST_DEBUG_OBJECT (sink, "wrote %u of %u", written, samples);
|
||||
written =
|
||||
gst_ring_buffer_commit_full (ringbuf, &sink->next_sample, data, samples,
|
||||
rate_num, rate_denom, &sink->abidata.ABI.rate_accum);
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "wrote %u of %u, resampled %" G_GUINT64_FORMAT,
|
||||
written, samples, sink->next_sample - render_offset);
|
||||
/* if we wrote all, we're done */
|
||||
if (written == samples)
|
||||
break;
|
||||
|
@ -694,11 +758,13 @@ no_sync:
|
|||
if (gst_base_sink_wait_preroll (bsink) != GST_FLOW_OK)
|
||||
goto stopping;
|
||||
|
||||
render_offset += written;
|
||||
samples -= written;
|
||||
data += written * bps;
|
||||
} while (TRUE);
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "next sample expected at %" G_GUINT64_FORMAT,
|
||||
sink->next_sample);
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (stop) && stop >= bsink->segment.stop) {
|
||||
GST_DEBUG_OBJECT (sink,
|
||||
"start playback because we are at the end of segment");
|
||||
|
|
|
@ -105,7 +105,15 @@ struct _GstBaseAudioSink {
|
|||
GstClock *provided_clock;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
union {
|
||||
struct {
|
||||
gint rate_num;
|
||||
gint rate_denom;
|
||||
gint rate_accum;
|
||||
} ABI;
|
||||
/* adding + 0 to mark ABI change to be undone later */
|
||||
gpointer _gst_reserved[GST_PADDING + 0];
|
||||
} abidata;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1174,54 +1174,155 @@ no_start:
|
|||
}
|
||||
}
|
||||
|
||||
#define FWD_SAMPLES(s,se,d,de) \
|
||||
G_STMT_START { \
|
||||
/* no rate conversion */ \
|
||||
guint towrite = MIN (se + bps - s, de - d); \
|
||||
/* simple copy */ \
|
||||
if (!skip) \
|
||||
memcpy (d, s, towrite); \
|
||||
*sample += towrite / bps; \
|
||||
s += towrite; \
|
||||
GST_DEBUG ("copy %u bytes", towrite); \
|
||||
} G_STMT_END
|
||||
|
||||
#define FWD_UP_SAMPLES(s,se,d,de) \
|
||||
G_STMT_START { \
|
||||
guint8 *ds = d; \
|
||||
while (s <= se && d < de) { \
|
||||
if (!skip) \
|
||||
memcpy (d, s, bps); \
|
||||
s += bps; \
|
||||
*accum += denom; \
|
||||
while (*accum > 0) { \
|
||||
*accum -= num; \
|
||||
d += bps; \
|
||||
} \
|
||||
} \
|
||||
*sample += (d - ds) / bps; \
|
||||
GST_DEBUG ("fwd_up %u bytes", d - ds); \
|
||||
} G_STMT_END
|
||||
|
||||
#define FWD_DOWN_SAMPLES(s,se,d,de) \
|
||||
G_STMT_START { \
|
||||
guint8 *ds = d; \
|
||||
while (s <= se && d < de) { \
|
||||
if (!skip) \
|
||||
memcpy (d, s, bps); \
|
||||
d += bps; \
|
||||
*accum -= num; \
|
||||
while (*accum < 0) { \
|
||||
*accum += denom; \
|
||||
s += bps; \
|
||||
} \
|
||||
} \
|
||||
*sample += (d - ds) / bps; \
|
||||
GST_DEBUG ("fwd_down %u bytes", d - ds); \
|
||||
} G_STMT_END
|
||||
|
||||
#define REV_UP_SAMPLES(s,se,d,de) \
|
||||
G_STMT_START { \
|
||||
guint8 *ds = d; \
|
||||
while (s <= se && d < de) { \
|
||||
if (!skip) \
|
||||
memcpy (d, se, bps); \
|
||||
se -= bps; \
|
||||
*accum += denom; \
|
||||
while (*accum > 0) { \
|
||||
*accum += num; \
|
||||
d += bps; \
|
||||
} \
|
||||
} \
|
||||
*sample += (d - ds) / bps; \
|
||||
GST_DEBUG ("rev_up %u bytes", d - ds); \
|
||||
} G_STMT_END
|
||||
|
||||
#define REV_DOWN_SAMPLES(s,se,d,de) \
|
||||
G_STMT_START { \
|
||||
guint8 *ds = d; \
|
||||
while (s <= se && d < de) { \
|
||||
if (!skip) \
|
||||
memcpy (d, se, bps); \
|
||||
d += bps; \
|
||||
*accum += num; \
|
||||
while (*accum < 0) { \
|
||||
*accum += denom; \
|
||||
se -= bps; \
|
||||
} \
|
||||
} \
|
||||
*sample += (d - ds) / bps; \
|
||||
GST_DEBUG ("rev_down %u bytes", d - ds); \
|
||||
} G_STMT_END
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_commit:
|
||||
* gst_ring_buffer_commit_full:
|
||||
* @buf: the #GstRingBuffer to commit
|
||||
* @sample: the sample position of the data
|
||||
* @data: the data to commit
|
||||
* @len: the number of samples in the data to commit
|
||||
* @num: the numerator of the speed
|
||||
* @denom: the denominator of the speed
|
||||
* @accum: accumulator for rate conversion.
|
||||
*
|
||||
* Commit @len samples pointed to by @data to the ringbuffer
|
||||
* @buf. The first sample should be written at position @sample in
|
||||
* the ringbuffer.
|
||||
* Commit @len samples pointed to by @data to the ringbuffer @buf.
|
||||
*
|
||||
* @len does not need to be a multiple of the segment size of the ringbuffer
|
||||
* although it is recommended for optimal performance.
|
||||
* @num and @denom define the rate conversion to perform on the the samples in
|
||||
* @data. For negative rates, @num must be negative and @denom positive.
|
||||
*
|
||||
* Returns: The number of samples written to the ringbuffer or -1 on
|
||||
* error.
|
||||
* When @num is positive, the first sample will be written at position @sample
|
||||
* in the ringbuffer. When @num is negative, the last sample will be written to
|
||||
* @sample in reverse order.
|
||||
*
|
||||
* @len does not need to be a multiple of the segment size of the ringbuffer (if
|
||||
* @num and @denom are both 1) although it is recommended for optimal performance.
|
||||
*
|
||||
* @sample will be updated with the next position in the ringbuffer. This
|
||||
* position will take into account any resampling done when writing the samples.
|
||||
*
|
||||
* Returns: The number of samples written to the ringbuffer or -1 on error. The
|
||||
* number of samples written can be less than @len when @buf was interrupted
|
||||
* with a flush or stop.
|
||||
*
|
||||
* Since: 0.10.11.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
guint
|
||||
gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
||||
guint len)
|
||||
gst_ring_buffer_commit_full (GstRingBuffer * buf, guint64 * sample,
|
||||
guchar * data, guint len, gint num, gint denom, gint * accum)
|
||||
{
|
||||
gint segdone;
|
||||
gint segsize, segtotal, bps, sps;
|
||||
guint8 *dest;
|
||||
guint to_write;
|
||||
guint8 *dest, *data_end;
|
||||
gint writeseg, sampleoff;
|
||||
|
||||
if (G_UNLIKELY (len == 0))
|
||||
return 0;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
|
||||
g_return_val_if_fail (buf->data != NULL, -1);
|
||||
g_return_val_if_fail (data != NULL, -1);
|
||||
g_return_val_if_fail (denom != 0, -1);
|
||||
|
||||
dest = GST_BUFFER_DATA (buf->data);
|
||||
segsize = buf->spec.segsize;
|
||||
segtotal = buf->spec.segtotal;
|
||||
bps = buf->spec.bytes_per_sample;
|
||||
sps = buf->samples_per_seg;
|
||||
|
||||
to_write = len;
|
||||
/* write out all samples */
|
||||
while (to_write > 0) {
|
||||
gint sampleslen;
|
||||
gint writeseg, sampleoff;
|
||||
/* data_end points to the last sample we have to write, not past it. */
|
||||
data_end = data + (bps * (len - 1));
|
||||
|
||||
/* figure out the segment and the offset inside the segment where
|
||||
* the sample should be written. */
|
||||
writeseg = sample / sps;
|
||||
sampleoff = (sample % sps);
|
||||
* the first sample should be written. */
|
||||
writeseg = *sample / sps;
|
||||
sampleoff = (*sample % sps) * bps;
|
||||
|
||||
/* write out all samples */
|
||||
while (data <= data_end) {
|
||||
gint avail;
|
||||
guint8 *d, *d_end;
|
||||
gint ws;
|
||||
gboolean skip;
|
||||
|
||||
while (TRUE) {
|
||||
gint diff;
|
||||
|
@ -1233,22 +1334,23 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
diff = writeseg - segdone;
|
||||
|
||||
GST_DEBUG
|
||||
("pointer at %d, sample %llu, write to %d-%d, to_write %d, diff %d, segtotal %d, segsize %d",
|
||||
segdone, sample, writeseg, sampleoff, to_write, diff, segtotal,
|
||||
segsize);
|
||||
("pointer at %d, write to %d-%d, diff %d, segtotal %d, segsize %d",
|
||||
segdone, writeseg, sampleoff, diff, segtotal, segsize);
|
||||
|
||||
/* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
|
||||
if (G_UNLIKELY (diff < 0)) {
|
||||
/* we need to drop one segment at a time, pretend we wrote a
|
||||
* segment. */
|
||||
sampleslen = MIN (sps, to_write);
|
||||
goto next;
|
||||
skip = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* write segment is within writable range, we can break the loop and
|
||||
* start writing the data. */
|
||||
if (diff < segtotal)
|
||||
if (diff < segtotal) {
|
||||
skip = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* else we need to wait for the segment to become writable. */
|
||||
if (!wait_segment (buf))
|
||||
|
@ -1256,31 +1358,77 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
}
|
||||
|
||||
/* we can write now */
|
||||
writeseg = writeseg % segtotal;
|
||||
sampleslen = MIN (sps - sampleoff, to_write);
|
||||
ws = writeseg % segtotal;
|
||||
avail = segsize - sampleoff;
|
||||
|
||||
GST_DEBUG_OBJECT (buf, "write @%p seg %d, off %d, sampleslen %d",
|
||||
dest + writeseg * segsize, writeseg, sampleoff, sampleslen);
|
||||
d = dest + (ws * segsize) + sampleoff;
|
||||
d_end = d + avail;
|
||||
|
||||
memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data,
|
||||
(sampleslen * bps));
|
||||
GST_DEBUG_OBJECT (buf, "write @%p seg %d, sps %d, off %d, avail %d",
|
||||
dest + ws * segsize, ws, sps, sampleoff, avail);
|
||||
|
||||
next:
|
||||
to_write -= sampleslen;
|
||||
sample += sampleslen;
|
||||
data += sampleslen * bps;
|
||||
if (G_LIKELY (num == 1 && denom == 1)) {
|
||||
/* no rate conversion, simply copy samples */
|
||||
FWD_SAMPLES (data, data_end, d, d_end);
|
||||
} else if (num >= 0) {
|
||||
if (num >= denom)
|
||||
/* forward speed up */
|
||||
FWD_UP_SAMPLES (data, data_end, d, d_end);
|
||||
else
|
||||
/* forward slow down */
|
||||
FWD_DOWN_SAMPLES (data, data_end, d, d_end);
|
||||
} else {
|
||||
if (-num >= denom)
|
||||
/* reverse speed up */
|
||||
REV_UP_SAMPLES (data, data_end, d, d_end);
|
||||
else
|
||||
/* reverse slow down */
|
||||
REV_DOWN_SAMPLES (data, data_end, d, d_end);
|
||||
}
|
||||
|
||||
return len - to_write;
|
||||
/* for the next iteration we write to the next segment at the beginning. */
|
||||
writeseg++;
|
||||
sampleoff = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
return (len - 1) - ((data_end - data) / bps);
|
||||
|
||||
/* ERRORS */
|
||||
not_started:
|
||||
{
|
||||
GST_DEBUG_OBJECT (buf, "stopped processing");
|
||||
return len - to_write;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_commit:
|
||||
* @buf: the #GstRingBuffer to commit
|
||||
* @sample: the sample position of the data
|
||||
* @data: the data to commit
|
||||
* @len: the number of samples in the data to commit
|
||||
*
|
||||
* Same as gst_ring_buffer_commit_full() but with a num, denom of 1, ignoring
|
||||
* accum.
|
||||
*
|
||||
* Returns: The number of samples written to the ringbuffer or -1 on
|
||||
* error.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
guint
|
||||
gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
||||
guint len)
|
||||
{
|
||||
guint res;
|
||||
guint64 spos = sample;
|
||||
|
||||
res = gst_ring_buffer_commit_full (buf, &spos, data, len, 1, 1, NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_read:
|
||||
* @buf: the #GstRingBuffer to read from
|
||||
|
|
|
@ -337,6 +337,9 @@ void gst_ring_buffer_clear_all (GstRingBuffer *buf);
|
|||
/* commit samples */
|
||||
guint gst_ring_buffer_commit (GstRingBuffer *buf, guint64 sample,
|
||||
guchar *data, guint len);
|
||||
guint gst_ring_buffer_commit_full (GstRingBuffer *buf, guint64 *sample,
|
||||
guchar *data, guint len,
|
||||
gint num, gint denom, gint *accum);
|
||||
/* read samples */
|
||||
guint gst_ring_buffer_read (GstRingBuffer *buf, guint64 sample,
|
||||
guchar *data, guint len);
|
||||
|
|
|
@ -177,6 +177,9 @@ speed_cb (GtkWidget * widget)
|
|||
GST_DEBUG ("speed change");
|
||||
cur_speed = gtk_range_get_value (GTK_RANGE (widget));
|
||||
|
||||
if (cur_speed == 0.0)
|
||||
return;
|
||||
|
||||
s_event = gst_event_new_seek (cur_speed,
|
||||
GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
|
||||
|
||||
|
@ -265,6 +268,8 @@ do_seek (GtkWidget * widget, gboolean flush, gboolean segment)
|
|||
stop = tmp;
|
||||
}
|
||||
|
||||
if (rate == 0.0)
|
||||
return TRUE;
|
||||
|
||||
GST_DEBUG ("seek to %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT ", rate %lf"
|
||||
" on element %s",
|
||||
|
|
|
@ -1330,8 +1330,6 @@ segment_done (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
|
|||
event = gst_event_new_seek (rate,
|
||||
GST_FORMAT_TIME, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1);
|
||||
|
||||
GST_DEBUG ("segmeent seek to start");
|
||||
|
||||
res = send_event (event);
|
||||
if (!res) {
|
||||
g_print ("segment seek failed\n");
|
||||
|
|
Loading…
Reference in a new issue