frank10 Posted March 14, 2012 Share Posted March 14, 2012 I have a Direct Show object with a method that needs two structs as arguments, defined as:HRESULT GetStreamCaps( [in] int iIndex, [out] AM_MEDIA_TYPE **pmt, [out] BYTE *pSCC ); [i]pmt[/i] [out] Address of a pointer to an AM_MEDIA_TYPE structure. The method allocates the structure and fills it with a media type.'GetStreamCaps hresult(int;ptr*;struct*);'so, it has to give me as 2° argument a pointer to a struct AM_MEDIA_TYPE filled with some media samplesthe 3° arg: I should receive a struct VIDEO_STREAM_CONFIG_CAPS that it has filled with info of video image.The important struct is the AM_MEDIA_TYPE and it's the one I don't get... while the VIDEO_STREAM_CONFIG is correctly filled after I pass the pointer to it.The c++ part of code I use (and it works well) is:VIDEO_STREAM_CONFIG_CAPS scc; AM_MEDIA_TYPE *pmtConfig; hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc); if (SUCCEEDED(hr)) { /* Examine the format, and possibly use it. */ if ((pmtConfig->formattype == FORMAT_VideoInfo) && (pmtConfig->pbFormat != NULL)) { VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmtConfig->pbFormat; BITMAPINFOHEADER *bmiHeader = &pVIH->bmiHeader; ....So, I get pbFormat.Instead in autoit I made:(I insert in the two structs the plain text of the other two GUID and SIZE, as I don't know how to construct nested struct to pass them to the method. with the VIDEO_STREAM worked.)expandcollapse popupLocal $_GUID = "DWORD Data1;" & _ "WORD Data2;" & _ "WORD Data3;" & _ "BYTE Data4[8];" Local $_SIZE = "LONG cx;" & _ "LONG cy;" Local $_VIDEO_STREAM_CONFIG_CAPS = $_GUID & _ "ULONG VideoStandard;" & _ $_SIZE & _ $_SIZE & _ $_SIZE & _ "int CropGranularityX;" & _ "int CropGranularityY;" & _ "int CropAlignX;" & _ "int CropAlignY;" & _ $_SIZE & _ $_SIZE & _ "int OutputGranularityX;" & _ "int OutputGranularityY;" & _ "int StretchTapsX;" & _ "int StretchTapsY;" & _ "int ShrinkTapsX;" & _ "int ShrinkTapsY;" & _ "int64 MinFrameInterval;" & _ "int64 MaxFrameInterval;" & _ "LONG MinBitsPerSecond;" & _ "LONG MaxBitsPerSecond;" Local $tVideoStream = DllStructCreate($_VIDEO_STREAM_CONFIG_CAPS) Local $_AM_MEDIA = $_GUID & _ $_GUID & _ 'BOOL bFixedSizeSamples;' & _ 'BOOL bTemporalCompression;' & _ 'ULONG lSampleSize;' & _ $_GUID & _ 'ptr pUnk;' & _ 'ULONG cbFormat;' & _ 'BYTE pbFormat;' Local $t_AM_MEDIA = DllStructCreate($_AM_MEDIA) local $pmtConfig= DllStructGetPtr($t_AM_MEDIA) , $scc= DllStructGetPtr($tVideoStream) $oStreamConfig.GetStreamCaps($iFormat, $pmtConfig, $scc); ConsoleWrite(DllStructGetData($t_AM_MEDIA, 0 ,$pmtConfig) & @crlf)The DllStructGetData sets @error at '3 = index would be outside of the struct.'What should I do ? Link to comment Share on other sites More sharing options...
ProgAndy Posted March 14, 2012 Share Posted March 14, 2012 The second argument receives a pointer to a struct. I think It should be something like this: Local $pmtConfig $oStreamConfig.GetStreamCaps($iFormat, $pmtConfig, $scc); $t_AM_MEDIA_TYPE = DLLStructCreate($AM_MEDIA_TYPE, $pmtConfig) *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
frank10 Posted March 14, 2012 Author Share Posted March 14, 2012 I tried but it gives me @error= 1 Struct not a correct struct returned by DllStructCreate. Link to comment Share on other sites More sharing options...
frank10 Posted March 14, 2012 Author Share Posted March 14, 2012 I'm sorry there was another problem, now it works. Thank you ProgAndy. Link to comment Share on other sites More sharing options...
frank10 Posted March 14, 2012 Author Share Posted March 14, 2012 (edited) I have some other problems:The last value of AM_MEDIA_TYPE should be the pointer pbFormat that is a ptr to a struct VIDEOINFOHEADER that has other struct inside:typedef struct tagVIDEOINFOHEADER { RECT rcSource; RECT rcTarget; DWORD dwBitRate; DWORD dwBitErrorRate; REFERENCE_TIME AvgTimePerFrame; BITMAPINFOHEADER bmiHeader; } VIDEOINFOHEADER; typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER;So in autoit:local $_RECT = 'LONG left;' & _ 'LONG top;' & _ 'LONG right;' & _ 'LONG bottom;' Local $_tagBITMAPINFOHEADER = 'DWORD biSize;' & _ 'LONG biWidth;' & _ 'LONG biHeight;' & _ 'WORD biPlanes;' & _ 'WORD biBitCount;' & _ 'DWORD biCompression;' & _ 'DWORD biSizeImage;' & _ 'LONG biXPelsPerMeter;' & _ 'LONG biYPelsPerMeter;' & _ 'DWORD biClrUsed;' & _ 'DWORD biClrImportant;' Local $_tagVIDEOINFOHEADER = $_RECT & _ $_RECT & _ 'DWORD dwBitRate;' & _ 'DWORD dwBitErrorRate;' & _ 'int64 AvgTimePerFrame;' & _ $_tagBITMAPINFOHEADER Local $ptr = _MemGlobalAlloc(DllStructGetData($t_AM_MEDIA_TYPE,"pbFormat")) Local $t_VIDEOINFOHEADER = DLLStructCreate($_tagVIDEOINFOHEADER, $ptr ) for $b =1 to 23 ConsoleWrite(DllStructGetData($t_VIDEOINFOHEADER,$b) & ' VIDEOINFOHEADER index='& $b &' err:'&@error& @CRLF) NextI make MemGlobal Alloc on pbFormat, because it says:"The pbFormat buffer must be allocated by calling CoTaskMemAlloc. To release the format block, call FreeMediaType."But the VIDEOINFOHEADER is filled randomly, both in index and contents: this example only from index 14 up to 22°:expandcollapse popupAM_MEDIA_TYPE struct: 1935960438 index=1 err:0 0 index=2 err:0 16 index=3 err:0 0x800000AA00389B71 index=4 err:0 844715353 index=5 err:0 0 index=6 err:0 16 index=7 err:0 0x800000AA00389B71 index=8 err:0 1 index=9 err:0 0 index=10 err:0 614400 index=11 err:0 89694080 index=12 err:0 50006 index=13 err:0 4558 index=14 err:0 0xBF0100AA0055595A index=15 err:0 0x00000000 index=16 err:0 88 index=17 err:0 56 index=18 err:0 ; this corresponds to pbFormat VIDEOINFOHEADER struct: 0 VIDEOINFOHEADER index=1 err:0 0 VIDEOINFOHEADER index=2 err:0 0 VIDEOINFOHEADER index=3 err:0 0 VIDEOINFOHEADER index=4 err:0 0 VIDEOINFOHEADER index=5 err:0 0 VIDEOINFOHEADER index=6 err:0 0 VIDEOINFOHEADER index=7 err:0 0 VIDEOINFOHEADER index=8 err:0 0 VIDEOINFOHEADER index=9 err:0 0 VIDEOINFOHEADER index=10 err:0 0 VIDEOINFOHEADER index=11 err:0 0 VIDEOINFOHEADER index=12 err:0 0 VIDEOINFOHEADER index=13 err:0 -953830003 VIDEOINFOHEADER index=14 err:0 46477 VIDEOINFOHEADER index=15 err:0 50981 VIDEOINFOHEADER index=16 err:0 3477847172 VIDEOINFOHEADER index=17 err:0 1692276246 VIDEOINFOHEADER index=18 err:0 1693178670 VIDEOINFOHEADER index=19 err:0 1686509102 VIDEOINFOHEADER index=20 err:0 1686509102 VIDEOINFOHEADER index=21 err:0 3090988164 VIDEOINFOHEADER index=22 err:0while I expect for example 640 on 'biwidth' element that should correspond to index 13° and '480' on the 14°. Edited March 14, 2012 by frank10 Link to comment Share on other sites More sharing options...
frank10 Posted March 15, 2012 Author Share Posted March 15, 2012 Do you have some ideas? What should I try? I really need this piece of code, as it's the only part I lack to make a webcam UDF in DirectShow. This part should let me choose the source video resolution desired. Link to comment Share on other sites More sharing options...
ProgAndy Posted March 15, 2012 Share Posted March 15, 2012 The data should already been allocated. Local $_AM_MEDIA = $_GUID & _ $_GUID & _ 'BOOL bFixedSizeSamples;' & _ 'BOOL bTemporalCompression;' & _ 'ULONG lSampleSize;' & _ $_GUID & _ 'ptr pUnk;' & _ 'ULONG cbFormat;' & _ 'ptr pbFormat;' ;<-- !!! ... $pbFormat = DLLStructGetData($t_AM_MEDIA, "pbFormat") $tFormat = DLLStructCreate(..., $pbFormat) ... PSEUDOCODE for freeing: CoTaskMemFree($pbFormat); $pUnk = DLLStructGetData($t_AM_MEDIA, "pUnk") If $pUnk Then IUnknown_Release($pUnk) $pAM_MEDIA = DLLStructGetPtr($t_AM_MEDIA) $t_AM_MEDIA = 0 CoTaskMemFree($pAM_MEDIA); *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
frank10 Posted March 15, 2012 Author Share Posted March 15, 2012 YES!Thank you, this pbFormat as ptr works.But, they declare: BYTE *pbFormat;and in the description they say: The pbFormat buffer must be allocated by calling CoTaskMemAllocThis confused me in the type definition. Link to comment Share on other sites More sharing options...
ProgAndy Posted March 15, 2012 Share Posted March 15, 2012 (edited) "BYTE *" states, that it is a pointer to a byte / an array of bytes. Since AutoIt does not support typed pointers, use "ptr"and in the description they say: The pbFormat buffer must be allocated by calling CoTaskMemAllocThat is if you create the structure yourself. You just want to read an already existing one. Edited March 15, 2012 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now