Jump to content

ioan

Members
  • Content Count

    44
  • Joined

  • Last visited

  • Days Won

    2

ioan last won the day on January 26

ioan had the most liked content!

Community Reputation

28 Excellent

About ioan

  • Birthday February 25

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. ioan

    I will be less active for a few weeks

    Wish you a fast full recovery! Take care!
  2. I never tried this, but there are some options for service recovery. If you exit the service with an error code, windows should restart it for you right away:
  3. I got an email from AWS today that my services send emails using 'Signature Version 2' which is deprecated and will be gone by the end of March. Only 'Signature Version 4' will be supported after that (https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). Right now I'm using TIdSMTP to send emails using SES. How do I change TIdSMTP to use sigv4?
  4. ioan

    Converting C struct to Delphi

    Well, I agree with you, but, for me, before I start to put effort into porting it to BrightScript I want to make sure it works on Delphi, where I can debug it and change the var types and structures to whatever is supported in BrightScript. Of course, this could be done directly in C, but I'm way more comfortable with Delphi... so I prefer to work twice just so I'm comfortable. Roku supports H.264, but not from a RTSP stream. The only RTSP that's available on Roku right now, as far as I know, it's in IP Camera Viewer, which is made by me and I had to implement RTSP by myself. Right now it only supports jpeg encoded RTSP streams (ONVIF compliant IP cameras must provide a JPEG encoded RTSP stream, but surprise, not all of them do). The only H.264 streaming Roku supports is HLS. Of course, it can play .mp4 and .ts files and the .ts files can be mp4 format. It cannot play raw h264 stream even if it's saved in a file. The RTSP part is identical for JPEG encoded streams and H.264 encoded streams. I also already implemented the capture of the raw h264 stream and now I'm trying to convert, on the fly, to mp4 (.ts) so Roku can play it as HLS. I won't even save the .ts as files. When Roku ask for the next chunk, I'll just serve the next buffered chunk I have. Of course, that means I have to have a webserver running on Roku... I have one in my application to provide an easier way to config the application and backup, but I'm not sure yet if it's performant enough to be able to serve hls. Majority of cheap Chinese IP cameras that people buy advertise as ONVIF compliant but provide only H264 stream. I receive emails daily from people asking why their camera doesn't work with my application. I got sick of answering so I'm trying to fix the problem. Now, if I'll be successful, I don't know. But I'll frustrate myself trying, that's for sure. Beats answering the same email every day.
  5. ioan

    Converting C struct to Delphi

    I created the dll myself from source code I got from github (https://github.com/aspt/mp4) and I modified the C source to open the file inside the dll, I just have to provide the name. The problem was that one of the struct that I needed to use to access the library had a FILE * member, where the handle to the opened file is stored. I got everything working late last night. Off topic: Now the hard part starts. I want to use this code on a Roku media player, but the problem is that to develop on Roku you have to use a scripting language called BrightScript. My plan is to convert the C code to Delphi and in the same time to understand the code, and then port it to BrightScript. My pet project is to get rtsp/h264 working on Roku.
  6. ioan

    Converting C struct to Delphi

    Yeah, I would probably convert the code to Delphi, but for now, for testing, I just need to convert some structs and one of them has a FILE * member: typedef struct MP4E_mux_tag { asp_vector_t tracks; // mp4 file tracks FILE * mp4file; // output file handle mp4e_size_t write_pos; // ## of bytes written ~ current file position (until 1st fseek) char * text_comment; // application-supplied file comment int enable_fragmentation; // flag, indicating streaming-friendly 'fragmentation' mode int fragments_count; // # of fragments in 'fragmentation' mode } MP4E_mux_t;
  7. ioan

    Converting C struct to Delphi

    Is 'FILE *' equivalent to THandle?
  8. ioan

    Converting C struct to Delphi

    Thanks David!
  9. ioan

    Converting C struct to Delphi

    Thank you for pointing the missed language member. About the enum, not sure what do you mean. How should it look like? Should I change like this? track_media_kind: integer;
  10. Does this C struct conversion to Delphi looks right to you? From C typedef struct { unsigned object_type_indication; unsigned char language[4]; enum { e_audio, e_video, e_private } track_media_kind; unsigned time_scale; unsigned default_duration; union { struct { unsigned channelcount; } a; struct { int width; int height; } v; } u; } MP4E_track_t; to Delphi: type track_media_kind_enum = (e_audio, e_video, e_private); type MP4E_track_t = record object_type_indication: LongWord; track_media_kind: track_media_kind_enum; time_scale: LongWord; default_duration: LongWord; case integer of 0: ( channelcount: LongWord ); 1: ( width: Integer; height: Integer; ); end; TIA
  11. ioan

    Change notification to not show the exe's name?

    That did it. Thank you!
  12. I'm using TTrayIcon to show notifications and I would like to change the notification title(?) from exe's name to my custom string (circled in the attached picture). Is it possible? This is my code to show the notification: procedure TfrmQueue.ShowMyNotification(ATitle, ABody: string); begin TrayIcon.BalloonTimeout := 3000; TrayIcon.BalloonTitle := ATitle; TrayIcon.BalloonHint := ABody; TrayIcon.ShowBalloonHint; end;
  13. I'm trying to use Vcl.Graphics.TWICImage on a Windows Server 2012 R2 and the following exception thrown: EInvalidGraphicOperation: Cannot create instance of class CLSID_WICImagingFactory (800401F0) Anyone knows the reason? On my development machine with Windows 10 Pro works fine. Oops, never mind, it seems that I forgot CoInitialize/CoUninitialize
  14. Well, I found the problem... I had to save to file the stream Data, not the original WicImage. Also, I had to keep the width/height as the original: uses avconst, activex, varutils, wincodec, consts; procedure ChangeTiffCompression(tiffFilename: string; tiffNewFileName: string); var Encoder: IWICBitmapEncoder; Frame: IWICBitmapFrameEncode; Props: IPropertyBag2; LStreamAdapter: IStream; PixelFormat: TGUID; LStream: IWICStream; Palette: IWICPalette; Data: TMemoryStream; ImagingFactory: IWICImagingFactory; WicImage: TWICImage; Options: TPropBag2; varValue: TPropVariant; hr: HRESULT; begin Data := TMemoryStream.Create; WicImage := TWICImage.Create; try WicImage.LoadFromFile(tiffFilename); Data.Clear; LStreamAdapter := TStreamAdapter.Create(Data); ImagingFactory := TWICImage.ImagingFactory; ImagingFactory.CreateStream(LStream); LStream.InitializeFromIStream(LStreamAdapter); ImagingFactory.CreateEncoder(WicImage.EncoderContainerFormat, guid_null, Encoder); Encoder.Initialize(LStream, WICBitmapEncoderNoCache); Encoder.CreateNewFrame(Frame, Props); FillChar(Options, SizeOf(Options), 0); Options.pstrName := POleStr('TiffCompressionMethod'); varValue.vt := VT_UI1; varValue.bVal := WICTiffCompressionCCITT3; hr := Props.Write(1, @Options, @varValue); if not SUCCEEDED(hr) then raise Exception.Create('Error Props.Write'); hr := Frame.Initialize(Props); if not SUCCEEDED(hr) then raise Exception.Create('Error Frame.Initialize'); WicImage.Handle.GetPixelFormat(PixelFormat); Frame.SetPixelFormat(PixelFormat); Frame.SetSize(WicImage.Width, WicImage.Height); ImagingFactory.CreatePalette(Palette); WicImage.Handle.CopyPalette(Palette); Frame.SetPalette(Palette); Frame.WriteSource(WicImage.Handle, nil); Frame.Commit; Encoder.Commit; Data.Position := 0; Data.SaveToFile(tiffNewFileName); finally Encoder := nil; ImagingFactory := nil; Data.Free; WicImage.Free; end; end;
  15. I advanced a little with this puzzle, but still the compression method is not changed in the new created tiff. I used this example from Windows documentation: https://docs.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder?redirectedfrom=MSDN#tiff-encoding-example Also, I used as a starting point the procedure TWICImage.SaveToStream(Stream: TStream); from unit Vcl.Graphics; The procedure bellow creates a new tiff, but the compression method is the same as the old tiff. Any idea how to do this right? uses avconst, activex, varutils, wincodec, consts; const FAX_WIDTH = 1728; FAX_HEIGHT = 2150; procedure ChangeTiffCompression(tiffFilename: string; tiffNewFileName: string); var Encoder: IWICBitmapEncoder; Frame: IWICBitmapFrameEncode; Props: IPropertyBag2; LStreamAdapter: IStream; PixelFormat: TGUID; LStream: IWICStream; Palette: IWICPalette; Data: TMemoryStream; ImagingFactory: IWICImagingFactory; WicBitmap: TWICImage; Options: TPropBag2; varValue: TPropVariant; begin Data := TMemoryStream.Create; WicBitmap := TWICImage.Create; try WicBitmap.LoadFromFile(tiffFilename); LStreamAdapter := TStreamAdapter.Create(Data); ImagingFactory := TWICImage.ImagingFactory; ImagingFactory.CreateStream(LStream); LStream.InitializeFromIStream(LStreamAdapter); ImagingFactory.CreateEncoder(GUID_ContainerFormatTiff, guid_null, Encoder); Encoder.Initialize(LStream, WICBitmapEncoderNoCache); Encoder.CreateNewFrame(Frame, Props); FillChar(Options, SizeOf(Options), 0); Options.pstrName := POleStr('TiffCompressionMethod'); varValue.vt := VT_UI1; varValue.bVal := WICTiffCompressionCCITT3; Props.Write(1, @Options, @varValue); Frame.Initialize(Props); WicBitmap.Handle.GetPixelFormat(PixelFormat); Frame.SetPixelFormat(PixelFormat); Frame.SetSize(FAX_WIDTH, FAX_HEIGHT); ImagingFactory.CreatePalette(Palette); WicBitmap.Handle.CopyPalette(Palette); Frame.SetPalette(Palette); Frame.WriteSource(WicBitmap.Handle, nil); Frame.Commit; Encoder.Commit; WicBitmap.SaveToFile(tiffNewFileName); Encoder := nil; ImagingFactory := nil; finally Data.Free; WicBitmap.Free; end; end;
×