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