Commit 008e4d3e authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

winegstreamer: Add YUV to ARGB32 transformation filter.

parent 05132fa7
...@@ -23,4 +23,5 @@ DEFINE_GUID(CLSID_Gstreamer_AudioConvert, 0x334b2ec9, 0xf2b5, 0x40b9, 0x84, 0x32 ...@@ -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_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(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(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);
...@@ -39,7 +39,8 @@ void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt); ...@@ -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_AudioConvert_create(IUnknown *pUnkOuter, HRESULT *phr);
IUnknown * CALLBACK Gstreamer_Mp3_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); IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);
DWORD Gstreamer_init(void); DWORD Gstreamer_init(void);
......
...@@ -677,7 +677,7 @@ static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECT ...@@ -677,7 +677,7 @@ static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECT
return S_OK; 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; GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout; GstCaps *capsin, *capsout;
...@@ -748,13 +748,13 @@ static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECT ...@@ -748,13 +748,13 @@ static HRESULT WINAPI Gstreamer_YUV_SetMediaType(TransformFilter *tf, PIN_DIRECT
return hr; return hr;
} }
static const TransformFilterFuncTable Gstreamer_YUV_vtbl = { static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
Gstreamer_transform_DecideBufferSize, Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin, Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData, Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd, Gstreamer_transform_ProcessEnd,
Gstreamer_YUV_QueryConnect, Gstreamer_YUV_QueryConnect,
Gstreamer_YUV_SetMediaType, Gstreamer_YUV2RGB_SetMediaType,
Gstreamer_YUV_ConnectInput, Gstreamer_YUV_ConnectInput,
Gstreamer_transform_Cleanup, Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream, Gstreamer_transform_EndOfStream,
...@@ -764,7 +764,7 @@ static const TransformFilterFuncTable Gstreamer_YUV_vtbl = { ...@@ -764,7 +764,7 @@ static const TransformFilterFuncTable Gstreamer_YUV_vtbl = {
Gstreamer_transform_QOS Gstreamer_transform_QOS
}; };
IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr) IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
{ {
IUnknown *obj = NULL; IUnknown *obj = NULL;
...@@ -776,7 +776,113 @@ IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr) ...@@ -776,7 +776,113 @@ IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkouter, HRESULT *phr)
return NULL; 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); TRACE("returning %p\n", obj);
......
...@@ -43,8 +43,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer); ...@@ -43,8 +43,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
static const WCHAR wGstreamer_Splitter[] = 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}; {'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[] = static const WCHAR wGstreamer_YUV2RGB[] =
{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','f','i','l','t','e','r',0}; {'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[] = static const WCHAR wGstreamer_Mp3[] =
{'G','S','t','r','e','a','m','e','r',' ','M','p','3',' ','f','i','l','t','e','r',0}; {'G','S','t','r','e','a','m','e','r',' ','M','p','3',' ','f','i','l','t','e','r',0};
static const WCHAR wGstreamer_AudioConvert[] = static const WCHAR wGstreamer_AudioConvert[] =
...@@ -115,9 +117,17 @@ static const AMOVIESETUP_PIN amfYUVPin[] = ...@@ -115,9 +117,17 @@ static const AMOVIESETUP_PIN amfYUVPin[] =
}, },
}; };
static const AMOVIESETUP_FILTER amfYUV = static const AMOVIESETUP_FILTER amfYUV2RGB =
{ &CLSID_Gstreamer_YUV, { &CLSID_Gstreamer_YUV2RGB,
wGstreamer_YUV, wGstreamer_YUV2RGB,
MERIT_UNLIKELY,
2,
amfYUVPin
};
static const AMOVIESETUP_FILTER amfYUV2ARGB =
{ &CLSID_Gstreamer_YUV2ARGB,
wGstreamer_YUV2ARGB,
MERIT_UNLIKELY, MERIT_UNLIKELY,
2, 2,
amfYUVPin amfYUVPin
...@@ -184,11 +194,18 @@ FactoryTemplate const g_Templates[] = { ...@@ -184,11 +194,18 @@ FactoryTemplate const g_Templates[] = {
&amfSplitter, &amfSplitter,
}, },
{ {
wGstreamer_YUV, wGstreamer_YUV2RGB,
&CLSID_Gstreamer_YUV, &CLSID_Gstreamer_YUV2RGB,
Gstreamer_YUV_create, Gstreamer_YUV2RGB_create,
NULL,
&amfYUV2RGB,
},
{
wGstreamer_YUV2ARGB,
&CLSID_Gstreamer_YUV2ARGB,
Gstreamer_YUV2ARGB_create,
NULL, NULL,
&amfYUV, &amfYUV2ARGB,
}, },
{ {
wGstreamer_Mp3, wGstreamer_Mp3,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment