View Full Version : DGdecode.dll
Inc
8th August 2005, 22:52
Yep I know so many times it as been asked how to get a bitmap out of dgdecode.dll. I already had a look at several sources like Aquaplanings, the "Getpic" code of Donald etc. but I wasnt able to see the right (API?)function to convert that RGB Data at the *rgb24 Pointer to a regular Bitmap for further use. BTW: Parsing out Width, Height, fps and lenght of the d2v works perfect.
Im working in PureBasic and as PBs Syntax is very easy you directly can see(understand the steps in my code).
Heres the documentated code sniplet:
; -------------------- Enumeration of Gadget Constants:
Enumeration
#Source
#Image_Window
EndEnumeration
; -------------------- The VideoInfo Structure:
Structure VideoInfo
width.l
height.l
fps_numerator.l
fps_denominator.l
num_frames.l
EndStructure
; -------------------- The Main Procedure:
Procedure d2vframe ( file$ )
OpenLibrary ( 0, "C:\Programme\AviSynth 2.5\plugins\DGDecode.dll") ; Opening the dgdcode.dll
*vi.VideoInfo = CallFunction( 0, "openMPEG2Source", file$) ;---- Filling out the VideoInfo Structure by accessing dgdecode.dll
Framecount = *vi\num_frames ; ---- Assigning the StructureVaraibles
Width = *vi\width
Height = *vi\height
Fps = *vi\fps_numerator/*vi\fps_denominator
bmi.BITMAPINFOHEADER ; ---- Assigning the BITMAPINFOHEADER Structure to bmi
bmi\biSize = SizeOf(BITMAPINFOHEADER)
bmi\biWidth = Width
bmi\biHeight = Height
bmi\biPlanes = 1
bmi\biBitCount = 32
bmi\biCompression = #BI_RGB
ImgID = CreateImage ( #PB_Any, 720, 576 ) ; ---- Creating The target Bitmap
hBmp = UseImage(ImgID) ; ---- Getting the Handle of that target Bitmap
For r = 0 To Framecount -1 ; ---- Starting the Loop
*rgb24 = CallFunction( 0, "getRGBFrame", r )
hdc = GetDC_(#Null)
hCDC = CreateCompatibleDC_(hdc)
SelectObject_( hCDC, hBmp )
SetDIBits_(hCDC, hBmp, 0, Height, *rgb24, bmi, #DIB_RGB_COLORS)
DeleteDC_(hCDC)
ReleaseDC_(#Null, hdc)
SetGadgetState(#Image_Window, hBmp) ;------Displaying the Bitmaphandle on the Imagewindow
Next r
CallFunction( 0, "closeVideo" )
CloseLibrary( 0 )
EndProcedure
As you can see the main Part are pure WinAPI_ Calls like in c++ or Delphi.
Thanks a lot in advance!
:)
neuron2
8th August 2005, 23:59
Did you have a question or are you just contributing your code?
Prodater64
9th August 2005, 00:03
Did you have a question or are you just contributing your code?
I think the question is:
What is the "right (API?)function to convert that RGB Data at the *rgb24 Pointer to a regular Bitmap for further use."
Inc
9th August 2005, 00:22
Sorry for not beeing clear, yes Prodater catched it as it was meant.
Thats what I wanna know, the correct API Calls for obtaining a regular Bitmap out of the *rgb24 pointer Data. (maybe there are also API Calls for flipping that RGB data? :) )
Inc
10th August 2005, 18:59
Noone an idea? Donald maybe?
neuron2
10th August 2005, 20:11
I don't know of an API call to do it, but the code is simple. Please refer to DGIndex's SaveBMP() function.
Inc
10th August 2005, 22:41
ok Ill have a look at it
thanks donald
Prodater64
12th August 2005, 17:16
What are dll functions to obtain framerate, framecount and fps?
Inc
12th August 2005, 17:34
Look at the VideoInfo Structure in my code right on top:Structure VideoInfo
width.l
height.l
fps_numerator.l
fps_denominator.l
num_frames.l
EndStructureThis is just a part of the common Avisynth "VideoInfo" Structure to obtain the Infos you menationed. And the same Field allocation used in Avisynths "VideoInfo" Structure is given in DGdecode.dll's output
Now I do assign the returned Data from "openMpeg2Source" (API Command of DGdecode.dll) to the Structure "Videoinfo" at the Memorypointer *vi.*vi.VideoInfo = CallFunction( 0, "openMPEG2Source", file$)
.. then you simply read out the fields from the *vi.VideoInfo Structure like: Framecount = *vi\num_frames
Width = *vi\width
Height = *vi\height
Fps = *vi\fps_numerator/*vi\fps_denominator
... all these commands shurely do exist in VB in its specific syntax.
Above it explains just the logic. But if you would have used the "search", you would have seen this:
http://forum.doom9.org/showthread.php?t=49952&highlight=dgdecode
All you need for VB - dgdecode/mpeg2dec processing.
Doom9
12th August 2005, 17:37
openMPEG2Source returns a VIDEOINFO*, from that you get what you're looking for. Note that VIDEOINFO is an AviSynth struct so you have to look in AviSynth.h for the prototype.
Inc
12th August 2005, 17:55
Back to my question, I had a look at createBitmap() in getpic.c and SafeBMP() in dgindex.c. So I understand that *rgb24 will be a mem.pointer to a "naked" flipped RGB Data. Then the right values out of mpeg2source's VideoInfo will be set into a BITMAPINFOHEADER structure included in a BITMAPINFO structure at a setted memorypointer like *Bmp.
Structure BITMAPINFOHEADER
biSize.l
biWidth.l
biHeight.l
biPlanes.l
biBitCount.l
biCompression.l
biSizeImage.l
biXPelsPerMeter.l
biYPelsPerMeter.l
biClrUsed.l
biClrImportant.l
EndStructure
Structure BITMAPINFO
bmiHeader.BITMAPINFOHEADER
bmiColors.s
EndStructure
So after that I should copy the Data from *rgb24 to the Memory of *Bmp right behind the BITMAPINFO Data, like ...
CopyMemory(*rgb24, *bmp + SizeOf(BITMAPINFO), Width*Height*3)
The Result would be a standard compilant RGB (flipped) Image at the Memorypointer *Bmp ? right?
It would be the same compatible RGB data if I would just load a xxxx.bmp file to such a Memorypointer?
Prodater64
12th August 2005, 18:12
Thanks.
mpucoder
12th August 2005, 18:23
Or use GetDIBits or SetDIBits, these will remap color space as needed.
Inc
13th August 2005, 05:10
I got it working.
2 Mistakes where the guilties:
- I assignet to SetDIBits a BITMAPINFOHEADER only instead of the complete BITMAPINFO
- and ... very strange, I had to call the getRGBFrame() routine via CallCFunction(...). Otherwise nothing works.
Here's the working code:
Enumeration
#SourceButton
#StopButton
#ImageWindow
#Info_Frame
#Width_Info
#Height_Info
#Frames_Info
#Fps_Info
EndEnumeration
Global FontID1, VideoWindow, ImgID
FontID1 = LoadFont(1, "Courier New", 10);, #PB_Font_Bold)
Procedure Open_Window(WinId)
If OpenWindow(WinId, 224, 9, 910, 505, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "d2v Playback")
If CreateGadgetList(WindowID())
SourceButton = ButtonGadget(#SourceButton, 10, 10, 160, 20, "Load d2v Source")
StopButton = ButtonGadget(#StopButton, 10, 40, 160, 20, "Stop")
VideoWindow = ImageGadget(#ImageWindow , 180, 10, 720, 480, 0);, #PB_Image_Border); The Image Display Window, #PB_Image_Border
Frame3DGadget(#Info_Frame, 10, 80, 160, 120, " d2v Info ")
TextGadget(#Width_Info, 25, 105, 120, 15, "Width :"): SetGadgetFont(#Width_Info, FontID1)
TextGadget(#Height_Info, 25, 125, 120, 15, "Height :"): SetGadgetFont(#Height_Info, FontID1)
TextGadget(#Fps_Info, 25, 145, 120, 15, "Fps :"): SetGadgetFont(#Fps_Info, FontID1)
TextGadget(#Frames_Info, 25, 165, 120, 15, "Frames :"): SetGadgetFont(#Frames_Info, FontID1)
ProcedureReturn WindowID()
EndIf
EndIf
EndProcedure
Procedure d2vframe ( file.s )
Structure myBITMAPINFO
bmiHeader.BITMAPINFOHEADER
bmiColors.RGBQUAD[1]
EndStructure
Structure VideoInfo ; Part of the common Avisynth.h VideoInfo structure
width.l
height.l
fps_numerator.l
fps_denominator.l
num_frames.l
EndStructure
Global frames, width, height, fps.f
Protected bmi.myBITMAPINFO ; Assigning the BITMAPINFO Structure to bmi
Protected width.l, height.l, hBmp.l, hdc.l, *vi.VideoInfo, *rgb24
OpenLibrary ( 0 , "DGDecode.dll") ; C:\Programme\AviSynth 2.5\plugins\
*vi.VideoInfo = CallCFunction( 0, "openMPEG2Source", file.s)
frames = *vi\num_frames
width = *vi\width
height = *vi\height
fps.f = (*vi\fps_numerator)/(*vi\fps_denominator)
SetGadgetText(#Width_Info, "Width : "+Str(width))
SetGadgetText(#Height_Info, "Height : "+Str(height))
SetGadgetText(#Frames_Info, "Fps : "+StrF(fps.f,3))
SetGadgetText(#Fps_Info, "Frames : "+Str(frames))
ImgID = CreateImage ( #PB_Any, width, height )
hBmp = UseImage(ImgID)
; Setting the BITMAPINFOHEADER using values obtained from openMPEG2Source()
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = width
bmi\bmiHeader\biHeight = -height ; EASY flipping of the image
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 24 ; -> RGB24 = getRGBFrame()'s native outputcolorspace!
bmi\bmiHeader\biCompression = #BI_RGB
resized = 0
For r = 0 To frames -1 ; Starting the playback loop
tempstart.f= ElapsedMilliseconds() ; get systemclock counter
*rgb24 = CallCFunction( 0, "getRGBFrame", r )
hdc = StartDrawing( ImageOutput() )
SetDIBits_(hdc, hBmp, 0, height, *rgb24, bmi, #DIB_RGB_COLORS)
StopDrawing()
SetGadgetState(#ImageWindow, hBmp) ; Displaying the framecontent on the imagewindow
If resized = 0 : ResizeWindow(width+195, height+30):resized=1:EndIf
Repeat ; Timer using systemclock keeps correct fps playback speed.
Delay(1) ; Avoiding 100% CPU load
pass.f = ElapsedMilliseconds()
Until pass-tempstart > (1000/fps)-0.00001 ; 39.99999 ; 40ms = 25 FPS PAL
If WindowEvent() = #PB_EventGadget And EventGadgetID() = #StopButton
Break
EndIf
Next r
CallCFunction( 0, "closeVideo" )
CloseLibrary( 0 )
EndProcedure
; -------------------------------- The Appl. Window Event Loop --------------------------------
quit=0
If Open_Window(0)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
quit=1
Case #PB_EventGadget
Select EventGadgetID()
Case #SourceButton
d2vfile.s = OpenFileRequester ( "Select d2v File", "", "d2v File|*.d2v", 0 )
If d2vfile
d2vframe( d2vfile ) ; Jump to the Procedure "d2vframe()" in the code above
EndIf
EndSelect
EndSelect
Until quit =1
CloseWindow(0)
EndIf
End
Thank you all for your assistance. :)
Prodater64
13th August 2005, 05:45
@Incredible: Why do you work over dgdecode.dll, if working over avisynth.dll you can obtain (maybe I wrong) the same but from any kind of video source?
neuron2
13th August 2005, 05:48
I had to call the getRGBFrame() routine via CallCFunction(...). Otherwise nothing works. You can use the getRGBFrame_SC() wrapper instead if you have a recent enough version of DGDecode.
Inc
13th August 2005, 12:22
yes, I catched that info about your implementation of that _SC Wrapper in the VB Thread. But Purebasic can access in regular all dll's without wrapper so I thought that's not the reason. Well now it works :) btw. Im working with dgmpgdec140.
@ Prodater
2 ways via avisynth.dll are possible:
- feeding the API commands AviFileXXXX() using a pre-builded avs script.
- directly accessing the Avisynth dll but thats a harder work as first I would have to convert the avisynth.h Headerfile for a proper usage of the dll if not working in c++.
And .... over all: I wanted to crack that nut by try and error.
Also I catched that thread about the Avisynth C interface wrapper by T.Barry but even if I know the commands, I would have to know how a simple api routine would have to be build for getting frames out of for example a simple avisource or mpeg2source (via invoke?).
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.