mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
gst-libs/gst/audio/gstbaseaudiosink.c: Use scale functions when possible.
Original commit message from CVS: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_get_time), (gst_base_audio_sink_setcaps), (gst_base_audio_sink_drain), (gst_base_audio_sink_preroll), (gst_base_audio_sink_render), (gst_base_audio_sink_change_state): Use scale functions when possible. Fix error messages. Free clockid when after waiting for EOS. Use G_(UN_)LIKLY when it makes sense. Fix sample clipping bug found by Arwed v. Merkatz fixes #330789.
This commit is contained in:
parent
50951316a5
commit
0be7d56eb9
2 changed files with 50 additions and 19 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2006-02-12 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||
(gst_base_audio_sink_get_time), (gst_base_audio_sink_setcaps),
|
||||
(gst_base_audio_sink_drain), (gst_base_audio_sink_preroll),
|
||||
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
|
||||
Use scale functions when possible.
|
||||
Fix error messages.
|
||||
Free clockid when after waiting for EOS.
|
||||
Use G_(UN_)LIKLY when it makes sense.
|
||||
Fix sample clipping bug found by Arwed v. Merkatz fixes #330789.
|
||||
|
||||
2006-02-12 Edward Hervey <edward@fluendo.com>
|
||||
|
||||
* gst/playback/gstplaybasebin.c: (prepare_output):
|
||||
|
|
|
@ -218,7 +218,8 @@ gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink)
|
|||
/* our processed samples are always increasing */
|
||||
samples = gst_ring_buffer_samples_done (sink->ringbuffer);
|
||||
|
||||
result = samples * GST_SECOND / sink->ringbuffer->spec.rate;
|
||||
result = gst_util_uint64_scale_int (samples, GST_SECOND,
|
||||
sink->ringbuffer->spec.rate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -320,7 +321,7 @@ parse_error:
|
|||
{
|
||||
GST_DEBUG_OBJECT (sink, "could not parse caps");
|
||||
GST_ELEMENT_ERROR (sink, STREAM, FORMAT,
|
||||
("cannot parse audio format."), ("cannot parse audio format."));
|
||||
(NULL), ("cannot parse audio format."));
|
||||
return FALSE;
|
||||
}
|
||||
acquire_error:
|
||||
|
@ -340,6 +341,9 @@ gst_base_audio_sink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
|
|||
*end = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
/* FIXME, this waits for the drain to happen but it cannot be
|
||||
* canceled.
|
||||
*/
|
||||
static gboolean
|
||||
gst_base_audio_sink_drain (GstBaseAudioSink * sink)
|
||||
{
|
||||
|
@ -364,6 +368,8 @@ gst_base_audio_sink_drain (GstBaseAudioSink * sink)
|
|||
|
||||
GST_DEBUG_OBJECT (sink, "waiting for last sample to play");
|
||||
gst_clock_id_wait (id, NULL);
|
||||
|
||||
gst_clock_id_unref (id);
|
||||
sink->next_sample = -1;
|
||||
} else {
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
|
@ -414,8 +420,7 @@ gst_base_audio_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
|
|||
wrong_state:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sink, "ringbuffer in wrong state");
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
|
||||
("sink not negotiated."), ("sink not negotiated."));
|
||||
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +474,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
|
||||
sink = GST_BASE_AUDIO_SINK (bsink);
|
||||
|
||||
if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
|
||||
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
|
||||
/* always resync after a discont */
|
||||
sink->next_sample = -1;
|
||||
}
|
||||
|
@ -477,13 +482,13 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
ringbuf = sink->ringbuffer;
|
||||
|
||||
/* can't do anything when we don't have the device */
|
||||
if (!gst_ring_buffer_is_acquired (ringbuf))
|
||||
if (G_UNLIKELY (!gst_ring_buffer_is_acquired (ringbuf)))
|
||||
goto wrong_state;
|
||||
|
||||
bps = ringbuf->spec.bytes_per_sample;
|
||||
|
||||
size = GST_BUFFER_SIZE (buf);
|
||||
if (size % bps != 0)
|
||||
if (G_UNLIKELY (size % bps) != 0)
|
||||
goto wrong_size;
|
||||
|
||||
samples = size / bps;
|
||||
|
@ -524,15 +529,17 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
/* see if some clipping happened */
|
||||
diff = ctime - time;
|
||||
if (diff > 0) {
|
||||
/* bring clipped time to samples */
|
||||
diff = gst_util_uint64_scale_int (diff, ringbuf->spec.rate, GST_SECOND);
|
||||
GST_DEBUG_OBJECT (sink, "clipping start to %" GST_TIME_FORMAT " %"
|
||||
G_GUINT64_FORMAT " samples", GST_TIME_ARGS (ctime), diff);
|
||||
samples -= diff;
|
||||
data += samples * bps;
|
||||
data += diff * bps;
|
||||
time = ctime;
|
||||
}
|
||||
diff = stop - cstop;
|
||||
if (diff > 0) {
|
||||
/* bring clipped time to samples */
|
||||
diff = gst_util_uint64_scale_int (diff, ringbuf->spec.rate, GST_SECOND);
|
||||
GST_DEBUG_OBJECT (sink, "clipping stop to %" GST_TIME_FORMAT " %"
|
||||
G_GUINT64_FORMAT " samples", GST_TIME_ARGS (cstop), diff);
|
||||
|
@ -559,7 +566,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
GST_TIME_ARGS (render_time), render_offset, samples);
|
||||
|
||||
/* roundoff errors in timestamp conversion */
|
||||
if (sink->next_sample != -1) {
|
||||
if (G_LIKELY (sink->next_sample != -1)) {
|
||||
diff = ABS ((gint64) render_offset - (gint64) sink->next_sample);
|
||||
|
||||
/* we tollerate a 10th of a second diff before we start resyncing. This
|
||||
|
@ -622,6 +629,7 @@ no_sync:
|
|||
|
||||
return GST_FLOW_OK;
|
||||
|
||||
/* SPECIAL cases */
|
||||
out_of_segment:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sink,
|
||||
|
@ -630,19 +638,18 @@ out_of_segment:
|
|||
GST_TIME_ARGS (bsink->segment.start));
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
/* ERRORS */
|
||||
wrong_state:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sink, "ringbuffer not negotiated");
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
|
||||
("sink not negotiated."), ("sink not negotiated."));
|
||||
GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
wrong_size:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sink, "wrong size");
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
|
||||
("sink received buffer of wrong size."),
|
||||
("sink received buffer of wrong size."));
|
||||
GST_ELEMENT_ERROR (sink, STREAM, WRONG_TYPE,
|
||||
(NULL), ("sink received buffer of wrong size."));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
stopping:
|
||||
|
@ -690,7 +697,7 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
gst_base_audio_sink_callback, sink);
|
||||
}
|
||||
if (!gst_ring_buffer_open_device (sink->ringbuffer))
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
goto open_failed;
|
||||
sink->next_sample = 0;
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
|
@ -699,20 +706,25 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockTime time, base;
|
||||
|
||||
/* FIXME, only start slaving when we really start the ringbuffer */
|
||||
GST_OBJECT_LOCK (sink);
|
||||
clock = GST_ELEMENT_CLOCK (sink);
|
||||
if (clock == NULL)
|
||||
goto no_clock;
|
||||
|
||||
/* FIXME, only start slaving when we really start the ringbuffer */
|
||||
/* if we are slaved to a clock, we need to set the initial
|
||||
* calibration */
|
||||
if (clock != sink->provided_clock) {
|
||||
GstClockTime time;
|
||||
GstClockTime rate_num, rate_denom;
|
||||
|
||||
base = element->base_time;
|
||||
time = gst_clock_get_internal_time (sink->provided_clock);
|
||||
|
||||
GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time));
|
||||
GST_DEBUG_OBJECT (sink,
|
||||
"time: %" GST_TIME_FORMAT " base: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time), GST_TIME_ARGS (base));
|
||||
|
||||
gst_clock_set_master (sink->provided_clock, clock);
|
||||
/* FIXME, this is not yet accurate enough for smooth playback */
|
||||
|
@ -722,6 +734,7 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
gst_clock_set_calibration (sink->provided_clock,
|
||||
time, element->base_time, rate_num, rate_denom);
|
||||
}
|
||||
no_clock:
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
break;
|
||||
}
|
||||
|
@ -754,4 +767,10 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
}
|
||||
|
||||
return ret;
|
||||
|
||||
open_failed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (sink, "open failed");
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue