summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2008-09-24 17:21:41 +0000
committerMichael Smith <msmith@xiph.org>2008-09-24 17:21:41 +0000
commita51c4c16b25416ca55ddca56a14c89be63782a90 (patch)
treea954d27933478ef5c400881dc7c8f815f6884892
parent5a97c0d534f49c7732b93deb24c5b05473dece68 (diff)
downloadgst-plugins-bad-a51c4c16b25416ca55ddca56a14c89be63782a90.tar.gz
gst-plugins-bad-a51c4c16b25416ca55ddca56a14c89be63782a90.tar.bz2
gst-plugins-bad-a51c4c16b25416ca55ddca56a14c89be63782a90.zip
sys/dshowdecwrapper/: Prefer known-good filters, create directly by GUID if possible, fall back to creating highest-m...
Original commit message from CVS: * 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.
-rw-r--r--ChangeLog14
-rw-r--r--sys/dshowdecwrapper/gstdshowaudiodec.cpp106
-rw-r--r--sys/dshowdecwrapper/gstdshowaudiodec.h1
-rw-r--r--sys/dshowdecwrapper/gstdshowfakesrc.cpp27
-rw-r--r--sys/dshowdecwrapper/gstdshowutil.cpp153
-rw-r--r--sys/dshowdecwrapper/gstdshowutil.h14
-rw-r--r--sys/dshowdecwrapper/gstdshowvideodec.cpp317
-rw-r--r--sys/dshowdecwrapper/gstdshowvideodec.h2
8 files changed, 362 insertions, 272 deletions
diff --git a/ChangeLog b/ChangeLog
index a7a8ae0b..1f34e0f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-09-24 Michael Smith <msmith@songbirdnest.com>
+
+ * 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 <wim.taymans@collabora.co.uk>
* gst/rtpmanager/rtpjitterbuffer.c: (rtp_jitter_buffer_insert),
diff --git a/sys/dshowdecwrapper/gstdshowaudiodec.cpp b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
index dd2d98d7..c2efec1e 100644
--- a/sys/dshowdecwrapper/gstdshowaudiodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowaudiodec.cpp
@@ -49,6 +49,8 @@
#include "gstdshowaudiodec.h"
#include <mmreg.h>
+#include <dmoreg.h>
+#include <wmcodecdsp.h>
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<IBaseFilter> 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 6301b31f..37f16070 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 8095c36e..170e9ed8 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 df2f65d1..ca1728be 100644
--- a/sys/dshowdecwrapper/gstdshowutil.cpp
+++ b/sys/dshowdecwrapper/gstdshowutil.cpp
@@ -20,6 +20,8 @@
*/
#include <atlbase.h>
+#include <dmodshow.h>
+#include <dmoreg.h>
#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<IFilterMapper2> mapper;
+ CComPtr<IEnumMoniker> enum_moniker;
+ CComPtr<IMoniker> moniker;
ULONG fetched;
- gchar *prefered_filter_upper = NULL;
- gboolean exit = FALSE;
-
- /* initialize output parameter */
- if (filter)
- *filter = NULL;
+ IBaseFilter *filter;
+
+ /* 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<IDMOWrapperFilter> wrapper;
+
+ 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;
+ }
- /* 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);
+ /* 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));
-
- hres = mapper->EnumMatchingFilters (&enum_moniker, 0, FALSE, MERIT_DO_NOT_USE+1,
- TRUE, 1, arrayInTypes, NULL, NULL, FALSE,
- TRUE, 1, arrayOutTypes, NULL, NULL);
+ 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, 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 ();
- }
-
- 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 ();
+ while(enum_moniker->Next (1, &moniker, &fetched) == S_OK)
+ {
+ hres = moniker->BindToObject(NULL, NULL,
+ IID_IBaseFilter, (void**)&filter);
+ if(SUCCEEDED(hres)) {
+ return filter;
}
-
- 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 0b5ca90e..80299fb2 100644
--- a/sys/dshowdecwrapper/gstdshowutil.h
+++ b/sys/dshowdecwrapper/gstdshowutil.h
@@ -31,12 +31,18 @@
#include <glib.h>
+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 80a1a193..e16de6f6 100644
--- a/sys/dshowdecwrapper/gstdshowvideodec.cpp
+++ b/sys/dshowdecwrapper/gstdshowvideodec.cpp
@@ -48,6 +48,8 @@
#endif
#include <atlbase.h>
+#include <dmoreg.h>
+#include <wmcodecdsp.h>
#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<IBaseFilter> 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 29953d82..66bb002f 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())