Aric Stewart : winegstreamer: Add output pin with audio format.
Alexandre Julliard
julliard at winehq.org
Wed Oct 27 12:51:02 CDT 2010
Module: wine
Branch: master
Commit: 30c1fe5836482d3a57f0f69cba4bac6ffba7ce9a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=30c1fe5836482d3a57f0f69cba4bac6ffba7ce9a
Author: Aric Stewart <aric at codeweavers.com>
Date: Tue Oct 26 11:39:55 2010 -0500
winegstreamer: Add output pin with audio format.
---
dlls/winegstreamer/gstdemux.c | 88 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 83 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 0b43191..b0b934c 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -74,7 +74,7 @@ struct GSTOutPin {
GstPad *their_src;
GstPad *my_sink;
- int isvid;
+ int isaud, isvid;
AM_MEDIA_TYPE * pmt;
HANDLE caps_event;
};
@@ -88,6 +88,63 @@ static const IBaseFilterVtbl GST_Vtbl;
static HRESULT GST_AddPin(GSTImpl *This, const PIN_INFO *piOutput, const AM_MEDIA_TYPE *amt);
static HRESULT GST_RemoveOutputPins(GSTImpl *This);
+static int amt_from_gst_caps_audio(GstCaps *caps, AM_MEDIA_TYPE *amt) {
+ WAVEFORMATEXTENSIBLE *wfe;
+ WAVEFORMATEX *wfx;
+ GstStructure *arg;
+ gint32 depth = 0, bpp = 0;
+ const char *typename;
+ arg = gst_caps_get_structure(caps, 0);
+ typename = gst_structure_get_name(arg);
+ if (!typename)
+ return 0;
+
+ wfe = CoTaskMemAlloc(sizeof(*wfe));
+ wfx = (WAVEFORMATEX*)wfe;
+ amt->majortype = MEDIATYPE_Audio;
+ amt->subtype = MEDIASUBTYPE_PCM;
+ amt->formattype = FORMAT_WaveFormatEx;
+ amt->pbFormat = (BYTE*)wfe;
+ amt->cbFormat = sizeof(*wfe);
+ amt->bFixedSizeSamples = 0;
+ amt->bTemporalCompression = 1;
+ amt->lSampleSize = 0;
+ amt->pUnk = NULL;
+
+ wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ if (!gst_structure_get_int(arg, "channels", (INT*)&wfx->nChannels))
+ return 0;
+ if (!gst_structure_get_int(arg, "rate", (INT*)&wfx->nSamplesPerSec))
+ return 0;
+ gst_structure_get_int(arg, "width", &depth);
+ gst_structure_get_int(arg, "depth", &bpp);
+ if (!depth || depth > 32 || depth % 8)
+ depth = bpp;
+ else if (!bpp)
+ bpp = depth;
+ wfe->Samples.wValidBitsPerSample = depth;
+ wfx->wBitsPerSample = bpp;
+ wfx->cbSize = sizeof(*wfe)-sizeof(*wfx);
+ switch (wfx->nChannels) {
+ case 1: wfe->dwChannelMask = KSAUDIO_SPEAKER_MONO; break;
+ case 2: wfe->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break;
+ case 4: wfe->dwChannelMask = KSAUDIO_SPEAKER_SURROUND; break;
+ case 5: wfe->dwChannelMask = (KSAUDIO_SPEAKER_5POINT1 & ~SPEAKER_LOW_FREQUENCY); break;
+ case 6: wfe->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
+ case 8: wfe->dwChannelMask = KSAUDIO_SPEAKER_7POINT1; break;
+ default:
+ wfe->dwChannelMask = 0;
+ }
+ if (!strcmp(typename, "audio/x-raw-float")) {
+ wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ wfx->wBitsPerSample = wfe->Samples.wValidBitsPerSample = 32;
+ } else
+ wfe->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample/8;
+ wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
+ return 1;
+}
+
static int amt_from_gst_caps_video(GstCaps *caps, AM_MEDIA_TYPE *amt) {
VIDEOINFOHEADER *vih = CoTaskMemAlloc(sizeof(*vih));
BITMAPINFOHEADER *bih = &vih->bmiHeader;
@@ -162,7 +219,17 @@ static gboolean accept_caps_sink(GstPad *pad, GstCaps *caps) {
int ret;
arg = gst_caps_get_structure(caps, 0);
typename = gst_structure_get_name(arg);
- if (!strcmp(typename, "video/x-raw-rgb")
+ if (!strcmp(typename, "audio/x-raw-int") ||
+ !strcmp(typename, "audio/x-raw-float")) {
+ if (!pin->isaud) {
+ ERR("Setting audio caps on non-audio pad?\n");
+ return 0;
+ }
+ ret = amt_from_gst_caps_audio(caps, &amt);
+ FreeMediaType(&amt);
+ TRACE("+%i\n", ret);
+ return ret;
+ } else if (!strcmp(typename, "video/x-raw-rgb")
|| !strcmp(typename, "video/x-raw-yuv")) {
if (!pin->isvid) {
ERR("Setting video caps on non-video pad?\n");
@@ -187,7 +254,14 @@ static gboolean setcaps_sink(GstPad *pad, GstCaps *caps) {
int ret;
arg = gst_caps_get_structure(caps, 0);
typename = gst_structure_get_name(arg);
- if (!strcmp(typename, "video/x-raw-rgb")
+ if (!strcmp(typename, "audio/x-raw-int") ||
+ !strcmp(typename, "audio/x-raw-float")) {
+ if (!pin->isaud) {
+ ERR("Setting audio caps on non-audio pad?\n");
+ return 0;
+ }
+ ret = amt_from_gst_caps_audio(caps, &amt);
+ } else if (!strcmp(typename, "video/x-raw-rgb")
|| !strcmp(typename, "video/x-raw-yuv")) {
if (!pin->isvid) {
ERR("Setting video caps on non-video pad?\n");
@@ -495,7 +569,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, gboolean last, GS
GstPad *mypad;
GSTOutPin *pin;
int ret;
- int isvid = 0;
+ int isvid = 0, isaud = 0;
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = (IBaseFilter *)This;
@@ -516,7 +590,10 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, gboolean last, GS
gst_pad_set_acceptcaps_function(mypad, accept_caps_sink);
gst_pad_set_acceptcaps_function(mypad, setcaps_sink);
- if (!strcmp(typename, "video/x-raw-rgb")
+ if (!strcmp(typename, "audio/x-raw-int") ||
+ !strcmp(typename, "audio/x-raw-float")) {
+ isaud = 1;
+ } else if (!strcmp(typename, "video/x-raw-rgb")
|| !strcmp(typename, "video/x-raw-yuv")) {
isvid = 1;
} else {
@@ -532,6 +609,7 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, gboolean last, GS
pin = This->ppPins[This->cStreams - 1];
gst_pad_set_element_private(mypad, pin);
pin->my_sink = mypad;
+ pin->isaud = isaud;
pin->isvid = isvid;
ret = gst_pad_link(pad, mypad);
More information about the wine-cvs
mailing list