Ok also ich hab das nun über einen kleinen umweg zum laufen gebracht
Ich wollte nicht nocheinmal alle Strukturen einzeln durchgehen und schaun wo der fehler liegt also hab ich
mir einen kleinen Helfer wrapper in C geschrieben.
Dessen Funktionen kann ich einfach mit Pointern füttern ohne selbst die Strukturen kennen zu müssen.
Hier mal der Code der Prozedur, damit lassen sich Frames aus einem Video extrahieren und als png speichern
Code: Alles auswählen
UsePNGImageEncoder()
XIncludeFile "./header/avcodec_h.pbi"
XIncludeFile "./header/avcodec_lib_import.pbi"
PBAVC_Init() ; same as av_register_all()
Procedure GetFrames(Filename.s, SaveAs.s, startFrame.l, nbFrames.l)
Protected *pFormatCtx, *pCodecCtx, *pCodec, *pFrame, *pFrameRGB, *buffer, videoStream.l, frameFinished.l
Protected *packet, *swscalCtx, width.l, height.l, pix_fmt.l, drawing_line.l, drawing_pos.l, r.l, g.l, b.l, i.l, s.l
; Open video file
*pFormatCtx = PBAVC_OpenFile(Filename)
If Not *pFormatCtx
ProcedureReturn 0 ; Couldn't open file
EndIf
; Retrieve stream information
If Not PBAVC_GetStreamInfo(*pFormatCtx)
PBAVC_GetStreamInfo(*pFormatCtx) ; Couldn't find stream information
EndIf
; Find the first video stream
videoStream = -1
For x = 0 To PBAVC_GetStreams(*pFormatCtx) - 1
If PBAVC_GetStreamType(*pFormatCtx, x) = #AVMEDIA_TYPE_VIDEO
videoStream = x
Break
EndIf
Next
If videoStream = -1
ProcedureReturn -1 ; Didn't find a video stream
EndIf
;Get a pointer to the codec context for the video stream
*pCodecCtx = PBAVC_GetCodecContext(*pFormatCtx, videoStream)
If Not *pCodecCtx
ProcedureReturn -2 ; videoStream to large (-1) or pointer 0
EndIf
; open the codec
*pCodec = PBAVC_OpenCodec(*pCodecCtx)
If *pCodec <= 0
ProcedureReturn -3 ; Couldn't open codec
EndIf
*pFrame = PBAVC_alloc_frame() ; same as avcodec_alloc_frame()
*pFrameRGB = PBAVC_alloc_frame()
*buffer = PBAVC_malloc(PBAVC_GetPictureSize(#PIX_FMT_RGB24, *pCodecCtx))
PBAVC_PictureFill(*pFrameRGB, *buffer, #PIX_FMT_RGB24, *pCodecCtx)
frameFinished = 0
*packet = AllocateMemory(PBAVC_GetStructSize(#PBAVPacket))
*swscalCtx = 0
i = 0
s = 0
While PBAVC_ReadFrame(*pFormatCtx, *packet) >= 0
If s >= startFrame
If PBAVC_GetPacketIndex(*packet) = videoStream
PBAVC_DecodeVideo(*pCodecCtx, *pFrame, @frameFinished, *packet)
If frameFinished
width = PBAVC_GetPictureWHP(*pCodecCtx, 0)
height = PBAVC_GetPictureWHP(*pCodecCtx, 1)
pix_fmt = PBAVC_GetPictureWHP(*pCodecCtx, 2)
*swscaledFrame = PBAVC_sws_scale(width, height, pix_fmt, #PIX_FMT_RGB24, *pFrame, *pFrameRGB)
If Not *swscaledFrame
ProcedureReturn -4
EndIf
*data_= PBAVC_GetEncodedInfo(*swscaledFrame, 2)
linesize.l = PBAVC_GetEncodedInfo(*swscaledFrame, 3)
CreateImage(0, width+1, height+1)
StartDrawing(ImageOutput(0))
drawing_line = 1
drawing_pos = 1
For x = 0 To width * height * 3 Step 3
r = PeekB(*data_ + x)
g = PeekB(*data_ + x + 1)
b = PeekB(*data_ + x + 2)
If drawing_pos <= width And drawing_line <= height
Plot(drawing_pos, drawing_line, RGB(r,g,b))
EndIf
If drawing_pos = width
drawing_line + 1
drawing_pos = 0
EndIf
drawing_pos + 1
Next
StopDrawing()
SaveImage(0, SaveAs + "_"+ Str(i) +".png", #PB_ImagePlugin_PNG)
FreeImage(0)
If i >= nbFrames
Break
EndIf
i + 1
EndIf
EndIf
EndIf
PBAVC_FreePacket(*packet)
s + 1
Wend
PBAVC_AVFree(*buffer)
PBAVC_AVFree(*pFrameRGB)
PBAVC_AVFree(*pFrame)
PBAVC_CloseCodec(*pCodecCtx)
PBAVC_CloseInputFile(*pFormatCtx)
ProcedureReturn 1
EndProcedure
GetFrames("d:\test.mpg", "abc",10000, 50)
Dummer weise haben nicht alle frames auch alle Bild informationen
Ich habe mal die zip geupdatet falls es sich wer anschauen will.
http://www.communityworld.de/libavcodec_test.zip
Mfg Nero