Ejemplo n.º 1
0
static void
gst_opensles_sink_init (GstOpenSLESSink * sink, GstOpenSLESSinkClass * gclass)
{
  sink->volume = DEFAULT_VOLUME;
  sink->mute = DEFAULT_MUTE;

  _opensles_query_capabilities (sink);

  gst_base_audio_sink_set_provide_clock (GST_BASE_AUDIO_SINK (sink), TRUE);
  /* Override some default values to fit on the AudioFlinger behaviour of
   * processing 20ms buffers as minimum buffer size. */
  GST_BASE_AUDIO_SINK (sink)->buffer_time = 400000;
  GST_BASE_AUDIO_SINK (sink)->latency_time = 20000;
}
Ejemplo n.º 2
0
static void
gst_opensles_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstOpenSLESSink *sink = GST_OPENSLES_SINK (object);
  GstRingBuffer *rb = GST_BASE_AUDIO_SINK (sink)->ringbuffer;

  switch (prop_id) {
    case PROP_VOLUME:
      sink->volume = g_value_get_double (value);
      if (rb && GST_IS_OPENSLES_RING_BUFFER (rb)) {
        gst_opensles_ringbuffer_set_volume (rb, sink->volume);
      }
      break;
    case PROP_MUTE:
      sink->mute = g_value_get_boolean (value);
      if (rb && GST_IS_OPENSLES_RING_BUFFER (rb)) {
        gst_opensles_ringbuffer_set_mute (rb, sink->mute);
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
Ejemplo n.º 3
0
static boolean
gst_directsound_sink_is_spdif_format (GstDirectSoundSink * dsoundsink)
{
  GstBufferFormatType type;

  type = GST_BASE_AUDIO_SINK (dsoundsink)->ringbuffer->spec.type;
  return type == GST_BUFTYPE_AC3 || type == GST_BUFTYPE_DTS;
}
Ejemplo n.º 4
0
/* initialize the new element
 * instantiate pads and add them to element
 * set functions
 * initialize structure
 */
static void
gst_osx_audio_sink_init (GstOsxAudioSink * sink, GstOsxAudioSinkClass * gclass)
{
/*  GstElementClass *klass = GST_ELEMENT_GET_CLASS (sink); */
  sink->ringbuffer = NULL;
  GST_DEBUG ("Initialising object");

  gst_osx_audio_sink_create_ringbuffer (GST_BASE_AUDIO_SINK (sink));
}
/* Called with the write_mutex held */
static void
gst_sunaudio_sink_do_delay (GstSunAudioSink * sink)
{
  GstBaseAudioSink *ba_sink = GST_BASE_AUDIO_SINK (sink);
  GstClockTime total_sleep;
  GstClockTime max_sleep;
  gint sleep_usecs;
  GTimeVal sleep_end;
  gint err;
  audio_info_t ainfo;
  guint diff;

  /* This code below ensures that we don't race any further than buffer_time 
   * ahead of the audio output, by sleeping if the next write call would cause
   * us to advance too far in the ring-buffer */
  LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
  if (err < 0)
    goto write_error;

  /* Compute our offset from the output (copes with overflow) */
  diff = (guint) (sink->segs_written) - ainfo.play.eof;
  if (diff > sink->segtotal) {
    /* This implies that reset did a flush just as the sound device aquired
     * some buffers internally, and it causes us to be out of sync with the
     * eof measure. This corrects it */
    sink->segs_written = ainfo.play.eof;
    diff = 0;
  }

  if (diff + 1 < sink->segtotal)
    return;                     /* no need to sleep at all */

  /* Never sleep longer than the initial number of undrained segments in the 
     device plus one */
  total_sleep = 0;
  max_sleep = (diff + 1) * (ba_sink->latency_time * GST_USECOND);
  /* sleep for a segment period between .eof polls */
  sleep_usecs = ba_sink->latency_time;

  /* Current time is our reference point */
  g_get_current_time (&sleep_end);

  /* If the next segment would take us too far along the ring buffer,
   * sleep for a bit to free up a slot. If there were a way to find out
   * when the eof field actually increments, we could use, but the only
   * notification mechanism seems to be SIGPOLL, which we can't use from
   * a support library */
  while (diff + 1 >= sink->segtotal && total_sleep < max_sleep) {
    GST_LOG_OBJECT (sink, "need to block to drain segment(s). "
        "Sleeping for %d us", sleep_usecs);

    g_time_val_add (&sleep_end, sleep_usecs);

    if (g_cond_timed_wait (sink->sleep_cond, sink->write_mutex, &sleep_end)) {
      GST_LOG_OBJECT (sink, "Waking up early due to reset");
      return;                   /* Got told to wake up */
    }
    total_sleep += (sleep_usecs * GST_USECOND);

    LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
    if (err < 0)
      goto write_error;

    /* Compute our (new) offset from the output (copes with overflow) */
    diff = (guint) g_atomic_int_get (&sink->segs_written) - ainfo.play.eof;
  }

  return;

write_error:
  GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
      ("Playback error on device '%s': %s", sink->device, strerror (errno)));
  return;
}