Jump to content

maXcomX

Members
  • Content Count

    34
  • Joined

  • Last visited

Everything posted by maXcomX

  1. maXcomX

    Bitmaps2Video for Windows Media Foundation

    By the way: wic.LoadFromFile(InputFilename); Consumes the most time depending on size and type.
  2. maXcomX

    Bitmaps2Video for Windows Media Foundation

    The video codec HEVC is well documented but difficult to understand . However, this codec needs to be initialized with a HEVC profile and optionally payload that is supported by Media Foundation. Now, the documentation is not very accurate about the supported profiles. Two of them are missing though. Note that Media Foundation only supports 2 payloads (0-1) 2 and 3 are not supported. Another misunderstanding is how Media Foundation slices a media source. For a regulair file it has a video related codec an audio related codec, maybe a subtitle stream and the container file that holds those. For example a MP4 container (.mp4 file) can contain various types of codecs. Like for example the HEVC video codec and a mp3 audio codec, a H264 video codec and a Dolby_AC3 audio codec etc. The coming MfPack version will be expanded with a Videocheat and video profiles unit to make life easier. New updates are regulair committed and can be found here Note that the H.265 encoder implements by documentation properties like CODECAPI_AVLowLatencyMode etc. are DirectShow properties and therefore should not be implemented in Media Foundation.
  3. maXcomX

    Bitmaps2Video for Windows Media Foundation

    When examine the code, it's not clear to me what the parameter ShowTime means. Lets say I want to render 3 images during the length of an audiofile in a slideshow, that would be the audiofile length div 3. So, each image will be shown for 1/3th during the audiofile length. Is this value the "ShowTime" or does ShowTime means the time 2 images are fading to onenother?
  4. maXcomX

    Bitmaps2Video for Windows Media Foundation

    Well, the code will not work on Delphi XE7. See: Some issues
  5. maXcomX

    Bitmaps2Video for Windows Media Foundation

    I use a special app that reads almost all possible result codes and when possible where to find more details. These codes and descriptions are stored in Delphi units.
  6. maXcomX

    Bitmaps2Video for Windows Media Foundation

    In that case assign the buffer to nil (which is silence) and try again. However an av will never happen unless the API is wrong translated or when you use sloppy code. You will always get an HResult when something goes wrong.
  7. maXcomX

    Bitmaps2Video for Windows Media Foundation

    In C++ they are called macro's. A thing Delphi does not have.
  8. maXcomX

    Bitmaps2Video for Windows Media Foundation

    Maybe you forgot to add a stream for sound? Container formats always have separate streams for sound and/or subtitles. That's why most players can play a video in native languages and subtitles.
  9. maXcomX

    Bitmaps2Video for Windows Media Foundation

    And will this give any user or debugger information about what exactly went wrong? The HResult code does. So, you have to be more specific when raising an exception, I would think.
  10. maXcomX

    Bitmaps2Video for Windows Media Foundation

    🙂 Learn C++ I would say. Delphi users are quite spoiled about resolving method results. But helaas, until now, there is no solution in Delphi to handle HResult in it's exception handlers for media foundation and directx. To be more specific: WinApi.Error.Pas is way outdated until version 10.3
  11. maXcomX

    Bitmaps2Video for Windows Media Foundation

    Checking the results of the media foundation methods is as easy as can be. The results will give you information about what went wrong in most cases. So, the standard exception handling in Delphi is not suitable and therefore you have to write our own exception handlers, because each hresult code is described in WinApi.WinError.pas or WinApi.MediaFoundationApi.MfError.pas and will exactly return what went wrong. Media Foundation and related API's are not part of the Delphi distributions from Embarcadero, and if they are, they are outdated in most cases. The Microsoft documentation explains the retuned values of the API methods very well.
  12. maXcomX

    Bitmaps2Video for Windows Media Foundation

    The sample only works on Delphi 10.3 and above.
  13. Hello, I'm trying to translate PSAPI_WORKING_SET_BLOCK (psapi.h) structure to Delphi. Now I'm struggling with as far as I become this far: type STRUCT_PSAPI_WORKING_SET_BLOCK = record private Flags: ULONG_PTR; function GetBits(const aIndex: NativeUInt): NativeUInt; procedure SetBits(const aIndex: NativeUInt; const aValue: NativeUInt); public property Protection: NativeUInt index $0005 read GetBits write SetBits; // 5 bits at offset 0 property ShareCount: NativeUInt index $0503 read GetBits write SetBits; // 3 bits at offset 5 property Shared: NativeUInt index $0801 read GetBits write SetBits; // 1 bit at offset 8 property Reserved: NativeUInt index $0903 read GetBits write SetBits; // 3 bits at offset 9 {$IFDEF WIN64} property VirtualPage: NativeUInt index $1253 read GetBits write SetBits; // 52 bits at offset 12 {$ELSE} property VirtualPage: NativeUInt index $1220 read GetBits write SetBits; // 20 bits at offset 9 {$ENDIF} end; PSAPI_WORKING_SET_BLOCK = record case Integer of 0: ( struct: STRUCT_PSAPI_WORKING_SET_BLOCK ); end; PPSAPI_WORKING_SET_BLOCK = ^PSAPI_WORKING_SET_BLOCK; The issue is that index is a integerConstant clause, so NativeUint will not work in this situation. How do I tackle this? Like this? type STRUCT_PSAPI_WORKING_SET_BLOCK = record private Flags: ULONG_PTR; function GetBits(const aIndex: Integer): NativeUInt; procedure SetBits(const aIndex: Integer; const aValue: NativeUInt); public property Protection: NativeUInt index 5 read GetBits write SetBits; // 5 bits at offset 0 property ShareCount: NativeUInt index 503 read GetBits write SetBits; // 3 bits at offset 5 property Shared: NativeUInt index 801 read GetBits write SetBits; // 1 bit at offset 8 property Reserved: NativeUInt index 903 read GetBits write SetBits; // 3 bits at offset 9 {$IFDEF WIN64} property VirtualPage: NativeUInt index 1253 read GetBits write SetBits; // 52 bits at offset 12 {$ELSE} property VirtualPage: NativeUInt index 1220 read GetBits write SetBits; // 20 bits at offset 9 {$ENDIF} end; PSAPI_WORKING_SET_BLOCK = record case Integer of 0: ( struct: STRUCT_PSAPI_WORKING_SET_BLOCK ); end; PPSAPI_WORKING_SET_BLOCK = ^PSAPI_WORKING_SET_BLOCK; And cast the GetBits and SetBits methods, aIndex parameter from Integer to NativeUInt when accessing the appropriate bits in the Flags field?
  14. maXcomX

    How to translate PSAPI_WORKING_SET_BLOCK?

    Sorry a bit late response. Delphi has a unit called psapi.pas, but it's incomplete , for some reason this record is not translated (since Delphi XE7, or earlier, the first translation of this header I found was from Borland). I did indeed made a mistake. So I translated it like this: STRUCT_PSAPI_WORKING_SET_BLOCK = record private Flags: ULONG_PTR; function GetBits(const aIndex: Integer): ULONG_PTR; procedure SetBits(const aIndex: Integer; const aValue: ULONG_PTR); public property Protection: ULONG_PTR index $0005 read GetBits write SetBits; // 5 bits at offset 0 property ShareCount: ULONG_PTR index $0503 read GetBits write SetBits; // 3 bits at offset 5 property Shared: ULONG_PTR index $0801 read GetBits write SetBits; // 1 bit at offset 8 property Reserved: ULONG_PTR index $0903 read GetBits write SetBits; // 3 bits at offset 9 {$IFDEF WIN64} property VirtualPage: ULONG_PTR index $1253 read GetBits write SetBits; // 52 bits at offset 12 {$ELSE} property VirtualPage: ULONG_PTR index $1220 read GetBits write SetBits; // 20 bits at offset 9 {$ENDIF} end; PSAPI_WORKING_SET_BLOCK = record public case Integer of 0: ( struct: STRUCT_PSAPI_WORKING_SET_BLOCK ); end; {$EXTERNALSYM PSAPI_WORKING_SET_BLOCK} PPSAPI_WORKING_SET_BLOCK = ^PSAPI_WORKING_SET_BLOCK; {$EXTERNALSYM PPSAPI_WORKING_SET_BLOCK} // PSAPI_WORKING_SET_BLOCK ///////////////////////////////////////////////////// function STRUCT_PSAPI_WORKING_SET_BLOCK.GetBits(const aIndex: Integer): ULONG_PTR; begin Result := GetUBits(Flags, aIndex); end; procedure STRUCT_PSAPI_WORKING_SET_BLOCK.SetBits(const aIndex: Integer; const aValue: ULONG_PTR); begin SetUBits(Flags, aIndex, aValue); end; // ///////////////////////////////////////////////////////////////////////////// // global unit helpers // Record helpers ////////////////////////////////////////////////////////////// function GetUBits(const Bits: ULONG_PTR; const aIndex: Integer): ULONG_PTR; begin Result := (Bits shr (aIndex shr 8)) and // offset ((1 shl Byte(aIndex)) - 1); // mask end; procedure SetUBits(var Bits: ULONG_PTR; const aIndex: Integer; const aValue: ULONG_PTR); var Offset: Byte; Mask: Integer; begin Mask := ((1 shl Byte(aIndex)) - 1); Assert(Integer(aValue) <= Mask); Offset := aIndex shr 8; Bits := (Bits and (not (Mask shl Offset))) or DWORD(aValue shl Offset); end; In the middle of discussing this issue with Rudy Veldhuis, he passed away 😞 But he pointed out in his blog which is still online, a similar solution. Henri Gourvest (from DSPack) opinion is to skip structs containing C/C++ bitshifting, because it's rarely used and what you commented that bitfield ordering is not standardized. So good reasons why Embarcadero still did not include this in psapi.pas? Thanks in advance, Tony.
  15. Every time I start up an app on OnFormCreate CoInitializeEx(Nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE); returns with 1 (S_FALSE) // The COM library is already initialized on this thread Does creating a form automatically initialize COM? and OnFormCreate CoInitializeEx(nil, COINIT_MULTITHREADED); returns with -2147417850 ($80010106 or 0x80010106) // can't find the description of this return value On Delphi 10.4, Win 11 latest update. What could be a possible issue?
  16. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Thanks, Remy. IAgileObject works as expected. This text confused me: E_ILLEGAL_METHOD_CALL On versions of Windows previous to Windows 10, this error may result if the function is called from an incorrect COM apartment, or if the passed IActivateAudioInterfaceCompletionHandler is not implemented on an agile object (aggregating a free-threaded marshaler). So on first thought, I would need an aggregated interface instead of an IAgileObject interface. And because IAgileObject is not defined in any Delphi version, TAggregatedObject bubbled up.. Being confused has nothing to do with Confucius I would say... For the audience I translated IAgileObject to Delphi (which should be declared in ObjIdl, part of Delphi ActiveX?) // Interface IAgileObject // ====================== // The IAgileObject interface is a marker interface that indicates that an object // is free threaded and can be called from any apartment. // Unlike what happens when aggregating the Free Threaded Marshaler (FTM), // implementing the IAgileObject interface doesn't affect what happens when marshaling a call. // Instead, the IAgileObject interface is recognized by the Global Interface Table (GIT). // When an object that implements the IAgileObject interface is placed in the GIT and // localized to another apartment, the object is called directly in the new apartment, rather than marshaling. {$HPPEMIT 'DECLARE_DINTERFACE_TYPE(IAgileObject);'} {$EXTERNALSYM IAgileObject} IAgileObject = interface(IUnknown) ['{94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90}'] // public end; IID_IAgileObject = IAgileObject; {$EXTERNALSYM IID_IAgileObject} Again: Thank you for your help and explanations on this subject.
  17. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Ok, thank you again for this useful info. I stumbled into this while writing a basic audio loopback application, where I experienced a strange behavior of function ActivateAudioInterfaceAsync. My first thought was it had something todo with ConitializeEx(). But reading the documentation again, the interface should be implemented on an agile object (aggregating a free-threaded marshaler. I think I need to implement the TAggregatedObject, but not sure if that is correct and how to implement this. I tried this: TActivateAudioInterfaceCompletionHandler = class(TInterfacedObject, IActivateAudioInterfaceCompletionHandler) public function ActivateCompleted(activateOperation: IActivateAudioInterfaceAsyncOperation): HRESULT; stdcall; end; TLoopbackCapture = class(TAggregatedObject, IActivateAudioInterfaceCompletionHandler) // etc // constructor constructor TLoopbackCapture.Create(oObj: IUnknown); var hr: HResult; begin inherited Create(IActivateAudioInterfaceCompletionHandler(oObj)); // etc // From the mainform creating tLoopBackCapture is called var OuterObj: TActivateAudioInterfaceCompletionHandler; oLoopbackCapture: TLoopbackCapture; procedure TfrmMain.FormCreate(Sender: TObject); begin OuterObj := TActivateAudioInterfaceCompletionHandler.Create(); oLoopbackCapture := TLoopbackCapture.Create(IActivateAudioInterfaceCompletionHandler(OuterObj)); end; But this approach doesn't work either. When calling ActivateAudioInterfaceAsync, function TAggregatedObject.QueryInterface(const IID: TGUID; out Obj): HResult; begin Result := IInterface(FController).QueryInterface(IID, Obj); << FController = nil end; No Interface ($80004002), IID = {'94EA2B94-E9CC-49E0-C0FF-EE64CA8F5B90'}, well actually that's the identifier of the IAgile interface.. Followed by EAccessError. So, I think implementing TAggregatedObject is not the way, but implementing IAgile should do it? It's a real headbanger.. 😞
  18. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    I must have overlooked something. When initializing an UI application, any earlier Conitialize() as default, should be set to ConitializeEx() when necessarily. So, if Assigned(InitProc) is true, CoUnitialize() should be called to change the thread model and set to ConitializeEx() to make callbacks working. Also the parameter COINIT_MULTITHREADED that only should be used by DOSbox and other windowless apps, should be COINIT_APARTMENTTHREADED for UI apps. Am I correct?
  19. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    I must have overlooked something. The place to call ConitializeEx() should not be called in OnFormCreate, as Remy commented by posting this link. The MS sample is a DOSbox sample, I forgot that when creating a form in Delphi ConitializeEx() has already being called. Thank you Remy.
  20. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Yes I can. I'm working on a new example that replaces the mmio methods, because they are or will be deprecated (like mmioOpen) And that make all other mmio related methods quite useless. So far I managed to translate a CPP example to it's Delphi equivalent. However Microsoft made a lot of samples based on a DOSBox interface. To be more specific, the DOSbox sample runs well on MS Visual Studio (returning the adequate result of CoInitializeEx() , but not within Delphi 10.4. Here Delphi source including the CPP source: LoopBackCapture_2.zip The Delphi sample uses MFPack
  21. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    It does what it's expected to do, but it will not explain why the function is resulting the results I mentioned.
  22. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Thank you Remy, but I've been through all those things. That's why I ended here 😉
  23. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Any way: Thanks a lot for your efforts to solve this issue!
  24. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Also, there is a big issue when trying to use WASAPI when CoInitializeEx fails. Methods like ActivateAudioInterfaceAsync will fail too with unpredictable results.
  25. maXcomX

    Why does CoInitializeEx returns 1 or $80010106 ?

    Thank you, but this is not an expected behaviour of this function, does it? For example if you run this code in C++ all goes well. Delphi issue?
×