Ejemplo n.º 1
0
static guint
gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
{
    GstAlsaSink *alsa;
    gint err;
    gint cptr;
    gint16 *ptr = data;

    alsa = GST_ALSA_SINK (asink);

    if (alsa->iec958 && alsa->need_swap) {
        guint i;

        GST_DEBUG_OBJECT (asink, "swapping bytes");
        for (i = 0; i < length / 2; i++) {
            ptr[i] = GUINT16_SWAP_LE_BE (ptr[i]);
        }
    }

    GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length);

    cptr = length / alsa->bytes_per_sample;

    GST_ALSA_SINK_LOCK (asink);
    while (cptr > 0) {
        /* start by doing a blocking wait for free space. Set the timeout
         * to 4 times the period time */
        err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
        if (err < 0) {
            GST_DEBUG_OBJECT (asink, "wait error, %d", err);
        } else {
            GST_DELAY_SINK_LOCK (asink);
            err = snd_pcm_writei (alsa->handle, ptr, cptr);
            GST_DELAY_SINK_UNLOCK (asink);
        }

        GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
        if (err < 0) {
            GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
            if (err == -EAGAIN) {
                continue;
            } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
                goto write_error;
            }
            continue;
        }

        ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
        cptr -= err;
    }
    GST_ALSA_SINK_UNLOCK (asink);

    return length - (cptr * alsa->bytes_per_sample);

write_error:
    {
        GST_ALSA_SINK_UNLOCK (asink);
        return length;              /* skip one period */
    }
}
Ejemplo n.º 2
0
static guint
gst_alsasink_delay (GstAudioSink * asink)
{
    GstAlsaSink *alsa;
    snd_pcm_sframes_t delay;
    int res;

    alsa = GST_ALSA_SINK (asink);

    GST_DELAY_SINK_LOCK (asink);
    res = snd_pcm_delay (alsa->handle, &delay);
    GST_DELAY_SINK_UNLOCK (asink);
    if (G_UNLIKELY (res < 0)) {
        /* on errors, report 0 delay */
        GST_DEBUG_OBJECT (alsa, "snd_pcm_delay returned %d", res);
        delay = 0;
    }
    if (G_UNLIKELY (delay < 0)) {
        /* make sure we never return a negative delay */
        GST_WARNING_OBJECT (alsa, "snd_pcm_delay returned negative delay");
        delay = 0;
    }

    return delay;
}
Ejemplo n.º 3
0
static gint
gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
{
  GstAlsaSink *alsa;
  gint err;
  gint cptr;
  guint8 *ptr = data;

  alsa = GST_ALSA_SINK (asink);

  if (alsa->iec958 && alsa->need_swap) {
    guint i;
    guint16 *ptr_tmp = (guint16 *) ptr;

    GST_DEBUG_OBJECT (asink, "swapping bytes");
    for (i = 0; i < length / 2; i++) {
      ptr_tmp[i] = GUINT16_SWAP_LE_BE (ptr_tmp[i]);
    }
  }

  GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length);

  cptr = length / alsa->bpf;

  GST_ALSA_SINK_LOCK (asink);
  while (cptr > 0) {
    /* start by doing a blocking wait for free space. Set the timeout
     * to 4 times the period time */
    err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
    if (err < 0) {
      GST_DEBUG_OBJECT (asink, "wait error, %d", err);
    } else {
      GST_DELAY_SINK_LOCK (asink);
      err = snd_pcm_writei (alsa->handle, ptr, cptr);
      GST_DELAY_SINK_UNLOCK (asink);
    }

    GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
    if (err < 0) {
      GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
      if (err == -EAGAIN) {
        continue;
      } else if (err == -ENODEV) {
        goto device_disappeared;
      } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
        goto write_error;
      }
      continue;
    }

    ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
    cptr -= err;
  }
  GST_ALSA_SINK_UNLOCK (asink);

  return length - (cptr * alsa->bpf);

write_error:
  {
    GST_ALSA_SINK_UNLOCK (asink);
    return length;              /* skip one period */
  }
device_disappeared:
  {
    GST_ELEMENT_ERROR (asink, RESOURCE, WRITE,
        (_("Error outputting to audio device. "
                "The device has been disconnected.")), (NULL));
    goto write_error;
  }
}