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; }
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; } }
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; }
/* 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; }