winegstreamer: Add gstreamer audio convert transform filter.

This commit is contained in:
Aric Stewart 2010-10-28 14:42:33 -05:00 committed by Alexandre Julliard
parent 5e79508fe9
commit 0e55930eff
4 changed files with 150 additions and 0 deletions

View File

@ -22,6 +22,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
DEFINE_GUID(CLSID_Gstreamer_AudioConvert, 0x334b2ec9, 0xf2b5, 0x40b9, 0x84, 0x32, 0x4a, 0x00, 0xe0, 0x03, 0x86, 0xa8);
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);

View File

@ -40,6 +40,7 @@
/* enum media */
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_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr);

View File

@ -690,6 +690,119 @@ IUnknown * CALLBACK Gstreamer_YUV_create(IUnknown *punkout, HRESULT *phr)
return obj;
}
static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) {
GstTfImpl *This = (GstTfImpl*)iface;
TRACE("%p %p\n", This, amt);
dump_AM_MEDIA_TYPE(amt);
if (!IsEqualGUID(&amt->majortype, &MEDIATYPE_Audio) ||
!IsEqualGUID(&amt->subtype, &MEDIASUBTYPE_PCM) ||
!IsEqualGUID(&amt->formattype, &FORMAT_WaveFormatEx))
return S_FALSE;
return S_OK;
}
static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
{
return S_OK;
}
static HRESULT WINAPI Gstreamer_AudioConvert_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;
WAVEFORMATEX *inwfe;
WAVEFORMATEX *outwfe;
WAVEFORMATEXTENSIBLE *outwfx;
HRESULT hr;
int inisfloat = 0, indepth;
if (dir != PINDIR_INPUT)
return S_OK;
if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
FreeMediaType(outpmt);
*outpmt = *amt;
outpmt->pUnk = NULL;
outpmt->cbFormat = sizeof(WAVEFORMATEXTENSIBLE);
outpmt->pbFormat = CoTaskMemAlloc(outpmt->cbFormat);
inwfe = (WAVEFORMATEX*)amt->pbFormat;
indepth = inwfe->wBitsPerSample;
if (inwfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
WAVEFORMATEXTENSIBLE *inwfx = (WAVEFORMATEXTENSIBLE*)inwfe;
inisfloat = IsEqualGUID(&inwfx->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
if (inwfx->Samples.wValidBitsPerSample)
indepth = inwfx->Samples.wValidBitsPerSample;
}
capsin = gst_caps_new_simple(inisfloat ? "audio/x-raw-float" : "audio/x-raw-int",
"endianness", G_TYPE_INT, 1234,
"width", G_TYPE_INT, inwfe->wBitsPerSample,
"depth", G_TYPE_INT, indepth,
"channels", G_TYPE_INT, inwfe->nChannels,
"rate", G_TYPE_INT, inwfe->nSamplesPerSec,
NULL);
outwfe = (WAVEFORMATEX*)outpmt->pbFormat;
outwfx = (WAVEFORMATEXTENSIBLE*)outwfe;
outwfe->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
outwfe->nChannels = 2;
outwfe->nSamplesPerSec = inwfe->nSamplesPerSec;
outwfe->wBitsPerSample = 16;
outwfe->nBlockAlign = outwfe->nChannels * outwfe->wBitsPerSample / 8;
outwfe->nAvgBytesPerSec = outwfe->nBlockAlign * outwfe->nSamplesPerSec;
outwfe->cbSize = sizeof(*outwfx) - sizeof(*outwfe);
outwfx->Samples.wValidBitsPerSample = outwfe->wBitsPerSample;
outwfx->dwChannelMask = SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT;
outwfx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
capsout = gst_caps_new_simple("audio/x-raw-int",
"endianness", G_TYPE_INT, 1234,
"width", G_TYPE_INT, outwfe->wBitsPerSample,
"depth", G_TYPE_INT, outwfx->Samples.wValidBitsPerSample,
"channels", G_TYPE_INT, outwfe->nChannels,
"rate", G_TYPE_INT, outwfe->nSamplesPerSec,
NULL);
hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout);
FIXME("%08x\n", hr);
gst_caps_unref(capsin);
gst_caps_unref(capsout);
This->cbBuffer = inwfe->nAvgBytesPerSec;
return hr;
}
static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = {
Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd,
Gstreamer_AudioConvert_QueryConnect,
Gstreamer_AudioConvert_SetMediaType,
Gstreamer_AudioConvert_ConnectInput,
Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream,
Gstreamer_transform_BeginFlush,
Gstreamer_transform_EndFlush,
Gstreamer_transform_NewSegment
};
IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkout, HRESULT *phr)
{
IUnknown *obj = NULL;
if (!Gstreamer_init())
{
*phr = E_FAIL;
return NULL;
}
*phr = Gstreamer_transform_create(punkout, &CLSID_Gstreamer_AudioConvert, "audioconvert", &Gstreamer_AudioConvert_vtbl, (LPVOID*)&obj);
return obj;
}
HRESULT WINAPI GSTTf_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
HRESULT hr;

View File

@ -49,6 +49,8 @@ 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_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[] =
{'G','S','t','r','e','a','m','e','r',' ','A','u','d','i','o','C','o','n','v','e','r','t',' ','f','i','l','t','e','r',0};
static WCHAR wNull[] = {'\0'};
@ -149,6 +151,32 @@ AMOVIESETUP_FILTER const amfMp3 =
amfMp3Pin
};
AMOVIESETUP_PIN amfAudioConvertPin[] =
{ { wNull,
FALSE, FALSE, FALSE, FALSE,
&GUID_NULL,
NULL,
1,
amfMTaudio
},
{
wNull,
FALSE, TRUE, FALSE, FALSE,
&GUID_NULL,
NULL,
1,
amfMTaudio
},
};
AMOVIESETUP_FILTER const amfAudioConvert =
{ &CLSID_Gstreamer_AudioConvert,
wGstreamer_AudioConvert,
MERIT_UNLIKELY,
2,
amfAudioConvertPin
};
FactoryTemplate const g_Templates[] = {
{
wGstreamer_Splitter,
@ -171,6 +199,13 @@ FactoryTemplate const g_Templates[] = {
NULL,
&amfMp3,
},
{
wGstreamer_AudioConvert,
&CLSID_Gstreamer_AudioConvert,
Gstreamer_AudioConvert_create,
NULL,
&amfAudioConvert,
},
};
const int g_cTemplates = sizeof(g_Templates) / sizeof (g_Templates[0]);