gchar * ks_property_set_to_string (const GUID * guid) { guint i; for (i = 0; i < sizeof (known_property_sets) / sizeof (known_property_sets[0]); i++) { if (IsEqualGUID (guid, &known_property_sets[i].guid)) return g_strdup_printf ("KSPROPSETID_%s", known_property_sets[i].name); } return ks_guid_to_string (guid); }
GList * ks_video_probe_filter_for_caps (HANDLE filter_handle) { GList *ret = NULL; gulong pin_count; guint pin_id; if (!ks_filter_get_pin_property (filter_handle, 0, KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &pin_count, sizeof (pin_count), NULL)) goto beach; GST_DEBUG ("pin_count = %d", pin_count); for (pin_id = 0; pin_id < pin_count; pin_id++) { KSPIN_COMMUNICATION pin_comm; KSPIN_DATAFLOW pin_flow; GUID pin_cat; if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, &pin_comm, sizeof (pin_comm), NULL)) continue; if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, &pin_flow, sizeof (pin_flow), NULL)) continue; if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin, KSPROPERTY_PIN_CATEGORY, &pin_cat, sizeof (pin_cat), NULL)) continue; GST_DEBUG ("pin[%u]: pin_comm=%d, pin_flow=%d", pin_id, pin_comm, pin_flow); if (pin_flow == KSPIN_DATAFLOW_OUT && memcmp (&pin_cat, &PINNAME_CAPTURE, sizeof (GUID)) == 0) { KSMULTIPLE_ITEM *items; if (ks_filter_get_pin_property_multi (filter_handle, pin_id, KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &items, NULL)) { KSDATARANGE *range = (KSDATARANGE *) (items + 1); guint i; for (i = 0; i < items->Count; i++) { if (IsEqualGUID (&range->MajorFormat, &KSDATAFORMAT_TYPE_VIDEO)) { KsVideoMediaType *entry; gpointer src_vscc, src_format; GstStructure *media_structure; entry = g_new0 (KsVideoMediaType, 1); entry->pin_id = pin_id; entry->range = g_malloc (range->FormatSize); memcpy ((gpointer) entry->range, range, range->FormatSize); if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo)) { KS_DATARANGE_VIDEO *vr = (KS_DATARANGE_VIDEO *) entry->range; src_vscc = &vr->ConfigCaps; src_format = &vr->VideoInfoHeader; entry->format_size = sizeof (vr->VideoInfoHeader); entry->sample_size = vr->VideoInfoHeader.bmiHeader.biSizeImage; } else if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo2)) { KS_DATARANGE_VIDEO2 *vr = (KS_DATARANGE_VIDEO2 *) entry->range; src_vscc = &vr->ConfigCaps; src_format = &vr->VideoInfoHeader; entry->format_size = sizeof (vr->VideoInfoHeader); entry->sample_size = vr->VideoInfoHeader.bmiHeader.biSizeImage; } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEGVideo)) { /* Untested and probably wrong... */ KS_DATARANGE_MPEG1_VIDEO *vr = (KS_DATARANGE_MPEG1_VIDEO *) entry->range; src_vscc = &vr->ConfigCaps; src_format = &vr->VideoInfoHeader; entry->format_size = sizeof (vr->VideoInfoHeader); entry->sample_size = vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage; } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) { /* Untested and probably wrong... */ KS_DATARANGE_MPEG2_VIDEO *vr = (KS_DATARANGE_MPEG2_VIDEO *) entry->range; src_vscc = &vr->ConfigCaps; src_format = &vr->VideoInfoHeader; entry->format_size = sizeof (vr->VideoInfoHeader); entry->sample_size = vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage; } else { gchar *guid_str; guid_str = ks_guid_to_string (&range->Specifier); GST_DEBUG ("pin[%u]: ignoring unknown specifier GUID %s", pin_id, guid_str); g_free (guid_str); ks_video_media_type_free (entry); entry = NULL; } if (entry != NULL) { g_assert (entry->sample_size != 0); memcpy ((gpointer) & entry->vscc, src_vscc, sizeof (entry->vscc)); entry->format = g_malloc (entry->format_size); memcpy (entry->format, src_format, entry->format_size); media_structure = ks_video_format_to_structure (range->SubFormat, range->MajorFormat); if (media_structure == NULL) { g_warning ("ks_video_format_to_structure returned NULL"); ks_video_media_type_free (entry); entry = NULL; } else if (ks_video_append_video_stream_cfg_fields (media_structure, &entry->vscc)) { entry->translated_caps = gst_caps_new_empty (); gst_caps_append_structure (entry->translated_caps, media_structure); } else { gst_structure_free (media_structure); ks_video_media_type_free (entry); entry = NULL; } if (entry != NULL) ret = g_list_prepend (ret, entry); } } /* REVISIT: Each KSDATARANGE should start on a 64-bit boundary */ range = (KSDATARANGE *) (((guchar *) range) + range->FormatSize); } g_free (items); } } } if (ret != NULL) { ret = g_list_reverse (ret); ret = ks_video_media_type_list_remove_duplicates (ret); } beach: return ret; }