Jump to content
Sign in to follow this  
frank10

struct as object's argument, DllStructGetData @error=3

Recommended Posts

frank10

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 samples

the 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.)

Local $_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 ?

Share this post


Link to post
Share on other sites
ProgAndy

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

Share this post


Link to post
Share on other sites
frank10

I tried but it gives me @error= 1 Struct not a correct struct returned by DllStructCreate.

Share this post


Link to post
Share on other sites
frank10

I'm sorry there was another problem, now it works.

Thank you ProgAndy.

Share this post


Link to post
Share on other sites
frank10

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)
Next

I 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°:

AM_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:0

while I expect for example 640 on 'biwidth' element that should correspond to index 13° and '480' on the 14°.

Edited by frank10

Share this post


Link to post
Share on other sites
frank10

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.

Share this post


Link to post
Share on other sites
ProgAndy

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

Share this post


Link to post
Share on other sites
frank10

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 CoTaskMemAlloc

This confused me in the type definition.

Share this post


Link to post
Share on other sites
ProgAndy

"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 CoTaskMemAlloc

That is if you create the structure yourself. You just want to read an already existing one. Edited 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

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×