예제 #1
0
static int preinit(const char *arg)
{
    enum MPGLType gltype = GLTYPE_X11;
#ifdef CONFIG_GL_WIN32
    gltype = GLTYPE_W32;
#endif
    if (!init_mpglcontext(&glctx, gltype))
        return -1;

    matrix_rows = DEFAULT_MATRIX_ROWS;
    matrix_cols = DEFAULT_MATRIX_COLS;

    if (subopt_parse(arg, subopts) != 0) {
        mp_msg(MSGT_VO, MSGL_FATAL,
                "\n-vo matrixview command line help:\n"
                "Example: mplayer -vo matrixview:cols=320:rows=240\n"
                "\n"
                "Options:\n"
                "\n"
                "  cols=<12-320>\n"
                "    Specify the number of columns of the matrix view, default %d\n"
                "\n"
                "  rows=<12-240>\n"
                "    Specify the number of rows of the matrix view, default %d\n"
                "\n"
                ,
                DEFAULT_MATRIX_COLS, DEFAULT_MATRIX_ROWS
              );
        return -1;
    }

    return 0;
}
예제 #2
0
파일: vo_gx.c 프로젝트: NeeMeese/mplayer-ce
static int preinit(const char *arg)
{
	subopt_parse(arg, subopts);
	mpgxInit(vfilter);
	mpgxSetupYUVp(colorspace, levelconv);
	return VO_FALSE;
}
예제 #3
0
static int init(int rate, int channels, int format, int flags) {
  float position[3] = {0, 0, 0};
  float direction[6] = {0, 0, 1, 0, -1, 0};
  float sppos[6][3] = {
    {-1, 0, 0.5}, {1, 0, 0.5},
    {-1, 0,  -1}, {1, 0,  -1},
    {0,  0,   1}, {0, 0, 0.1},
  };
  ALCdevice *dev = NULL;
  ALCcontext *ctx = NULL;
  ALCint freq = 0;
  ALCint attribs[] = {ALC_FREQUENCY, rate, 0, 0};
  int i;
  opt_t subopts[] = {
    {NULL}
  };
  if (subopt_parse(ao_subdevice, subopts) != 0) {
    print_help();
    return 0;
  }
  if (channels > MAX_CHANS) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Invalid number of channels: %i\n", channels);
    goto err_out;
  }
  dev = alcOpenDevice(NULL);
  if (!dev) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] could not open device\n");
    goto err_out;
  }
  ctx = alcCreateContext(dev, attribs);
  alcMakeContextCurrent(ctx);
  alListenerfv(AL_POSITION, position);
  alListenerfv(AL_ORIENTATION, direction);
  alGenSources(channels, sources);
  for (i = 0; i < channels; i++) {
    cur_buf[i] = 0;
    unqueue_buf[i] = 0;
    alGenBuffers(NUM_BUF, buffers[i]);
    alSourcefv(sources[i], AL_POSITION, sppos[i]);
    alSource3f(sources[i], AL_VELOCITY, 0, 0, 0);
  }
  if (channels == 1)
    alSource3f(sources[0], AL_POSITION, 0, 0, 1);
  ao_data.channels = channels;
  alcGetIntegerv(dev, ALC_FREQUENCY, 1, &freq);
  if (alcGetError(dev) == ALC_NO_ERROR && freq)
    rate = freq;
  ao_data.samplerate = rate;
  ao_data.format = AF_FORMAT_S16_NE;
  ao_data.bps = channels * rate * 2;
  ao_data.buffersize = CHUNK_SIZE * NUM_BUF;
  ao_data.outburst = channels * CHUNK_SIZE;
  tmpbuf = malloc(CHUNK_SIZE);
  return 1;

err_out:
  return 0;
}
예제 #4
0
파일: vo_png.c 프로젝트: astiob/mplayer2
static int preinit(const char *arg)
{
    z_compression = 0;
    use_alpha = 0;
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }
    return 0;
}
예제 #5
0
static int preinit(const char *arg)
{
	int card = -1;
	char *ao_file = NULL;

	const opt_t subopts[] = {
		{"card", OPT_ARG_INT, &card, NULL},
		{"file", OPT_ARG_MSTRZ, &ao_file, NULL},
		{NULL}
	};

	if(subopt_parse(ao_subdevice, subopts) != 0)
	{
		mp_msg(MSGT_VO, MSGL_ERR, "AO_MPEGPES, Unrecognized options\n");
		return -1;
	}
	if(card==-1)
	{
		//search the first usable card
		int n;
		char file[30];
		for(n=0; n<4; n++)
		{
			sprintf(file, "/dev/dvb/adapter%d/audio0", n);
			if(access(file, F_OK | W_OK)==0)
			{
				card = n+1;
				break;
			}
        	}
	}
	if((card < 1) || (card > 4))
	{
		mp_msg(MSGT_VO, MSGL_ERR, "DVB card number must be between 1 and 4\n");
		return -1;
	}
	card--;

#ifdef CONFIG_DVB
	if(!ao_file)
		return init_device(card);
#else
	if(!ao_file)
		return vo_mpegpes_fd;	//video fd
#endif

	vo_mpegpes_fd2=open(ao_file,O_WRONLY|O_CREAT,0666);
	if(vo_mpegpes_fd2<0)
	{
		mp_msg(MSGT_VO, MSGL_ERR, "ao_mpegpes: %s\n", strerror(errno));
		return -1;
	}
	return vo_mpegpes_fd2;
}
예제 #6
0
파일: vo_png.c 프로젝트: 0p1pp1/mplayer
static int preinit(const char *arg)
{
    z_compression = 0;
    png_outdir = strdup(".");
    png_outfile_prefix = strdup("");
    use_alpha = 0;
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }
    avcodec_register_all();
    return 0;
}
예제 #7
0
파일: vo_png.c 프로젝트: HermiG/mplayer2
static int preinit(const char *arg)
{
    z_compression = 0;
    use_alpha = 0;
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }
    avctx = avcodec_alloc_context();
    if (avcodec_open(avctx, avcodec_find_encoder(CODEC_ID_PNG)) < 0) {
        uninit();
        return -1;
    }
    avctx->compression_level = z_compression;
    return 0;
}
예제 #8
0
파일: vo_mng.c 프로젝트: 0p1pp1/mplayer
/**
 * @brief pre-initialize MNG vo module
 * @param[in] *arg arguments passed to MNG vo module (output file name)
 * @return 0 on success, 1 on error
 */
static int preinit(const char *arg)
{
    if (subopt_parse(arg, subopts)) {
        mp_msg(MSGT_VO, MSGL_ERR,
               "\n-vo mng command line help:\n"
               "Example: mplayer -vo mng:output=file.mng\n"
               "\nOptions:\n"
               "  output=<filename>\n"
               "    Specify the output file.  The default is out.mng.\n"
               "\n");
        vomng_prop_cleanup();
        return 1;
    }
    if (!vomng.out_file_name)
        vomng.out_file_name = strdup("out.mng");

    return 0;
}
예제 #9
0
/**
 * Initialize framebuffer
 */
static int preinit(const char *arg)
{
    opt_t subopts[] = {
        {"fb_overlay_only", OPT_ARG_BOOL, &fb_overlay_only, NULL},
        {"dbl_buffer", OPT_ARG_BOOL, &dbl_buffer, NULL},
        {NULL}
    };

    if (subopt_parse(arg, subopts) != 0) {
        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] unknown suboptions: %s\n", arg);
        return -1;
    }

    dev_fd = open("/dev/fb0", O_RDWR);

    if (dev_fd == -1) {
        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error /dev/fb0\n");
        return -1;
    }

    ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo_p0);
    close(dev_fd);

    dev_fd = open("/dev/fb1", O_RDWR);

    if (dev_fd == -1) {
        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Error /dev/fb1\n");
        return -1;
    }

    ioctl(dev_fd, FBIOGET_VSCREENINFO, &sinfo);
    ioctl(dev_fd, OMAPFB_QUERY_PLANE, &pinfo);
    ioctl(dev_fd, OMAPFB_QUERY_MEM, &minfo);

    if (!fb_overlay_only && !vo_init())
    {
        mp_msg(MSGT_VO, MSGL_FATAL, "[omapfb] Could not open X, overlay only...\n");        
        fb_overlay_only = 1;
    }

    return 0;
}
예제 #10
0
static int preinit(const char *arg)
{
	int card = 1;
	char *ao_file = NULL;

	opt_t subopts[] = {
		{"card", OPT_ARG_INT, &card, NULL},
		{"file", OPT_ARG_MSTRZ, &ao_file, NULL},
		{NULL}
	};

	if(subopt_parse(ao_subdevice, subopts) != 0)
	{
		mp_msg(MSGT_VO, MSGL_ERR, "AO_MPEGPES, Unrecognized options\n");
		return -1;
	}
	if((card < 1) || (card > 4))
	{
		mp_msg(MSGT_VO, MSGL_ERR, "DVB card number must be between 1 and 4\n");
		return -1;
	}
	card--;

#ifdef HAVE_DVB
	if(!ao_file)
		return init_device(card);
#else	
	if(!ao_file)
		return vo_mpegpes_fd;	//video fd
#endif

	vo_mpegpes_fd2=open(ao_file,O_WRONLY|O_CREAT,0666);
	if(vo_mpegpes_fd2<0)
	{
		mp_msg(MSGT_VO, MSGL_ERR, "ao_mpegpes: %s\n", strerror(errno));
		return -1;
	}
	return vo_mpegpes_fd2;
}
예제 #11
0
static int preinit(const char *arg)
{
    const opt_t subopts[] = {
        {"outfile",     OPT_ARG_MSTRZ,    &md5sum_outfile,   NULL},
        {NULL, 0, NULL, NULL}
    };

    mp_msg(MSGT_VO, MSGL_V, "%s: %s\n", info.short_name,
           "Parsing suboptions.");

    md5sum_outfile = strdup("md5sums");
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }

    mp_msg(MSGT_VO, MSGL_V, "%s: outfile --> %s\n", info.short_name,
                                                            md5sum_outfile);

    mp_msg(MSGT_VO, MSGL_V, "%s: %s\n", info.short_name,
           "Suboptions parsed OK.");
    return 0;
}
예제 #12
0
파일: vo_tga.c 프로젝트: dontsueme/ncmjb
static int preinit(const char *arg) {
	int id = 0;
	const opt_t subopts[] = {
	{ "id",          OPT_ARG_INT,  &id,  NULL},
	{ "mode", OPT_ARG_INT, &smp.buffercount, NULL },
	{ NULL } };

	if (subopt_parse(arg, subopts) != 0) {
		//mp_msg(MSGT_VO, MSGL_WARN, MSGTR_LIBVO_TGA_UnknownSubdevice, arg);
		mp_tmsg(MSGT_VO,MSGL_WARN, "[VO_TGA] Unknown subdevice: %s.\n",arg);
		return ENOSYS;
	}

	if (smp.buffercount < 1 || smp.buffercount > 2 || id < 0) { //Todo: check if shm_setting_id exists
		return -1;
	}
	printf("buffercount: %d  id: %d\n", smp.buffercount, id);

	initstruct(&smp);
	setNames(id, &smp);

	return 0;
}
예제 #13
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_scaletempo_t* s = af->setup;
  switch(cmd){
  case AF_CONTROL_REINIT:{
    af_data_t* data = (af_data_t*)arg;
    float srate = data->rate / 1000.0f;
    int nch = data->nch;
    int bps;
    int use_int = 0;
    int frames_stride, frames_overlap;
    int i, j;

    mp_msg(MSGT_AFILTER, MSGL_V,
           "[scaletempo] %.3f speed * %.3f scale_nominal = %.3f\n",
           s->speed, s->scale_nominal, s->scale);

    if (s->scale == 1.0) {
      if (s->speed_tempo && s->speed_pitch)
        return AF_DETACH;
      memcpy(af->data, data, sizeof(af_data_t));
      return af_test_output(af, data);
    }

    af->data->rate = data->rate;
    af->data->nch  = data->nch;
    if ( data->format == AF_FORMAT_S16_LE
         || data->format == AF_FORMAT_S16_BE ) {
      use_int = 1;
      af->data->format  = AF_FORMAT_S16_NE;
      af->data->bps     = bps = 2;
    } else {
      af->data->format = AF_FORMAT_FLOAT_NE;
      af->data->bps    = bps = 4;
    }

    frames_stride           = srate * s->ms_stride;
    s->bytes_stride         = frames_stride * bps * nch;
    s->bytes_stride_scaled  = s->scale * s->bytes_stride;
    s->frames_stride_scaled = s->scale * frames_stride;
    s->frames_stride_error  = 0;
    af->mul = (double)s->bytes_stride / s->bytes_stride_scaled;

    frames_overlap = frames_stride * s->percent_overlap;
    if (frames_overlap <= 0) {
      s->bytes_standing   = s->bytes_stride;
      s->samples_standing = s->bytes_standing / bps;
      s->output_overlap   = NULL;
    } else {
      int old_overlap = s->bytes_overlap;
      s->samples_overlap  = frames_overlap * nch;
      s->bytes_overlap    = frames_overlap * nch * bps;
      s->bytes_standing   = s->bytes_stride - s->bytes_overlap;
      s->samples_standing = s->bytes_standing / bps;
      s->buf_overlap      = realloc(s->buf_overlap, s->bytes_overlap);
      s->table_blend      = realloc(s->table_blend, s->bytes_overlap * 4);
      if(!s->buf_overlap || !s->table_blend) {
        mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
        return AF_ERROR;
      }
      // not necessarily correct, but keeping old data if possible
      // avoids clicks when changing speed.
      if (s->bytes_overlap != old_overlap)
        memset(s->buf_overlap, 0, s->bytes_overlap);
      if (use_int) {
        int32_t* pb = s->table_blend;
        int64_t blend = 0;
        for (i=0; i<frames_overlap; i++) {
          int32_t v = blend / frames_overlap;
          for (j=0; j<nch; j++) {
            *pb++ = v;
          }
          blend += 65536;  // 2^16
        }
        s->output_overlap = output_overlap_s16;
      } else {
        float* pb = s->table_blend;
        for (i=0; i<frames_overlap; i++) {
          float v = i / (float)frames_overlap;
          for (j=0; j<nch; j++) {
            *pb++ = v;
          }
        }
        s->output_overlap = output_overlap_float;
      }
    }

    s->frames_search = (frames_overlap > 1) ? srate * s->ms_search : 0;
    if (s->frames_search <= 0) {
      s->best_overlap_offset = NULL;
    } else {
      if (use_int) {
        int64_t t = frames_overlap;
        int32_t n = 8589934588LL / (t * t);  // 4 * (2^31 - 1) / t^2
        int32_t* pw;
        s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap * 2 + UNROLL_PADDING);
        s->table_window = realloc(s->table_window, s->bytes_overlap * 2 - nch * bps * 2);
        if(!s->buf_pre_corr || !s->table_window) {
          mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
          return AF_ERROR;
        }
        memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0, UNROLL_PADDING);
        pw = s->table_window;
        for (i=1; i<frames_overlap; i++) {
          int32_t v = ( i * (t - i) * n ) >> 15;
          for (j=0; j<nch; j++) {
            *pw++ = v;
          }
        }
        s->best_overlap_offset = best_overlap_offset_s16;
      } else {
        float* pw;
        s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap);
        s->table_window = realloc(s->table_window, s->bytes_overlap - nch * bps);
        if(!s->buf_pre_corr || !s->table_window) {
          mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
          return AF_ERROR;
        }
        pw = s->table_window;
        for (i=1; i<frames_overlap; i++) {
          float v = i * (frames_overlap - i);
          for (j=0; j<nch; j++) {
            *pw++ = v;
          }
        }
        s->best_overlap_offset = best_overlap_offset_float;
      }
    }

    s->bytes_per_frame = bps * nch;
    s->num_channels    = nch;

    s->bytes_queue
      = (s->frames_search + frames_stride + frames_overlap) * bps * nch;
    s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING);
    if(!s->buf_queue) {
      mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
      return AF_ERROR;
    }

    mp_msg (MSGT_AFILTER, MSGL_DBG2, "[scaletempo] "
            "%.2f stride_in, %i stride_out, %i standing, "
            "%i overlap, %i search, %i queue, %s mode\n",
            s->frames_stride_scaled,
            (int)(s->bytes_stride / nch / bps),
            (int)(s->bytes_standing / nch / bps),
            (int)(s->bytes_overlap / nch / bps),
            s->frames_search,
            (int)(s->bytes_queue / nch / bps),
            (use_int?"s16":"float"));

    return af_test_output(af, (af_data_t*)arg);
  }
  case AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET:{
    if (s->speed_tempo) {
      if (s->speed_pitch) {
        break;
      }
      s->speed = *(float*)arg;
      s->scale = s->speed * s->scale_nominal;
    } else {
      if (s->speed_pitch) {
        s->speed = 1 / *(float*)arg;
        s->scale = s->speed * s->scale_nominal;
        break;
      }
    }
    return AF_OK;
  }
  case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_SET:{
    s->scale = *(float*)arg;
    return AF_OK;
  }
  case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_GET:
    *(float*)arg = s->scale;
    return AF_OK;
  case AF_CONTROL_COMMAND_LINE:{
    strarg_t speed = {};
    opt_t subopts[] = {
      {"scale",   OPT_ARG_FLOAT, &s->scale_nominal, NULL},
      {"stride",  OPT_ARG_FLOAT, &s->ms_stride, NULL},
      {"overlap", OPT_ARG_FLOAT, &s->percent_overlap, NULL},
      {"search",  OPT_ARG_FLOAT, &s->ms_search, NULL},
      {"speed",   OPT_ARG_STR,   &speed, NULL},
      {NULL},
    };
    if (subopt_parse(arg, subopts) != 0) {
      return AF_ERROR;
    }
    if (s->scale_nominal <= 0) {
      mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": scale > 0\n");
      return AF_ERROR;
    }
    if (s->ms_stride <= 0) {
      mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": stride > 0\n");
      return AF_ERROR;
    }
    if (s->percent_overlap < 0 || s->percent_overlap > 1) {
      mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": 0 <= overlap <= 1\n");
      return AF_ERROR;
    }
    if (s->ms_search < 0) {
      mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": search >= 0\n");
      return AF_ERROR;
    }
    if (speed.len > 0) {
      if (strcmp(speed.str, "pitch") == 0) {
        s->speed_tempo = 0;
        s->speed_pitch = 1;
      } else if (strcmp(speed.str, "tempo") == 0) {
        s->speed_tempo = 1;
        s->speed_pitch = 0;
      } else if (strcmp(speed.str, "none") == 0) {
        s->speed_tempo = 0;
        s->speed_pitch = 0;
      } else if (strcmp(speed.str, "both") == 0) {
        s->speed_tempo = 1;
        s->speed_pitch = 1;
      } else {
        mp_msg(MSGT_AFILTER, MSGL_ERR, "[scaletempo] "
               MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
               ": speed=[pitch|tempo|none|both]\n");
        return AF_ERROR;
      }
    }
    s->scale = s->speed * s->scale_nominal;
    mp_msg(MSGT_AFILTER, MSGL_DBG2, "[scaletempo] %6.3f scale, %6.2f stride, %6.2f overlap, %6.2f search, speed = %s\n", s->scale_nominal, s->ms_stride, s->percent_overlap, s->ms_search, (s->speed_tempo?(s->speed_pitch?"tempo and speed":"tempo"):(s->speed_pitch?"pitch":"none")));
    return AF_OK;
  }
  }
예제 #14
0
파일: ao_jack.c 프로젝트: 0p1pp1/mplayer
static int init(int rate, int channels, int format, int flags) {
  const char **matching_ports = NULL;
  char *port_name = NULL;
  char *client_name = NULL;
  int autostart = 0;
  int connect = 1;
  const opt_t subopts[] = {
    {"port", OPT_ARG_MSTRZ, &port_name, NULL},
    {"name", OPT_ARG_MSTRZ, &client_name, NULL},
    {"estimate", OPT_ARG_BOOL, &estimate, NULL},
    {"autostart", OPT_ARG_BOOL, &autostart, NULL},
    {"connect", OPT_ARG_BOOL, &connect, NULL},
    {NULL}
  };
  jack_options_t open_options = JackUseExactName;
  int port_flags = JackPortIsInput;
  int i;
  estimate = 1;
  if (subopt_parse(ao_subdevice, subopts) != 0) {
    print_help();
    return 0;
  }
  if (channels > MAX_CHANS) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", channels);
    goto err_out;
  }
  if (!client_name) {
    client_name = malloc(40);
    sprintf(client_name, "MPlayer [%d]", getpid());
  }
  if (!autostart)
    open_options |= JackNoStartServer;
  client = jack_client_open(client_name, open_options, NULL);
  if (!client) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n");
    goto err_out;
  }
  buffer = av_fifo_alloc(BUFFSIZE);
  jack_set_process_callback(client, outputaudio, 0);

  // list matching ports if connections should be made
  if (connect) {
    if (!port_name)
      port_flags |= JackPortIsPhysical;
    matching_ports = jack_get_ports(client, port_name, NULL, port_flags);
    i = 0;
    while (matching_ports && matching_ports[i]) i++;
    if (!i) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n");
      goto err_out;
    }
    if (channels > i) channels = i;
  }
  num_ports = channels;

  // create out_* output ports
  for (i = 0; i < num_ports; i++) {
    char pname[30];
    snprintf(pname, 30, "out_%d", i);
    ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    if (!ports[i]) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n");
      goto err_out;
    }
  }
  if (jack_activate(client)) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n");
    goto err_out;
  }
  for (i = 0; i < num_ports && matching_ports && matching_ports[i]; i++) {
    if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n");
      goto err_out;
    }
  }
  rate = jack_get_sample_rate(client);
  jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) +
                         jack_get_buffer_size(client)) / (float)rate;
  callback_interval = 0;

  ao_data.channels = channels;
  ao_data.samplerate = rate;
  ao_data.format = AF_FORMAT_FLOAT_NE;
  ao_data.bps = channels * rate * sizeof(float);
  ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS;
  ao_data.outburst = CHUNK_SIZE;
  free(matching_ports);
  free(port_name);
  free(client_name);
  return 1;

err_out:
  free(matching_ports);
  free(port_name);
  free(client_name);
  if (client)
    jack_client_close(client);
  av_fifo_free(buffer);
  buffer = NULL;
  return 0;
}
static int
preinit (const char *arg)
{
  struct v4l2_output vout;
  int err;

  if (subopt_parse (arg, subopts) != 0)
  {
    mp_msg (MSGT_VO, MSGL_FATAL,
            "\n-vo ivtv command line help:\n"
            "Example: mplayer -vo ivtv:device=/dev/video16:output=2\n"
            "\nOptions:\n"
            "  device=/dev/videoX\n"
            "    Name of the MPEG decoder device file.\n"
            "  output=<0-...>\n"
            "    V4L2 id of the TV output.\n"
            "\n" );
    return -1;
  }

  if (!device)
    device = strdup (DEFAULT_MPEG_DECODER);

  ivtv_fd = open (device, O_RDWR);
  if (ivtv_fd < 0)
  {
    free (device);
    mp_msg (MSGT_VO, MSGL_FATAL, "%s %s\n", IVTV_VO_HDR, strerror (errno));
    return -1;
  }

  /* list available outputs */
  vout.index = 0;
  err = 1;
  mp_msg (MSGT_VO, MSGL_INFO, "%s Available video outputs: ", IVTV_VO_HDR);
  while (ioctl (ivtv_fd, VIDIOC_ENUMOUTPUT, &vout) >= 0)
  {
    err = 0;
    mp_msg (MSGT_VO, MSGL_INFO, "'#%d, %s' ", vout.index, vout.name);
    vout.index++;
  }
  if (err)
  {
    mp_msg (MSGT_VO, MSGL_INFO, "none\n");
    free (device);
    return -1;
  }
  else
    mp_msg (MSGT_VO, MSGL_INFO, "\n");

  /* set user specified output */
  if (output != -1)
  {
    if (ioctl (ivtv_fd, VIDIOC_S_OUTPUT, &output) < 0)
    {
      mp_msg (MSGT_VO, MSGL_ERR,
              "%s can't set output (%s)\n", IVTV_VO_HDR, strerror (errno));
      free (device);
      return -1;
    }
  }

  /* display device name */
  mp_msg (MSGT_VO, MSGL_INFO, "%s using %s\n", IVTV_VO_HDR, device);
  free (device);

  /* display current video output */
  if (ioctl (ivtv_fd, VIDIOC_G_OUTPUT, &output) == 0)
  {
    vout.index = output;
    if (ioctl (ivtv_fd, VIDIOC_ENUMOUTPUT, &vout) < 0)
    {
      mp_msg (MSGT_VO, MSGL_ERR,
              "%s can't get output (%s).\n", IVTV_VO_HDR, strerror (errno));
      return -1;
    }
    else
      mp_msg (MSGT_VO, MSGL_INFO,
              "%s video output: %s\n", IVTV_VO_HDR, vout.name);
  }
  else
  {
    mp_msg (MSGT_VO, MSGL_ERR,
            "%s can't get output (%s).\n", IVTV_VO_HDR, strerror (errno));
    return -1;
  }

  /* clear output */
  ivtv_reset (1);

  return 0;
}
예제 #16
0
파일: ao_sdl.c 프로젝트: zerix/mpv
static int init(struct ao *ao, char *params)
{
    if (SDL_WasInit(SDL_INIT_AUDIO)) {
        mp_msg(MSGT_AO, MSGL_ERR, "[sdl] already initialized\n");
        return -1;
    }

    float buflen = 0; // use SDL default
    float bufcnt = 2;
    const opt_t subopts[] = {
        {"buflen", OPT_ARG_FLOAT, &buflen, NULL},
        {"bufcnt", OPT_ARG_FLOAT, &bufcnt, NULL},
        {NULL}
    };
    if (subopt_parse(params, subopts) != 0) {
        print_help();
        return -1;
    }

    struct priv *priv = talloc_zero(ao, struct priv);
    ao->priv = priv;

    if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
        if (!ao->probing)
            mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_Init failed\n");
        uninit(ao, true);
        return -1;
    }

    struct mp_chmap_sel sel = {0};
    mp_chmap_sel_add_waveext_def(&sel);
    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) {
        uninit(ao, true);
        return -1;
    }

    SDL_AudioSpec desired, obtained;

    switch (ao->format) {
        case AF_FORMAT_U8: desired.format = AUDIO_U8; break;
        case AF_FORMAT_S8: desired.format = AUDIO_S8; break;
        case AF_FORMAT_U16_LE: desired.format = AUDIO_U16LSB; break;
        case AF_FORMAT_U16_BE: desired.format = AUDIO_U16MSB; break;
        default:
        case AF_FORMAT_S16_LE: desired.format = AUDIO_S16LSB; break;
        case AF_FORMAT_S16_BE: desired.format = AUDIO_S16MSB; break;
#ifdef AUDIO_S32LSB
        case AF_FORMAT_S32_LE: desired.format = AUDIO_S32LSB; break;
#endif
#ifdef AUDIO_S32MSB
        case AF_FORMAT_S32_BE: desired.format = AUDIO_S32MSB; break;
#endif
#ifdef AUDIO_F32LSB
        case AF_FORMAT_FLOAT_LE: desired.format = AUDIO_F32LSB; break;
#endif
#ifdef AUDIO_F32MSB
        case AF_FORMAT_FLOAT_BE: desired.format = AUDIO_F32MSB; break;
#endif
    }
    desired.freq = ao->samplerate;
    desired.channels = ao->channels.num;
    desired.samples = FFMIN(32768, ceil_power_of_two(ao->samplerate * buflen));
    desired.callback = audio_callback;
    desired.userdata = ao;

    mp_msg(MSGT_AO, MSGL_V, "[sdl] requested format: %d Hz, %d channels, %x, "
           "buffer size: %d samples\n",
           (int) desired.freq, (int) desired.channels,
           (int) desired.format, (int) desired.samples);

    obtained = desired;
    if (SDL_OpenAudio(&desired, &obtained)) {
        if (!ao->probing)
            mp_msg(MSGT_AO, MSGL_ERR, "[sdl] could not open audio: %s\n",
                SDL_GetError());
        uninit(ao, true);
        return -1;
    }

    mp_msg(MSGT_AO, MSGL_V, "[sdl] obtained format: %d Hz, %d channels, %x, "
           "buffer size: %d samples\n",
           (int) obtained.freq, (int) obtained.channels,
           (int) obtained.format, (int) obtained.samples);

    switch (obtained.format) {
        case AUDIO_U8: ao->format = AF_FORMAT_U8; break;
        case AUDIO_S8: ao->format = AF_FORMAT_S8; break;
        case AUDIO_S16LSB: ao->format = AF_FORMAT_S16_LE; break;
        case AUDIO_S16MSB: ao->format = AF_FORMAT_S16_BE; break;
        case AUDIO_U16LSB: ao->format = AF_FORMAT_U16_LE; break;
        case AUDIO_U16MSB: ao->format = AF_FORMAT_U16_BE; break;
#ifdef AUDIO_S32LSB
        case AUDIO_S32LSB: ao->format = AF_FORMAT_S32_LE; break;
#endif
#ifdef AUDIO_S32MSB
        case AUDIO_S32MSB: ao->format = AF_FORMAT_S32_BE; break;
#endif
#ifdef AUDIO_F32LSB
        case AUDIO_F32LSB: ao->format = AF_FORMAT_FLOAT_LE; break;
#endif
#ifdef AUDIO_F32MSB
        case AUDIO_F32MSB: ao->format = AF_FORMAT_FLOAT_BE; break;
#endif
        default:
            if (!ao->probing)
                mp_msg(MSGT_AO, MSGL_ERR,
                       "[sdl] could not find matching format\n");
            uninit(ao, true);
            return -1;
    }

    if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, obtained.channels)) {
        uninit(ao, true);
        return -1;
    }

    ao->samplerate = obtained.freq;
    priv->buffer = av_fifo_alloc(obtained.size * bufcnt);
    priv->buffer_mutex = SDL_CreateMutex();
    if (!priv->buffer_mutex) {
        mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_CreateMutex failed\n");
        uninit(ao, true);
        return -1;
    }
    priv->underrun_cond = SDL_CreateCond();
    if (!priv->underrun_cond) {
        mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_CreateCond failed\n");
        uninit(ao, true);
        return -1;
    }

    priv->unpause = 1;
    priv->paused = 1;
    priv->callback_time0 = priv->callback_time1 = mp_time_us();

    return 1;
}
예제 #17
0
파일: vo_xv.c 프로젝트: kax4/mpv
static int preinit(struct vo *vo, const char *arg)
{
    XvPortID xv_p;
    int busy_ports = 0;
    unsigned int i;
    strarg_t ck_src_arg = { 0, NULL };
    strarg_t ck_method_arg = { 0, NULL };
    struct xvctx *ctx = talloc_zero(vo, struct xvctx);
    vo->priv = ctx;
    int xv_adaptor = -1;

    if (!vo_init(vo))
        return -1;

    struct vo_x11_state *x11 = vo->x11;

    const opt_t subopts[] =
    {
      /* name         arg type     arg var         test */
      {  "port",      OPT_ARG_INT, &x11->xv_port,  int_pos },
      {  "adaptor",   OPT_ARG_INT, &xv_adaptor,    int_non_neg },
      {  "ck",        OPT_ARG_STR, &ck_src_arg,    xv_test_ck },
      {  "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },
      {  NULL }
    };

    x11->xv_port = 0;

    /* parse suboptions */
    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }

    /* modify colorkey settings according to the given options */
    xv_setup_colorkeyhandling(vo, ck_method_arg.str, ck_src_arg.str);

    /* check for Xvideo extension */
    unsigned int ver, rel, req, ev, err;
    if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
        mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] Sorry, Xv not supported by this X11 version/driver\n[VO_XV] ******** Try with  -vo x11 *********\n");
        goto error;
    }

    /* check for Xvideo support */
    if (Success !=
        XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
                        &ctx->adaptors, &ctx->ai)) {
        mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] XvQueryAdaptors failed.\n");
        goto error;
    }

    /* check adaptors */
    if (x11->xv_port) {
        int port_found;

        for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
            if ((ctx->ai[i].type & XvInputMask)
                && (ctx->ai[i].type & XvImageMask)) {
                for (xv_p = ctx->ai[i].base_id;
                     xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
                     ++xv_p) {
                    if (xv_p == x11->xv_port) {
                        port_found = 1;
                        break;
                    }
                }
            }
        }
        if (port_found) {
            if (XvGrabPort(x11->display, x11->xv_port, CurrentTime))
                x11->xv_port = 0;
        } else {
            mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Invalid port parameter, overriding with port 0.\n");
            x11->xv_port = 0;
        }
    }

    for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) {
        /* check if adaptor number has been specified */
        if (xv_adaptor != -1 && xv_adaptor != i)
            continue;

        if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
            for (xv_p = ctx->ai[i].base_id;
                 xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
                if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
                    x11->xv_port = xv_p;
                    mp_msg(MSGT_VO, MSGL_V,
                           "[VO_XV] Using Xv Adapter #%d (%s)\n",
                           i, ctx->ai[i].name);
                    break;
                } else {
                    mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Could not grab port %i.\n",
                           (int) xv_p);
                    ++busy_ports;
                }
        }
    }
    if (!x11->xv_port) {
        if (busy_ports)
            mp_tmsg(MSGT_VO, MSGL_ERR,
                "[VO_XV] Could not find free Xvideo port - maybe another process is already\n"\
                "[VO_XV] using it. Close all video applications, and try again. If that does\n"\
                "[VO_XV] not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n");
        else
            mp_tmsg(MSGT_VO, MSGL_ERR,
                "[VO_XV] It seems there is no Xvideo support for your video card available.\n"\
                "[VO_XV] Run 'xvinfo' to verify its Xv support and read\n"\
                "[VO_XV] DOCS/HTML/en/video.html#xv!\n"\
                "[VO_XV] See 'mpv -vo help' for other (non-xv) video out drivers.\n"\
                "[VO_XV] Try -vo x11.\n");
        goto error;
    }

    if (!vo_xv_init_colorkey(vo)) {
        goto error;             // bail out, colorkey setup failed
    }
    vo_xv_enable_vsync(vo);
    vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);

    ctx->fo = XvListImageFormats(x11->display, x11->xv_port,
                                 (int *) &ctx->formats);

    ctx->osd_backup = talloc_steal(ctx, mp_draw_sub_backup_new());

    return 0;

  error:
    uninit(vo);                 // free resources
    return -1;
}
예제 #18
0
파일: ao_pcm.c 프로젝트: BOTCrusher/sagetv
// open & setup audio device
// return: 1=success 0=fail
static int init(int rate,int channels,int format,int flags){
	int bits;
	opt_t subopts[] = {
	  {"waveheader", OPT_ARG_BOOL, &ao_pcm_waveheader, NULL},
	  {"file",       OPT_ARG_MSTRZ, &ao_outputfilename, NULL},
	  {"fast",       OPT_ARG_BOOL, &fast, NULL},
	  {NULL}
	};
	// set defaults
	ao_pcm_waveheader = 1;

	if (subopt_parse(ao_subdevice, subopts) != 0) {
	  return 0;
	}
	if (!ao_outputfilename){
	  ao_outputfilename =
	    strdup(ao_pcm_waveheader?"audiodump.wav":"audiodump.pcm");
	}

	/* bits is only equal to format if (format == 8) or (format == 16);
	   this means that the following "if" is a kludge and should
	   really be a switch to be correct in all cases */

	bits=8;
	switch(format){
	case AF_FORMAT_S8:
	    format=AF_FORMAT_U8;
	case AF_FORMAT_U8:
	    break;
	default:
	    format=AF_FORMAT_S16_LE;
	    bits=16;
	    break;
	}

	ao_data.outburst = 65536;
	ao_data.buffersize= 2*65536;
	ao_data.channels=channels;
	ao_data.samplerate=rate;
	ao_data.format=format;
	ao_data.bps=channels*rate*(bits/8);

	wavhdr.riff = le2me_32(WAV_ID_RIFF);
	wavhdr.wave = le2me_32(WAV_ID_WAVE);
	wavhdr.fmt = le2me_32(WAV_ID_FMT);
	wavhdr.fmt_length = le2me_32(16);
	wavhdr.fmt_tag = le2me_16(WAV_ID_PCM);
	wavhdr.channels = le2me_16(ao_data.channels);
	wavhdr.sample_rate = le2me_32(ao_data.samplerate);
	wavhdr.bytes_per_second = le2me_32(ao_data.bps);
	wavhdr.bits = le2me_16(bits);
	wavhdr.block_align = le2me_16(ao_data.channels * (bits / 8));
	
	wavhdr.data = le2me_32(WAV_ID_DATA);
	wavhdr.data_length=le2me_32(0x7ffff000);
	wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;

	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_FileInfo, ao_outputfilename, 
	       (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate, 
	       (channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format));
	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_HintInfo);

	fp = fopen(ao_outputfilename, "wb");
	if(fp) {
		if(ao_pcm_waveheader){ /* Reserve space for wave header */
			fwrite(&wavhdr,sizeof(wavhdr),1,fp);
			wavhdr.file_length=wavhdr.data_length=0;
		}
		return 1;
	}
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_PCM_CantOpenOutputFile, 
               ao_outputfilename);
	return 0;
}
예제 #19
0
static int init(int rate,int channels,int format,int flags)
{
AudioStreamBasicDescription inDesc;
ComponentDescription desc;
Component comp;
AURenderCallbackStruct renderCallback;
OSStatus err;
UInt32 size, maxFrames, b_alive;
char *psz_name;
AudioDeviceID devid_def = 0;
int device_id, display_help = 0;

    const opt_t subopts[] = {
        {"device_id", OPT_ARG_INT,  &device_id,    NULL},
        {"help",      OPT_ARG_BOOL, &display_help, NULL},
        {NULL}
    };

    // set defaults
    device_id = 0;

    if (subopt_parse(ao_subdevice, subopts) != 0 || display_help) {
        print_help();
        if (!display_help)
            return 0;
    }

    ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags);

    ao = calloc(1, sizeof(ao_coreaudio_t));

    ao->i_selected_dev = 0;
    ao->b_supports_digital = 0;
    ao->b_digital = 0;
    ao->b_muted = 0;
    ao->b_stream_format_changed = 0;
    ao->i_hog_pid = -1;
    ao->i_stream_id = 0;
    ao->i_stream_index = -1;
    ao->b_revert = 0;
    ao->b_changed_mixing = 0;

    if (device_id == 0) {
        /* Find the ID of the default Device. */
        err = GetAudioProperty(kAudioObjectSystemObject,
                               kAudioHardwarePropertyDefaultOutputDevice,
                               sizeof(UInt32), &devid_def);
        if (err != noErr)
        {
            ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err);
            goto err_out;
        }
    } else {
        devid_def = device_id;
    }

    /* Retrieve the name of the device. */
    err = GetAudioPropertyString(devid_def,
                                 kAudioObjectPropertyName,
                                 &psz_name);
    if (err != noErr)
    {
        ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err);
        goto err_out;
    }

    ao_msg(MSGT_AO,MSGL_V, "got audio output device ID: %"PRIu32" Name: %s\n", devid_def, psz_name );

    /* Probe whether device support S/PDIF stream output if input is AC3 stream. */
    if (AF_FORMAT_IS_AC3(format)) {
        if (AudioDeviceSupportsDigital(devid_def))
        {
            ao->b_supports_digital = 1;
        }
        ao_msg(MSGT_AO, MSGL_V,
               "probe default audio output device about support for digital s/pdif output: %d\n",
               ao->b_supports_digital );
    }

    free(psz_name);

    // Save selected device id
    ao->i_selected_dev = devid_def;

	// Build Description for the input format
	inDesc.mSampleRate=rate;
	inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM;
	inDesc.mChannelsPerFrame=channels;
	inDesc.mBitsPerChannel=af_fmt2bits(format);

    if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) {
	// float
		inDesc.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked;
    }
    else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI) {
	// signed int
		inDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked;
    }
    else {
	// unsigned int
		inDesc.mFormatFlags = kAudioFormatFlagIsPacked;
    }
    if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE)
        inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian;

    inDesc.mFramesPerPacket = 1;
    ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8);
    print_format(MSGL_V, "source:",&inDesc);

    if (ao->b_supports_digital)
    {
        b_alive = 1;
        err = GetAudioProperty(ao->i_selected_dev,
                               kAudioDevicePropertyDeviceIsAlive,
                               sizeof(UInt32), &b_alive);
        if (err != noErr)
            ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err);
        if (!b_alive)
            ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" );

        /* S/PDIF output need device in HogMode. */
        err = GetAudioProperty(ao->i_selected_dev,
                               kAudioDevicePropertyHogMode,
                               sizeof(pid_t), &ao->i_hog_pid);
        if (err != noErr)
        {
            /* This is not a fatal error. Some drivers simply don't support this property. */
            ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is hogged: [%4.4s]\n",
                     (char *)&err);
            ao->i_hog_pid = -1;
        }

        if (ao->i_hog_pid != -1 && ao->i_hog_pid != getpid())
        {
            ao_msg(MSGT_AO, MSGL_WARN, "Selected audio device is exclusively in use by another program.\n" );
            goto err_out;
        }
        ao->stream_format = inDesc;
        return OpenSPDIF();
    }

	/* original analog output code */
	desc.componentType = kAudioUnitType_Output;
	desc.componentSubType = (device_id == 0) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
	desc.componentFlags = 0;
	desc.componentFlagsMask = 0;

	comp = FindNextComponent(NULL, &desc);  //Finds an component that meets the desc spec's
	if (comp == NULL) {
		ao_msg(MSGT_AO, MSGL_WARN, "Unable to find Output Unit component\n");
		goto err_out;
	}

	err = OpenAComponent(comp, &(ao->theOutputUnit));  //gains access to the services provided by the component
	if (err) {
		ao_msg(MSGT_AO, MSGL_WARN, "Unable to open Output Unit component: [%4.4s]\n", (char *)&err);
		goto err_out;
	}

	// Initialize AudioUnit
	err = AudioUnitInitialize(ao->theOutputUnit);
	if (err) {
		ao_msg(MSGT_AO, MSGL_WARN, "Unable to initialize Output Unit component: [%4.4s]\n", (char *)&err);
		goto err_out1;
	}

	size =  sizeof(AudioStreamBasicDescription);
	err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inDesc, size);

	if (err) {
		ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the input format: [%4.4s]\n", (char *)&err);
		goto err_out2;
	}

	size = sizeof(UInt32);
	err = AudioUnitGetProperty(ao->theOutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Input, 0, &maxFrames, &size);

	if (err)
	{
		ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned [%4.4s] when getting kAudioDevicePropertyBufferSize\n", (char *)&err);
		goto err_out2;
	}

	//Set the Current Device to the Default Output Unit.
    err = AudioUnitSetProperty(ao->theOutputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &ao->i_selected_dev, sizeof(ao->i_selected_dev));

	ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame;

	ao_data.samplerate = inDesc.mSampleRate;
	ao_data.channels = inDesc.mChannelsPerFrame;
    ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame;
    ao_data.outburst = ao->chunk_size;
	ao_data.buffersize = ao_data.bps;

	ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size;
    ao->buffer_len = ao->num_chunks * ao->chunk_size;
    ao->buffer = av_fifo_alloc(ao->buffer_len);

	ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len);

    renderCallback.inputProc = theRenderProc;
    renderCallback.inputProcRefCon = 0;
    err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct));
	if (err) {
		ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback: [%4.4s]\n", (char *)&err);
		goto err_out2;
	}

	reset();

    return CONTROL_OK;

err_out2:
    AudioUnitUninitialize(ao->theOutputUnit);
err_out1:
    CloseComponent(ao->theOutputUnit);
err_out:
    av_fifo_free(ao->buffer);
    free(ao);
    ao = NULL;
    return CONTROL_FALSE;
}
static int
preinit (const char *arg)
{
  struct v4l2_output vout;
  struct v4l2_ext_controls ctrls;
  int err;

  if (subopt_parse (arg, subopts) != 0)
  {
    mp_msg (MSGT_VO, MSGL_FATAL,
            "\n-vo v4l2 command line help:\n"
            "Example: mplayer -vo v4l2:device=/dev/video16:output=2\n"
            "\nOptions:\n"
            "  device=/dev/videoX\n"
            "    Name of the MPEG decoder device file.\n"
            "  output=<0-...>\n"
            "    V4L2 id of the TV output.\n"
            "\n" );
    return -1;
  }

  if (!device)
    device = strdup (DEFAULT_MPEG_DECODER);

  v4l2_fd = open (device, O_RDWR);
  if (v4l2_fd < 0)
  {
    free (device);
    mp_msg (MSGT_VO, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror (errno));
    return -1;
  }

  /* check for device hardware MPEG decoding capability */
  ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
  ctrls.count = 0;
  ctrls.controls = NULL;

  if (ioctl (v4l2_fd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0)
  {
    free (device);
    mp_msg (MSGT_OPEN, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror (errno));
    return -1;
  }

  /* list available outputs */
  vout.index = 0;
  err = 1;
  mp_msg (MSGT_VO, MSGL_INFO, "%s Available video outputs: ", V4L2_VO_HDR);
  while (ioctl (v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) >= 0)
  {
    err = 0;
    mp_msg (MSGT_VO, MSGL_INFO, "'#%d, %s' ", vout.index, vout.name);
    vout.index++;
  }
  if (err)
  {
    mp_msg (MSGT_VO, MSGL_INFO, "none\n");
    free (device);
    return -1;
  }
  else
    mp_msg (MSGT_VO, MSGL_INFO, "\n");

  /* set user specified output */
  if (output != -1)
  {
    if (ioctl (v4l2_fd, VIDIOC_S_OUTPUT, &output) < 0)
    {
      mp_msg (MSGT_VO, MSGL_ERR,
              "%s can't set output (%s)\n", V4L2_VO_HDR, strerror (errno));
      free (device);
      return -1;
    }
  }

  /* display device name */
  mp_msg (MSGT_VO, MSGL_INFO, "%s using %s\n", V4L2_VO_HDR, device);
  free (device);

  /* display current video output */
  if (ioctl (v4l2_fd, VIDIOC_G_OUTPUT, &output) == 0)
  {
    vout.index = output;
    if (ioctl (v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) < 0)
    {
      mp_msg (MSGT_VO, MSGL_ERR,
              "%s can't get output (%s).\n", V4L2_VO_HDR, strerror (errno));
      return -1;
    }
    else
      mp_msg (MSGT_VO, MSGL_INFO,
              "%s video output: %s\n", V4L2_VO_HDR, vout.name);
  }
  else
  {
    mp_msg (MSGT_VO, MSGL_ERR,
            "%s can't get output (%s).\n", V4L2_VO_HDR, strerror (errno));
    return -1;
  }

  return 0;
}
예제 #21
0
static int preinit(const char *arg) {
	vo_zr2_priv_t *p = &priv;
	const char *dev = NULL;
	char *dev_arg = NULL, *norm_arg = NULL;
	int norm = VIDEO_MODE_AUTO, prebuf = 0;
	const opt_t subopts[] = { /* don't want warnings with -Wall... */
		{ "dev",    OPT_ARG_MSTRZ, &dev_arg,   NULL 	       },
		{ "prebuf", OPT_ARG_BOOL,  &prebuf,    pbc },
		{ "norm",   OPT_ARG_MSTRZ, &norm_arg,  nc  },
		{ NULL,     0, 		   NULL,       NULL 	       }
	};

	VERBOSE("preinit() called with arg: %s\n", arg);
	memset(p, 0, sizeof(*p)); /* set defaults */
	p->vdes = -1;

	if (subopt_parse(arg, subopts)) {
		mp_msg(MSGT_VO, MSGL_FATAL,
				"Allowed suboptions for -vo zr2 are:\n"
				"-  dev=DEVICE               (default: %s)\n"
				"-  norm=PAL|NTSC|SECAM|auto (default: auto)\n"
				"-  prebuf/noprebuf          (default:"
				" noprebuf)\n"
				"\n"
				"Example: mplayer -vo zr2:dev=/dev/video1:"
				"norm=PAL movie.avi\n\n"
				, guess_device(NULL, 0));
		free(norm_arg);
		free(dev_arg);
		return -1;
	}

	/* interpret the strings we got from subopt_parse */
	if (norm_arg) {
		norm = get_norm(norm_arg);
		free(norm_arg);
	}

	if (dev_arg) dev = dev_arg;

	dev = guess_device(dev, 1);
	if (!dev) {
		free(dev_arg);
		uninit();
		return 1;
	}

	p->vdes = open(dev, O_RDWR);
	if (p->vdes < 0) {
		ERROR("error opening %s: %s\n", dev, strerror(errno));
		free(dev_arg);
		uninit();
		return 1;
	}

	free(dev_arg);

	/* check if we really are dealing with a zoran card */
	if (ioctl(p->vdes, MJPIOC_G_PARAMS, &p->zp) < 0) {
		ERROR("%s probably is not a DC10(+)/buz/lml33\n", dev);
		uninit();
		return 1;
	}

	VERBOSE("kernel driver version %d.%d, current norm is %s\n",
			p->zp.major_version, p->zp.minor_version,
			normstring(p->zp.norm));

	/* changing the norm in the zoran_params and MJPIOC_S_PARAMS
	 * does nothing the last time I tried, so bail out if the norm
	 * is not correct */
	if (norm != VIDEO_MODE_AUTO &&  p->zp.norm != norm) {
		ERROR("mplayer currently can't change the video norm, "
				"change it with (eg.) XawTV and retry.\n");
		uninit();
		return 1;
	}

	/* gather useful information */
	if (ioctl(p->vdes, VIDIOCGCAP, &p->vc) < 0) {
		ERROR("error getting video capabilities from %s\n", dev);
		uninit();
		return 1;
	}

	VERBOSE("card reports maxwidth=%d, maxheight=%d\n",
			p->vc.maxwidth, p->vc.maxheight);

	/* according to the mjpegtools source, some cards return a bogus
	 * vc.maxwidth, correct it here. If a new zoran card appears with a
	 * maxwidth different 640, 720 or 768 this code may lead to problems */
	if (p->vc.maxwidth != 640 && p->vc.maxwidth != 768) {
		VERBOSE("card probably reported bogus width (%d), "
				"changing to 720\n", p->vc.maxwidth);
		p->vc.maxwidth = 720;
	}

	p->zrq.count = ZR2_MJPEG_NBUFFERS;
	p->zrq.size = ZR2_MJPEG_SIZE;

	if (ioctl(p->vdes, MJPIOC_REQBUFS, &p->zrq)) {
		ERROR("error requesting %d buffers of size %d\n",
				ZR2_MJPEG_NBUFFERS, ZR2_MJPEG_NBUFFERS);
		uninit();
		return 1;
	}

	VERBOSE("got %ld buffers of size %ld (wanted %d buffers of size %d)\n",
			p->zrq.count, p->zrq.size, ZR2_MJPEG_NBUFFERS,
			ZR2_MJPEG_SIZE);

	p->buf = (unsigned char*)mmap(0, p->zrq.count*p->zrq.size,
			PROT_READ|PROT_WRITE, MAP_SHARED, p->vdes, 0);

	if (p->buf == MAP_FAILED) {
		ERROR("error mapping requested buffers: %s", strerror(errno));
		uninit();
		return 1;
	}

    	return 0;
}
예제 #22
0
static int preinit(const char *arg)
{
    int ppm_type = 0, pgm_type = 0, pgmyuv_type = 0,
        raw_mode = 0, ascii_mode = 0;
    const opt_t subopts[] = {
        {"ppm",         OPT_ARG_BOOL,   &ppm_type,      NULL},
        {"pgm",         OPT_ARG_BOOL,   &pgm_type,      NULL},
        {"pgmyuv",      OPT_ARG_BOOL,   &pgmyuv_type,   NULL},
        {"raw",         OPT_ARG_BOOL,   &raw_mode,      NULL},
        {"ascii",       OPT_ARG_BOOL,   &ascii_mode,    NULL},
        {"outdir",      OPT_ARG_MSTRZ,  &pnm_outdir,    NULL},
        {"subdirs",     OPT_ARG_MSTRZ,  &pnm_subdirs,   NULL},
        {"maxfiles",    OPT_ARG_INT,    &pnm_maxfiles,  (opt_test_f)int_pos},
        {NULL, 0, NULL, NULL}
    };
    const char *info_message = NULL;

    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
                                            MSGTR_VO_ParsingSuboptions);

    pnm_maxfiles = 1000;
    pnm_outdir = strdup(".");
    pnm_subdirs = NULL;

    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }

    pnm_type     = PNM_TYPE_PPM;
    pnm_mode     = PNM_RAW_MODE;

    if (pgmyuv_type) pnm_type     = PNM_TYPE_PGMYUV;
    if (pgm_type)    pnm_type     = PNM_TYPE_PGM;
    if (ppm_type)    pnm_type     = PNM_TYPE_PPM;
    if (ascii_mode)  pnm_mode     = PNM_ASCII_MODE;
    if (raw_mode)    pnm_mode     = PNM_RAW_MODE;

    switch (pnm_mode) {
        case PNM_ASCII_MODE:
            info_message = MSGTR_VO_PNM_ASCIIMode;
            break;
        case PNM_RAW_MODE:
            info_message = MSGTR_VO_PNM_RawMode;
            break;
    }
    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message);

    switch (pnm_type) {
        case PNM_TYPE_PPM:
            info_message = MSGTR_VO_PNM_PPMType;
            break;
        case PNM_TYPE_PGM:
            info_message = MSGTR_VO_PNM_PGMType;
            break;
        case PNM_TYPE_PGMYUV:
            info_message = MSGTR_VO_PNM_PGMYUVType;
            break;
    }
    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message);

    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
                                            MSGTR_VO_SuboptionsParsedOK);
    return 0;
}
예제 #23
0
static int preinit(const char *arg)
{
    opt_t subopts[] = {
        {"progressive", OPT_ARG_BOOL,   &jpeg_progressive_mode, NULL, 0},
        {"baseline",    OPT_ARG_BOOL,   &jpeg_baseline,         NULL, 0},
        {"optimize",    OPT_ARG_INT,    &jpeg_optimize,
                                            (opt_test_f)int_zero_hundred, 0},
        {"smooth",      OPT_ARG_INT,    &jpeg_smooth,
                                            (opt_test_f)int_zero_hundred, 0},
        {"quality",     OPT_ARG_INT,    &jpeg_quality,
                                            (opt_test_f)int_zero_hundred, 0},
        {"dpi",         OPT_ARG_INT,    &jpeg_dpi,              NULL, 0},
        {"outdir",      OPT_ARG_MSTRZ,  &jpeg_outdir,           NULL, 0},
        {"subdirs",     OPT_ARG_MSTRZ,  &jpeg_subdirs,          NULL, 0},
        {"maxfiles",    OPT_ARG_INT,    &jpeg_maxfiles, (opt_test_f)int_pos, 0},
        {NULL, 0, NULL, NULL, 0}
    };
    const char *info_message = NULL;

    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
                                            MSGTR_VO_ParsingSuboptions);

    jpeg_progressive_mode = 0;
    jpeg_baseline = 1;
    jpeg_optimize = 100;
    jpeg_smooth = 0;
    jpeg_quality = 75;
    jpeg_maxfiles = 1000;
    jpeg_outdir = strdup(".");
    jpeg_subdirs = NULL;

    if (subopt_parse(arg, subopts) != 0) {
        return -1;
    }

    if (jpeg_progressive_mode) info_message = MSGTR_VO_JPEG_ProgressiveJPEG;
    else info_message = MSGTR_VO_JPEG_NoProgressiveJPEG;
    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message);

    if (jpeg_baseline) info_message = MSGTR_VO_JPEG_BaselineJPEG;
    else info_message = MSGTR_VO_JPEG_NoBaselineJPEG;
    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message);

    mp_msg(MSGT_VO, MSGL_V, "%s: optimize --> %d\n", info.short_name,
                                                                jpeg_optimize);
    mp_msg(MSGT_VO, MSGL_V, "%s: smooth --> %d\n", info.short_name,
                                                                jpeg_smooth);
    mp_msg(MSGT_VO, MSGL_V, "%s: quality --> %d\n", info.short_name,
                                                                jpeg_quality);
    mp_msg(MSGT_VO, MSGL_V, "%s: dpi --> %d\n", info.short_name,
                                                                jpeg_dpi);
    mp_msg(MSGT_VO, MSGL_V, "%s: outdir --> %s\n", info.short_name,
                                                                jpeg_outdir);
    if (jpeg_subdirs) {
        mp_msg(MSGT_VO, MSGL_V, "%s: subdirs --> %s\n", info.short_name,
                                                                jpeg_subdirs);
        mp_msg(MSGT_VO, MSGL_V, "%s: maxfiles --> %d\n", info.short_name,
                                                                jpeg_maxfiles);
    }

    mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
                                            MSGTR_VO_SuboptionsParsedOK);
    return 0;
}
예제 #24
0
파일: ao_alsa.c 프로젝트: C3MA/fc_mplayer
/*
    open & setup audio device
    return: 1=success 0=fail
*/
static int init(int rate_hz, int channels, int format, int flags)
{
    unsigned int alsa_buffer_time = 500000; /* 0.5 s */
    unsigned int alsa_fragcount = 16;
    int err;
    int block;
    strarg_t device;
    snd_pcm_uframes_t chunk_size;
    snd_pcm_uframes_t bufsize;
    snd_pcm_uframes_t boundary;
    const opt_t subopts[] = {
      {"block", OPT_ARG_BOOL, &block, NULL},
      {"device", OPT_ARG_STR, &device, str_maxlen},
      {NULL}
    };

    char alsa_device[ALSA_DEVICE_SIZE + 1];
    // make sure alsa_device is null-terminated even when using strncpy etc.
    memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1);

    mp_msg(MSGT_AO,MSGL_V,"alsa-init: requested format: %d Hz, %d channels, %x\n", rate_hz,
	channels, format);
    alsa_handler = NULL;
#if SND_LIB_VERSION >= 0x010005
    mp_msg(MSGT_AO,MSGL_V,"alsa-init: using ALSA %s\n", snd_asoundlib_version());
#else
    mp_msg(MSGT_AO,MSGL_V,"alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR);
#endif

    snd_lib_error_set_handler(alsa_error_handler);

    ao_data.samplerate = rate_hz;
    ao_data.format = format;
    ao_data.channels = channels;

    switch (format)
      {
      case AF_FORMAT_S8:
	alsa_format = SND_PCM_FORMAT_S8;
	break;
      case AF_FORMAT_U8:
	alsa_format = SND_PCM_FORMAT_U8;
	break;
      case AF_FORMAT_U16_LE:
	alsa_format = SND_PCM_FORMAT_U16_LE;
	break;
      case AF_FORMAT_U16_BE:
	alsa_format = SND_PCM_FORMAT_U16_BE;
	break;
      case AF_FORMAT_AC3_LE:
      case AF_FORMAT_S16_LE:
      case AF_FORMAT_IEC61937_LE:
	alsa_format = SND_PCM_FORMAT_S16_LE;
	break;
      case AF_FORMAT_AC3_BE:
      case AF_FORMAT_S16_BE:
      case AF_FORMAT_IEC61937_BE:
	alsa_format = SND_PCM_FORMAT_S16_BE;
	break;
      case AF_FORMAT_U32_LE:
	alsa_format = SND_PCM_FORMAT_U32_LE;
	break;
      case AF_FORMAT_U32_BE:
	alsa_format = SND_PCM_FORMAT_U32_BE;
	break;
      case AF_FORMAT_S32_LE:
	alsa_format = SND_PCM_FORMAT_S32_LE;
	break;
      case AF_FORMAT_S32_BE:
	alsa_format = SND_PCM_FORMAT_S32_BE;
	break;
      case AF_FORMAT_U24_LE:
	alsa_format = SND_PCM_FORMAT_U24_3LE;
	break;
      case AF_FORMAT_U24_BE:
	alsa_format = SND_PCM_FORMAT_U24_3BE;
	break;
      case AF_FORMAT_S24_LE:
	alsa_format = SND_PCM_FORMAT_S24_3LE;
	break;
      case AF_FORMAT_S24_BE:
	alsa_format = SND_PCM_FORMAT_S24_3BE;
	break;
      case AF_FORMAT_FLOAT_LE:
	alsa_format = SND_PCM_FORMAT_FLOAT_LE;
	break;
      case AF_FORMAT_FLOAT_BE:
	alsa_format = SND_PCM_FORMAT_FLOAT_BE;
	break;
      case AF_FORMAT_MU_LAW:
	alsa_format = SND_PCM_FORMAT_MU_LAW;
	break;
      case AF_FORMAT_A_LAW:
	alsa_format = SND_PCM_FORMAT_A_LAW;
	break;

      default:
	alsa_format = SND_PCM_FORMAT_MPEG; //? default should be -1
	break;
      }

    //subdevice parsing
    // set defaults
    block = 1;
    /* switch for spdif
     * sets opening sequence for SPDIF
     * sets also the playback and other switches 'on the fly'
     * while opening the abstract alias for the spdif subdevice
     * 'iec958'
     */
    if (AF_FORMAT_IS_IEC61937(format)) {
	device.str = "iec958";
	mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n", channels);
    }
  else
        /* in any case for multichannel playback we should select
         * appropriate device
         */
        switch (channels) {
	case 1:
	case 2:
	  device.str = "default";
	  mp_msg(MSGT_AO,MSGL_V,"alsa-init: setup for 1/2 channel(s)\n");
	  break;
	case 4:
	  if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
	    // hack - use the converter plugin
	    device.str = "plug:surround40";
	  else
	    device.str = "surround40";
	  mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround40\n");
	  break;
	case 6:
	  if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
	    device.str = "plug:surround51";
	  else
	    device.str = "surround51";
	  mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n");
	  break;
	case 8:
	  if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
	    device.str = "plug:surround71";
	  else
	    device.str = "surround71";
	  mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround71\n");
	  break;
	default:
	  device.str = "default";
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ChannelsNotSupported,channels);
        }
    device.len = strlen(device.str);
    if (subopt_parse(ao_subdevice, subopts) != 0) {
        print_help();
        return 0;
    }
    parse_device(alsa_device, device.str, device.len);

    mp_msg(MSGT_AO,MSGL_V,"alsa-init: using device %s\n", alsa_device);

    if (!alsa_handler) {
      int open_mode = block ? 0 : SND_PCM_NONBLOCK;
      int isac3 =  AF_FORMAT_IS_IEC61937(format);
      //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
      mp_msg(MSGT_AO,MSGL_V,"alsa-init: opening device in %sblocking mode\n", block ? "" : "non-");
      if ((err = try_open_device(alsa_device, open_mode, isac3)) < 0)
	{
	  if (err != -EBUSY && !block) {
	    mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_OpenInNonblockModeFailed);
	    if ((err = try_open_device(alsa_device, 0, isac3)) < 0) {
	      mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err));
	      return 0;
	    }
	  } else {
	    mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PlaybackOpenError, snd_strerror(err));
	    return 0;
	  }
	}

      if ((err = snd_pcm_nonblock(alsa_handler, 0)) < 0) {
         mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_ErrorSetBlockMode, snd_strerror(err));
      } else {
	mp_msg(MSGT_AO,MSGL_V,"alsa-init: device reopened in blocking mode\n");
      }

      snd_pcm_hw_params_alloca(&alsa_hwparams);
      snd_pcm_sw_params_alloca(&alsa_swparams);

      // setting hw-parameters
      if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetInitialParameters,
		 snd_strerror(err));
	  return 0;
	}

      err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,
					 SND_PCM_ACCESS_RW_INTERLEAVED);
      if (err < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetAccessType,
	       snd_strerror(err));
	return 0;
      }

      /* workaround for nonsupported formats
	 sets default format to S16_LE if the given formats aren't supported */
      if ((err = snd_pcm_hw_params_test_format(alsa_handler, alsa_hwparams,
                                             alsa_format)) < 0)
      {
         mp_msg(MSGT_AO,MSGL_INFO,
		MSGTR_AO_ALSA_FormatNotSupportedByHardware, af_fmt2str_short(format));
         alsa_format = SND_PCM_FORMAT_S16_LE;
         if (AF_FORMAT_IS_AC3(ao_data.format))
           ao_data.format = AF_FORMAT_AC3_LE;
         else if (AF_FORMAT_IS_IEC61937(ao_data.format))
           ao_data.format = AF_FORMAT_IEC61937_LE;
         else
         ao_data.format = AF_FORMAT_S16_LE;
      }

      if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams,
					      alsa_format)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetFormat,
		 snd_strerror(err));
	  return 0;
	}

      if ((err = snd_pcm_hw_params_set_channels_near(alsa_handler, alsa_hwparams,
						     &ao_data.channels)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetChannels,
		 snd_strerror(err));
	  return 0;
	}

      /* workaround for buggy rate plugin (should be fixed in ALSA 1.0.11)
         prefer our own resampler, since that allows users to choose the resampler,
         even per file if desired */
#if SND_LIB_VERSION >= 0x010009
      if ((err = snd_pcm_hw_params_set_rate_resample(alsa_handler, alsa_hwparams,
						     0)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToDisableResampling,
		 snd_strerror(err));
	  return 0;
	}
#endif

      if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams,
						 &ao_data.samplerate, NULL)) < 0)
        {
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSamplerate2,
		 snd_strerror(err));
	  return 0;
        }

      bytes_per_sample = af_fmt2bits(ao_data.format) / 8;
      bytes_per_sample *= ao_data.channels;
      ao_data.bps = ao_data.samplerate * bytes_per_sample;

	if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams,
							  &alsa_buffer_time, NULL)) < 0)
	  {
	    mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetBufferTimeNear,
		   snd_strerror(err));
	    return 0;
	  }

	if ((err = snd_pcm_hw_params_set_periods_near(alsa_handler, alsa_hwparams,
						      &alsa_fragcount, NULL)) < 0) {
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriods,
		 snd_strerror(err));
	  return 0;
	}

      /* finally install hardware parameters */
      if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetHwParameters,
		 snd_strerror(err));
	  return 0;
	}
      // end setting hw-params


      // gets buffersize for control
      if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize)) < 0)
	{
	  mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBufferSize, snd_strerror(err));
	  return 0;
	}
      else {
	ao_data.buffersize = bufsize * bytes_per_sample;
	  mp_msg(MSGT_AO,MSGL_V,"alsa-init: got buffersize=%i\n", ao_data.buffersize);
      }

      if ((err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetPeriodSize, snd_strerror(err));
	return 0;
      } else {
	mp_msg(MSGT_AO,MSGL_V,"alsa-init: got period size %li\n", chunk_size);
      }
      ao_data.outburst = chunk_size * bytes_per_sample;

      /* setting software parameters */
      if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters,
	       snd_strerror(err));
	return 0;
      }
#if SND_LIB_VERSION >= 0x000901
      if ((err = snd_pcm_sw_params_get_boundary(alsa_swparams, &boundary)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetBoundary,
	       snd_strerror(err));
	return 0;
      }
#else
      boundary = 0x7fffffff;
#endif
      /* start playing when one period has been written */
      if ((err = snd_pcm_sw_params_set_start_threshold(alsa_handler, alsa_swparams, chunk_size)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStartThreshold,
	       snd_strerror(err));
	return 0;
      }
      /* disable underrun reporting */
      if ((err = snd_pcm_sw_params_set_stop_threshold(alsa_handler, alsa_swparams, boundary)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetStopThreshold,
	       snd_strerror(err));
	return 0;
      }
#if SND_LIB_VERSION >= 0x000901
      /* play silence when there is an underrun */
      if ((err = snd_pcm_sw_params_set_silence_size(alsa_handler, alsa_swparams, boundary)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetSilenceSize,
	       snd_strerror(err));
	return 0;
      }
#endif
      if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) {
	mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToGetSwParameters,
	       snd_strerror(err));
	return 0;
      }
      /* end setting sw-params */

      mp_msg(MSGT_AO,MSGL_V,"alsa: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n",
	     ao_data.samplerate, ao_data.channels, (int)bytes_per_sample, ao_data.buffersize,
	     snd_pcm_format_description(alsa_format));

    } // end switch alsa_handler (spdif)
    alsa_can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams);
    return 1;
} // end init
static int parse_suboptions(const char *arg) {
    char *pseudoargv[4], *osdcolor = NULL, *subcolor = NULL, **strings,
         *helpmsg = NULL;
    int pseudoargc, displayhelp = 0, *booleans;
    const opt_t extra_opts[] = {
            {"osdcolor", OPT_ARG_MSTRZ, &osdcolor,    NULL},
            {"subcolor", OPT_ARG_MSTRZ, &subcolor,    NULL},
            {"help",     OPT_ARG_BOOL,  &displayhelp, NULL} };
    opt_t *subopts = NULL, *p;
    char * const strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
        "-width", "-height", "-minwidth", "-minheight", "-maxwidth",
        "-maxheight", "-recwidth", "-recheight", "-bright",  "-contrast",
        "-gamma",  "-dimmul", "-boldmul", "-random" };
    char * const booleans_list[] = {"-dim", "-bold", "-reverse", "-normal",
        "-boldfont", "-inverse", "-extended", "-eight", "-dither",
        "-floyd_steinberg", "-error_distribution"};
    char * const nobooleans_list[] = {"-nodim", "-nobold", "-noreverse", "-nonormal",
        "-noboldfont", "-noinverse", "-noextended", "-noeight", "-nodither",
        "-nofloyd_steinberg", "-noerror_distribution"};
    const int nstrings = sizeof(strings_list) / sizeof(char*);
    const int nbooleans = sizeof(booleans_list) / sizeof(char*);
    const int nextra_opts = sizeof(extra_opts) / sizeof(opt_t);
    const int nsubopts = nstrings + nbooleans + nextra_opts;
    int i, retval = 0;

    subopts = calloc(nsubopts + 1, sizeof(opt_t));
    strings = calloc(nstrings, sizeof(char*));
    booleans = calloc(nbooleans, sizeof(int));

    p = subopts;
    for (i=0; i<nstrings; i++, p++) {
        p->name = strings_list[i] + 1; // skip '-'
        p->type = OPT_ARG_MSTRZ;
        p->valp = &strings[i];
    }
    for (i=0; i<nbooleans; i++, p++) {
        p->name = booleans_list[i] + 1;
        p->type = OPT_ARG_BOOL;
        p->valp = &booleans[i];
    }
    memcpy(p, extra_opts, sizeof(extra_opts));

    retval = subopt_parse(arg, subopts);

    if (retval == 0 && displayhelp) {
        helpmsg = strdup(aa_help);
        for (i=0; i<(signed)strlen(helpmsg); i++)
            if (helpmsg[i] == '-') helpmsg[i] = ' ';
        mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_HelpHeader);
        mp_msg(MSGT_VO, MSGL_INFO, "%s\n\n", helpmsg);
        mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_AdditionalOptions);
        retval = -1;
    }
    if (retval == 0) {
        pseudoargv[3] = NULL;
        for (i=0; i<nstrings; i++) {
            pseudoargc = 3;         // inside loop because aalib changes it
            if (strings[i] != NULL) {
                pseudoargv[1] = strings_list[i];
                pseudoargv[2] = strings[i];
                aa_parseoptions(&aa_defparams, &aa_defrenderparams,
                                                &pseudoargc, pseudoargv);
            }
        }
        pseudoargv[2] = NULL;
        for (i=0; i<nbooleans; i++) {
            pseudoargc = 2;
            if (booleans[i]) pseudoargv[1] = booleans_list[i];
            else pseudoargv[1] = nobooleans_list[i];
            aa_parseoptions(&aa_defparams, &aa_defrenderparams,
                                                &pseudoargc, pseudoargv);
        }
        if (osdcolor) aaopt_osdcolor = getcolor(osdcolor);
        if (subcolor) aaopt_subcolor = getcolor(subcolor);
    }

    free(subopts);
    free(booleans);
    if (strings) {
        for (i=0; i<nstrings; i++)
            free(strings[i]);
        free(strings);
    }
    free(osdcolor);
    free(subcolor);
    free(helpmsg);
    return retval;
}