static int preinit(sh_audio_t *sh_audio) { DMO_AudioDecoder* ds_adec; int chans=(audio_output_channels==sh_audio->wf->nChannels) ? audio_output_channels : (sh_audio->wf->nChannels>=2 ? 2 : 1); if(!(ds_adec=DMO_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf,chans))) { mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_MissingDLLcodec,sh_audio->codec->dll); return 0; } sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; sh_audio->channels=chans; sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; sh_audio->samplesize=2; sh_audio->audio_in_minsize=4*sh_audio->wf->nBlockAlign; if(sh_audio->audio_in_minsize<8192) sh_audio->audio_in_minsize=8192; sh_audio->audio_out_minsize=4*16384; sh_audio->context = ds_adec; mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Win32/DMO audio codec init OK!\n"); return 1; }
static gboolean dmo_audiodec_sink_setcaps (GstPad * pad, GstCaps * caps) { DMOAudioDec *dec = (DMOAudioDec *) gst_pad_get_parent (pad); DMOAudioDecClass *klass = (DMOAudioDecClass *) G_OBJECT_GET_CLASS (dec); GstStructure *s = gst_caps_get_structure (caps, 0); gchar *dll; gint size; WAVEFORMATEX * hdr = NULL; const GValue *v; GstBuffer *extradata = NULL; GstCaps *out; gboolean ret = FALSE; guint32 fourcc; GST_DEBUG_OBJECT (dec, "setcaps called with %" GST_PTR_FORMAT, caps); Check_FS_Segment (); if (dec->ctx) { DMO_AudioDecoder_Destroy (dec->ctx); dec->ctx = NULL; } /* read data */ if (!gst_structure_get_int (s, "bitrate", &dec->bitrate) || !gst_structure_get_int (s, "block_align", &dec->block_align) || !gst_structure_get_int (s, "rate", &dec->rate) || !gst_structure_get_int (s, "channels", &dec->channels) || !gst_structure_get_int (s, "depth", &dec->depth)) { goto beach; } if ((v = gst_structure_get_value (s, "codec_data"))) extradata = gst_value_get_buffer (v); if (!gst_structure_get_fourcc (s, "format", &fourcc)) fourcc = klass->entry->format; /* set up dll initialization */ dll = g_strdup_printf ("%s.dll", klass->entry->dll); size = sizeof (WAVEFORMATEX) + (extradata ? GST_BUFFER_SIZE (extradata) : 0); hdr = g_malloc0 (size); if (extradata) { /* Codec data is appended after our header */ memcpy (((guchar *) hdr) + sizeof (WAVEFORMATEX), GST_BUFFER_DATA (extradata), GST_BUFFER_SIZE (extradata)); hdr->cbSize = GST_BUFFER_SIZE (extradata); } hdr->wFormatTag = fourcc; hdr->nChannels = dec->channels; hdr->nSamplesPerSec = dec->rate; hdr->nAvgBytesPerSec = dec->bitrate / 8; hdr->nBlockAlign = dec->block_align; hdr->wBitsPerSample = dec->depth; GST_DEBUG ("Will now open %s using %d bps %d channels", dll, dec->bitrate, dec->channels); if (!(dec->ctx = DMO_AudioDecoder_Open (dll, &klass->entry->guid, hdr))) { GST_ERROR ("Failed to open DLL %s", dll); g_free (dll); g_free (hdr); goto beach; } g_free (dll); g_free (hdr); DMO_AudioDecoder_GetOutputInfos (dec->ctx, &dec->out_buffer_size, &dec->out_align); DMO_AudioDecoder_GetInputInfos (dec->ctx, &dec->in_buffer_size, &dec->in_align, &dec->lookahead); /* negotiate output */ out = gst_caps_from_string (klass->entry->srccaps); gst_caps_set_simple (out, "width", G_TYPE_INT, dec->depth, "depth", G_TYPE_INT, dec->depth, "rate", G_TYPE_INT, dec->rate, "channels", G_TYPE_INT, dec->channels, NULL); if (dec->channels > 2 && dec->channels <= 11) { GstAudioChannelPosition pos[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_LFE, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT }; gst_audio_set_channel_positions (gst_caps_get_structure (out, 0), pos); } if (!gst_pad_set_caps (dec->srcpad, out)) { gst_caps_unref (out); GST_ERROR ("Failed to negotiate output"); goto beach; } gst_caps_unref (out); ret = TRUE; beach: gst_object_unref (dec); return ret; }