mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 16:35:40 +00:00
get rid of bytestreams
Original commit message from CVS: get rid of bytestreams
This commit is contained in:
parent
7b30d7b9a4
commit
b5a22d8630
2 changed files with 67 additions and 61 deletions
|
@ -109,7 +109,7 @@ static void gst_alsa_sink_loop (GstElement *element);
|
||||||
static void gst_alsa_src_loop (GstElement *element);
|
static void gst_alsa_src_loop (GstElement *element);
|
||||||
static void gst_alsa_xrun_recovery (GstAlsa *this);
|
static void gst_alsa_xrun_recovery (GstAlsa *this);
|
||||||
|
|
||||||
static gboolean gst_alsa_sink_check_event (GstAlsa *this, gint pad_nr);
|
static gboolean gst_alsa_sink_check_event (GstAlsa *this, gint pad_nr, GstEvent *event);
|
||||||
|
|
||||||
/* alsa setup / start / stop functions */
|
/* alsa setup / start / stop functions */
|
||||||
static gboolean gst_alsa_probe_hw_params (GstAlsa *this, GstAlsaFormat *format);
|
static gboolean gst_alsa_probe_hw_params (GstAlsa *this, GstAlsaFormat *format);
|
||||||
|
@ -270,10 +270,10 @@ gst_alsa_class_init (GstAlsaClass *klass)
|
||||||
2, 64, 2, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
2, 64, 2, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PERIODSIZE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PERIODSIZE,
|
||||||
g_param_spec_int ("period-size", "Period size", "Number of frames (samples on each channel) in one hardware period",
|
g_param_spec_int ("period-size", "Period size", "Number of frames (samples on each channel) in one hardware period",
|
||||||
64, 8192, 8192, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
2, 8192, 8192, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFERSIZE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFFERSIZE,
|
||||||
g_param_spec_int ("buffer-size", "Buffer size", "Number of frames the hardware buffer can hold",
|
g_param_spec_int ("buffer-size", "Buffer size", "Number of frames the hardware buffer can hold",
|
||||||
128, 65536, 16384, G_PARAM_READWRITE));
|
4, 65536, 16384, G_PARAM_READWRITE));
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_AUTORECOVER,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_AUTORECOVER,
|
||||||
g_param_spec_boolean ("autorecover", "Automatic xrun recovery", "When TRUE tries to reduce processor load on xruns",
|
g_param_spec_boolean ("autorecover", "Automatic xrun recovery", "When TRUE tries to reduce processor load on xruns",
|
||||||
TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||||
|
@ -292,6 +292,12 @@ gst_alsa_init (GstAlsa *this)
|
||||||
/* init values */
|
/* init values */
|
||||||
this->handle = NULL;
|
this->handle = NULL;
|
||||||
this->transmit = NULL;
|
this->transmit = NULL;
|
||||||
|
for (i = 0; i < GST_ALSA_MAX_CHANNELS; i++) {
|
||||||
|
this->pads[i].pad = NULL;
|
||||||
|
this->pads[i].data = NULL;
|
||||||
|
this->pads[i].size = 0;
|
||||||
|
this->pads[i].buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
GST_FLAG_SET (this, GST_ELEMENT_THREAD_SUGGESTED);
|
GST_FLAG_SET (this, GST_ELEMENT_THREAD_SUGGESTED);
|
||||||
|
|
||||||
|
@ -299,7 +305,6 @@ gst_alsa_init (GstAlsa *this)
|
||||||
this->stream = SND_PCM_STREAM_CAPTURE;
|
this->stream = SND_PCM_STREAM_CAPTURE;
|
||||||
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
|
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
|
||||||
this->pads[0].pad = gst_pad_new_from_template (gst_alsa_src_pad_factory (), "src");
|
this->pads[0].pad = gst_pad_new_from_template (gst_alsa_src_pad_factory (), "src");
|
||||||
this->pads[0].bs = NULL;
|
|
||||||
gst_pad_set_bufferpool_function(this->pads[0].pad, gst_alsa_src_get_buffer_pool);
|
gst_pad_set_bufferpool_function(this->pads[0].pad, gst_alsa_src_get_buffer_pool);
|
||||||
|
|
||||||
/* set the rate to a sensible value. we can't have gobject construct this
|
/* set the rate to a sensible value. we can't have gobject construct this
|
||||||
|
@ -309,13 +314,9 @@ gst_alsa_init (GstAlsa *this)
|
||||||
this->stream = SND_PCM_STREAM_PLAYBACK;
|
this->stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_sink_loop);
|
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_sink_loop);
|
||||||
this->pads[0].pad = gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
|
this->pads[0].pad = gst_pad_new_from_template (gst_alsa_sink_pad_factory (), "sink");
|
||||||
this->pads[0].bs = gst_bytestream_new (this->pads[0].pad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_element_add_pad (GST_ELEMENT (this), this->pads[0].pad);
|
gst_element_add_pad (GST_ELEMENT (this), this->pads[0].pad);
|
||||||
for (i = 1; i < GST_ALSA_MAX_CHANNELS; i++) {
|
|
||||||
this->pads[i].pad = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_pad_set_link_function (this->pads[0].pad, gst_alsa_link);
|
gst_pad_set_link_function (this->pads[0].pad, gst_alsa_link);
|
||||||
gst_pad_set_getcaps_function (this->pads[0].pad, gst_alsa_get_caps);
|
gst_pad_set_getcaps_function (this->pads[0].pad, gst_alsa_get_caps);
|
||||||
|
@ -327,12 +328,13 @@ gst_alsa_dispose (GObject *object)
|
||||||
gint i;
|
gint i;
|
||||||
GstAlsa *this = GST_ALSA (object);
|
GstAlsa *this = GST_ALSA (object);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
||||||
|
|
||||||
for (i = 0; i < ((GstElement *) this)->numpads; i++) {
|
for (i = 0; i < ((GstElement *) this)->numpads; i++) {
|
||||||
if (this->pads[i].bs)
|
if (this->pads[i].buf) {
|
||||||
gst_bytestream_destroy (this->pads[i].bs);
|
gst_data_unref (GST_DATA (this->pads[i].buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
gst_alsa_set_property (GObject *object, guint prop_id, const GValue *value,
|
gst_alsa_set_property (GObject *object, guint prop_id, const GValue *value,
|
||||||
|
@ -535,9 +537,7 @@ found_channel:
|
||||||
gst_pad_set_link_function (this->pads[channel].pad, gst_alsa_link);
|
gst_pad_set_link_function (this->pads[channel].pad, gst_alsa_link);
|
||||||
gst_pad_set_getcaps_function (this->pads[channel].pad, gst_alsa_get_caps);
|
gst_pad_set_getcaps_function (this->pads[channel].pad, gst_alsa_get_caps);
|
||||||
gst_element_add_pad (GST_ELEMENT (this), this->pads[channel].pad);
|
gst_element_add_pad (GST_ELEMENT (this), this->pads[channel].pad);
|
||||||
if (G_OBJECT_TYPE (this) == GST_TYPE_ALSA_SINK)
|
if (G_OBJECT_TYPE (this) == GST_TYPE_ALSA_SRC)
|
||||||
this->pads[channel].bs = gst_bytestream_new (this->pads[channel].pad);
|
|
||||||
else
|
|
||||||
gst_pad_set_bufferpool_function(this->pads[channel].pad, gst_alsa_src_get_buffer_pool);
|
gst_pad_set_bufferpool_function(this->pads[channel].pad, gst_alsa_src_get_buffer_pool);
|
||||||
|
|
||||||
return this->pads[channel].pad;
|
return this->pads[channel].pad;
|
||||||
|
@ -967,8 +967,12 @@ gst_alsa_change_state (GstElement *element)
|
||||||
g_free (this->format);
|
g_free (this->format);
|
||||||
this->format = NULL;
|
this->format = NULL;
|
||||||
for (i = 0; i < element->numpads; i++) {
|
for (i = 0; i < element->numpads; i++) {
|
||||||
if (this->pads[i].bs)
|
if (this->pads[i].buf) {
|
||||||
gst_bytestream_reset (this->pads[i].bs);
|
gst_data_unref (GST_DATA (this->pads[i].buf));
|
||||||
|
this->pads[i].buf = NULL;
|
||||||
|
this->pads[i].data = NULL;
|
||||||
|
this->pads[i].size = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
|
@ -1137,35 +1141,18 @@ gst_alsa_sink_loop (GstElement *element)
|
||||||
{
|
{
|
||||||
snd_pcm_sframes_t avail, avail2, copied;
|
snd_pcm_sframes_t avail, avail2, copied;
|
||||||
gint i;
|
gint i;
|
||||||
gint bytes, num_bytes; /* per channel */
|
guint bytes; /* per channel */
|
||||||
GstAlsa *this = GST_ALSA (element);
|
GstAlsa *this = GST_ALSA (element);
|
||||||
|
|
||||||
g_return_if_fail (this != NULL);
|
g_return_if_fail (this != NULL);
|
||||||
|
|
||||||
/* caps nego: fetch 1 byte from every pad */
|
|
||||||
if (this->format == NULL) {
|
|
||||||
GST_DEBUG (GST_CAT_NEGOTIATION, "starting caps negotiation");
|
|
||||||
for (i = 0; i < element->numpads; i++) {
|
|
||||||
g_assert (this->pads[i].pad != NULL);
|
|
||||||
do {
|
|
||||||
num_bytes = gst_bytestream_peek_bytes (this->pads[i].bs, &this->pads[i].data, 1);
|
|
||||||
} while (num_bytes == 0 && gst_alsa_sink_check_event (this, i));
|
|
||||||
if (num_bytes == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this->format == NULL) {
|
|
||||||
gst_element_error (GST_ELEMENT (this), "alsasink: No caps available");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sink_restart:
|
sink_restart:
|
||||||
|
|
||||||
avail = gst_alsa_update_avail (this);
|
avail = gst_alsa_update_avail (this);
|
||||||
if (avail == -EPIPE) goto sink_restart;
|
if (avail == -EPIPE) goto sink_restart;
|
||||||
if (avail < 0) return;
|
if (avail < 0) return;
|
||||||
if (avail > 0) {
|
if (avail > 0) {
|
||||||
int width = snd_pcm_format_physical_width (this->format->format);
|
int width;
|
||||||
|
|
||||||
/* Not enough space. We grab data nonetheless and sleep afterwards */
|
/* Not enough space. We grab data nonetheless and sleep afterwards */
|
||||||
if (avail < this->period_size) {
|
if (avail < this->period_size) {
|
||||||
|
@ -1173,17 +1160,33 @@ sink_restart:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check how many bytes we still have in all our bytestreams */
|
/* check how many bytes we still have in all our bytestreams */
|
||||||
bytes = avail * ( width / 8 ) * (element->numpads == 1 ? this->format->channels : 1);
|
bytes = G_MAXUINT;
|
||||||
for (i = 0; i < element->numpads; i++) {
|
for (i = 0; i < element->numpads; i++) {
|
||||||
g_assert (this->pads[i].pad != NULL);
|
GstAlsaPad *pad = &this->pads[i];
|
||||||
do {
|
g_assert (pad->pad != NULL);
|
||||||
num_bytes = gst_bytestream_peek_bytes (this->pads[i].bs, &this->pads[i].data, bytes);
|
while (pad->size == 0) {
|
||||||
} while (num_bytes == 0 && gst_alsa_sink_check_event (this, i));
|
pad->buf = gst_pad_pull (pad->pad);
|
||||||
if (num_bytes == 0)
|
if (GST_IS_EVENT (pad->buf)) {
|
||||||
return;
|
gboolean cont = gst_alsa_sink_check_event (this, i, GST_EVENT (pad->buf));
|
||||||
bytes = MIN (bytes, num_bytes);
|
gst_data_unref (GST_DATA (pad->buf));
|
||||||
|
pad->buf = NULL;
|
||||||
|
if (cont)
|
||||||
|
continue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pad->size = pad->buf->size;
|
||||||
|
pad->data = pad->buf->data;
|
||||||
|
}
|
||||||
|
bytes = MIN (bytes, pad->size);
|
||||||
}
|
}
|
||||||
avail = bytes / (width / 8 ) / (element->numpads == 1 ? this->format->channels : 1);
|
/* caps nego failed somewhere */
|
||||||
|
if (this->format == NULL) {
|
||||||
|
gst_element_error (GST_ELEMENT (this), "alsasink: No caps available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = snd_pcm_format_physical_width (this->format->format);
|
||||||
|
avail = MIN (avail, bytes / (width / 8 ) / (element->numpads == 1 ? this->format->channels : 1));
|
||||||
|
|
||||||
/* wait until the hw buffer has enough space */
|
/* wait until the hw buffer has enough space */
|
||||||
while (gst_element_get_state (element) == GST_STATE_PLAYING && (avail2 = gst_alsa_update_avail (this)) < avail) {
|
while (gst_element_get_state (element) == GST_STATE_PLAYING && (avail2 = gst_alsa_update_avail (this)) < avail) {
|
||||||
|
@ -1203,8 +1206,17 @@ sink_restart:
|
||||||
|
|
||||||
/* flush the data */
|
/* flush the data */
|
||||||
bytes = copied * ( width / 8 ) * (element->numpads == 1 ? this->format->channels : 1);
|
bytes = copied * ( width / 8 ) * (element->numpads == 1 ? this->format->channels : 1);
|
||||||
for (i = 0; i < element->numpads; i++)
|
for (i = 0; i < element->numpads; i++) {
|
||||||
gst_bytestream_flush (this->pads[i].bs, bytes);
|
GstAlsaPad *pad = &this->pads[i];
|
||||||
|
if ((pad->size -= bytes) == 0) {
|
||||||
|
gst_data_unref (GST_DATA (pad->buf));
|
||||||
|
pad->buf = NULL; /* needed? */
|
||||||
|
pad->data = NULL; /* needed? */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_assert (pad->size > 0);
|
||||||
|
pad->data += bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING && snd_pcm_avail_update (this->handle) == 0) {
|
if (snd_pcm_state(this->handle) != SND_PCM_STATE_RUNNING && snd_pcm_avail_update (this->handle) == 0) {
|
||||||
|
@ -1267,10 +1279,10 @@ src_restart:
|
||||||
/* push the data to gstreamer if it's big enough to fill up a buffer. */
|
/* push the data to gstreamer if it's big enough to fill up a buffer. */
|
||||||
for (i = 0; i < element->numpads; i++) {
|
for (i = 0; i < element->numpads; i++) {
|
||||||
pad = &this->pads[i];
|
pad = &this->pads[i];
|
||||||
pad->offset += MIN (copied, this->period_size - pad->offset);
|
pad->size += MIN (copied, this->period_size - pad->size);
|
||||||
|
|
||||||
if (pad->offset >= this->period_size) {
|
if (pad->size >= this->period_size) {
|
||||||
g_assert (pad->offset <= this->period_size);
|
g_assert (pad->size <= this->period_size);
|
||||||
|
|
||||||
buf = gst_buffer_new_from_pool (pool, 0, 0);
|
buf = gst_buffer_new_from_pool (pool, 0, 0);
|
||||||
|
|
||||||
|
@ -1281,7 +1293,7 @@ src_restart:
|
||||||
gst_pad_push (pad->pad, buf);
|
gst_pad_push (pad->pad, buf);
|
||||||
|
|
||||||
pad->data = NULL;
|
pad->data = NULL;
|
||||||
pad->offset = 0;
|
pad->size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,14 +1347,10 @@ gst_alsa_xrun_recovery (GstAlsa *this)
|
||||||
|
|
||||||
/* TRUE, if everything should continue */
|
/* TRUE, if everything should continue */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_alsa_sink_check_event (GstAlsa *this, gint pad_nr)
|
gst_alsa_sink_check_event (GstAlsa *this, gint pad_nr, GstEvent *event)
|
||||||
{
|
{
|
||||||
GstEvent *event = NULL;
|
|
||||||
guint32 avail;
|
|
||||||
gboolean cont = TRUE;
|
gboolean cont = TRUE;
|
||||||
|
|
||||||
gst_bytestream_get_status (this->pads[pad_nr].bs, &avail, &event);
|
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/bytestream/bytestream.h>
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#define GST_ALSA_MAX_CHANNELS 64 /* we don't support more than 64 channels */
|
#define GST_ALSA_MAX_CHANNELS 64 /* we don't support more than 64 channels */
|
||||||
#define GST_ALSA_MIN_RATE 8000
|
#define GST_ALSA_MIN_RATE 8000
|
||||||
|
@ -87,9 +85,9 @@ typedef int (*GstAlsaTransmitFunction) (GstAlsa *this, snd_pcm_sframes_t *avail)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstByteStream *bs;
|
guint8 *data; /* pointer into buffer */
|
||||||
guint8 *data;
|
guint size; /* sink: bytes left in buffer */
|
||||||
guint8 offset;
|
GstBuffer *buf; /* current buffer */
|
||||||
} GstAlsaPad;
|
} GstAlsaPad;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
snd_pcm_format_t format;
|
snd_pcm_format_t format;
|
||||||
|
|
Loading…
Reference in a new issue