示例#1
0
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;
}
示例#2
0
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);
    }
}