[PATCH 1/2] winegstreamer: Add YUV to ARGB32 transformation filter.

Andrew Eikum aeikum at codeweavers.com
Thu May 12 14:27:00 CDT 2016


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/winegstreamer/gst_guids.h   |   3 +-
 dlls/winegstreamer/gst_private.h |   3 +-
 dlls/winegstreamer/gsttffilter.c | 116 +++++++++++++++++++++++++++++++++++++--
 dlls/winegstreamer/main.c        |  35 +++++++++---
 4 files changed, 141 insertions(+), 16 deletions(-)

diff --git a/dlls/winegstreamer/gst_guids.h b/dlls/winegstreamer/gst_guids.h
index 6b45bc4..b445dc5 100644
--- a/dlls/winegstreamer/gst_guids.h
+++ b/dlls/winegstreamer/gst_guids.h
@@ -23,4 +23,5 @@ DEFINE_GUID(CLSID_Gstreamer_AudioConvert, 0x334b2ec9, 0xf2b5, 0x40b9, 0x84, 0x32
 DEFINE_GUID(CLSID_Gstreamer_Mp3, 0x728dcf55, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa);
 DEFINE_GUID(CLSID_Gstreamer_Splitter, 0xf9d8d64e, 0xa144, 0x47dc, 0x8e, 0xe0, 0xf5, 0x34, 0x98, 0x37, 0x2c, 0x29);
 DEFINE_GUID(WINESUBTYPE_Gstreamer, 0xffffffff, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa);
-DEFINE_GUID(CLSID_Gstreamer_YUV, 0x2d5507df, 0x5ac9, 0x4bb9, 0x9c, 0x09, 0xb2, 0x80, 0xfc, 0x0b, 0xce, 0x01);
+DEFINE_GUID(CLSID_Gstreamer_YUV2RGB, 0x2d5507df, 0x5ac9, 0x4bb9, 0x9c, 0x09, 0xb2, 0x80, 0xfc, 0x0b, 0xce, 0x01);
+DEFINE_GUID(CLSID_Gstreamer_YUV2ARGB, 0x2d5507df, 0x5ac9, 0x4bb9, 0x9c, 0x09, 0xb2, 0x80, 0xfc, 0x0b, 0xce, 0x02);
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 4b29f21..a1f201c 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -39,7 +39,8 @@ void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
 
 IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *pUnkOuter, HRESULT *phr);
 IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *pUnkOuter, HRESULT *phr);
-IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *pUnkOuter, HRESULT *phr);
+IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *pUnkOuter, HRESULT *phr);
+IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *pUnkOuter, HRESULT *phr);
 IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
 
 DWORD Gstreamer_init(void);
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index 2209c5e..52aa267 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -677,7 +677,7 @@ static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECT
     return S_OK;
 }
 
-static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir,  const AM_MEDIA_TYPE *amt)
+static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir,  const AM_MEDIA_TYPE *amt)
 {
     GstTfImpl *This = (GstTfImpl*)tf;
     GstCaps *capsin, *capsout;
@@ -748,13 +748,13 @@ static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECT
     return hr;
 }
 
-static const TransformFilterFuncTable Gstreamer_YUV_vtbl = {
+static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
     Gstreamer_transform_DecideBufferSize,
     Gstreamer_transform_ProcessBegin,
     Gstreamer_transform_ProcessData,
     Gstreamer_transform_ProcessEnd,
     Gstreamer_YUV_QueryConnect,
-    Gstreamer_YUV_SetMediaType,
+    Gstreamer_YUV2RGB_SetMediaType,
     Gstreamer_YUV_ConnectInput,
     Gstreamer_transform_Cleanup,
     Gstreamer_transform_EndOfStream,
@@ -764,7 +764,7 @@ static const TransformFilterFuncTable Gstreamer_YUV_vtbl = {
     Gstreamer_transform_QOS
 };
 
-IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr)
+IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
 {
     IUnknown *obj = NULL;
 
@@ -776,7 +776,113 @@ IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr)
         return NULL;
     }
 
-    *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_YUV, "videoconvert", &Gstreamer_YUV_vtbl, (LPVOID*)&obj);
+    *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_YUV2RGB, "videoconvert", &Gstreamer_YUV2RGB_vtbl, (LPVOID*)&obj);
+
+    TRACE("returning %p\n", obj);
+
+    return obj;
+}
+
+static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir,  const AM_MEDIA_TYPE *amt)
+{
+    GstTfImpl *This = (GstTfImpl*)tf;
+    GstCaps *capsin, *capsout;
+    AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
+    HRESULT hr;
+    int avgtime;
+    LONG width, height;
+
+    TRACE("%p 0x%x %p\n", This, dir, amt);
+
+    mark_wine_thread();
+
+    if (dir != PINDIR_INPUT)
+        return S_OK;
+
+    if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
+        return E_FAIL;
+
+    FreeMediaType(outpmt);
+    CopyMediaType(outpmt, amt);
+
+    if (IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo)) {
+        VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)outpmt->pbFormat;
+        avgtime = vih->AvgTimePerFrame;
+        width = vih->bmiHeader.biWidth;
+        height = vih->bmiHeader.biHeight;
+        if (vih->bmiHeader.biHeight > 0)
+            vih->bmiHeader.biHeight = -vih->bmiHeader.biHeight;
+        vih->bmiHeader.biBitCount = 32;
+        vih->bmiHeader.biCompression = BI_RGB;
+        vih->bmiHeader.biSizeImage = width * abs(height) * 3;
+    } else {
+        VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)outpmt->pbFormat;
+        avgtime = vih->AvgTimePerFrame;
+        width = vih->bmiHeader.biWidth;
+        height = vih->bmiHeader.biHeight;
+        if (vih->bmiHeader.biHeight > 0)
+            vih->bmiHeader.biHeight = -vih->bmiHeader.biHeight;
+        vih->bmiHeader.biBitCount = 32;
+        vih->bmiHeader.biCompression = BI_RGB;
+        vih->bmiHeader.biSizeImage = width * abs(height) * 3;
+    }
+    if (!avgtime)
+        avgtime = 10000000 / 30;
+
+    outpmt->subtype = MEDIASUBTYPE_ARGB32;
+
+    capsin = gst_caps_new_simple("video/x-raw",
+                                 "format", G_TYPE_STRING,
+                                   gst_video_format_to_string(
+                                     gst_video_format_from_fourcc(amt->subtype.Data1)),
+                                 "width", G_TYPE_INT, width,
+                                 "height", G_TYPE_INT, height,
+                                 "framerate", GST_TYPE_FRACTION, 10000000, avgtime,
+                                 NULL);
+    capsout = gst_caps_new_simple("video/x-raw",
+                                  "format", G_TYPE_STRING, "BGRA",
+                                  "width", G_TYPE_INT, width,
+                                  "height", G_TYPE_INT, height,
+                                  "framerate", GST_TYPE_FRACTION, 10000000, avgtime,
+                                   NULL);
+
+    hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout);
+    gst_caps_unref(capsin);
+    gst_caps_unref(capsout);
+
+    This->cbBuffer = width * height * 4;
+    return hr;
+}
+
+static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = {
+    Gstreamer_transform_DecideBufferSize,
+    Gstreamer_transform_ProcessBegin,
+    Gstreamer_transform_ProcessData,
+    Gstreamer_transform_ProcessEnd,
+    Gstreamer_YUV_QueryConnect,
+    Gstreamer_YUV2ARGB_SetMediaType,
+    Gstreamer_YUV_ConnectInput,
+    Gstreamer_transform_Cleanup,
+    Gstreamer_transform_EndOfStream,
+    Gstreamer_transform_BeginFlush,
+    Gstreamer_transform_EndFlush,
+    Gstreamer_transform_NewSegment,
+    Gstreamer_transform_QOS
+};
+
+IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *punkouter, HRESULT *phr)
+{
+    IUnknown *obj = NULL;
+
+    TRACE("%p %p\n", punkouter, phr);
+
+    if (!Gstreamer_init())
+    {
+        *phr = E_FAIL;
+        return NULL;
+    }
+
+    *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_YUV2ARGB, "videoconvert", &Gstreamer_YUV2ARGB_vtbl, (LPVOID*)&obj);
 
     TRACE("returning %p\n", obj);
 
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 7b9cd31..2bb69f4 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -43,8 +43,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
 
 static const WCHAR wGstreamer_Splitter[] =
 {'G','S','t','r','e','a','m','e','r',' ','s','p','l','i','t','t','e','r',' ','f','i','l','t','e','r',0};
-static const WCHAR wGstreamer_YUV[] =
-{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','f','i','l','t','e','r',0};
+static const WCHAR wGstreamer_YUV2RGB[] =
+{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','t','o',' ','R','G','B',' ','f','i','l','t','e','r',0};
+static const WCHAR wGstreamer_YUV2ARGB[] =
+{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','t','o',' ','A','R','G','B',' ','f','i','l','t','e','r',0};
 static const WCHAR wGstreamer_Mp3[] =
 {'G','S','t','r','e','a','m','e','r',' ','M','p','3',' ','f','i','l','t','e','r',0};
 static const WCHAR wGstreamer_AudioConvert[] =
@@ -115,9 +117,17 @@ static const AMOVIESETUP_PIN amfYUVPin[] =
     },
 };
 
-static const AMOVIESETUP_FILTER amfYUV =
-{   &CLSID_Gstreamer_YUV,
-    wGstreamer_YUV,
+static const AMOVIESETUP_FILTER amfYUV2RGB =
+{   &CLSID_Gstreamer_YUV2RGB,
+    wGstreamer_YUV2RGB,
+    MERIT_UNLIKELY,
+    2,
+    amfYUVPin
+};
+
+static const AMOVIESETUP_FILTER amfYUV2ARGB =
+{   &CLSID_Gstreamer_YUV2ARGB,
+    wGstreamer_YUV2ARGB,
     MERIT_UNLIKELY,
     2,
     amfYUVPin
@@ -184,11 +194,18 @@ FactoryTemplate const g_Templates[] = {
         &amfSplitter,
     },
     {
-        wGstreamer_YUV,
-        &CLSID_Gstreamer_YUV,
-        Gstreamer_YUV_create,
+        wGstreamer_YUV2RGB,
+        &CLSID_Gstreamer_YUV2RGB,
+        Gstreamer_YUV2RGB_create,
         NULL,
-        &amfYUV,
+        &amfYUV2RGB,
+    },
+    {
+        wGstreamer_YUV2ARGB,
+        &CLSID_Gstreamer_YUV2ARGB,
+        Gstreamer_YUV2ARGB_create,
+        NULL,
+        &amfYUV2ARGB,
     },
     {
         wGstreamer_Mp3,
-- 
2.8.2





More information about the wine-patches mailing list