dshowsrcwrapper: indent

This commit is contained in:
Julien Isorce 2009-09-07 10:59:53 +02:00
parent 9844d73b37
commit 0518509f0a
8 changed files with 367 additions and 296 deletions

View file

@ -23,31 +23,31 @@
#include "gstdshowfakesink.h" #include "gstdshowfakesink.h"
void void
gst_dshow_free_mediatype (AM_MEDIA_TYPE *pmt) gst_dshow_free_mediatype (AM_MEDIA_TYPE * pmt)
{ {
if (pmt != NULL) { if (pmt != NULL) {
if (pmt->cbFormat != 0) { if (pmt->cbFormat != 0) {
CoTaskMemFree((PVOID)pmt->pbFormat); CoTaskMemFree ((PVOID) pmt->pbFormat);
pmt->cbFormat = 0; pmt->cbFormat = 0;
pmt->pbFormat = NULL; pmt->pbFormat = NULL;
} }
if (pmt->pUnk != NULL) { if (pmt->pUnk != NULL) {
/* Unecessary because pUnk should not be used, but safest. */ /* Unecessary because pUnk should not be used, but safest. */
pmt->pUnk->Release(); pmt->pUnk->Release ();
pmt->pUnk = NULL; pmt->pUnk = NULL;
} }
CoTaskMemFree(pmt); CoTaskMemFree (pmt);
} }
} }
void void
gst_dshow_free_pin_mediatype (gpointer pt) gst_dshow_free_pin_mediatype (gpointer pt)
{ {
GstCapturePinMediaType * pin_mediatype = (GstCapturePinMediaType *) pt; GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) pt;
if (pin_mediatype) { if (pin_mediatype) {
if (pin_mediatype->capture_pin) { if (pin_mediatype->capture_pin) {
pin_mediatype->capture_pin->Release(); pin_mediatype->capture_pin->Release ();
pin_mediatype->capture_pin = NULL; pin_mediatype->capture_pin = NULL;
} }
if (pin_mediatype->mediatype) { if (pin_mediatype->mediatype) {
@ -58,51 +58,53 @@ gst_dshow_free_pin_mediatype (gpointer pt)
} }
GstCapturePinMediaType * GstCapturePinMediaType *
gst_dshow_new_pin_mediatype (IPin *pin, gint id, IAMStreamConfig * streamcaps) gst_dshow_new_pin_mediatype (IPin * pin, gint id, IAMStreamConfig * streamcaps)
{ {
GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1); GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1);
HRESULT hres = streamcaps->GetStreamCaps(id, &pin_mediatype->mediatype, (BYTE *) & pin_mediatype->vscc); HRESULT hres = streamcaps->GetStreamCaps (id, &pin_mediatype->mediatype,
(BYTE *) & pin_mediatype->vscc);
if (FAILED (hres) || !pin_mediatype->mediatype) { if (FAILED (hres) || !pin_mediatype->mediatype) {
gst_dshow_free_pin_mediatype (pin_mediatype); gst_dshow_free_pin_mediatype (pin_mediatype);
return NULL; return NULL;
} }
pin->AddRef(); pin->AddRef ();
pin_mediatype->capture_pin = pin; pin_mediatype->capture_pin = pin;
return pin_mediatype; return pin_mediatype;
} }
void void
gst_dshow_free_pins_mediatypes (GList *pins_mediatypes) gst_dshow_free_pins_mediatypes (GList * pins_mediatypes)
{ {
guint i = 0; guint i = 0;
for (; i < g_list_length (pins_mediatypes); i++) { for (; i < g_list_length (pins_mediatypes); i++) {
GList *mylist = g_list_nth (pins_mediatypes, i); GList *mylist = g_list_nth (pins_mediatypes, i);
if (mylist && mylist->data) if (mylist && mylist->data)
gst_dshow_free_pin_mediatype ((GstCapturePinMediaType *)mylist->data); gst_dshow_free_pin_mediatype ((GstCapturePinMediaType *) mylist->data);
} }
g_list_free (pins_mediatypes); g_list_free (pins_mediatypes);
} }
gboolean gboolean
gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type, gst_dshow_check_mediatype (AM_MEDIA_TYPE * media_type, const GUID sub_type,
const GUID format_type) const GUID format_type)
{ {
RPC_STATUS rpcstatus; RPC_STATUS rpcstatus;
g_return_val_if_fail (media_type != NULL, FALSE); g_return_val_if_fail (media_type != NULL, FALSE);
return return
UuidCompare (&media_type->subtype, (UUID *) &sub_type, UuidCompare (&media_type->subtype, (UUID *) & sub_type,
&rpcstatus) == 0 && rpcstatus == RPC_S_OK && &rpcstatus) == 0 && rpcstatus == RPC_S_OK &&
UuidCompare (&media_type->formattype, (UUID *) &format_type, UuidCompare (&media_type->formattype, (UUID *) & format_type,
&rpcstatus) == 0 && rpcstatus == RPC_S_OK; &rpcstatus) == 0 && rpcstatus == RPC_S_OK;
} }
gboolean gboolean
gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin) gst_dshow_get_pin_from_filter (IBaseFilter * filter, PIN_DIRECTION pindir,
IPin ** pin)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
IEnumPins *enumpins = NULL; IEnumPins *enumpins = NULL;
@ -111,18 +113,17 @@ gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin *
*pin = NULL; *pin = NULL;
hres = filter->EnumPins (&enumpins); hres = filter->EnumPins (&enumpins);
if (FAILED(hres)) { if (FAILED (hres)) {
return ret; return ret;
} }
while (enumpins->Next (1, &pintmp, NULL) == S_OK) while (enumpins->Next (1, &pintmp, NULL) == S_OK) {
{
PIN_DIRECTION pindirtmp; PIN_DIRECTION pindirtmp;
hres = pintmp->QueryDirection (&pindirtmp); hres = pintmp->QueryDirection (&pindirtmp);
if (hres == S_OK && pindir == pindirtmp) { if (hres == S_OK && pindir == pindirtmp) {
*pin = pintmp; *pin = pintmp;
ret = TRUE; ret = TRUE;
break; break;
} }
pintmp->Release (); pintmp->Release ();
} }
@ -131,9 +132,10 @@ gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin *
return ret; return ret;
} }
gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, gboolean
CLSID output_majortype, CLSID output_subtype, gst_dshow_find_filter (CLSID input_majortype, CLSID input_subtype,
gchar * prefered_filter_name, IBaseFilter **filter) CLSID output_majortype, CLSID output_subtype,
gchar * prefered_filter_name, IBaseFilter ** filter)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
HRESULT hres; HRESULT hres;
@ -156,48 +158,54 @@ gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype,
_strupr (prefered_filter_upper); _strupr (prefered_filter_upper);
} }
hres = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC, hres = CoCreateInstance (CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
IID_IFilterMapper2, (void **) &mapper); IID_IFilterMapper2, (void **) &mapper);
if (FAILED(hres)) if (FAILED (hres))
goto clean; goto clean;
memcpy(&arrayInTypes[0], &input_majortype, sizeof (CLSID)); memcpy (&arrayInTypes[0], &input_majortype, sizeof (CLSID));
memcpy(&arrayInTypes[1], &input_subtype, sizeof (CLSID)); memcpy (&arrayInTypes[1], &input_subtype, sizeof (CLSID));
memcpy(&arrayOutTypes[0], &output_majortype, sizeof (CLSID)); memcpy (&arrayOutTypes[0], &output_majortype, sizeof (CLSID));
memcpy(&arrayOutTypes[1], &output_subtype, sizeof (CLSID)); memcpy (&arrayOutTypes[1], &output_subtype, sizeof (CLSID));
hres = mapper->EnumMatchingFilters (&enum_moniker, 0, FALSE, MERIT_DO_NOT_USE+1, hres =
TRUE, 1, arrayInTypes, NULL, NULL, FALSE, mapper->EnumMatchingFilters (&enum_moniker, 0, FALSE,
TRUE, 1, arrayOutTypes, NULL, NULL); MERIT_DO_NOT_USE + 1, TRUE, 1, arrayInTypes, NULL, NULL, FALSE, TRUE, 1,
if (FAILED(hres)) arrayOutTypes, NULL, NULL);
if (FAILED (hres))
goto clean; goto clean;
enum_moniker->Reset (); enum_moniker->Reset ();
while(hres = enum_moniker->Next (1, &moniker, &fetched),hres == S_OK while (hres = enum_moniker->Next (1, &moniker, &fetched), hres == S_OK
&& !exit) { && !exit) {
IBaseFilter *filter_temp = NULL; IBaseFilter *filter_temp = NULL;
IPropertyBag *property_bag = NULL; IPropertyBag *property_bag = NULL;
gchar * friendly_name = NULL; gchar *friendly_name = NULL;
hres = moniker->BindToStorage (NULL, NULL, IID_IPropertyBag, (void **)&property_bag); hres =
if(SUCCEEDED(hres) && property_bag) { moniker->BindToStorage (NULL, NULL, IID_IPropertyBag,
(void **) &property_bag);
if (SUCCEEDED (hres) && property_bag) {
VARIANT varFriendlyName; VARIANT varFriendlyName;
VariantInit (&varFriendlyName); VariantInit (&varFriendlyName);
hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL); hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL);
if(hres == S_OK && varFriendlyName.bstrVal) { if (hres == S_OK && varFriendlyName.bstrVal) {
friendly_name = g_utf16_to_utf8((const gunichar2*)varFriendlyName.bstrVal, friendly_name =
wcslen(varFriendlyName.bstrVal), NULL, NULL, NULL); g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
if (friendly_name) wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL);
_strupr (friendly_name); if (friendly_name)
_strupr (friendly_name);
SysFreeString (varFriendlyName.bstrVal); SysFreeString (varFriendlyName.bstrVal);
} }
property_bag->Release (); property_bag->Release ();
} }
hres = moniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&filter_temp); hres =
if(SUCCEEDED(hres) && filter_temp) { moniker->BindToObject (NULL, NULL, IID_IBaseFilter,
(void **) &filter_temp);
if (SUCCEEDED (hres) && filter_temp) {
ret = TRUE; ret = TRUE;
if (filter) { if (filter) {
if (*filter) if (*filter)
@ -207,13 +215,13 @@ gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype,
(*filter)->AddRef (); (*filter)->AddRef ();
if (prefered_filter_upper && friendly_name && if (prefered_filter_upper && friendly_name &&
strstr(friendly_name, prefered_filter_upper)) strstr (friendly_name, prefered_filter_upper))
exit = TRUE; exit = TRUE;
} }
/* if we just want to know if the formats are supported OR /* if we just want to know if the formats are supported OR
if we don't care about what will be the filter used if we don't care about what will be the filter used
=> we can stop enumeration */ => we can stop enumeration */
if (!filter || !prefered_filter_upper) if (!filter || !prefered_filter_upper)
exit = TRUE; exit = TRUE;
@ -238,7 +246,8 @@ clean:
gchar * gchar *
gst_dshow_getdevice_from_devicename (const GUID *device_category, gchar **device_name) gst_dshow_getdevice_from_devicename (const GUID * device_category,
gchar ** device_name)
{ {
gchar *ret = NULL; gchar *ret = NULL;
ICreateDevEnum *devices_enum = NULL; ICreateDevEnum *devices_enum = NULL;
@ -249,44 +258,47 @@ gst_dshow_getdevice_from_devicename (const GUID *device_category, gchar **devic
gboolean bfound = FALSE; gboolean bfound = FALSE;
hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&devices_enum); IID_ICreateDevEnum, (void **) &devices_enum);
if(hres != S_OK) { if (hres != S_OK) {
/*error*/ /*error */
goto clean; goto clean;
} }
hres = devices_enum->CreateClassEnumerator (*device_category, hres = devices_enum->CreateClassEnumerator (*device_category,
&enum_moniker, 0); &enum_moniker, 0);
if (hres != S_OK || !enum_moniker) { if (hres != S_OK || !enum_moniker) {
/*error*/ /*error */
goto clean; goto clean;
} }
enum_moniker->Reset (); enum_moniker->Reset ();
while(hres = enum_moniker->Next (1, &moniker, &fetched),hres == S_OK while (hres = enum_moniker->Next (1, &moniker, &fetched), hres == S_OK
&& !bfound) { && !bfound) {
IPropertyBag *property_bag = NULL; IPropertyBag *property_bag = NULL;
hres = moniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void **)&property_bag); hres =
if(SUCCEEDED(hres) && property_bag) { moniker->BindToStorage (NULL, NULL, IID_IPropertyBag,
(void **) &property_bag);
if (SUCCEEDED (hres) && property_bag) {
VARIANT varFriendlyName; VARIANT varFriendlyName;
VariantInit (&varFriendlyName); VariantInit (&varFriendlyName);
hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL); hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL);
if(hres == S_OK && varFriendlyName.bstrVal) { if (hres == S_OK && varFriendlyName.bstrVal) {
gchar * friendly_name = g_utf16_to_utf8((const gunichar2*)varFriendlyName.bstrVal, gchar *friendly_name =
wcslen(varFriendlyName.bstrVal), NULL, NULL, NULL); g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL);
if (!*device_name) { if (!*device_name) {
*device_name = g_strdup (friendly_name); *device_name = g_strdup (friendly_name);
} }
if (_stricmp(*device_name, friendly_name) == 0) { if (_stricmp (*device_name, friendly_name) == 0) {
WCHAR *wszDisplayName = NULL; WCHAR *wszDisplayName = NULL;
hres = moniker->GetDisplayName (NULL, NULL, &wszDisplayName); hres = moniker->GetDisplayName (NULL, NULL, &wszDisplayName);
if(hres == S_OK && wszDisplayName) { if (hres == S_OK && wszDisplayName) {
ret = g_utf16_to_utf8((const gunichar2*)wszDisplayName, ret = g_utf16_to_utf8 ((const gunichar2 *) wszDisplayName,
wcslen(wszDisplayName), NULL, NULL, NULL); wcslen (wszDisplayName), NULL, NULL, NULL);
CoTaskMemFree (wszDisplayName); CoTaskMemFree (wszDisplayName);
} }
bfound = TRUE; bfound = TRUE;
@ -311,39 +323,41 @@ clean:
} }
gboolean gboolean
gst_dshow_show_propertypage (IBaseFilter *base_filter) gst_dshow_show_propertypage (IBaseFilter * base_filter)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
ISpecifyPropertyPages *pProp = NULL; ISpecifyPropertyPages *pProp = NULL;
HRESULT hres = base_filter->QueryInterface (IID_ISpecifyPropertyPages, (void **)&pProp); HRESULT hres =
if (SUCCEEDED(hres)) base_filter->QueryInterface (IID_ISpecifyPropertyPages, (void **) &pProp);
{ if (SUCCEEDED (hres)) {
/* Get the filter's name and IUnknown pointer.*/ /* Get the filter's name and IUnknown pointer. */
FILTER_INFO FilterInfo; FILTER_INFO FilterInfo;
CAUUID caGUID; CAUUID caGUID;
IUnknown *pFilterUnk = NULL; IUnknown *pFilterUnk = NULL;
hres = base_filter->QueryFilterInfo (&FilterInfo); hres = base_filter->QueryFilterInfo (&FilterInfo);
base_filter->QueryInterface (IID_IUnknown, (void **)&pFilterUnk); base_filter->QueryInterface (IID_IUnknown, (void **) &pFilterUnk);
/* Show the page. */ /* Show the page. */
pProp->GetPages (&caGUID); pProp->GetPages (&caGUID);
pProp->Release (); pProp->Release ();
OleCreatePropertyFrame(GetDesktopWindow(), 0, 0, FilterInfo.achName, OleCreatePropertyFrame (GetDesktopWindow (), 0, 0, FilterInfo.achName,
1, &pFilterUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL); 1, &pFilterUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL);
pFilterUnk->Release (); pFilterUnk->Release ();
FilterInfo.pGraph->Release (); FilterInfo.pGraph->Release ();
CoTaskMemFree(caGUID.pElems); CoTaskMemFree (caGUID.pElems);
} }
return ret; return ret;
} }
GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* name, GstCaps *
GstCapturePinMediaType *pin_mediatype) gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar * name,
GstCapturePinMediaType * pin_mediatype)
{ {
GstCaps *video_caps = NULL; GstCaps *video_caps = NULL;
GstStructure *video_structure = NULL; GstStructure *video_structure = NULL;
VIDEOINFOHEADER *video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; VIDEOINFOHEADER *video_info =
(VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
pin_mediatype->defaultWidth = video_info->bmiHeader.biWidth; pin_mediatype->defaultWidth = video_info->bmiHeader.biWidth;
pin_mediatype->defaultHeight = video_info->bmiHeader.biHeight; pin_mediatype->defaultHeight = video_info->bmiHeader.biHeight;
@ -363,15 +377,15 @@ GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* nam
} }
/* other video format */ /* other video format */
if (!video_caps){ if (!video_caps) {
if (g_strcasecmp (name, "video/x-dv, systemstream=FALSE") == 0) { if (g_strcasecmp (name, "video/x-dv, systemstream=FALSE") == 0) {
video_caps = gst_caps_new_simple ("video/x-dv", video_caps = gst_caps_new_simple ("video/x-dv",
"systemstream", G_TYPE_BOOLEAN, FALSE, "systemstream", G_TYPE_BOOLEAN, FALSE,
"format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'), "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
NULL); NULL);
} else if (g_strcasecmp (name, "video/x-dv, systemstream=TRUE") == 0) { } else if (g_strcasecmp (name, "video/x-dv, systemstream=TRUE") == 0) {
video_caps = gst_caps_new_simple ("video/x-dv", video_caps = gst_caps_new_simple ("video/x-dv",
"systemstream", G_TYPE_BOOLEAN, TRUE, NULL); "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
return video_caps; return video_caps;
} }
} }
@ -392,12 +406,13 @@ GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* nam
/* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */ /* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */
gst_structure_set (video_structure, gst_structure_set (video_structure,
"width", GST_TYPE_INT_RANGE, pin_mediatype->vscc.MinOutputSize.cx, pin_mediatype->vscc.MaxOutputSize.cx, "width", GST_TYPE_INT_RANGE, pin_mediatype->vscc.MinOutputSize.cx,
"height", GST_TYPE_INT_RANGE, pin_mediatype->vscc.MinOutputSize.cy, pin_mediatype->vscc.MaxOutputSize.cy, pin_mediatype->vscc.MaxOutputSize.cx, "height", GST_TYPE_INT_RANGE,
"framerate", GST_TYPE_FRACTION_RANGE, pin_mediatype->vscc.MinOutputSize.cy,
(gint) (10000000 / pin_mediatype->vscc.MaxFrameInterval), 1, pin_mediatype->vscc.MaxOutputSize.cy, "framerate",
(gint) (10000000 / pin_mediatype->vscc.MinFrameInterval), 1, GST_TYPE_FRACTION_RANGE,
NULL); (gint) (10000000 / pin_mediatype->vscc.MaxFrameInterval), 1,
(gint) (10000000 / pin_mediatype->vscc.MinFrameInterval), 1, NULL);
return video_caps; return video_caps;
} }

View file

@ -43,42 +43,46 @@ typedef struct _GstCapturePinMediaType
gint defaultHeight; gint defaultHeight;
gint defaultFPS; gint defaultFPS;
gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits
gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits
} GstCapturePinMediaType; } GstCapturePinMediaType;
/* free memory of the input pin mediatype */ /* free memory of the input pin mediatype */
void gst_dshow_free_pin_mediatype (gpointer pt); void gst_dshow_free_pin_mediatype (gpointer pt);
/* free memory of the input dshow mediatype */ /* free memory of the input dshow mediatype */
void gst_dshow_free_mediatype (AM_MEDIA_TYPE *pmt); void gst_dshow_free_mediatype (AM_MEDIA_TYPE * pmt);
/* create a new capture media type that handles dshow video caps of a capture pin */ /* create a new capture media type that handles dshow video caps of a capture pin */
GstCapturePinMediaType *gst_dshow_new_pin_mediatype (IPin *pin, gint id, IAMStreamConfig * streamcaps); GstCapturePinMediaType *gst_dshow_new_pin_mediatype (IPin * pin, gint id,
IAMStreamConfig * streamcaps);
/* free the memory of all mediatypes of the input list if pin mediatype */ /* free the memory of all mediatypes of the input list if pin mediatype */
void gst_dshow_free_pins_mediatypes (GList *mediatypes); void gst_dshow_free_pins_mediatypes (GList * mediatypes);
/* allow to know what kind of media type we have */ /* allow to know what kind of media type we have */
gboolean gst_dshow_check_mediatype (AM_MEDIA_TYPE *media_type, const GUID sub_type, const GUID format_type); gboolean gst_dshow_check_mediatype (AM_MEDIA_TYPE * media_type,
const GUID sub_type, const GUID format_type);
/* get a pin from directshow filter */ /* get a pin from directshow filter */
gboolean gst_dshow_get_pin_from_filter (IBaseFilter *filter, PIN_DIRECTION pindir, IPin **pin); gboolean gst_dshow_get_pin_from_filter (IBaseFilter * filter,
PIN_DIRECTION pindir, IPin ** pin);
/* find and return a filter according to the input and output types */ /* find and return a filter according to the input and output types */
gboolean gst_dshow_find_filter(CLSID input_majortype, CLSID input_subtype, gboolean gst_dshow_find_filter (CLSID input_majortype, CLSID input_subtype,
CLSID output_majortype, CLSID output_subtype, CLSID output_majortype, CLSID output_subtype,
gchar * prefered_filter_name, IBaseFilter **filter); gchar * prefered_filter_name, IBaseFilter ** filter);
/* get the dshow device path from device friendly name. /* get the dshow device path from device friendly name.
If friendly name is not set, it will return the first available device */ If friendly name is not set, it will return the first available device */
gchar *gst_dshow_getdevice_from_devicename (const GUID *device_category, gchar **device_name); gchar *gst_dshow_getdevice_from_devicename (const GUID * device_category,
gchar ** device_name);
/* show the capture filter property page (generally used to setup the device). the page is modal*/ /* show the capture filter property page (generally used to setup the device). the page is modal*/
gboolean gst_dshow_show_propertypage (IBaseFilter *base_filter); gboolean gst_dshow_show_propertypage (IBaseFilter * base_filter);
/* transform a dshow video caps to a gstreamer video caps */ /* transform a dshow video caps to a gstreamer video caps */
GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* name, GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format,
GstCapturePinMediaType *pin_mediatype); const gchar * name, GstCapturePinMediaType * pin_mediatype);
#endif /* _GSTDSHOW_ */ #endif /* _GSTDSHOW_ */

View file

@ -167,13 +167,13 @@ gst_dshowaudiosrc_class_init (GstDshowAudioSrcClass * klass)
(gobject_class, PROP_DEVICE, (gobject_class, PROP_DEVICE,
g_param_spec_string ("device", "Device", g_param_spec_string ("device", "Device",
"Directshow device reference (classID/name)", NULL, "Directshow device reference (classID/name)", NULL,
static_cast<GParamFlags>(G_PARAM_READWRITE))); static_cast < GParamFlags > (G_PARAM_READWRITE)));
g_object_class_install_property g_object_class_install_property
(gobject_class, PROP_DEVICE_NAME, (gobject_class, PROP_DEVICE_NAME,
g_param_spec_string ("device-name", "Device name", g_param_spec_string ("device-name", "Device name",
"Human-readable name of the sound device", NULL, "Human-readable name of the sound device", NULL,
static_cast<GParamFlags>(G_PARAM_READWRITE))); static_cast < GParamFlags > (G_PARAM_READWRITE)));
GST_DEBUG_CATEGORY_INIT (dshowaudiosrc_debug, "dshowaudiosrc", 0, GST_DEBUG_CATEGORY_INIT (dshowaudiosrc_debug, "dshowaudiosrc", 0,
"Directshow audio source"); "Directshow audio source");
@ -236,7 +236,7 @@ gst_dshowaudiosrc_dispose (GObject * gobject)
/* clean dshow */ /* clean dshow */
if (src->audio_cap_filter) if (src->audio_cap_filter)
src->audio_cap_filter->Release(); src->audio_cap_filter->Release ();
CoUninitialize (); CoUninitialize ();
@ -271,34 +271,35 @@ gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src)
ULONG fetched; ULONG fetched;
hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID *) &devices_enum); IID_ICreateDevEnum, (LPVOID *) & devices_enum);
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't create an instance of the system device enumerator (error=0x%x)", hres); GST_ERROR
("Can't create an instance of the system device enumerator (error=0x%x)",
hres);
array = NULL; array = NULL;
goto clean; goto clean;
} }
hres = devices_enum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, hres = devices_enum->CreateClassEnumerator (CLSID_AudioInputDeviceCategory,
&moniker_enum, 0); &moniker_enum, 0);
if (hres != S_OK || !moniker_enum) { if (hres != S_OK || !moniker_enum) {
GST_ERROR ("Can't get enumeration of audio devices (error=0x%x)", hres); GST_ERROR ("Can't get enumeration of audio devices (error=0x%x)", hres);
array = NULL; array = NULL;
goto clean; goto clean;
} }
moniker_enum->Reset(); moniker_enum->Reset ();
while (hres = moniker_enum->Next(1, &moniker, &fetched), while (hres = moniker_enum->Next (1, &moniker, &fetched), hres == S_OK) {
hres == S_OK) {
IPropertyBag *property_bag = NULL; IPropertyBag *property_bag = NULL;
hres = moniker->BindToStorage(NULL, NULL, IID_IPropertyBag, hres = moniker->BindToStorage (NULL, NULL, IID_IPropertyBag,
(LPVOID *) &property_bag); (LPVOID *) & property_bag);
if (SUCCEEDED (hres) && property_bag) { if (SUCCEEDED (hres) && property_bag) {
VARIANT varFriendlyName; VARIANT varFriendlyName;
VariantInit (&varFriendlyName); VariantInit (&varFriendlyName);
hres = property_bag->Read(L"FriendlyName", &varFriendlyName, NULL); hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL);
if (hres == S_OK && varFriendlyName.bstrVal) { if (hres == S_OK && varFriendlyName.bstrVal) {
gchar *friendly_name = gchar *friendly_name =
g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal, g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
@ -312,17 +313,17 @@ gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src)
g_free (friendly_name); g_free (friendly_name);
SysFreeString (varFriendlyName.bstrVal); SysFreeString (varFriendlyName.bstrVal);
} }
property_bag->Release(); property_bag->Release ();
} }
moniker->Release(); moniker->Release ();
} }
clean: clean:
if (moniker_enum) if (moniker_enum)
moniker_enum->Release(); moniker_enum->Release ();
if (devices_enum) if (devices_enum)
devices_enum->Release(); devices_enum->Release ();
return array; return array;
} }
@ -416,13 +417,14 @@ gst_dshowaudiosrc_get_caps (GstBaseSrc * basesrc)
if (!src->audio_cap_filter) { if (!src->audio_cap_filter) {
hres = CreateBindCtx (0, &lpbc); hres = CreateBindCtx (0, &lpbc);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
hres = MkParseDisplayName (lpbc, (LPCOLESTR) unidevice, &dwEaten, &audiom); hres =
MkParseDisplayName (lpbc, (LPCOLESTR) unidevice, &dwEaten, &audiom);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
hres = audiom->BindToObject(lpbc, NULL, IID_IBaseFilter, hres = audiom->BindToObject (lpbc, NULL, IID_IBaseFilter,
(LPVOID *) &src->audio_cap_filter); (LPVOID *) & src->audio_cap_filter);
audiom->Release(); audiom->Release ();
} }
lpbc->Release(); lpbc->Release ();
} }
} }
@ -432,39 +434,41 @@ gst_dshowaudiosrc_get_caps (GstBaseSrc * basesrc)
IEnumPins *enumpins = NULL; IEnumPins *enumpins = NULL;
HRESULT hres; HRESULT hres;
hres = src->audio_cap_filter->EnumPins(&enumpins); hres = src->audio_cap_filter->EnumPins (&enumpins);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
while (enumpins->Next(1, &capture_pin, NULL) == S_OK) { while (enumpins->Next (1, &capture_pin, NULL) == S_OK) {
IKsPropertySet *pKs = NULL; IKsPropertySet *pKs = NULL;
hres = capture_pin->QueryInterface(IID_IKsPropertySet, (LPVOID *) &pKs); hres =
capture_pin->QueryInterface (IID_IKsPropertySet, (LPVOID *) & pKs);
if (SUCCEEDED (hres) && pKs) { if (SUCCEEDED (hres) && pKs) {
DWORD cbReturned; DWORD cbReturned;
GUID pin_category; GUID pin_category;
RPC_STATUS rpcstatus; RPC_STATUS rpcstatus;
hres = hres =
pKs->Get(AMPROPSETID_Pin, pKs->Get (AMPROPSETID_Pin,
AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID), AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID),
&cbReturned); &cbReturned);
/* we only want capture pins */ /* we only want capture pins */
if (UuidCompare (&pin_category, (UUID *) &PIN_CATEGORY_CAPTURE, if (UuidCompare (&pin_category, (UUID *) & PIN_CATEGORY_CAPTURE,
&rpcstatus) == 0) { &rpcstatus) == 0) {
IAMStreamConfig *streamcaps = NULL; IAMStreamConfig *streamcaps = NULL;
if (SUCCEEDED (capture_pin->QueryInterface(IID_IAMStreamConfig, (LPVOID *) &streamcaps))) { if (SUCCEEDED (capture_pin->QueryInterface (IID_IAMStreamConfig,
(LPVOID *) & streamcaps))) {
src->caps = src->caps =
gst_dshowaudiosrc_getcaps_from_streamcaps (src, capture_pin, gst_dshowaudiosrc_getcaps_from_streamcaps (src, capture_pin,
streamcaps); streamcaps);
streamcaps->Release(); streamcaps->Release ();
} }
} }
pKs->Release(); pKs->Release ();
} }
capture_pin->Release(); capture_pin->Release ();
} }
enumpins->Release(); enumpins->Release ();
} }
} }
@ -492,7 +496,7 @@ gst_dshowaudiosrc_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
if (src->media_filter) if (src->media_filter)
hres = src->media_filter->Run(0); hres = src->media_filter->Run (0);
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't RUN the directshow capture graph (error=0x%x)", hres); GST_ERROR ("Can't RUN the directshow capture graph (error=0x%x)", hres);
src->is_running = FALSE; src->is_running = FALSE;
@ -503,9 +507,10 @@ gst_dshowaudiosrc_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
if (src->media_filter) if (src->media_filter)
hres = src->media_filter->Stop(); hres = src->media_filter->Stop ();
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't STOP the directshow capture graph (error=0x%x)", hres); GST_ERROR ("Can't STOP the directshow capture graph (error=0x%x)",
hres);
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;
} }
src->is_running = FALSE; src->is_running = FALSE;
@ -531,26 +536,34 @@ gst_dshowaudiosrc_open (GstAudioSrc * asrc)
hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IFilterGraph, (LPVOID *) & src->filter_graph); IID_IFilterGraph, (LPVOID *) & src->filter_graph);
if (hres != S_OK || !src->filter_graph) { if (hres != S_OK || !src->filter_graph) {
GST_ERROR ("Can't create an instance of the directshow graph manager (error=0x%x)", hres); GST_ERROR
("Can't create an instance of the directshow graph manager (error=0x%x)",
hres);
goto error; goto error;
} }
hres = src->filter_graph->QueryInterface(IID_IMediaFilter, (LPVOID *) &src->media_filter); hres =
src->filter_graph->QueryInterface (IID_IMediaFilter,
(LPVOID *) & src->media_filter);
if (hres != S_OK || !src->media_filter) { if (hres != S_OK || !src->media_filter) {
GST_ERROR ("Can't get IMediacontrol interface from the graph manager (error=0x%x)", hres); GST_ERROR
("Can't get IMediacontrol interface from the graph manager (error=0x%x)",
hres);
goto error; goto error;
} }
src->dshow_fakesink = new CDshowFakeSink; src->dshow_fakesink = new CDshowFakeSink;
src->dshow_fakesink->AddRef(); src->dshow_fakesink->AddRef ();
hres = src->filter_graph->AddFilter(src->audio_cap_filter, L"capture"); hres = src->filter_graph->AddFilter (src->audio_cap_filter, L"capture");
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't add the directshow capture filter to the graph (error=0x%x)", hres); GST_ERROR
("Can't add the directshow capture filter to the graph (error=0x%x)",
hres);
goto error; goto error;
} }
hres = src->filter_graph->AddFilter(src->dshow_fakesink, L"fakesink"); hres = src->filter_graph->AddFilter (src->dshow_fakesink, L"fakesink");
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't add our fakesink filter to the graph (error=0x%x)", hres); GST_ERROR ("Can't add our fakesink filter to the graph (error=0x%x)", hres);
goto error; goto error;
@ -560,16 +573,16 @@ gst_dshowaudiosrc_open (GstAudioSrc * asrc)
error: error:
if (src->dshow_fakesink) { if (src->dshow_fakesink) {
src->dshow_fakesink->Release(); src->dshow_fakesink->Release ();
src->dshow_fakesink = NULL; src->dshow_fakesink = NULL;
} }
if (src->media_filter) { if (src->media_filter) {
src->media_filter->Release(); src->media_filter->Release ();
src->media_filter = NULL; src->media_filter = NULL;
} }
if (src->filter_graph) { if (src->filter_graph) {
src->filter_graph->Release(); src->filter_graph->Release ();
src->filter_graph = NULL; src->filter_graph = NULL;
} }
@ -606,8 +619,8 @@ gst_dshowaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
pin_mediatype = (GstCapturePinMediaType *) type->data; pin_mediatype = (GstCapturePinMediaType *) type->data;
src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype); src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype);
src->dshow_fakesink->gst_set_buffer_callback( src->dshow_fakesink->gst_set_buffer_callback (
(push_buffer_func) gst_dshowaudiosrc_push_buffer, src); (push_buffer_func) gst_dshowaudiosrc_push_buffer, src);
gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT,
&input_pin); &input_pin);
@ -616,12 +629,14 @@ gst_dshowaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
goto error; goto error;
} }
hres = src->filter_graph->ConnectDirect(pin_mediatype->capture_pin, hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin,
input_pin, NULL); input_pin, NULL);
input_pin->Release(); input_pin->Release ();
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't connect capture filter with fakesink filter (error=0x%x)", hres); GST_ERROR
("Can't connect capture filter with fakesink filter (error=0x%x)",
hres);
goto error; goto error;
} }
@ -648,14 +663,14 @@ gst_dshowaudiosrc_unprepare (GstAudioSrc * asrc)
gst_dshow_get_pin_from_filter (src->audio_cap_filter, PINDIR_OUTPUT, gst_dshow_get_pin_from_filter (src->audio_cap_filter, PINDIR_OUTPUT,
&output_pin); &output_pin);
if (output_pin) { if (output_pin) {
hres = src->filter_graph->Disconnect(output_pin); hres = src->filter_graph->Disconnect (output_pin);
output_pin->Release(); output_pin->Release ();
} }
gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin); gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin);
if (input_pin) { if (input_pin) {
hres = src->filter_graph->Disconnect(input_pin); hres = src->filter_graph->Disconnect (input_pin);
input_pin->Release(); input_pin->Release ();
} }
return TRUE; return TRUE;
@ -670,19 +685,19 @@ gst_dshowaudiosrc_close (GstAudioSrc * asrc)
return TRUE; return TRUE;
/*remove filters from the graph */ /*remove filters from the graph */
src->filter_graph->RemoveFilter(src->audio_cap_filter); src->filter_graph->RemoveFilter (src->audio_cap_filter);
src->filter_graph->RemoveFilter(src->dshow_fakesink); src->filter_graph->RemoveFilter (src->dshow_fakesink);
/*release our gstreamer dshow sink */ /*release our gstreamer dshow sink */
src->dshow_fakesink->Release(); src->dshow_fakesink->Release ();
src->dshow_fakesink = NULL; src->dshow_fakesink = NULL;
/*release media filter interface */ /*release media filter interface */
src->media_filter->Release(); src->media_filter->Release ();
src->media_filter = NULL; src->media_filter = NULL;
/*release the filter graph manager */ /*release the filter graph manager */
src->filter_graph->Release(); src->filter_graph->Release ();
src->filter_graph = NULL; src->filter_graph = NULL;
return TRUE; return TRUE;
@ -760,7 +775,7 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin,
if (!streamcaps) if (!streamcaps)
return NULL; return NULL;
streamcaps->GetNumberOfCapabilities(&icount, &isize); streamcaps->GetNumberOfCapabilities (&icount, &isize);
if (isize != sizeof (ascc)) if (isize != sizeof (ascc))
return NULL; return NULL;
@ -768,10 +783,10 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin,
for (; i < icount; i++) { for (; i < icount; i++) {
GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1); GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1);
pin->AddRef(); pin->AddRef ();
pin_mediatype->capture_pin = pin; pin_mediatype->capture_pin = pin;
hres = streamcaps->GetStreamCaps(i, &pin_mediatype->mediatype, hres = streamcaps->GetStreamCaps (i, &pin_mediatype->mediatype,
(BYTE *) & ascc); (BYTE *) & ascc);
if (hres == S_OK && pin_mediatype->mediatype) { if (hres == S_OK && pin_mediatype->mediatype) {
GstCaps *mediacaps = NULL; GstCaps *mediacaps = NULL;
@ -779,7 +794,8 @@ gst_dshowaudiosrc_getcaps_from_streamcaps (GstDshowAudioSrc * src, IPin * pin,
if (!caps) if (!caps)
caps = gst_caps_new_empty (); caps = gst_caps_new_empty ();
if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx)) { if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_PCM,
FORMAT_WaveFormatEx)) {
WAVEFORMATEX *wavformat = WAVEFORMATEX *wavformat =
(WAVEFORMATEX *) pin_mediatype->mediatype->pbFormat; (WAVEFORMATEX *) pin_mediatype->mediatype->pbFormat;
mediacaps = mediacaps =

View file

@ -65,7 +65,7 @@ struct _GstDshowAudioSrc
IMediaFilter *media_filter; IMediaFilter *media_filter;
IFilterGraph *filter_graph; IFilterGraph *filter_graph;
/* bytes array*/ /* bytes array */
GByteArray *gbarray; GByteArray *gbarray;
GMutex *gbarray_lock; GMutex *gbarray_lock;

View file

@ -21,28 +21,30 @@
#include "gstdshowfakesink.h" #include "gstdshowfakesink.h"
CDshowFakeSink::CDshowFakeSink() : CDshowFakeSink::CDshowFakeSink ():
m_hres(S_OK), m_hres (S_OK),
m_callback(NULL), m_callback (NULL),
m_data(NULL), m_data (NULL),
CBaseRenderer(CLSID_DshowFakeSink, "DshowFakeSink", NULL, &m_hres) CBaseRenderer (CLSID_DshowFakeSink, "DshowFakeSink", NULL, &m_hres)
{ {
} }
STDMETHODIMP CDshowFakeSink::gst_set_media_type (AM_MEDIA_TYPE *pmt) STDMETHODIMP CDshowFakeSink::gst_set_media_type (AM_MEDIA_TYPE * pmt)
{ {
m_MediaType.Set (*pmt); m_MediaType.Set (*pmt);
return S_OK; return S_OK;
} }
STDMETHODIMP CDshowFakeSink::gst_set_buffer_callback (push_buffer_func push, gpointer data) STDMETHODIMP
CDshowFakeSink::gst_set_buffer_callback (push_buffer_func push,
gpointer data)
{ {
m_callback = push; m_callback = push;
m_data = data; m_data = data;
return S_OK; return S_OK;
} }
HRESULT CDshowFakeSink::CheckMediaType(const CMediaType *pmt) HRESULT CDshowFakeSink::CheckMediaType (const CMediaType * pmt)
{ {
if (pmt != NULL) { if (pmt != NULL) {
if (*pmt == m_MediaType) if (*pmt == m_MediaType)
@ -52,19 +54,21 @@ HRESULT CDshowFakeSink::CheckMediaType(const CMediaType *pmt)
return S_FALSE; return S_FALSE;
} }
HRESULT CDshowFakeSink::DoRenderSample(IMediaSample *pMediaSample) HRESULT CDshowFakeSink::DoRenderSample (IMediaSample * pMediaSample)
{ {
if(pMediaSample && m_callback) if (pMediaSample && m_callback) {
{ BYTE *
BYTE *pBuffer = NULL; pBuffer = NULL;
LONGLONG lStart = 0, lStop = 0; LONGLONG
pMediaSample->GetPointer(&pBuffer); lStart = 0, lStop = 0;
long size = pMediaSample->GetActualDataLength(); pMediaSample->GetPointer (&pBuffer);
pMediaSample->GetTime(&lStart, &lStop); long
lStart*=100; size = pMediaSample->GetActualDataLength ();
lStop*=100; pMediaSample->GetTime (&lStart, &lStop);
m_callback(pBuffer, size, m_data, lStart, lStop); lStart *= 100;
lStop *= 100;
m_callback (pBuffer, size, m_data, lStart, lStop);
} }
return S_OK; return S_OK;
} }

View file

@ -26,20 +26,25 @@
//{6A780808-9725-4d0b-8695-A4DD8D210773} //{6A780808-9725-4d0b-8695-A4DD8D210773}
static const GUID CLSID_DshowFakeSink = static const GUID CLSID_DshowFakeSink =
{ 0x6a780808, 0x9725, 0x4d0b, { 0x86, 0x95, 0xa4, 0xdd, 0x8d, 0x21, 0x7, 0x73 } }; { 0x6a780808, 0x9725, 0x4d0b, {0x86, 0x95, 0xa4, 0xdd, 0x8d, 0x21, 0x7,
0x73}
};
typedef bool (*push_buffer_func) (byte *buffer, long size, gpointer src_object, UINT64 start, UINT64 stop); typedef bool (*push_buffer_func) (byte * buffer, long size, gpointer src_object,
UINT64 start, UINT64 stop);
class CDshowFakeSink : public CBaseRenderer class CDshowFakeSink:public CBaseRenderer
{ {
public: public:
CDshowFakeSink (); CDshowFakeSink ();
virtual ~CDshowFakeSink () {} virtual ~ CDshowFakeSink ()
{
}
virtual HRESULT CheckMediaType (const CMediaType *pmt); virtual HRESULT CheckMediaType (const CMediaType * pmt);
virtual HRESULT DoRenderSample (IMediaSample *pMediaSample); virtual HRESULT DoRenderSample (IMediaSample * pMediaSample);
STDMETHOD (gst_set_media_type) (AM_MEDIA_TYPE *pmt); STDMETHOD (gst_set_media_type) (AM_MEDIA_TYPE * pmt);
STDMETHOD (gst_set_buffer_callback) (push_buffer_func push, gpointer data); STDMETHOD (gst_set_buffer_callback) (push_buffer_func push, gpointer data);
protected: protected:

View file

@ -45,17 +45,14 @@ const GUID MEDIASUBTYPE_I420
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC, GST_PAD_SRC,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS ( GST_STATIC_CAPS (GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_YUV ("{ I420 }") ";" GST_VIDEO_CAPS_YUV ("{ I420 }") ";"
"video/x-dv," "video/x-dv,"
"systemstream = (boolean) FALSE," "systemstream = (boolean) FALSE,"
"width = (int) [ 1, MAX ]," "width = (int) [ 1, MAX ],"
"height = (int) [ 1, MAX ]," "height = (int) [ 1, MAX ],"
"framerate = (fraction) [ 0, MAX ]," "framerate = (fraction) [ 0, MAX ],"
"format = (fourcc) dvsd;" "format = (fourcc) dvsd;" "video/x-dv," "systemstream = (boolean) TRUE")
"video/x-dv,"
"systemstream = (boolean) TRUE")
); );
static void gst_dshowvideosrc_init_interfaces (GType type); static void gst_dshowvideosrc_init_interfaces (GType type);
@ -180,13 +177,13 @@ gst_dshowvideosrc_class_init (GstDshowVideoSrcClass * klass)
(gobject_class, PROP_DEVICE, (gobject_class, PROP_DEVICE,
g_param_spec_string ("device", "Device", g_param_spec_string ("device", "Device",
"Directshow device path (@..classID/name)", NULL, "Directshow device path (@..classID/name)", NULL,
static_cast<GParamFlags>(G_PARAM_READWRITE))); static_cast < GParamFlags > (G_PARAM_READWRITE)));
g_object_class_install_property g_object_class_install_property
(gobject_class, PROP_DEVICE_NAME, (gobject_class, PROP_DEVICE_NAME,
g_param_spec_string ("device-name", "Device name", g_param_spec_string ("device-name", "Device name",
"Human-readable name of the sound device", NULL, "Human-readable name of the sound device", NULL,
static_cast<GParamFlags>(G_PARAM_READWRITE))); static_cast < GParamFlags > (G_PARAM_READWRITE)));
GST_DEBUG_CATEGORY_INIT (dshowvideosrc_debug, "dshowvideosrc", 0, GST_DEBUG_CATEGORY_INIT (dshowvideosrc_debug, "dshowvideosrc", 0,
"Directshow video source"); "Directshow video source");
@ -238,10 +235,14 @@ gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
if (res != -1) { if (res != -1) {
GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res); GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res);
if (type_pin_mediatype) { if (type_pin_mediatype) {
GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) type_pin_mediatype->data; GstCapturePinMediaType *pin_mediatype =
gst_structure_fixate_field_nearest_int (structure, "width", pin_mediatype->defaultWidth); (GstCapturePinMediaType *) type_pin_mediatype->data;
gst_structure_fixate_field_nearest_int (structure, "height", pin_mediatype->defaultHeight); gst_structure_fixate_field_nearest_int (structure, "width",
gst_structure_fixate_field_nearest_fraction (structure, "framerate", pin_mediatype->defaultFPS, 1); pin_mediatype->defaultWidth);
gst_structure_fixate_field_nearest_int (structure, "height",
pin_mediatype->defaultHeight);
gst_structure_fixate_field_nearest_fraction (structure, "framerate",
pin_mediatype->defaultFPS, 1);
} }
} }
} }
@ -273,7 +274,7 @@ gst_dshowvideosrc_dispose (GObject * gobject)
/* clean dshow */ /* clean dshow */
if (src->video_cap_filter) { if (src->video_cap_filter) {
src->video_cap_filter->Release(); src->video_cap_filter->Release ();
src->video_cap_filter = NULL; src->video_cap_filter = NULL;
} }
@ -354,35 +355,34 @@ gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src)
ULONG fetched; ULONG fetched;
hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, hres = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID *) &devices_enum); IID_ICreateDevEnum, (LPVOID *) & devices_enum);
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't create system device enumerator (error=0x%x)", hres); GST_ERROR ("Can't create system device enumerator (error=0x%x)", hres);
array = NULL; array = NULL;
goto clean; goto clean;
} }
hres = devices_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, hres = devices_enum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory,
&moniker_enum, 0); &moniker_enum, 0);
if (hres != S_OK || !moniker_enum) { if (hres != S_OK || !moniker_enum) {
GST_ERROR ("Can't get enumeration of video devices (error=0x%x)", hres); GST_ERROR ("Can't get enumeration of video devices (error=0x%x)", hres);
array = NULL; array = NULL;
goto clean; goto clean;
} }
moniker_enum->Reset(); moniker_enum->Reset ();
while (hres = moniker_enum->Next(1, &moniker, &fetched), while (hres = moniker_enum->Next (1, &moniker, &fetched), hres == S_OK) {
hres == S_OK) {
IPropertyBag *property_bag = NULL; IPropertyBag *property_bag = NULL;
hres = hres =
moniker->BindToStorage(NULL, NULL, IID_IPropertyBag, moniker->BindToStorage (NULL, NULL, IID_IPropertyBag,
(LPVOID *) &property_bag); (LPVOID *) & property_bag);
if (SUCCEEDED (hres) && property_bag) { if (SUCCEEDED (hres) && property_bag) {
VARIANT varFriendlyName; VARIANT varFriendlyName;
VariantInit (&varFriendlyName); VariantInit (&varFriendlyName);
hres = property_bag->Read(L"FriendlyName", &varFriendlyName, NULL); hres = property_bag->Read (L"FriendlyName", &varFriendlyName, NULL);
if (hres == S_OK && varFriendlyName.bstrVal) { if (hres == S_OK && varFriendlyName.bstrVal) {
gchar *friendly_name = gchar *friendly_name =
g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal, g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
@ -396,17 +396,17 @@ gst_dshowvideosrc_get_device_name_values (GstDshowVideoSrc * src)
g_free (friendly_name); g_free (friendly_name);
SysFreeString (varFriendlyName.bstrVal); SysFreeString (varFriendlyName.bstrVal);
} }
property_bag->Release(); property_bag->Release ();
} }
moniker->Release(); moniker->Release ();
} }
clean: clean:
if (moniker_enum) if (moniker_enum)
moniker_enum->Release(); moniker_enum->Release ();
if (devices_enum) if (devices_enum)
devices_enum->Release(); devices_enum->Release ();
return array; return array;
} }
@ -500,13 +500,14 @@ gst_dshowvideosrc_get_caps (GstBaseSrc * basesrc)
if (!src->video_cap_filter) { if (!src->video_cap_filter) {
hres = CreateBindCtx (0, &lpbc); hres = CreateBindCtx (0, &lpbc);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
hres = MkParseDisplayName (lpbc, (LPCOLESTR) unidevice, &dwEaten, &videom); hres =
MkParseDisplayName (lpbc, (LPCOLESTR) unidevice, &dwEaten, &videom);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
hres = videom->BindToObject(lpbc, NULL, IID_IBaseFilter, hres = videom->BindToObject (lpbc, NULL, IID_IBaseFilter,
(LPVOID *) &src->video_cap_filter); (LPVOID *) & src->video_cap_filter);
videom->Release(); videom->Release ();
} }
lpbc->Release(); lpbc->Release ();
} }
} }
@ -520,28 +521,29 @@ gst_dshowvideosrc_get_caps (GstBaseSrc * basesrc)
IEnumPins *enumpins = NULL; IEnumPins *enumpins = NULL;
HRESULT hres; HRESULT hres;
hres = src->video_cap_filter->EnumPins(&enumpins); hres = src->video_cap_filter->EnumPins (&enumpins);
if (SUCCEEDED (hres)) { if (SUCCEEDED (hres)) {
while (enumpins->Next(1, &capture_pin, NULL) == S_OK) { while (enumpins->Next (1, &capture_pin, NULL) == S_OK) {
IKsPropertySet *pKs = NULL; IKsPropertySet *pKs = NULL;
hres = capture_pin->QueryInterface(IID_IKsPropertySet, (LPVOID *) &pKs); hres =
capture_pin->QueryInterface (IID_IKsPropertySet, (LPVOID *) & pKs);
if (SUCCEEDED (hres) && pKs) { if (SUCCEEDED (hres) && pKs) {
DWORD cbReturned; DWORD cbReturned;
GUID pin_category; GUID pin_category;
RPC_STATUS rpcstatus; RPC_STATUS rpcstatus;
hres = hres =
pKs->Get(AMPROPSETID_Pin, pKs->Get (AMPROPSETID_Pin,
AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID), AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID),
&cbReturned); &cbReturned);
/* we only want capture pins */ /* we only want capture pins */
if (UuidCompare (&pin_category, (UUID *) &PIN_CATEGORY_CAPTURE, if (UuidCompare (&pin_category, (UUID *) & PIN_CATEGORY_CAPTURE,
&rpcstatus) == 0) { &rpcstatus) == 0) {
IAMStreamConfig *streamcaps = NULL; IAMStreamConfig *streamcaps = NULL;
if (SUCCEEDED (capture_pin->QueryInterface( if (SUCCEEDED (capture_pin->QueryInterface (IID_IAMStreamConfig,
IID_IAMStreamConfig, (LPVOID *) &streamcaps))) { (LPVOID *) & streamcaps))) {
GstCaps *caps = GstCaps *caps =
gst_dshowvideosrc_getcaps_from_streamcaps (src, capture_pin, gst_dshowvideosrc_getcaps_from_streamcaps (src, capture_pin,
streamcaps); streamcaps);
@ -549,16 +551,16 @@ gst_dshowvideosrc_get_caps (GstBaseSrc * basesrc)
if (caps) { if (caps) {
gst_caps_append (src->caps, caps); gst_caps_append (src->caps, caps);
} }
streamcaps->Release(); streamcaps->Release ();
} }
} }
pKs->Release(); pKs->Release ();
} }
capture_pin->Release(); capture_pin->Release ();
} }
enumpins->Release(); enumpins->Release ();
} }
} }
@ -586,7 +588,7 @@ gst_dshowvideosrc_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
if (src->media_filter) if (src->media_filter)
hres = src->media_filter->Run(0); hres = src->media_filter->Run (0);
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't RUN the directshow capture graph (error=0x%x)", hres); GST_ERROR ("Can't RUN the directshow capture graph (error=0x%x)", hres);
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;
@ -594,7 +596,7 @@ gst_dshowvideosrc_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
if (src->media_filter) if (src->media_filter)
hres = src->media_filter->Stop(); hres = src->media_filter->Stop ();
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't STOP the directshow capture graph (error=%d)", hres); GST_ERROR ("Can't STOP the directshow capture graph (error=%d)", hres);
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;
@ -618,27 +620,32 @@ gst_dshowvideosrc_start (GstBaseSrc * bsrc)
hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IFilterGraph, (LPVOID *) & src->filter_graph); IID_IFilterGraph, (LPVOID *) & src->filter_graph);
if (hres != S_OK || !src->filter_graph) { if (hres != S_OK || !src->filter_graph) {
GST_ERROR ("Can't create an instance of the dshow graph manager (error=0x%x)", hres); GST_ERROR
("Can't create an instance of the dshow graph manager (error=0x%x)",
hres);
goto error; goto error;
} }
hres = src->filter_graph->QueryInterface(IID_IMediaFilter, hres = src->filter_graph->QueryInterface (IID_IMediaFilter,
(LPVOID *) &src->media_filter); (LPVOID *) & src->media_filter);
if (hres != S_OK || !src->media_filter) { if (hres != S_OK || !src->media_filter) {
GST_ERROR ("Can't get IMediacontrol interface from the graph manager (error=0x%x)", hres); GST_ERROR
("Can't get IMediacontrol interface from the graph manager (error=0x%x)",
hres);
goto error; goto error;
} }
src->dshow_fakesink = new CDshowFakeSink; src->dshow_fakesink = new CDshowFakeSink;
src->dshow_fakesink->AddRef(); src->dshow_fakesink->AddRef ();
hres = src->filter_graph->AddFilter(src->video_cap_filter, L"capture"); hres = src->filter_graph->AddFilter (src->video_cap_filter, L"capture");
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't add video capture filter to the graph (error=0x%x)", hres); GST_ERROR ("Can't add video capture filter to the graph (error=0x%x)",
hres);
goto error; goto error;
} }
hres = src->filter_graph->AddFilter(src->dshow_fakesink, L"sink"); hres = src->filter_graph->AddFilter (src->dshow_fakesink, L"sink");
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't add our fakesink filter to the graph (error=0x%x)", hres); GST_ERROR ("Can't add our fakesink filter to the graph (error=0x%x)", hres);
goto error; goto error;
@ -648,16 +655,16 @@ gst_dshowvideosrc_start (GstBaseSrc * bsrc)
error: error:
if (src->dshow_fakesink) { if (src->dshow_fakesink) {
src->dshow_fakesink->Release(); src->dshow_fakesink->Release ();
src->dshow_fakesink = NULL; src->dshow_fakesink = NULL;
} }
if (src->media_filter) { if (src->media_filter) {
src->media_filter->Release(); src->media_filter->Release ();
src->media_filter = NULL; src->media_filter = NULL;
} }
if (src->filter_graph) { if (src->filter_graph) {
src->filter_graph->Release(); src->filter_graph->Release ();
src->filter_graph = NULL; src->filter_graph = NULL;
} }
@ -691,7 +698,8 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res); GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res);
if (type_pin_mediatype) { if (type_pin_mediatype) {
GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) type_pin_mediatype->data; GstCapturePinMediaType *pin_mediatype =
(GstCapturePinMediaType *) type_pin_mediatype->data;
gchar *caps_string = NULL; gchar *caps_string = NULL;
gchar *src_caps_string = NULL; gchar *src_caps_string = NULL;
@ -706,24 +714,29 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
gst_structure_get_fraction (s, "framerate", &numerator, &denominator); gst_structure_get_fraction (s, "framerate", &numerator, &denominator);
/* check if the desired video size is valid about granularity */ /* check if the desired video size is valid about granularity */
/* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */ /* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */
/* See remarks in gst_dshowvideosrc_getcaps_from_streamcaps function */ /* See remarks in gst_dshowvideosrc_getcaps_from_streamcaps function */
if (pin_mediatype->granularityWidth != 0 && width % pin_mediatype->granularityWidth != 0) if (pin_mediatype->granularityWidth != 0
g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, pin_mediatype->granularityWidth) ; && width % pin_mediatype->granularityWidth != 0)
if (pin_mediatype->granularityHeight !=0 && height % pin_mediatype->granularityHeight != 0) g_warning ("your desired video size is not valid : %d mod %d !=0\n",
g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, pin_mediatype->granularityHeight) ; width, pin_mediatype->granularityWidth);
if (pin_mediatype->granularityHeight != 0
&& height % pin_mediatype->granularityHeight != 0)
g_warning ("your desired video size is not valid : %d mod %d !=0\n",
height, pin_mediatype->granularityHeight);
/* update mediatype */ /* update mediatype */
video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
video_info->bmiHeader.biWidth = width; video_info->bmiHeader.biWidth = width;
video_info->bmiHeader.biHeight = height; video_info->bmiHeader.biHeight = height;
video_info->AvgTimePerFrame = (LONGLONG) (10000000 * denominator / (double)numerator); video_info->AvgTimePerFrame =
video_info->bmiHeader.biSizeImage = DIBSIZE(video_info->bmiHeader); (LONGLONG) (10000000 * denominator / (double) numerator);
pin_mediatype->mediatype->lSampleSize = DIBSIZE(video_info->bmiHeader); video_info->bmiHeader.biSizeImage = DIBSIZE (video_info->bmiHeader);
pin_mediatype->mediatype->lSampleSize = DIBSIZE (video_info->bmiHeader);
src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype); src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype);
src->dshow_fakesink->gst_set_buffer_callback( src->dshow_fakesink->gst_set_buffer_callback (
(push_buffer_func) gst_dshowvideosrc_push_buffer, src); (push_buffer_func) gst_dshowvideosrc_push_buffer, src);
gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT,
&input_pin); &input_pin);
@ -732,12 +745,14 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
goto error; goto error;
} }
hres = src->filter_graph->ConnectDirect(pin_mediatype->capture_pin, hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin,
input_pin, pin_mediatype->mediatype); input_pin, pin_mediatype->mediatype);
input_pin->Release(); input_pin->Release ();
if (hres != S_OK) { if (hres != S_OK) {
GST_ERROR ("Can't connect capture filter with fakesink filter (error=0x%x)", hres); GST_ERROR
("Can't connect capture filter with fakesink filter (error=0x%x)",
hres);
goto error; goto error;
} }
@ -779,30 +794,30 @@ gst_dshowvideosrc_stop (GstBaseSrc * bsrc)
gst_dshow_get_pin_from_filter (src->video_cap_filter, PINDIR_OUTPUT, gst_dshow_get_pin_from_filter (src->video_cap_filter, PINDIR_OUTPUT,
&output_pin); &output_pin);
if (output_pin) { if (output_pin) {
hres = src->filter_graph->Disconnect(output_pin); hres = src->filter_graph->Disconnect (output_pin);
output_pin->Release(); output_pin->Release ();
} }
gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin); gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin);
if (input_pin) { if (input_pin) {
hres = src->filter_graph->Disconnect(input_pin); hres = src->filter_graph->Disconnect (input_pin);
input_pin->Release(); input_pin->Release ();
} }
/*remove filters from the graph */ /*remove filters from the graph */
src->filter_graph->RemoveFilter(src->video_cap_filter); src->filter_graph->RemoveFilter (src->video_cap_filter);
src->filter_graph->RemoveFilter(src->dshow_fakesink); src->filter_graph->RemoveFilter (src->dshow_fakesink);
/*release our gstreamer dshow sink */ /*release our gstreamer dshow sink */
src->dshow_fakesink->Release(); src->dshow_fakesink->Release ();
src->dshow_fakesink = NULL; src->dshow_fakesink = NULL;
/*release media filter interface */ /*release media filter interface */
src->media_filter->Release(); src->media_filter->Release ();
src->media_filter = NULL; src->media_filter = NULL;
/*release the filter graph manager */ /*release the filter graph manager */
src->filter_graph->Release(); src->filter_graph->Release ();
src->filter_graph = NULL; src->filter_graph = NULL;
return TRUE; return TRUE;
@ -852,8 +867,8 @@ gst_dshowvideosrc_create (GstPushSrc * psrc, GstBuffer ** buf)
} }
GST_DEBUG ("dshowvideosrc_create => pts %" GST_TIME_FORMAT " duration %" GST_DEBUG ("dshowvideosrc_create => pts %" GST_TIME_FORMAT " duration %"
GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*buf)), GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (*buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (*buf)));
return GST_FLOW_OK; return GST_FLOW_OK;
} }
@ -872,7 +887,7 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
if (!streamcaps) if (!streamcaps)
return NULL; return NULL;
streamcaps->GetNumberOfCapabilities(&icount, &isize); streamcaps->GetNumberOfCapabilities (&icount, &isize);
if (isize != sizeof (vscc)) if (isize != sizeof (vscc))
return NULL; return NULL;
@ -882,25 +897,35 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
for (; i < icount; i++) { for (; i < icount; i++) {
GstCapturePinMediaType *pin_mediatype = GstCapturePinMediaType *pin_mediatype =
gst_dshow_new_pin_mediatype (pin, i, streamcaps); gst_dshow_new_pin_mediatype (pin, i, streamcaps);
if (pin_mediatype) { if (pin_mediatype) {
GstCaps *mediacaps = NULL; GstCaps *mediacaps = NULL;
if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_I420, FORMAT_VideoInfo)) { if (gst_dshow_check_mediatype (pin_mediatype->mediatype,
mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_I420, NULL, pin_mediatype); MEDIASUBTYPE_I420, FORMAT_VideoInfo)) {
mediacaps =
gst_dshow_new_video_caps (GST_VIDEO_FORMAT_I420, NULL,
pin_mediatype);
} else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) { } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype,
mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_BGR, NULL, pin_mediatype); MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) {
mediacaps =
gst_dshow_new_video_caps (GST_VIDEO_FORMAT_BGR, NULL,
pin_mediatype);
} else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) { } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype,
mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN, "video/x-dv, systemstream=FALSE", MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) {
pin_mediatype); mediacaps =
gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN,
"video/x-dv, systemstream=FALSE", pin_mediatype);
} else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) { } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype,
mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN, "video/x-dv, systemstream=TRUE", MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) {
pin_mediatype); mediacaps =
gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN,
"video/x-dv, systemstream=TRUE", pin_mediatype);
pin_mediatype->granularityWidth = 0; pin_mediatype->granularityWidth = 0;
pin_mediatype->granularityHeight = 0; pin_mediatype->granularityHeight = 0;
@ -908,7 +933,7 @@ gst_dshowvideosrc_getcaps_from_streamcaps (GstDshowVideoSrc * src, IPin * pin,
if (mediacaps) { if (mediacaps) {
src->pins_mediatypes = src->pins_mediatypes =
g_list_append (src->pins_mediatypes, pin_mediatype); g_list_append (src->pins_mediatypes, pin_mediatype);
gst_caps_append (caps, mediacaps); gst_caps_append (caps, mediacaps);
} else { } else {
/* failed to convert dshow caps */ /* failed to convert dshow caps */
@ -964,8 +989,9 @@ gst_dshowvideosrc_push_buffer (byte * buffer, long size, gpointer src_object,
memcpy (GST_BUFFER_DATA (buf), buffer, size); memcpy (GST_BUFFER_DATA (buf), buffer, size);
} }
GST_DEBUG ("push_buffer => pts %" GST_TIME_FORMAT "duration %" GST_TIME_FORMAT, GST_DEBUG ("push_buffer => pts %" GST_TIME_FORMAT "duration %"
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (stop - start)); GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (stop - start));
/* the negotiate() method already set caps on the source pad */ /* the negotiate() method already set caps on the source pad */
gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src))); gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));

View file

@ -31,7 +31,8 @@
#include "gstdshowfakesink.h" #include "gstdshowfakesink.h"
// 30323449-0000-0010-8000-00AA00389B71 MEDIASUBTYPE_I420 // 30323449-0000-0010-8000-00AA00389B71 MEDIASUBTYPE_I420
DEFINE_GUID(MEDIASUBTYPE_I420, 0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71); DEFINE_GUID (MEDIASUBTYPE_I420, 0x30323449, 0x0000, 0x0010, 0x80, 0x00, 0x00,
0xAA, 0x00, 0x38, 0x9B, 0x71);
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_DSHOWVIDEOSRC (gst_dshowvideosrc_get_type()) #define GST_TYPE_DSHOWVIDEOSRC (gst_dshowvideosrc_get_type())
@ -70,9 +71,9 @@ struct _GstDshowVideoSrc
IFilterGraph *filter_graph; IFilterGraph *filter_graph;
/* the last buffer from DirectShow */ /* the last buffer from DirectShow */
GCond * buffer_cond; GCond *buffer_cond;
GMutex * buffer_mutex; GMutex *buffer_mutex;
GstBuffer * buffer; GstBuffer *buffer;
gboolean stop_requested; gboolean stop_requested;
gboolean is_rgb; gboolean is_rgb;