+2005-08-25 Thomas Vander Stichele <thomas at apestaart dot org>
+
+ * gst/audioresample/debug.c:
+ * gst/audioresample/gstaudioresample.c:
+ add room for extra overlap samples when asked to transform size
+ protect against possible mem corruption and check for discrepancies
+ between written size and outbuffer's size so we can warn for
+ potential problems
+ * gst/audioresample/resample.c: (resample_init),
+ (resample_get_output_size_for_input), (resample_get_output_size),
+ (resample_set_n_channels), (resample_set_format):
+ set debug level based on RESAMPLE_DEBUG env var
+ make sure that get_output_size* returns a whole number of
+ sample_size
+ set sample_size each time either channel or format is set
+ * gst/audioresample/resample_chunk.c: (resample_scale_chunk):
+ * gst/audioresample/resample_functable.c:
+ (resample_scale_functable):
+ * gst/audioresample/resample_ref.c: (resample_scale_ref):
+ remove r->sample_size, it's done in resample.c now
+ add some debugging to the ref implementation
+ make sure we only give back bytes that are wholes of the sample
+ size
+
2005-08-25 Jan Schmidt <thaytan@mad.scientist.com>
* gst/playback/gstplaybasebin.c: (fill_buffer):
Revert unpopular change for GST_MESSAGE_SRC to GObject.
2005-08-25 Stefan Kost <ensonic@users.sf.net>
* gst/volume/gstvolume.c:
- made set_caps function static
+ made set_caps function static
2005-08-24 Wim Taymans <wim@fluendo.com>
2005-08-24 Thomas Vander Stichele <thomas at apestaart dot org>
* check/Makefile.am:
+ * configure.ac:
+ add core's plugins to the mix so that playbin works
+ * check/generic/states.c: (GST_START_TEST):
+ set a 0 timeout on pipelines, so they don't force the next
+ state change
+ * gst/playback/gstplaybasebin.c: (setup_source), (prepare_output),
+ (gst_play_base_bin_change_state):
+ remove the crappy error handling and do GST error handling
+
+2005-08-24 Thomas Vander Stichele <thomas at apestaart dot org>
+
+ * check/Makefile.am:
* check/generic/states.c: (GST_START_TEST), (states_suite), (main):
add same test as to core, it bitches out on playbin atm.
};
#define SUPPORTED_CAPS \
- GST_STATIC_CAPS (\
+GST_STATIC_CAPS ( \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, MAX ], " \
"endianness = (int) BYTE_ORDER, " \
"width = (int) 16, " \
"depth = (int) 16, " \
- "signed = (boolean) true")
+ "signed = (boolean) true " \
+)
#if 0
/* disabled because it segfaults */
return TRUE;
}
-gboolean audioresample_transform_size (GstBaseTransform * base,
+gboolean
+ audioresample_transform_size (GstBaseTransform * base,
GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
- guint * othersize)
-{
+ guint * othersize) {
GstAudioresample *audioresample = GST_AUDIORESAMPLE (base);
ResampleState *state;
GstCaps *srccaps, *sinkcaps;
gboolean use_internal = FALSE; /* whether we use the internal state */
gboolean ret = TRUE;
- /* FIXME: make sure incaps/outcaps get renamed to caps/othercaps, since
- * interpretation depends on the direction */
+ GST_DEBUG_OBJECT (base, "asked to transform size %d in direction %s",
+ size, direction == GST_PAD_SINK ? "SINK" : "SRC");
if (direction == GST_PAD_SINK) {
sinkcaps = caps;
srccaps = othercaps;
use_internal = TRUE;
state = audioresample->resample;
} else {
+ GST_DEBUG_OBJECT (audioresample,
+ "caps are not the set caps, creating state");
state = resample_new ();
resample_set_state_from_caps (state, sinkcaps, srccaps, NULL, NULL, NULL);
}
- /* we can use our own state to answer the question */
if (direction == GST_PAD_SINK) {
/* asked to convert size of an incoming buffer */
*othersize = resample_get_output_size_for_input (state, size);
/* take a best guess, this is called cheating */
*othersize = floor (size * state->i_rate / state->o_rate);
}
+ *othersize += state->sample_size;
+
+ /* we make room for one extra sample, given that the resampling filter
+ * can output an extra one for non-integral i_rate/o_rate */
+ GST_DEBUG_OBJECT (base, "transformed size %d to %d", size, *othersize);
if (!use_internal) {
resample_free (state);
return ret;
}
-gboolean audioresample_set_caps (GstBaseTransform * base, GstCaps * incaps,
- GstCaps * outcaps)
-{
+gboolean
+ audioresample_set_caps (GstBaseTransform * base, GstCaps * incaps,
+ GstCaps * outcaps) {
gboolean ret;
gint inrate, outrate;
int channels;
resample_add_input_data (r, data, size, NULL, NULL);
outsize = resample_get_output_size (r);
- if (outsize != GST_BUFFER_SIZE (outbuf)) {
+ GST_DEBUG_OBJECT (audioresample, "audioresample can give me %d bytes",
+ outsize);
+
+ /* protect against mem corruption */
+ if (outsize > GST_BUFFER_SIZE (outbuf)) {
GST_WARNING_OBJECT (audioresample,
"overriding audioresample's outsize %d with outbuffer's size %d",
outsize, GST_BUFFER_SIZE (outbuf));
outsize = GST_BUFFER_SIZE (outbuf);
}
+ /* catch possibly wrong size differences */
+ if (GST_BUFFER_SIZE (outbuf) - outsize > r->sample_size) {
+ GST_WARNING_OBJECT (audioresample,
+ "audioresample's outsize %d too far from outbuffer's size %d",
+ outsize, GST_BUFFER_SIZE (outbuf));
+ }
outsize = resample_get_output_data (r, GST_BUFFER_DATA (outbuf), outsize);
GST_BUFFER_TIMESTAMP (outbuf) =
audioresample->offset * GST_SECOND / audioresample->o_rate;
audioresample->offset += outsize / sizeof (gint16) / audioresample->channels;
+ GST_BUFFER_DURATION (outbuf) = outsize * GST_SECOND / audioresample->o_rate;
- if (outsize != GST_BUFFER_SIZE (outbuf)) {
+ /* check for possible mem corruption */
+ if (outsize > GST_BUFFER_SIZE (outbuf)) {
+ /* this is an error that when it happens, would need fixing in the
+ * resample library; we told
+ * it we wanted only GST_BUFFER_SIZE (outbuf), and it gave us more ! */
+ GST_WARNING_OBJECT (audioresample,
+ "audioresample, you memory corrupting bastard. "
+ "you gave me outsize %d while my buffer was size %d",
+ outsize, GST_BUFFER_SIZE (outbuf));
+ return GST_FLOW_ERROR;
+ }
+ /* catch possibly wrong size differences */
+ if (GST_BUFFER_SIZE (outbuf) - outsize > r->sample_size) {
GST_WARNING_OBJECT (audioresample,
- "audioresample, you bastard ! you only gave me %d bytes, not %d",
+ "audioresample's written outsize %d too far from outbuffer's size %d",
outsize, GST_BUFFER_SIZE (outbuf));
- /* if the size we get is smaller than the buffer, it's still fine; we
- * just waste a bit of space on the end */
- if (outsize < GST_BUFFER_SIZE (outbuf)) {
- GST_BUFFER_SIZE (outbuf) = outsize;
- return GST_FLOW_OK;
- } else {
- /* this is an error that needs fixing in the resample library; we told
- * it we wanted only GST_BUFFER_SIZE (outbuf), and it gave us more ! */
- return GST_FLOW_ERROR;
- }
}
return GST_FLOW_OK;
switch (prop_id) {
case ARG_FILTERLEN:
audioresample->filter_length = g_value_get_int (value);
- GST_DEBUG_OBJECT (GST_ELEMENT (audioresample), "new filter length %d\n",
+ GST_DEBUG_OBJECT (GST_ELEMENT (audioresample), "new filter length %d",
audioresample->filter_length);
resample_set_filter_length (audioresample->resample,
audioresample->filter_length);
resample_init (void)
{
static int inited = 0;
+ const char *debug;
if (!inited) {
oil_init ();
inited = 1;
}
+
+ if ((debug = g_getenv ("RESAMPLE_DEBUG"))) {
+ resample_debug_set_level (atoi (debug));
+ }
}
ResampleState *
int
resample_get_output_size_for_input (ResampleState * r, int size)
{
- return floor (size * r->o_rate / r->i_rate);
+ int outsize;
+ double outd;
+
+ g_return_val_if_fail (r->sample_size != 0, 0);
+
+ RESAMPLE_DEBUG ("size %d, o_rate %f, i_rate %f", size, r->o_rate, r->i_rate);
+ outd = (double) size / r->i_rate * r->o_rate;
+ outsize = (int) floor (outd);
+
+ /* round off for sample size */
+ return outsize - (outsize % r->sample_size);
}
int
resample_get_output_size (ResampleState * r)
{
- return floor (audioresample_buffer_queue_get_depth (r->queue) * r->o_rate /
- r->i_rate);
+ return resample_get_output_size_for_input (r,
+ audioresample_buffer_queue_get_depth (r->queue));
}
int
resample_set_n_channels (ResampleState * r, int n_channels)
{
r->n_channels = n_channels;
+ r->sample_size = r->n_channels * resample_format_size (r->format);
r->need_reinit = 1;
}
resample_set_format (ResampleState * r, ResampleFormat format)
{
r->format = format;
+ r->sample_size = r->n_channels * resample_format_size (r->format);
r->need_reinit = 1;
}
resample_scale_ref (ResampleState * r)
{
if (r->need_reinit) {
- r->sample_size = r->n_channels * resample_format_size (r->format);
RESAMPLE_DEBUG ("sample size %d", r->sample_size);
if (r->buffer)
#endif
}
- while (r->o_size > 0) {
+ RESAMPLE_DEBUG ("asked to resample %d bytes", r->o_size);
+
+ while (r->o_size >= r->sample_size) {
double midpoint;
int i;
int j;
- RESAMPLE_DEBUG ("i_start %g", r->i_start);
midpoint = r->i_start + (r->filter_length - 1) * 0.5 * r->i_inc;
+ RESAMPLE_DEBUG ("still need to output %d bytes, i_start %g, midpoint %f",
+ r->o_size, r->i_start, midpoint);
if (midpoint > 0.5 * r->i_inc) {
RESAMPLE_ERROR ("inconsistent state");
}
while (midpoint < -0.5 * r->i_inc) {
AudioresampleBuffer *buffer;
+ RESAMPLE_DEBUG ("midpoint %f < %f, r->i_inc %f", midpoint,
+ -0.5 * r->i_inc, r->i_inc);
buffer = audioresample_buffer_queue_pull (r->queue, r->sample_size);
if (buffer == NULL) {
RESAMPLE_ERROR ("buffer_queue_pull returned NULL");
r->o_buf += r->sample_size;
r->o_size -= r->sample_size;
}
-
}