gboolean gst_sndio_prepare (struct gstsndio *sio, GstAudioRingBufferSpec *spec) { struct sio_par par, retpar; unsigned nchannels; GST_DEBUG_OBJECT (sio, "prepare"); if (spec->type != GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only raw buffer format supported by sndio"), (NULL)); return FALSE; } if (!GST_AUDIO_INFO_IS_INTEGER(&spec->info)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only integer format supported"), (NULL)); return FALSE; } if (GST_AUDIO_INFO_DEPTH(&spec->info) % 8) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Only depths multiple of 8 are supported"), (NULL)); return FALSE; } sio_initpar (&par); switch (GST_AUDIO_INFO_FORMAT (&spec->info)) { case GST_AUDIO_FORMAT_S8: case GST_AUDIO_FORMAT_U8: case GST_AUDIO_FORMAT_S16LE: case GST_AUDIO_FORMAT_S16BE: case GST_AUDIO_FORMAT_U16LE: case GST_AUDIO_FORMAT_U16BE: case GST_AUDIO_FORMAT_S32LE: case GST_AUDIO_FORMAT_S32BE: case GST_AUDIO_FORMAT_U32LE: case GST_AUDIO_FORMAT_U32BE: case GST_AUDIO_FORMAT_S24_32LE: case GST_AUDIO_FORMAT_S24_32BE: case GST_AUDIO_FORMAT_U24_32LE: case GST_AUDIO_FORMAT_U24_32BE: case GST_AUDIO_FORMAT_S24LE: case GST_AUDIO_FORMAT_S24BE: case GST_AUDIO_FORMAT_U24LE: case GST_AUDIO_FORMAT_U24BE: break; default: GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE, ("Unsupported audio format"), ("format = %d", GST_AUDIO_INFO_FORMAT (&spec->info))); return FALSE; } par.sig = GST_AUDIO_INFO_IS_SIGNED(&spec->info); par.bits = GST_AUDIO_INFO_WIDTH(&spec->info); par.bps = GST_AUDIO_INFO_DEPTH(&spec->info) / 8; if (par.bps > 1) par.le = GST_AUDIO_INFO_IS_LITTLE_ENDIAN(&spec->info); if (par.bits < par.bps * 8) par.msb = 0; par.rate = GST_AUDIO_INFO_RATE(&spec->info); if (sio->mode == SIO_PLAY) par.pchan = GST_AUDIO_INFO_CHANNELS(&spec->info); else par.rchan = GST_AUDIO_INFO_CHANNELS(&spec->info); par.round = par.rate / 1000000. * spec->latency_time; par.appbufsz = par.rate / 1000000. * spec->buffer_time; if (!sio_setpar (sio->hdl, &par)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Unsupported audio encoding"), (NULL)); return FALSE; } if (!sio_getpar (sio->hdl, &retpar)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Couldn't get audio device parameters"), (NULL)); return FALSE; } #if 0 fprintf(stderr, "format = %s, " "requested: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, " "rate = %d, pchan = %d, round = %d, appbufsz = %d; " "returned: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, " "rate = %d, pchan = %d, round = %d, appbufsz = %d, bufsz = %d\n", GST_AUDIO_INFO_NAME(&spec->info), par.sig, par.bits, par.bps, par.le, par.msb, par.rate, par.pchan, par.round, par.appbufsz, retpar.sig, retpar.bits, retpar.bps, retpar.le, retpar.msb, retpar.rate, retpar.pchan, retpar.round, retpar.appbufsz, retpar.bufsz); #endif if (par.bits != retpar.bits || par.bps != retpar.bps || par.rate != retpar.rate || (sio->mode == SIO_PLAY && par.pchan != retpar.pchan) || (sio->mode == SIO_REC && par.rchan != retpar.rchan) || (par.bps > 1 && par.le != retpar.le) || (par.bits < par.bps * 8 && par.msb != retpar.msb)) { GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE, ("Audio device refused requested parameters"), (NULL)); return FALSE; } nchannels = (sio->mode == SIO_PLAY) ? retpar.pchan : retpar.rchan; spec->segsize = retpar.round * retpar.bps * nchannels; spec->segtotal = retpar.bufsz / retpar.round; sio->bpf = retpar.bps * nchannels; sio->delay = 0; sio_onmove (sio->hdl, gst_sndio_cb, sio); if (!sio_start (sio->hdl)) { GST_ELEMENT_ERROR (sio->obj, RESOURCE, OPEN_READ_WRITE, ("Could not start sndio"), (NULL)); return FALSE; } return TRUE; }
static gboolean gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps) { GstWavEnc *wavenc; GstStructure *structure; const gchar *name; gint chans, rate; GstCaps *ccaps; wavenc = GST_WAVENC (gst_pad_get_parent (pad)); ccaps = gst_pad_get_current_caps (pad); if (wavenc->sent_header && ccaps && !gst_caps_can_intersect (caps, ccaps)) { gst_caps_unref (ccaps); GST_WARNING_OBJECT (wavenc, "cannot change format in middle of stream"); goto fail; } if (ccaps) gst_caps_unref (ccaps); GST_DEBUG_OBJECT (wavenc, "got caps: %" GST_PTR_FORMAT, caps); structure = gst_caps_get_structure (caps, 0); name = gst_structure_get_name (structure); if (!gst_structure_get_int (structure, "channels", &chans) || !gst_structure_get_int (structure, "rate", &rate)) { GST_WARNING_OBJECT (wavenc, "caps incomplete"); goto fail; } if (strcmp (name, "audio/x-raw") == 0) { GstAudioInfo info; if (!gst_audio_info_from_caps (&info, caps)) goto fail; if (GST_AUDIO_INFO_IS_INTEGER (&info)) wavenc->format = GST_RIFF_WAVE_FORMAT_PCM; else if (GST_AUDIO_INFO_IS_FLOAT (&info)) wavenc->format = GST_RIFF_WAVE_FORMAT_IEEE_FLOAT; else goto fail; wavenc->width = GST_AUDIO_INFO_WIDTH (&info); } else if (strcmp (name, "audio/x-alaw") == 0) { wavenc->format = GST_RIFF_WAVE_FORMAT_ALAW; wavenc->width = 8; } else if (strcmp (name, "audio/x-mulaw") == 0) { wavenc->format = GST_RIFF_WAVE_FORMAT_MULAW; wavenc->width = 8; } else { GST_WARNING_OBJECT (wavenc, "Unsupported format %s", name); goto fail; } wavenc->channels = chans; wavenc->rate = rate; GST_LOG_OBJECT (wavenc, "accepted caps: format=0x%04x chans=%u width=%u rate=%u", wavenc->format, wavenc->channels, wavenc->width, wavenc->rate); gst_object_unref (wavenc); return TRUE; fail: gst_object_unref (wavenc); return FALSE; }
static gboolean gst_two_lame_set_format (GstAudioEncoder * enc, GstAudioInfo * info) { GstTwoLame *twolame; gint out_samplerate; gint version; GstCaps *othercaps; twolame = GST_TWO_LAME (enc); /* parameters already parsed for us */ twolame->samplerate = GST_AUDIO_INFO_RATE (info); twolame->num_channels = GST_AUDIO_INFO_CHANNELS (info); twolame->float_input = !GST_AUDIO_INFO_IS_INTEGER (info); /* but we might be asked to reconfigure, so reset */ gst_two_lame_release_memory (twolame); GST_DEBUG_OBJECT (twolame, "setting up twolame"); if (!gst_two_lame_setup (twolame)) goto setup_failed; out_samplerate = twolame_get_out_samplerate (twolame->glopts); if (out_samplerate == 0) goto zero_output_rate; if (out_samplerate != twolame->samplerate) { GST_WARNING_OBJECT (twolame, "output samplerate %d is different from incoming samplerate %d", out_samplerate, twolame->samplerate); } version = twolame_get_version (twolame->glopts); if (version == TWOLAME_MPEG2) version = 2; else version = 1; othercaps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "mpegaudioversion", G_TYPE_INT, version, "layer", G_TYPE_INT, 2, "channels", G_TYPE_INT, twolame->mode == TWOLAME_MONO ? 1 : twolame->num_channels, "rate", G_TYPE_INT, out_samplerate, NULL); /* and use these caps */ gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (twolame), othercaps); gst_caps_unref (othercaps); /* report needs to base class: * hand one frame at a time, if we are pretty sure what a frame is */ if (out_samplerate == twolame->samplerate) { gst_audio_encoder_set_frame_samples_min (enc, 1152); gst_audio_encoder_set_frame_samples_max (enc, 1152); gst_audio_encoder_set_frame_max (enc, 1); } return TRUE; zero_output_rate: { GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS, (NULL), ("TwoLAME decided on a zero sample rate")); return FALSE; } setup_failed: { GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS, (_("Failed to configure TwoLAME encoder. Check your encoding parameters.")), (NULL)); return FALSE; } }