AVBin Example code..
Posted: Sat Nov 22, 2008 11:59 pm
Hi Paul,Paul wrote:ok, I've looked a little more into it so I have this now...
I think I am not yet understanding how to use avbin_read since it returns -1 (error). What do you have for this so far?Code: Select all
Enumeration #AVBIN_RESULT_ERROR =-1 #AVBIN_RESULT_OK = 0 EndEnumeration Enumeration #AVBIN_STREAM_TYPE_UNKNOWN = 0 #AVBIN_STREAM_TYPE_VIDEO = 1 #AVBIN_STREAM_TYPE_AUDIO = 2 EndEnumeration Enumeration #AVBIN_SAMPLE_FORMAT_U8 = 0 #AVBIN_SAMPLE_FORMAT_S16 = 1 #AVBIN_SAMPLE_FORMAT_S24 = 2 #AVBIN_SAMPLE_FORMAT_S32 = 3 #AVBIN_SAMPLE_FORMAT_FLOAT = 4 EndEnumeration Enumeration #AVBIN_LOG_QUIET =-8 #AVBIN_LOG_PANIC = 0 #AVBIN_LOG_FATAL = 8 #AVBIN_LOG_ERROR = 16 #AVBIN_LOG_WARNING = 24 #AVBIN_LOG_INFO = 32 #AVBIN_LOG_VERBOSE = 40 #AVBIN_LOG_DEBUG = 48 EndEnumeration Structure AVbinFileInfo structure_size.l n_streams.l start_time.q duration.q title.s{512} author.s{512} copyright.s{512} comment.s{512} album.s{512} year.l track.l genre.s{32} EndStructure Structure AVbinStreamInfo structure_size.l type.l StructureUnion width.l sample_format.l EndStructureUnion StructureUnion height.l sample_rate.l EndStructureUnion StructureUnion sample_aspect_num.l sample_bits.l EndStructureUnion StructureUnion sample_aspect_den.l channels.l EndStructureUnion EndStructure Structure AVbinPacket structure_size.l timestamp.q stream_index.l *data.q size.l EndStructure #MicroSecond=1000000 Prototype.l Proto_avbin_init() Prototype.l Proto_avbin_open_filename(filename.s) Prototype Proto_avbin_close_file(avFile.l) Prototype.l Proto_avbin_file_info(avFile.l,fiStructure.l) Prototype.l Proto_avbin_stream_info(avFile.l,avStream.l,siStructure.l) Prototype.l Proto_avbin_open_stream(avFile.l,avStream.l) Prototype.l Proto_avbin_close_stream(avStream.l) Prototype.l Proto_avbin_read(avFile.l,pStructure.l) hLib=OpenLibrary(#PB_Any,"avbin.dll") If hLib avbin_init.Proto_avbin_init=GetFunction(hLib,"avbin_init") avbin_open_filename.Proto_avbin_open_filename=GetFunction(hLib,"avbin_open_filename") avbin_close_file.Proto_avbin_close_file=GetFunction(hLib,"avbin_close_file") avbin_file_info.Proto_avbin_file_info=GetFunction(hLib,"avbin_file_info") avbin_stream_info.Proto_avbin_stream_info=GetFunction(hLib,"avbin_stream_info") avbin_open_stream.Proto_avbin_open_stream=GetFunction(hLib,"avbin_open_stream") avbin_close_stream.Proto_avbin_close_stream=GetFunction(hLib,"avbin_close_stream") avbin_read.Proto_avbin_read=GetFunction(hLib,"avbin_read") ;file$=GetCurrentDirectory()+"days.mp3" ;file$=GetCurrentDirectory()+"test.mpg" file$=GetCurrentDirectory()+"flake.mpg" avbin_init() avFile=avbin_open_filename(file$) finfo.AVbinFileInfo\structure_size=SizeOf(AVbinFileInfo) avbin_file_info(avFile,finfo) ;{ streams=finfo\n_streams Debug streams Debug finfo\start_time dur=AddDate(Date(2000,1,1,0,0,0),#PB_Date_Second,finfo\duration / #MicroSecond) Debug FormatDate("%ii:%ss",dur) Debug "----------" Debug finfo\title Debug finfo\author Debug finfo\copyright Debug finfo\comment Debug finfo\album Debug finfo\year Debug finfo\track Debug finfo\genre Debug "----------" ;} For idx=0 To streams-1 sinfo.AVbinStreamInfo\structure_size=SizeOf(AVbinStreamInfo) avbin_stream_info(avFile,idx,sinfo) Select sinfo\type Case #AVBIN_STREAM_TYPE_VIDEO aspect.f=sinfo\sample_aspect_num/sinfo\sample_aspect_den Debug aspect Debug sinfo\width Debug sinfo\height Case #AVBIN_STREAM_TYPE_AUDIO Debug sinfo\sample_format Debug sinfo\sample_rate Debug sinfo\sample_bits Debug sinfo\channels EndSelect Debug "----------" Next hStream=avbin_open_stream(avFile,StreamIndex) pinfo.AVbinPacket\structure_size=SizeOf(AVbinPacket) pinfo\timestamp=0 pinfo\stream_index=hStream Debug avbin_read(avFile,pinfo) avbin_close_stream(hStream) avbin_close_file(avFile) CloseLibrary(hLib) EndIf End
Also I am not getting meta data from the files so there is most likely a mistake there also
It's better to share all our knowledge in stead of PM's..
Here's my current example code, NO audio, i have
problems with audio packets and it has a very poor
simplistic cpu eating video display method at this
moment, sowwy..
Get the library here:
http://avbin.googlecode.com/files/avbin-win32-5.zip
I left out debugging the title, author, etc data in this example.
Code: Select all
; AVBin For PureBasic (attempt)
; -------------------
; v 181108 decoding frames from video streams
; v 181108 Display video frames in 24 bit RGB format
; v 211108 Simple video timing
; - 211108 Audio testing, having real problems here
; structures
Structure _AVbinFileInfo
size_t.l
n_streams.l
starttime.q
duration.q
title.c[512]
author.c[512]
copyright.c[512]
comment.c[512]
album.c[512]
year.l
track.l
genre.c[32]
EndStructure
Structure _AVbinStreamInfo
structuresize.l ; size
AVBinStreamType.l ; 0 (unknown),1 (video) of 2 (audio)
; BELOW SHOULD BE STRUCTUREUNION FOR AUDIO AND VIDEO
; --------------------------------------------------
width.l ; or avbinsampleformat
height.l ; or samplerate
sample_aspect_num.l ; or sample_bits
sample_aspect_den.l ; or channels
EndStructure
Structure _AVbinPacket
structure_size.q ; why quad?
timestamp.q ; timestamp uint64_t
streamindex.l ; int
*dat.l ; long
size.q ; why quad?
EndStructure
; test
Structure _AVbinFile
*context ;AVFormatContext *context;
*packet ;AVPacket *packet;
EndStructure
Structure _AVBinStream
type.l ;int type;
*format_context ;AVFormatContext *format_context;
*codec_context ;AVCodecContext *codec_context;
*frame ;AVFrame *frame;
EndStructure
; procedures
Procedure ReverseMemoryB(*memory.Byte,length.l)
Protected *memend.Byte
If length>SizeOf(Byte)
*memend=(*memory+length)-SizeOf(Byte)
length>>1
While length>0
Swap *memory\b,*memend\b
*memory+SizeOf(Byte)
*memend-SizeOf(Byte)
length-SizeOf(Byte)
Wend
EndIf
EndProcedure
Procedure ImageFlipH(img_id) ; Flip an image on it's Horizontal axis
msImageFlipH=ElapsedMilliseconds()
result = #False
If IsImage(img_id)
hOldImage.l = ImageID(img_id)
img_w = ImageWidth(img_id)
img_h = ImageHeight(img_id)
Dim Points.Point(2)
Points(0)\x = img_w
Points(0)\y = 0
Points(1)\x = 0
Points(1)\y = 0
Points(2)\x = img_w
Points(2)\y = img_h
main_dc = GetDC_(WindowID(0))
source_dc = CreateCompatibleDC_(main_dc)
SelectObject_(source_dc,hOldImage)
dest_dc = main_dc
SelectObject_(dest_dc,hNewImage)
result = PlgBlt_(dest_dc,@Points(), source_dc, 0, 0, img_w, img_h, 0, 0, 0)
DeleteDC_(source_dc)
DeleteDC_(dest_dc)
EndIf
ProcedureReturn result
EndProcedure
; test video file, please adjust to your needs...
; ---------------------------------------------------
testfile.s = "F:\bb.20080116.asf"
; window
OpenWindow(0,0,0,10,10 ,"AVBIN - (FFMPEG) Libavcodec/Libavformat WRAPPER",#WS_SYSMENU|1)
; open avbin and video file
If OpenLibrary(0, "avbin.dll") And (FileSize(testfile.s)>0)
; get all needed functions
*avbin_init = GetFunction(0, "avbin_init")
*avbin_open_filename = GetFunction(0, "avbin_open_filename")
*avbin_file_info = GetFunction(0, "avbin_file_info")
*avbin_stream_info = GetFunction(0, "avbin_stream_info")
*avbin_open_stream = GetFunction(0, "avbin_open_stream")
*avbin_read = GetFunction(0, "avbin_read")
*avbin_decode_audio = GetFunction(0, "avbin_decode_audio")
*avbin_decode_video = GetFunction(0, "avbin_decode_video")
*avbin_close_stream = GetFunction(0, "avbin_close_stream")
*avbin_close_file = GetFunction(0, "avbin_close_file")
; check if everything is ok..
If *avbin_init And *avbin_open_filename And *avbin_file_info And *avbin_stream_info And *avbin_open_stream
If *avbin_read And *avbin_decode_audio And *avbin_decode_video
If *avbin_close_stream And *avbin_close_file
; init avbin
*avbinresult = CallFunctionFast(*avbin_init)
; avbin open file and info
*avbinfile._AVBinFile = CallFunctionFast(*avbin_open_filename, testfile.s)
*AVBinFileInfo._AVbinFileInfo = AllocateMemory(SizeOf(_AVbinFileInfo))
*AVBinFileInfo\size_t = SizeOf(_AVbinFileInfo)
CallFunctionFast(*avbin_file_info, *AVBinFile, *AVBinFileInfo)
; checkout if stream(s) available
If *AVBinFileInfo\n_streams>0
; check starttime, duration and totaltime..
st.d = *AVBinFileInfo\starttime
dr.d = *AVBinFileInfo\duration
tot.d = st+dr
st.d = 0
tk.d = GetTickCount_()
; allocate memory avbin structures
If *AVBinPacket._AVBinPacket = 0
*AVBinPacket._AVBinPacket = AllocateMemory(SizeOf(_AVbinPacket))
*AVBinPacket\structure_size = SizeOf(_AVbinPacket)
EndIf
If *AVBinStreamInfo._AVBinStreamInfo = 0
*AVBinStreamInfo._AVBinStreamInfo = AllocateMemory(SizeOf(_AVbinStreamInfo))
*AVBinStreamInfo\structuresize = SizeOf(_AVbinStreamInfo)
EndIf
; examine available streams
For a = 0 To *AVBinFileInfo\n_streams-1
; get stream info
CallFunctionFast(*avbin_stream_info, *AVBinFile, a, *AVBinStreamInfo)
; video stream
If *AVBinStreamInfo\AVBinStreamType = 1
If IsImage(0)=0
CreateImage(0,*AVBinStreamInfo\width,*AVBinStreamInfo\height, 32)
ResizeWindow(0, WindowX(0)-(*AVBinStreamInfo\width/2), WindowY(0)-(*AVBinStreamInfo\height/2), *AVBinStreamInfo\width, *AVBinStreamInfo\height)
*image = AllocateMemory((*AVBinStreamInfo\width * *AVBinStreamInfo\height) * 3)
EndIf
If *AVBinStream._AVBinStream = 0
*AVbinStream._AVBinStream = CallFunctionFast(*avbin_open_stream, *avbinfile, a)
video = a
EndIf
EndIf
; audio stream
If *AVBinStreamInfo\AVBinStreamType = 2
If *AVBinStream1._AVBinStream = 0
*AVbinStream1._AVBinStream = CallFunctionFast(*avbin_open_stream, *avbinfile, a)
audio=a
If *audio = 0
*audio = AllocateMemory(CallFunction(0, "avbin_get_audio_buffer_size"))
*size = AllocateMemory(4)
EndIf
EndIf
EndIf
Next
; program loop..
; --------------
While st<tot And wevent<>#PB_Event_CloseWindow
; windowevents
wevent=WindowEvent()
; it might be showtime
If st.d >= ts.d And wevent<>#PB_Event_CloseWindow
; read a packet
CallFunctionFast(*avbin_read, *avbinfile, *AVBinPacket)
; video packet
If *avbinpacket\size And *avbinpacket\streamindex=video
ts.d = *AVBinPacket\timestamp
bytesused.l = CallFunctionFast(*avbin_decode_video, *AVbinStream, *AVBinPacket\dat, *avbinpacket\size, *image)
If bytesused
If st.d = 0
st.d = *AVBinPacket\timestamp+10
EndIf
; reverse memory, needed to correct image but VERY SLOW!!!!!!! comment to disable
ReverseMemoryB(*image, (*AVBinStreamInfo\width * *AVBinStreamInfo\height) * 3)
IW = *AVBinStreamInfo\width
IH = *AVBinStreamInfo\height
bmi.BITMAPINFO
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = IW
bmi\bmiHeader\biHeight = IH
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 24
bmi\bmiHeader\biCompression = #BI_RGB
hdc = StartDrawing(ImageOutput(0))
SetDIBits_(hdc,ImageID(0),0,IH,*image,bmi,#DIB_RGB_COLORS)
StopDrawing()
; flip image and blit (draw to window)
ImageFlipH(0)
EndIf
EndIf
; audio packet
If *avbinpacket\size And *avbinpacket\streamindex=audio
;bytesused1.l = CallFunction(0, "avcodec_decode_audio2", *AVBinStream1\codec_context, *AVBinPacket\dat, Str(*AVBinPacket\size), *audio, *size)
;bytesused1.l = CallFunctionFast(*avbin_decode_audio, *AVBinStream1, *AVBinPacket\dat, *avbinpacket\size, *audio, *size)
;Debug bytesused1
;If bytesused1
; If st.d = 0
; st.d = *AVBinPacket\timestamp+10
; EndIf
; Debug bytesused1
;EndIf
EndIf
EndIf
; delay
Delay(1)
; timing..
tk1.d =GetTickCount_()
If tk1.d-tk.d>=102.4
If st.d>0
st.d + (tk1.d-tk.d)*1024
EndIf
tk.d=tk1.d
EndIf
Wend
; free
If *AVBinStreamInfo
FreeMemory(*AVBinStreamInfo)
EndIf
If *AVBinPacket
FreeMemory(*AVBinPacket)
EndIf
If IsImage(0)>0
FreeImage(0)
FreeMemory(*image)
CloseWindow(0)
EndIf
If *avbinstream
CallFunctionFast(*avbin_close_stream, *avbinstream)
EndIf
If *AVBinStream1
CallFunctionFast(*avbin_close_stream, *avbinstream1)
EndIf
EndIf
CallFunctionFast(*avbin_close_file, *avbinfile)
Else
Debug "AVBIN: Closing functions fail.."
EndIf
Else
Debug "AVBIN: Decode and reading functions fail.."
EndIf
Else
Debug "AVBIN: Init and opening functions fail.."
EndIf
CloseLibrary(0)
EndIf
End