[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