static void gst_nas_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstNasSink *nassink; nassink = GST_NAS_SINK (object); switch (prop_id) { case ARG_MUTE: nassink->mute = g_value_get_boolean (value); break; case ARG_HOST: g_free (nassink->host); nassink->host = g_value_dup_string (value); if (nassink->host == NULL) nassink->host = g_strdup (g_getenv ("AUDIOSERVER")); if (nassink->host == NULL) nassink->host = g_strdup (g_getenv ("DISPLAY")); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean gst_nas_sink_unprepare (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); if (sink->flow != AuNone) { AuBool clocked; int num_elements; AuStatus status; AuElement *oldelems; GST_DEBUG_OBJECT (sink, "flushing buffer"); NAS_flush (sink); oldelems = AuGetElements (sink->audio, sink->flow, &clocked, &num_elements, &status); if (num_elements > 0) { GST_DEBUG_OBJECT (sink, "GetElements status: %i", status); if (oldelems) AuFreeElements (sink->audio, num_elements, oldelems); } AuStopFlow (sink->audio, sink->flow, NULL); AuReleaseScratchFlow (sink->audio, sink->flow, NULL); sink->flow = AuNone; } sink->need_data = 0; return TRUE; }
static void gst_nas_sink_finalize (GObject * object) { GstNasSink *nassink = GST_NAS_SINK (object); g_free (nassink->host); G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gst_nas_sink_reset (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); GST_DEBUG_OBJECT (sink, "reset"); NAS_flush (sink); }
static void gst_nas_sink_reset (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); GST_DEBUG_OBJECT (sink, "reset"); if (sink->flow != AuNone) AuStopFlow (sink->audio, sink->flow, NULL); }
static gboolean gst_nas_sink_close (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); if (sink->audio) { AuCloseServer (sink->audio); sink->audio = NULL; } GST_DEBUG_OBJECT (sink, "closed audio device"); return TRUE; }
static gboolean gst_nas_sink_open (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); GST_DEBUG_OBJECT (sink, "opening, host = '%s'", GST_STR_NULL (sink->host)); /* Open Server */ sink->audio = AuOpenServer (sink->host, 0, NULL, 0, NULL, NULL); if (sink->audio == NULL) { GST_DEBUG_OBJECT (sink, "opening failed"); return FALSE; } sink->flow = AuNone; sink->need_data = 0; /* Start a flow */ GST_DEBUG_OBJECT (asink, "opened audio device"); return TRUE; }
static void gst_nas_sink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstNasSink *nassink; nassink = GST_NAS_SINK (object); switch (prop_id) { case ARG_MUTE: g_value_set_boolean (value, nassink->mute); break; case ARG_HOST: g_value_set_string (value, nassink->host); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstCaps * gst_nas_sink_getcaps (GstBaseSink * bsink) { GstNasSink *nassink = GST_NAS_SINK (bsink); const GstCaps *templatecaps; AuServer *server; GstCaps *fixated, *caps; int i; server = nassink->audio; templatecaps = gst_static_pad_template_get_caps (&sink_factory); if (server == NULL) return gst_caps_copy (templatecaps); fixated = gst_caps_copy (templatecaps); for (i = 0; i < gst_caps_get_size (fixated); i++) { GstStructure *structure; gint min, max; min = AuServerMinSampleRate (server); max = AuServerMaxSampleRate (server); structure = gst_caps_get_structure (fixated, i); if (min == max) gst_structure_set (structure, "rate", G_TYPE_INT, max, NULL); else gst_structure_set (structure, "rate", GST_TYPE_INT_RANGE, min, max, NULL); } caps = gst_caps_intersect (fixated, templatecaps); gst_caps_unref (fixated); if (nassink->audio == NULL) AuCloseServer (server); return caps; }
static guint gst_nas_sink_write (GstAudioSink * asink, gpointer data, guint length) { GstNasSink *nassink = GST_NAS_SINK (asink); int used = 0; NAS_flush (nassink); if (!nassink->mute && nassink->audio != NULL && nassink->flow != AuNone) { if (nassink->need_data == 0) return 0; used = nassink->need_data > length ? length : nassink->need_data; AuWriteElement (nassink->audio, nassink->flow, 0, used, data, AuFalse, NULL); nassink->need_data -= used; if (used == length) AuSync (nassink->audio, AuFalse); } else used = length; return used; }
static gboolean gst_nas_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstNasSink *sink = GST_NAS_SINK (asink); /*spec->bytes_per_sample = sink->rate * NAS_SOUND_PORT_DURATION; */ /*spec->bytes_per_sample = (spec->width / 8) * spec->channels; */ memset (spec->silence_sample, 0, spec->bytes_per_sample); GST_DEBUG_OBJECT (sink, "Sample %d", spec->bytes_per_sample); if (sink->audio == NULL) return TRUE; if (sink->flow != AuNone) { GST_DEBUG_OBJECT (sink, "flushing buffer"); NAS_flush (sink); AuStopFlow (sink->audio, sink->flow, NULL); AuReleaseScratchFlow (sink->audio, sink->flow, NULL); sink->flow = AuNone; } return NAS_createFlow (sink, spec); }
static gboolean gst_nas_sink_close (GstAudioSink * asink) { GstNasSink *sink = GST_NAS_SINK (asink); if (sink->audio == NULL) return TRUE; if (sink->flow != AuNone) { NAS_flush (sink); AuStopFlow (sink->audio, sink->flow, NULL); AuReleaseScratchFlow (sink->audio, sink->flow, NULL); sink->flow = AuNone; } sink->need_data = 0; AuCloseServer (sink->audio); sink->audio = NULL; GST_DEBUG_OBJECT (sink, "closed audio device"); return TRUE; }
static gboolean gst_nas_sink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) { GstNasSink *sink = GST_NAS_SINK (asink); AuElement elements[2]; AuUint32 buf_samples; unsigned char format; format = gst_nas_sink_sink_get_format (spec); if (format == 0) { GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS, (NULL), ("Unable to get format %d", spec->format)); return FALSE; } GST_DEBUG_OBJECT (sink, "Format: %d %d\n", spec->format, format); sink->flow = AuGetScratchFlow (sink->audio, NULL); if (sink->flow == 0) { GST_DEBUG_OBJECT (sink, "couldn't get flow"); return FALSE; } buf_samples = spec->rate * NAS_SOUND_PORT_DURATION; /* spec->segsize = gst_util_uint64_scale (buf_samples * spec->bytes_per_sample, spec->latency_time, GST_SECOND / GST_USECOND); spec->segsize -= spec->segsize % spec->bytes_per_sample; spec->segtotal = spec->buffer_time / spec->latency_time; */ spec->segsize = buf_samples * spec->bytes_per_sample; spec->segtotal = 1; memset (spec->silence_sample, 0, spec->bytes_per_sample); GST_DEBUG_OBJECT (sink, "Bytes per sample %d", spec->bytes_per_sample); GST_DEBUG_OBJECT (sink, "Rate %d Format %d tracks %d bufs %d %d/%d w %d", spec->rate, format, spec->channels, (gint) buf_samples, spec->segsize, spec->segtotal, spec->width); AuMakeElementImportClient (&elements[0], /* element */ spec->rate, /* rate */ format, /* format */ spec->channels, /* number of tracks */ AuTrue, /* discart */ buf_samples, /* max samples */ (AuUint32) (buf_samples / 100 * AuSoundPortLowWaterMark), /* low water mark */ 0, /* num actions */ NULL); sink->device = NAS_getDevice (sink->audio, spec->channels); if (sink->device == AuNone) { GST_DEBUG_OBJECT (sink, "no device with %i tracks found", spec->channels); return FALSE; } AuMakeElementExportDevice (&elements[1], /* element */ 0, /* input */ sink->device, /* device */ spec->rate, /* rate */ AuUnlimitedSamples, /* num samples */ 0, /* num actions */ NULL); /* actions */ AuSetElements (sink->audio, /* server */ sink->flow, /* flow ID */ AuTrue, /* clocked */ 2, /* num elements */ elements, /* elements */ NULL); AuRegisterEventHandler (sink->audio, /* server */ AuEventHandlerIDMask, /* value mask */ 0, /* type */ sink->flow, /* flow ID */ NAS_EventHandler, /* callback */ (AuPointer) sink); /* data */ AuStartFlow (sink->audio, sink->flow, NULL); return TRUE; }