Пример #1
0
static void
finalize (GObject *object)
{
  GeglProperties *o = GEGL_PROPERTIES (object);
  if (o->user_data)
    {
      Priv *p = (Priv*)o->user_data;
      flush_audio (o);
      flush_video (o);

      av_write_trailer (p->oc);

      if (p->video_st)
        close_video (p, p->oc, p->video_st);
      if (p->audio_st)
        close_audio (p, p->oc, p->audio_st);

      avio_closep (&p->oc->pb);
      avformat_free_context (p->oc);

      g_free (o->user_data);
      o->user_data = NULL;
    }

  G_OBJECT_CLASS (g_type_class_peek_parent (G_OBJECT_GET_CLASS (object)))->finalize (object);
}
Пример #2
0
// close audio device
static void uninit(int immed){
    // throw away buffered data in the audio driver's STREAMS queue
    if (immed)
	flush_audio(audio_fd);
    else
	ioctl(audio_fd, AUDIO_DRAIN, 0);
    close(audio_fd);
}
Пример #3
0
// stop playing and empty buffers (for seeking/pause)
static void reset(void){
    audio_info_t info;
    flush_audio(audio_fd);

    AUDIO_INITINFO(&info);
    info.play.samples = 0;
    info.play.eof = 0;
    info.play.error = 0;
    ioctl(audio_fd, AUDIO_SETINFO, &info);

    queued_bursts = 0;
    queued_samples = 0;
}
Пример #4
0
// try to figure out, if the soundcard driver provides usable (precise)
// sample counter information
static int realtime_samplecounter_available(char *dev)
{
    int fd = -1;
    audio_info_t info;
    int rtsc_ok = RTSC_DISABLED;
    int len;
    void *silence = NULL;
    struct timeval start, end;
    struct timespec delay;
    int usec_delay;
    unsigned last_samplecnt;
    unsigned increment;
    unsigned min_increment;

    len = 44100 * 4 / 4;    /* amount of data for 0.25sec of 44.1khz, stereo,
			     * 16bit.  44kbyte can be sent to all supported
			     * sun audio devices without blocking in the
			     * "write" below.
			     */
    silence = calloc(1, len);
    if (silence == NULL)
	goto error;

    if ((fd = open(dev, O_WRONLY)) < 0)
	goto error;

    AUDIO_INITINFO(&info);
    info.play.sample_rate = 44100;
    info.play.channels = AUDIO_CHANNELS_STEREO;
    info.play.precision = AUDIO_PRECISION_16;
    info.play.encoding = AUDIO_ENCODING_LINEAR;
    info.play.samples = 0;
    if (ioctl(fd, AUDIO_SETINFO, &info)) {
	if ( mp_msg_test(MSGT_AO,MSGL_V) )
	    mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_SUN_RtscSetinfoFailed);
	goto error;
    }

    if (write(fd, silence, len) != len) {
	if ( mp_msg_test(MSGT_AO,MSGL_V) )
	    mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_SUN_RtscWriteFailed);
	goto error;
    }

    if (ioctl(fd, AUDIO_GETINFO, &info)) {
	if ( mp_msg_test(MSGT_AO,MSGL_V) )
	    perror("rtsc: GETINFO1");
	goto error;
    }

    last_samplecnt = info.play.samples;
    min_increment = ~0;

    gettimeofday(&start, NULL);
    for (;;) {
	delay.tv_sec = 0;
	delay.tv_nsec = 10000000;
	nanosleep(&delay, NULL);
	gettimeofday(&end, NULL);
	usec_delay = (end.tv_sec - start.tv_sec) * 1000000
	    + end.tv_usec - start.tv_usec;

	// stop monitoring sample counter after 0.2 seconds
	if (usec_delay > 200000)
	    break;

	if (ioctl(fd, AUDIO_GETINFO, &info)) {
	    if ( mp_msg_test(MSGT_AO,MSGL_V) )
		perror("rtsc: GETINFO2 failed");
	    goto error;
	}
	if (info.play.samples < last_samplecnt) {
	    if ( mp_msg_test(MSGT_AO,MSGL_V) )
		mp_msg(MSGT_AO,MSGL_V,"rtsc: %d > %d?\n", last_samplecnt, info.play.samples);
	    goto error;
	}

	if ((increment = info.play.samples - last_samplecnt) > 0) {
	    if ( mp_msg_test(MSGT_AO,MSGL_V) )
	        mp_msg(MSGT_AO,MSGL_V,"ao_sun: sample counter increment: %d\n", increment);
	    if (increment < min_increment) {
		min_increment = increment;
		if (min_increment < 2000)
		    break;	// looks good
	    }
	}
	last_samplecnt = info.play.samples;
    }

    /*
     * For 44.1kkz, stereo, 16-bit format we would send sound data in 16kbytes
     * chunks (== 4096 samples) to the audio device.  If we see a minimum
     * sample counter increment from the soundcard driver of less than
     * 2000 samples,  we assume that the driver provides a useable realtime
     * sample counter in the AUDIO_INFO play.samples field.  Timing based
     * on sample counts should be much more accurate than counting whole
     * 16kbyte chunks.
     */
    if (min_increment < 2000)
	rtsc_ok = RTSC_ENABLED;

    if ( mp_msg_test(MSGT_AO,MSGL_V) )
	mp_msg(MSGT_AO,MSGL_V,"ao_sun: minimum sample counter increment per 10msec interval: %d\n"
	       "\t%susing sample counter based timing code\n",
	       min_increment, rtsc_ok == RTSC_ENABLED ? "" : "not ");


error:
    if (silence != NULL) free(silence);
    if (fd >= 0) {
	// remove the 0 bytes from the above measurement from the
	// audio driver's STREAMS queue
        flush_audio(fd);
	close(fd);
    }

    return rtsc_ok;
}