Closed Steph55 closed 2 years ago
Hi,
Yes, not all guids are declared in DirectN. You get get all guid values from headers or from this online tool here: https://www.magnumdb.com
Same for this: https://www.magnumdb.com/search?q=*AVEncCommonQuality
This depends on how they are declared in the original header files. And actually, this is how it's declared in Windows Kits\10\Include\10.0.22000.0\um\mfreadwrite.h
:
enum __MIDL___MIDL_itf_mfreadwrite_0000_0001_0001
{
MF_SOURCE_READER_INVALID_STREAM_INDEX = 0xffffffff,
MF_SOURCE_READER_ALL_STREAMS = 0xfffffffe,
MF_SOURCE_READER_ANY_STREAM = 0xfffffffe,
MF_SOURCE_READER_FIRST_AUDIO_STREAM = 0xfffffffd,
MF_SOURCE_READER_FIRST_VIDEO_STREAM = 0xfffffffc,
MF_SOURCE_READER_MEDIASOURCE = 0xffffffff
} ;
Windows Kits\10\Include\10.0.22000.0\um\mfapi.h
, it can be easily adapted to C#:MFGetAttributeRatio(
IMFAttributes* pAttributes,
REFGUID guidKey,
_Out_ UINT32* punNumerator,
_Out_ UINT32* punDenominator
)
{
return MFGetAttribute2UINT32asUINT64(pAttributes, guidKey, punNumerator, punDenominator);
}
MFGetAttribute2UINT32asUINT64(
IMFAttributes* pAttributes,
REFGUID guidKey,
_Out_ UINT32* punHigh32,
_Out_ UINT32* punLow32
)
{
UINT64 unPacked;
HRESULT hr = S_OK;
hr = pAttributes->GetUINT64(guidKey, &unPacked);
if (FAILED(hr)) {
return hr;
}
Unpack2UINT32AsUINT64(unPacked, punHigh32, punLow32);
return hr;
}
Unpack2UINT32AsUINT64(UINT64 unPacked, _Out_ UINT32* punHigh, _Out_ UINT32* punLow)
{
*punHigh = HI32(unPacked);
*punLow = LO32(unPacked);
}
HI32(UINT64 unPacked)
{
return (UINT32)(unPacked >> 32);
}
LO32(UINT64 unPacked)
{
return (UINT32)unPacked;
}
typeof(AnyType).Guid
will give you an interface guid.Thank you very much for your answer, it is much useful! You are quite generous. Now I still have a few other things.
1) A little correction for the future version of DirectN: The following seems to be the proper signature for SetCurrentMediaType of IMFSourceReader for it to work :
[PreserveSig]
HRESULT SetCurrentMediaType(/* [annotation][in] _In_ */ uint dwStreamIndex, /* [annotation][out][in] _Reserved_ */ IntPtr pdwReserved, /* [annotation][in] _In_ */ IMFMediaType pMediaType);
When we call it, we need to pass IntPtr.Zero as the second parameter.
2) I'm having trouble with the codecApi->GetValue() and codecApi->SetValue() functions. I did not find any helper function in DirectN for the Variant type.
I saw on the following page that you already studied the subject: https://stackoverflow.com/questions/49323410/com-interop-and-marshaling-of-variantvt-ptr
Did you do something for this in DirectN, maybe I did not find it?
Hi,
true. This is a bug in the .h declaration of SetCurrentMediaType in the Windows SDK. The annotation specifies it as [out][in], not optional, so the generator doesn't generate an IntPtr where it should... I've fixed the .cs.
VARIANTs are normally handled by .NET (this is not the case with PROPVARIANTs). The SO post is very specific as the VARIANT used there was an invalid one.
You can use GetObjectForNativeVariant to convert from IntPtr into an object and the opposite: GetNativeVariantForObject
Thank you Simon!
However, it appears that it is not simple to deal with the variant variables, when I read the following three-part article: Using VARIANTs in Managed Code Part 1 | limbioliong (wordpress.com) https://limbioliong.wordpress.com/2011/09/04/using-variants-in-managed-code-part-1/
Le mar. 7 déc. 2021 à 14:38, Simon Mourier @.***> a écrit :
Hi,
1.
true. This is a bug in the .h declaration of SetCurrentMediaType in the Windows SDK. The annotation specifies it as [out][in], not optional, so the generator doesn't generate an IntPtr where it should... I've fixed the .cs. 2.
VARIANTs are normally handled by the .NET (this is not the case with PROPVARIANTs). The SO post is very specific as the VARIANT used there was an invalid one.
You can use GetObjectForNativeVariant https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.getobjectfornativevariant to convert from IntPtr into an object and the opposite: GetNativeVariantForObject
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/smourier/DirectN/issues/25#issuecomment-988212498, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADJJUEHP6SLFVRYTWOE6E53UPZPERANCNFSM5JKD3EKA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
From .NET this is fairly simple, just use the functions and ask again if you face any real issue.
Here is the code I'm trying to use:
var codecApi = pWriter.GetServiceForStream<ICodecAPI>(writerVideoStreamIndex, new Guid(), typeof(ICodecAPI).GUID);
if (codecApi != null)
{
codecApi.Object.GetValue(CODECAPI_AVEncCommonQuality, out IntPtr intPtrQualité);
var o = Marshal.GetObjectForNativeVariant(intPtrQualité);
But the value I get for intPtrQualité is 0x0000000000000013 and I get an execution Engine Exception...
That may be an issue with ICodecAPI definition, the most simple way is to redefine it like this:
...
[PreserveSig]
HRESULT GetValue(/* [in] */ [MarshalAs(UnmanagedType.LPStruct)] Guid Api, /* [annotation][out] _Out_ */ out object Value);
...
[PreserveSig]
HRESULT SetValue(/* [in] */ [MarshalAs(UnmanagedType.LPStruct)] Guid Api, /* [annotation][in] _In_ */ ref object Value);
Closing due to inactivity
Thank you for your last correction! I was able to progress in my test of DirectN.
1) Now it seems that DMOs are missing, like this one, for instance:
CColorConvertDMO (CLSID_CColorConvertDMO)
2) Guids are missing like: CODECAPI_AVEncCommonQuality
3) This enum of DirectN is far from user friendly:
public enum __MIDL___MIDL_itf_mfreadwrite_0000_0001_0001 { MF_SOURCE_READER_INVALID_STREAM_INDEX = -1, MF_SOURCE_READER_ALL_STREAMS = -2, MF_SOURCE_READER_ANY_STREAM = -2, MF_SOURCE_READER_FIRST_AUDIO_STREAM = -3, MF_SOURCE_READER_FIRST_VIDEO_STREAM = -4, MF_SOURCE_READER_MEDIASOURCE = -1, }
4) When I call the following function with valid parameters:
Functions.MFGetAttributeRatio(pType, MFConstants.MF_MT_FRAME_RATE_RANGE_MAX, out uint frameRateNum, out uint frameRateDem).ThrowOnError();
I get the error:
System.EntryPointNotFoundException : 'Unable to find an entry point named 'MFGetAttributeRatio' in DLL 'mfplat'.'
5) Also, in order to replace the C++ function __uuidof, I wrote the following, because I did not find how in DirectN. You can include it, if needed:
public Guid __uuidof<T>() { var attribs = Attribute.GetCustomAttributes(typeof(T), typeof(GuidAttribute)); foreach (GuidAttribute attrib in attribs) { if (attrib.GetType() == typeof(GuidAttribute)) return new Guid(attrib.Value); } return new Guid(); }