diff --git a/ChangeLog b/ChangeLog index a7a8ae0be7..1f34e0f981 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-09-24 Michael Smith + + * sys/dshowdecwrapper/gstdshowaudiodec.cpp: + * sys/dshowdecwrapper/gstdshowaudiodec.h: + * sys/dshowdecwrapper/gstdshowfakesrc.cpp: + * sys/dshowdecwrapper/gstdshowutil.cpp: + * sys/dshowdecwrapper/gstdshowutil.h: + * sys/dshowdecwrapper/gstdshowvideodec.cpp: + * sys/dshowdecwrapper/gstdshowvideodec.h: + Prefer known-good filters, create directly by GUID if possible, + fall back to creating highest-merit filter otherwise. + Fixes playback with random dshow filters installed in some + cases. + 2008-09-23 Wim Taymans * gst/rtpmanager/rtpjitterbuffer.c: (rtp_jitter_buffer_insert), diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.cpp b/sys/dshowdecwrapper/gstdshowaudiodec.cpp index dd2d98d7d9..c2efec1ea2 100644 --- a/sys/dshowdecwrapper/gstdshowaudiodec.cpp +++ b/sys/dshowdecwrapper/gstdshowaudiodec.cpp @@ -49,6 +49,8 @@ #include "gstdshowaudiodec.h" #include +#include +#include GST_DEBUG_CATEGORY_STATIC (dshowaudiodec_debug); #define GST_CAT_DEFAULT dshowaudiodec_debug @@ -81,45 +83,76 @@ static gboolean gst_dshowaudiodec_setup_graph (GstDshowAudioDec * adec, GstCaps { fourcc , 0x0000, 0x0010, \ { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }} +/* WMA we should always use the DMO */ +static PreferredFilter preferred_wma_filters[] = { + {&CLSID_CWMADecMediaObject, &DMOCATEGORY_AUDIO_DECODER}, + {0} +}; + +/* Prefer the Vista (DMO) decoder if present, otherwise the XP + * decoder (not a DMO), otherwise fallback to highest-merit */ +static const GUID CLSID_XP_MP3_DECODER = {0x38BE3000, 0xDBF4, 0x11D0, + {0x86,0x0E,0x00,0xA0,0x24,0xCF,0xEF,0x6D}}; +static PreferredFilter preferred_mp3_filters[] = { + {&CLSID_CMP3DecMediaObject, &DMOCATEGORY_AUDIO_DECODER}, + {&CLSID_XP_MP3_DECODER}, + {0} +}; + +/* MPEG 1/2: use the MPEG Audio Decoder filter */ +static const GUID CLSID_WINDOWS_MPEG_AUDIO_DECODER = + {0x4A2286E0, 0x7BEF, 0x11CE, + {0x9B, 0xD9, 0x00, 0x00, 0xE2, 0x02, 0x59, 0x9C}}; +static PreferredFilter preferred_mpegaudio_filters[] = { + {&CLSID_WINDOWS_MPEG_AUDIO_DECODER}, + {0} +}; + static const AudioCodecEntry audio_dec_codecs[] = { - {"dshowadec_wma1", - "Windows Media Audio 7", + {"dshowadec_wma1", "Windows Media Audio 7", WAVE_FORMAT_MSAUDIO1, - "audio/x-wma, wmaversion = (int) 1"}, - {"dshowadec_wma2", - "Windows Media Audio 8", + "audio/x-wma, wmaversion = (int) 1", + preferred_wma_filters}, + + {"dshowadec_wma2", "Windows Media Audio 8", WAVE_FORMAT_WMAUDIO2, - "audio/x-wma, wmaversion = (int) 2"}, - {"dshowadec_wma3", - "Windows Media Audio 9 Professional", + "audio/x-wma, wmaversion = (int) 2", + preferred_wma_filters}, + + {"dshowadec_wma3", "Windows Media Audio 9 Professional", WAVE_FORMAT_WMAUDIO3, - "audio/x-wma, wmaversion = (int) 3"}, - {"dshowadec_wma4", - "Windows Media Audio 9 Lossless", + "audio/x-wma, wmaversion = (int) 3", + preferred_wma_filters}, + + {"dshowadec_wma4", "Windows Media Audio 9 Lossless", WAVE_FORMAT_WMAUDIO_LOSSLESS, - "audio/x-wma, wmaversion = (int) 4"}, - {"dshowadec_wms", - "Windows Media Audio Voice v9", + "audio/x-wma, wmaversion = (int) 4", + preferred_wma_filters}, + + {"dshowadec_wms", "Windows Media Audio Voice v9", WAVE_FORMAT_WMAVOICE9, - "audio/x-wms"}, - {"dshowadec_mp3", - "MPEG Layer 3 Audio", + "audio/x-wms", + preferred_wma_filters}, + + {"dshowadec_mp3", "MPEG Layer 3 Audio", WAVE_FORMAT_MPEGLAYER3, "audio/mpeg, " "mpegversion = (int) 1, " "layer = (int)3, " "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ], " - "parsed= (boolean) true"}, - {"dshowadec_mpeg_1_2", - "MPEG Layer 1,2 Audio", + "parsed= (boolean) true", + preferred_mp3_filters}, + + {"dshowadec_mpeg_1_2", "MPEG Layer 1,2 Audio", WAVE_FORMAT_MPEG, "audio/mpeg, " "mpegversion = (int) 1, " "layer = (int) [ 1, 2 ], " "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ], " - "parsed= (boolean) true"}, + "parsed= (boolean) true", + preferred_mpegaudio_filters}, }; HRESULT AudioFakeSink::DoRenderSample(IMediaSample *pMediaSample) @@ -230,7 +263,7 @@ HRESULT AudioFakeSink::DoRenderSample(IMediaSample *pMediaSample) done: return S_OK; } - + HRESULT AudioFakeSink::CheckMediaType(const CMediaType *pmt) { if(pmt != NULL) @@ -921,11 +954,12 @@ gst_dshowaudiodec_create_graph_and_filters (GstDshowAudioDec * adec) adec->fakesrc->AddRef(); /* create decoder filter */ - if (!gst_dshow_find_filter (MEDIATYPE_Audio, + adec->decfilter = gst_dshow_find_filter (MEDIATYPE_Audio, insubtype, MEDIATYPE_Audio, outsubtype, - NULL, &adec->decfilter)) { + klass->entry->preferred_filters); + if (adec->decfilter == NULL) { GST_ELEMENT_ERROR (adec, STREAM, FAILED, ("Can't create an instance of the decoder filter"), (NULL)); goto error; @@ -1038,21 +1072,22 @@ dshow_adec_register (GstPlugin * plugin) hr = CoInitialize(0); for (i = 0; i < sizeof (audio_dec_codecs) / sizeof (AudioCodecEntry); i++) { GType type; - + CComPtr filter; GUID insubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (audio_dec_codecs[i].format); GUID outsubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (WAVE_FORMAT_PCM); - if (gst_dshow_find_filter (MEDIATYPE_Audio, + + filter = gst_dshow_find_filter (MEDIATYPE_Audio, insubtype, MEDIATYPE_Audio, outsubtype, - NULL, NULL)) { + audio_dec_codecs[i].preferred_filters); - GST_CAT_DEBUG (dshowaudiodec_debug, "Registering %s", - audio_dec_codecs[i].element_name); + if (filter) + { + GST_DEBUG ("Registering %s", audio_dec_codecs[i].element_name); tmp = &audio_dec_codecs[i]; - type = - g_type_register_static (GST_TYPE_ELEMENT, + type = g_type_register_static (GST_TYPE_ELEMENT, audio_dec_codecs[i].element_name, &info, (GTypeFlags)0); if (!gst_element_register (plugin, audio_dec_codecs[i].element_name, GST_RANK_PRIMARY, type)) { @@ -1060,10 +1095,11 @@ dshow_adec_register (GstPlugin * plugin) } GST_CAT_DEBUG (dshowaudiodec_debug, "Registered %s", audio_dec_codecs[i].element_name); - } else { - GST_CAT_DEBUG (dshowaudiodec_debug, - "Element %s not registered (the format is not supported by the system)", - audio_dec_codecs[i].element_name); + } + else { + GST_DEBUG ("Element %s not registered " + "(the format is not supported by the system)", + audio_dec_codecs[i].element_name); } } diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.h b/sys/dshowdecwrapper/gstdshowaudiodec.h index 6301b31f52..37f16070ea 100644 --- a/sys/dshowdecwrapper/gstdshowaudiodec.h +++ b/sys/dshowdecwrapper/gstdshowaudiodec.h @@ -60,6 +60,7 @@ typedef struct { gchar *element_longname; /* Description string for element */ gint32 format; /* WAVEFORMATEX format */ gchar *sinkcaps; /* GStreamer caps of input format */ + PreferredFilter *preferred_filters; /* NULL-terminated list of preferred filters */ } AudioCodecEntry; #define GST_TYPE_DSHOWAUDIODEC (gst_dshowaudiodec_get_type()) diff --git a/sys/dshowdecwrapper/gstdshowfakesrc.cpp b/sys/dshowdecwrapper/gstdshowfakesrc.cpp index 8095c36e13..170e9ed89e 100644 --- a/sys/dshowdecwrapper/gstdshowfakesrc.cpp +++ b/sys/dshowdecwrapper/gstdshowfakesrc.cpp @@ -46,14 +46,33 @@ HRESULT FakeOutputPin::GetMediaType(int iPosition, return VFW_S_NO_MORE_ITEMS; } +#if 0 +#define GUID_FORMAT "0x%.8x 0x%.4x 0x%.4x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x" +#define GUID_ARGS(g) g.Data1, g.Data2, g.Data3, \ + g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], \ + g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7] + +static void printMediaType (AM_MEDIA_TYPE *mt) +{ + GST_DEBUG (":: majortype: "GUID_FORMAT, GUID_ARGS(mt->majortype)); + GST_DEBUG (":: subtype: "GUID_FORMAT, GUID_ARGS(mt->subtype)); + + GST_DEBUG (":: bFixedSizeSamples: %d", mt->bFixedSizeSamples); + GST_DEBUG (":: bTemporalCompression: %d", mt->bTemporalCompression); + GST_DEBUG (":: cbFormat: %d", mt->cbFormat); + GST_DEBUG (":: formattype: %x", mt->formattype); + GST_DEBUG (":: lSampleSize: %lu", mt->lSampleSize); + GST_DEBUG (":: pbFormat: %p", mt->pbFormat); +} +#endif HRESULT FakeOutputPin::CheckMediaType(const CMediaType *pmt) { - if (m_MediaType == *pmt) { - return S_OK; - } + if (m_MediaType == *pmt) { + return S_OK; + } - return S_FALSE; + return S_FALSE; } HRESULT FakeOutputPin::DecideBufferSize (IMemAllocator *pAlloc, diff --git a/sys/dshowdecwrapper/gstdshowutil.cpp b/sys/dshowdecwrapper/gstdshowutil.cpp index df2f65d11c..ca1728bec9 100644 --- a/sys/dshowdecwrapper/gstdshowutil.cpp +++ b/sys/dshowdecwrapper/gstdshowutil.cpp @@ -20,6 +20,8 @@ */ #include +#include +#include #include "gstdshowutil.h" #include "gstdshowfakesrc.h" @@ -49,108 +51,87 @@ gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir) return NULL; } -gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, - CLSID output_majortype, CLSID output_subtype, - gchar * prefered_filter_name, IBaseFilter **filter) +IBaseFilter * +gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, + CLSID output_majortype, CLSID output_subtype, + PreferredFilter *preferred_filters) { - gboolean ret = FALSE; HRESULT hres; - GUID arrayInTypes[2]; - GUID arrayOutTypes[2]; - IFilterMapper2 *mapper = NULL; - IEnumMoniker *enum_moniker = NULL; - IMoniker *moniker = NULL; + GUID inTypes[2]; + GUID outTypes[2]; + CComPtr mapper; + CComPtr enum_moniker; + CComPtr moniker; ULONG fetched; - gchar *prefered_filter_upper = NULL; - gboolean exit = FALSE; + IBaseFilter *filter; - /* initialize output parameter */ - if (filter) - *filter = NULL; + /* First, see if any of our preferred filters is available. + * If not, we fall back to the highest-ranked installed filter */ + if (preferred_filters) { + while (preferred_filters->filter_guid) + { + /* If the filter is a DMO, we need to do this a bit differently */ + if (preferred_filters->dmo_category) + { + CComPtr wrapper; - /* create a private copy of prefered filter substring in upper case */ - if (prefered_filter_name) { - prefered_filter_upper = g_strdup (prefered_filter_name); - strupr (prefered_filter_upper); + hres = CoCreateInstance (CLSID_DMOWrapperFilter, NULL, + CLSCTX_INPROC, + IID_IBaseFilter, (void **)&filter); + if (SUCCEEDED(hres)) { + hres = filter->QueryInterface (&wrapper); + if (SUCCEEDED(hres)) { + hres = wrapper->Init (*preferred_filters->filter_guid, + *preferred_filters->dmo_category); + if (SUCCEEDED(hres)) + return filter; + } + filter->Release(); + } + } + else + { + hres = CoCreateInstance (*preferred_filters->filter_guid, + NULL, CLSCTX_INPROC, + IID_IBaseFilter, (void **)&filter); + if (SUCCEEDED(hres)) + return filter; + } + + /* Continue to the next filter */ + preferred_filters++; + } } hres = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, IID_IFilterMapper2, (void **) &mapper); if (FAILED(hres)) - goto clean; + return NULL; - memcpy(&arrayInTypes[0], &input_majortype, sizeof (CLSID)); - memcpy(&arrayInTypes[1], &input_subtype, sizeof (CLSID)); - memcpy(&arrayOutTypes[0], &output_majortype, sizeof (CLSID)); - memcpy(&arrayOutTypes[1], &output_subtype, sizeof (CLSID)); + inTypes[0] = input_majortype; + inTypes[1] = input_subtype; + outTypes[0] = output_majortype; + outTypes[1] = output_subtype; - hres = mapper->EnumMatchingFilters (&enum_moniker, 0, FALSE, MERIT_DO_NOT_USE+1, - TRUE, 1, arrayInTypes, NULL, NULL, FALSE, - TRUE, 1, arrayOutTypes, NULL, NULL); + hres = mapper->EnumMatchingFilters (&enum_moniker, 0, + FALSE, MERIT_DO_NOT_USE+1, + TRUE, 1, inTypes, NULL, NULL, FALSE, + TRUE, 1, outTypes, NULL, NULL); if (FAILED(hres)) - goto clean; + return NULL; enum_moniker->Reset (); - - while(hres = enum_moniker->Next (1, &moniker, &fetched),hres == S_OK - && !exit) { - IBaseFilter *filter_temp = NULL; - IPropertyBag *property_bag = NULL; - gchar * friendly_name = NULL; - hres = moniker->BindToStorage (NULL, NULL, IID_IPropertyBag, (void **)&property_bag); - if(SUCCEEDED(hres) && property_bag) { - VARIANT varFriendlyName; - VariantInit (&varFriendlyName); - - hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL); - if(hres == S_OK && varFriendlyName.bstrVal) { - friendly_name = g_utf16_to_utf8((const gunichar2*)varFriendlyName.bstrVal, - wcslen(varFriendlyName.bstrVal), NULL, NULL, NULL); - if (friendly_name) - strupr (friendly_name); - SysFreeString (varFriendlyName.bstrVal); - } - property_bag->Release (); + while(enum_moniker->Next (1, &moniker, &fetched) == S_OK) + { + hres = moniker->BindToObject(NULL, NULL, + IID_IBaseFilter, (void**)&filter); + if(SUCCEEDED(hres)) { + return filter; } - - hres = moniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&filter_temp); - if(SUCCEEDED(hres) && filter_temp) { - ret = TRUE; - if (filter) { - if (*filter) - (*filter)->Release (); - - *filter = filter_temp; - (*filter)->AddRef (); - - if (prefered_filter_upper && friendly_name && - strstr(friendly_name, prefered_filter_upper)) - exit = TRUE; - } - - /* if we just want to know if the formats are supported OR - if we don't care about what will be the filter used - => we can stop enumeration */ - if (!filter || !prefered_filter_upper) - exit = TRUE; - - filter_temp->Release (); - } - - if (friendly_name) - g_free (friendly_name); - moniker->Release (); + moniker.Release (); } -clean: - if (prefered_filter_upper) - g_free (prefered_filter_upper); - if (enum_moniker) - enum_moniker->Release (); - if (mapper) - mapper->Release (); - - return ret; + return NULL; } diff --git a/sys/dshowdecwrapper/gstdshowutil.h b/sys/dshowdecwrapper/gstdshowutil.h index 0b5ca90e24..80299fb275 100644 --- a/sys/dshowdecwrapper/gstdshowutil.h +++ b/sys/dshowdecwrapper/gstdshowutil.h @@ -31,12 +31,18 @@ #include +typedef struct { + const GUID *filter_guid; /* The filter GUID, or DMO GUID */ + const GUID *dmo_category; /* If non-NULL, the filter is a DMO of this + category */ +} PreferredFilter; + /* get a pin from directshow filter */ IPin *gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir); /* find and return a filter according to the input and output types */ -gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, - CLSID output_majortype, CLSID output_subtype, - gchar * prefered_filter_name, IBaseFilter **filter); - +IBaseFilter * +gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, + CLSID output_majortype, CLSID output_subtype, + PreferredFilter *preferred_filters); #endif /* _GST_DSHOW_UTIL_H_ */ diff --git a/sys/dshowdecwrapper/gstdshowvideodec.cpp b/sys/dshowdecwrapper/gstdshowvideodec.cpp index 80a1a1931e..e16de6f654 100644 --- a/sys/dshowdecwrapper/gstdshowvideodec.cpp +++ b/sys/dshowdecwrapper/gstdshowvideodec.cpp @@ -48,6 +48,8 @@ #endif #include +#include +#include #include "gstdshowvideodec.h" @@ -107,140 +109,168 @@ static gboolean gst_dshowvideodec_get_filter_output_format (GstDshowVideoDec * #define GUID_MEDIASUBTYPE_RGB32 {0xe436eb7e, 0x524f, 0x11ce, { 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 }} #define GUID_MEDIASUBTYPE_RGB565 {0xe436eb7b, 0x524f, 0x11ce, { 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 }} +/* WMV always uses the WMV DMO */ +static PreferredFilter preferred_wmv_filters[] = { + {&CLSID_CWMVDecMediaObject, &DMOCATEGORY_VIDEO_DECODER}, {0} +}; + +static const GUID CLSID_AVI_DECOMPRESSOR = + {0xCF49D4E0, 0x1115, 0x11CE, + {0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}}; +static PreferredFilter preferred_cinepack_filters[] = { + {&CLSID_AVI_DECOMPRESSOR}, {0} +}; + +/* Various MPEG-4 video variants */ +// MPG4, mpg4, MP42, mp42 +static PreferredFilter preferred_mpeg4_filters[] = { + {&CLSID_CMpeg4DecMediaObject, &DMOCATEGORY_VIDEO_DECODER}, {0}}; +// MP4S, mp4s, M4S2, m4s2 +static PreferredFilter preferred_mp4s_filters[] = { + {&CLSID_CMpeg4sDecMediaObject, &DMOCATEGORY_VIDEO_DECODER}, {0}}; +// MP43, mp43 +static PreferredFilter preferred_mp43_filters[] = { + {&CLSID_CMpeg43DecMediaObject, &DMOCATEGORY_VIDEO_DECODER}, {0}}; + +static const GUID CLSID_MPEG_VIDEO_DECODER = + {0xFEB50740, 0x7BEF, 0x11CE, + {0x9B, 0xD9, 0x00, 0x00, 0xE2, 0x02, 0x59, 0x9C}}; +static PreferredFilter preferred_mpeg1_filters[] = { + {&CLSID_MPEG_VIDEO_DECODER}, {0} +}; + + /* video codecs array */ static const VideoCodecEntry video_dec_codecs[] = { - {"dshowvdec_wmv1", - "Windows Media Video 7", - "DMO", - GST_MAKE_FOURCC ('W', 'M', 'V', '1'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV1, - "video/x-wmv, wmvversion = (int) 1", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_wmv2", - "Windows Media Video 8", - "DMO", - GST_MAKE_FOURCC ('W', 'M', 'V', '2'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV2, - "video/x-wmv, wmvversion = (int) 2", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_wmv3", - "Windows Media Video 9", - "DMO", - GST_MAKE_FOURCC ('W', 'M', 'V', '3'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV3, - "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMV3", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_wmvp", - "Windows Media Video 9 Image", - "DMO", - GST_MAKE_FOURCC ('W', 'M', 'V', 'P'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVP, - "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMVP", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_wmva", - "Windows Media Video 9 Advanced", - "DMO", - GST_MAKE_FOURCC ('W', 'M', 'V', 'A'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVA, - "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMVA", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_cinepak", - "Cinepack", - "AVI Decompressor", - 0x64697663, - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_CVID, - "video/x-cinepak", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_RGB32, - "video/x-raw-rgb, bpp=(int)32, depth=(int)24, " - "endianness=(int)4321, red_mask=(int)65280, " - "green_mask=(int)16711680, blue_mask=(int)-16777216"}, - {"dshowvdec_msmpeg41", - "Microsoft ISO MPEG-4 version 1", - "DMO", - GST_MAKE_FOURCC ('M', 'P', '4', 'S'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP4S, - "video/x-msmpeg, msmpegversion=(int)41", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_msmpeg42", - "Microsoft ISO MPEG-4 version 2", - "DMO", - GST_MAKE_FOURCC ('M', 'P', '4', '2'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP42, - "video/x-msmpeg, msmpegversion=(int)42", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_msmpeg43", - "Microsoft ISO MPEG-4 version 3", - "DMO", - GST_MAKE_FOURCC ('M', 'P', '4', '3'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP43, - "video/x-msmpeg, msmpegversion=(int)43", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_msmpeg4", - "Microsoft ISO MPEG-4 version 1.1", - "DMO", - GST_MAKE_FOURCC ('M', '4', 'S', '2'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_M4S2, - "video/x-msmpeg, msmpegversion=(int)4", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, + {"dshowvdec_wmv1", "Windows Media Video 7", + GST_MAKE_FOURCC ('W', 'M', 'V', '1'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV1, + "video/x-wmv, wmvversion = (int) 1", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_wmv_filters}, + + {"dshowvdec_wmv2", "Windows Media Video 8", + GST_MAKE_FOURCC ('W', 'M', 'V', '2'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV2, + "video/x-wmv, wmvversion = (int) 2", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_wmv_filters}, + + {"dshowvdec_wmv3", "Windows Media Video 9", + GST_MAKE_FOURCC ('W', 'M', 'V', '3'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVV3, + "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMV3", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_wmv_filters}, + + {"dshowvdec_wmvp", "Windows Media Video 9 Image", + GST_MAKE_FOURCC ('W', 'M', 'V', 'P'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVP, + "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMVP", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_wmv_filters}, + + {"dshowvdec_wmva", "Windows Media Video 9 Advanced", + GST_MAKE_FOURCC ('W', 'M', 'V', 'A'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_WMVA, + "video/x-wmv, wmvversion = (int) 3, " "format = (fourcc) WMVA", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_wmv_filters}, + + {"dshowvdec_cinepak", "Cinepack", + 0x64697663, + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_CVID, + "video/x-cinepak", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_RGB32, + "video/x-raw-rgb, bpp=(int)32, depth=(int)24, " + "endianness=(int)4321, red_mask=(int)65280, " + "green_mask=(int)16711680, blue_mask=(int)-16777216", + preferred_cinepack_filters}, + + {"dshowvdec_msmpeg41", "Microsoft ISO MPEG-4 version 1", + GST_MAKE_FOURCC ('M', 'P', '4', 'S'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP4S, + "video/x-msmpeg, msmpegversion=(int)41", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mp4s_filters}, + + {"dshowvdec_msmpeg42", "Microsoft ISO MPEG-4 version 2", + GST_MAKE_FOURCC ('M', 'P', '4', '2'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP42, + "video/x-msmpeg, msmpegversion=(int)42", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mpeg4_filters}, + + {"dshowvdec_msmpeg43", "Microsoft ISO MPEG-4 version 3", + GST_MAKE_FOURCC ('M', 'P', '4', '3'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MP43, + "video/x-msmpeg, msmpegversion=(int)43", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mp43_filters}, + + {"dshowvdec_msmpeg4", "Microsoft ISO MPEG-4 version 1.1", + GST_MAKE_FOURCC ('M', '4', 'S', '2'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_M4S2, + "video/x-msmpeg, msmpegversion=(int)4", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mp4s_filters}, + {"dshowvdec_mpeg1", - "MPEG-1 Video", - "MPEG Video Decoder", - GST_MAKE_FOURCC ('M', 'P', 'E', 'G'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MPEG1Payload, - "video/mpeg, mpegversion= (int) 1, " - "parsed= (boolean) true, " "systemstream= (boolean) false", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_xvid", - "XVID Video", - "ffdshow", - GST_MAKE_FOURCC ('X', 'V', 'I', 'D'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_XVID, - "video/x-xvid", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_divx5", - "DIVX 5.0 Video", - "ffdshow", - GST_MAKE_FOURCC ('D', 'X', '5', '0'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DX50, - "video/x-divx, divxversion=(int)5", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_divx4", - "DIVX 4.0 Video", - "ffdshow", - GST_MAKE_FOURCC ('D', 'I', 'V', 'X'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DIVX, - "video/x-divx, divxversion=(int)4", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"}, - {"dshowvdec_divx3", - "DIVX 3.0 Video", - "ffdshow", - GST_MAKE_FOURCC ('D', 'I', 'V', '3'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DIV3, - "video/x-divx, divxversion=(int)3", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2"} - /*, - { "dshowvdec_mpeg4", - "DMO", - GST_MAKE_FOURCC ('M', 'P', 'G', '4'), - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MPG4, - "video/mpeg, msmpegversion=(int)4", - GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, - "video/x-raw-yuv, format=(fourcc)YUY2" - } */ + "MPEG-1 Video", + GST_MAKE_FOURCC ('M', 'P', 'E', 'G'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MPEG1Payload, + "video/mpeg, mpegversion= (int) 1, " + "parsed= (boolean) true, " "systemstream= (boolean) false", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mpeg1_filters}, + + {"dshowvdec_mpeg4", "MPEG-4 Video", + GST_MAKE_FOURCC ('M', 'P', 'G', '4'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_MPG4, + "video/mpeg, msmpegversion=(int)4", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2", + preferred_mpeg4_filters}, + + /* The rest of these have no preferred filter; windows doesn't come + * with anything appropriate */ + {"dshowvdec_xvid", "XVID Video", + GST_MAKE_FOURCC ('X', 'V', 'I', 'D'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_XVID, + "video/x-xvid", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2"}, + + {"dshowvdec_divx5", "DIVX 5.0 Video", + GST_MAKE_FOURCC ('D', 'X', '5', '0'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DX50, + "video/x-divx, divxversion=(int)5", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2"}, + + {"dshowvdec_divx4", "DIVX 4.0 Video", + GST_MAKE_FOURCC ('D', 'I', 'V', 'X'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DIVX, + "video/x-divx, divxversion=(int)4", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2"}, + + {"dshowvdec_divx3", "DIVX 3.0 Video", + GST_MAKE_FOURCC ('D', 'I', 'V', '3'), + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_DIV3, + "video/x-divx, divxversion=(int)3", + GUID_MEDIATYPE_VIDEO, GUID_MEDIASUBTYPE_YUY2, + "video/x-raw-yuv, format=(fourcc)YUY2"} }; HRESULT VideoFakeSink::DoRenderSample(IMediaSample *pMediaSample) @@ -975,11 +1005,13 @@ gst_dshowvideodec_create_graph_and_filters (GstDshowVideoDec * vdec) } /* search a decoder filter and create it */ - if (!gst_dshow_find_filter (klass->entry->input_majortype, + vdec->decfilter = gst_dshow_find_filter ( + klass->entry->input_majortype, klass->entry->input_subtype, klass->entry->output_majortype, klass->entry->output_subtype, - klass->entry->preferred_filter_substring, &vdec->decfilter)) { + klass->entry->preferred_filters); + if (vdec->decfilter == NULL) { GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance " "of the decoder filter"), (NULL)); goto error; @@ -1136,15 +1168,17 @@ dshow_vdec_register (GstPlugin * plugin) for (i = 0; i < sizeof (video_dec_codecs) / sizeof (VideoCodecEntry); i++) { GType type; + CComPtr filter; - if (gst_dshow_find_filter (video_dec_codecs[i].input_majortype, + filter = gst_dshow_find_filter ( + video_dec_codecs[i].input_majortype, video_dec_codecs[i].input_subtype, video_dec_codecs[i].output_majortype, video_dec_codecs[i].output_subtype, - video_dec_codecs[i].preferred_filter_substring, NULL)) { + video_dec_codecs[i].preferred_filters); + if (filter != NULL) { - GST_CAT_DEBUG (dshowvideodec_debug, "Registering %s", - video_dec_codecs[i].element_name); + GST_DEBUG ("Registering %s", video_dec_codecs[i].element_name); tmp = &video_dec_codecs[i]; type = @@ -1154,12 +1188,11 @@ dshow_vdec_register (GstPlugin * plugin) GST_RANK_PRIMARY, type)) { return FALSE; } - GST_CAT_DEBUG (dshowvideodec_debug, "Registered %s", - video_dec_codecs[i].element_name); + GST_DEBUG ("Registered %s", video_dec_codecs[i].element_name); } else { - GST_CAT_DEBUG (dshowvideodec_debug, - "Element %s not registered (the format is not supported by the system)", - video_dec_codecs[i].element_name); + GST_DEBUG ("Element %s not registered " + "(the format is not supported by the system)", + video_dec_codecs[i].element_name); } } diff --git a/sys/dshowdecwrapper/gstdshowvideodec.h b/sys/dshowdecwrapper/gstdshowvideodec.h index 29953d82df..66bb002f48 100644 --- a/sys/dshowdecwrapper/gstdshowvideodec.h +++ b/sys/dshowdecwrapper/gstdshowvideodec.h @@ -55,7 +55,6 @@ G_BEGIN_DECLS typedef struct { gchar *element_name; /* The gst element factory name */ gchar *element_longname; /* Description string for element */ - gchar *preferred_filter_substring; /* TODO: Remove this? */ gint32 format; /* ??? */ GUID input_majortype; GUID input_subtype; @@ -63,6 +62,7 @@ typedef struct { GUID output_majortype; GUID output_subtype; gchar *srccaps; + PreferredFilter *preferred_filters; } VideoCodecEntry; #define GST_TYPE_DSHOWVIDEODEC (gst_dshowvideodec_get_type())