static GstClockTime gst_alsasrc_get_timestamp (GstAlsaSrc * asrc) { snd_pcm_status_t *status; snd_htimestamp_t tstamp; GstClockTime timestamp; snd_pcm_uframes_t avail; gint err = -EPIPE; if (G_UNLIKELY (!asrc)) { GST_ERROR_OBJECT (asrc, "No alsa handle created yet !"); return GST_CLOCK_TIME_NONE; } if (G_UNLIKELY (snd_pcm_status_malloc (&status) != 0)) { GST_ERROR_OBJECT (asrc, "snd_pcm_status_malloc failed"); return GST_CLOCK_TIME_NONE; } if (G_UNLIKELY (snd_pcm_status (asrc->handle, status) != 0)) { GST_ERROR_OBJECT (asrc, "snd_pcm_status failed"); return GST_CLOCK_TIME_NONE; } /* in case an xrun condition has occured we need to handle this */ if (snd_pcm_status_get_state (status) != SND_PCM_STATE_RUNNING) { if (xrun_recovery (asrc, asrc->handle, err) < 0) { GST_WARNING_OBJECT (asrc, "Could not recover from xrun condition !"); } /* reload the status alsa status object, since recovery made it invalid */ if (G_UNLIKELY (snd_pcm_status (asrc->handle, status) != 0)) { GST_ERROR_OBJECT (asrc, "snd_pcm_status failed"); } } /* get high resolution time stamp from driver */ snd_pcm_status_get_htstamp (status, &tstamp); timestamp = GST_TIMESPEC_TO_TIME (tstamp); /* max available frames sets the depth of the buffer */ avail = snd_pcm_status_get_avail (status); /* calculate the timestamp of the next sample to be read */ timestamp -= gst_util_uint64_scale_int (avail, GST_SECOND, asrc->rate); /* compensate for the fact that we really need the timestamp of the * previously read data segment */ timestamp -= asrc->period_time * 1000; snd_pcm_status_free (status); GST_LOG_OBJECT (asrc, "ALSA timestamp : %" GST_TIME_FORMAT ", delay %lu", GST_TIME_ARGS (timestamp), avail); return timestamp; }
static void alsa_prefill( void ) { snd_pcm_status_t *status; char buf[512]; int frames, cnt; snd_pcm_status_malloc( &status ); snd_pcm_status( alsa.pcm, status ); frames = snd_pcm_status_get_avail(status); snd_pcm_status_free( status ); memset( buf, 0, sizeof(buf) ); cnt = sizeof(buf)/alsa.bpf; for( ; frames > 0; frames -= cnt ) { if( cnt > frames ) cnt = frames; snd_pcm_writei( alsa.pcm, buf, sizeof(buf)/alsa.bpf ); } }
void DAUDIO_Close(void* id, int isSource) { AlsaPcmInfo* info = (AlsaPcmInfo*) id; TRACE0("DAUDIO_Close\n"); if (info != NULL) { if (info->handle != NULL) { snd_pcm_close(info->handle); } if (info->hwParams) { snd_pcm_hw_params_free(info->hwParams); } if (info->swParams) { snd_pcm_sw_params_free(info->swParams); } #ifdef GET_POSITION_METHOD2 if (info->positionStatus) { snd_pcm_status_free(info->positionStatus); } #endif free(info); } }