probleme beim einbinden von libavcodec : gelöst per umweg

Für allgemeine Fragen zur Programmierung mit PureBasic.
Nero
Beiträge: 285
Registriert: 08.11.2004 01:50

probleme beim einbinden von libavcodec : gelöst per umweg

Beitrag von Nero »

Hiho,

Die tage hatte ich mal wieder lust irgendwas zu machen und hab mich einfach mal an der einbindung der libavcodec.dll vom ffmpeg probiert.
Allerdings die informationen die man dazu findet sind grösten teils sehr veraltet.
Ich habe dann dieses tutorial gefunden http://www.inb.uni-luebeck.de/~boehme/u ... codec.html und wollte es in pb
umsetzen.
Zuerst habe ich angefangen die die AVFormatContext struktur und deren sub strukturen nach pb zu übersetzen aber scheinbar hab ich
wohl ein paar fehler gemach den schon beim ausführen des 3 befehls des Tutorials bekomme ich eine "Invalid memory access" error >_<

Da die Includefiles mit den structuren und den Lib imports zu lang fürs Forum sind hab ich mal alles in ein zip gepackt und hoch geladen
da sind auch die nötigen dlls bei. (Die funktionen im import file sind noch alle ohne parameter bis auf die beiden die ich bisher brauchte.)

Hier mal mein source: http://www.communityworld.de/libavcodec_test.zip

Ansonsten meine Quellen für das ganze bisher sind folgende.
Aus dem Englischen forum: http://www.purebasic.fr/english/viewtop ... libavcodec : leider zu alt deren Strukturen stimmen nicht mehr
ffmpeg doc: http://ffmpeg.org/doxygen/trunk/index.html
die dlls & libs aus der shared & dev von hier: http://ffmpeg.zeranoe.com/builds/
das tutorial : http://www.inb.uni-luebeck.de/~boehme/u ... codec.html

Vieleicht kann mir von euch jemand weiterhelfen was ich bei den Strukturen falsch gemacht habe.

Mfg Nero
Zuletzt geändert von Nero am 19.09.2011 15:41, insgesamt 1-mal geändert.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: probleme beim einbinden von libavcodec

Beitrag von edel »

av_open_input_file will einen Zeiger auf einen Zeiger.

Versuch es mal so

Code: Alles auswählen

av_open_input_file(@*pFormatCtx, Filename)
Und benutze ImportC statt Import.
Nero
Beiträge: 285
Registriert: 08.11.2004 01:50

Re: probleme beim einbinden von libavcodec

Beitrag von Nero »

Ah danke so funktioniert es :allright: danke

Mfg Nero
Nero
Beiträge: 285
Registriert: 08.11.2004 01:50

Re: probleme beim einbinden von libavcodec

Beitrag von Nero »

Hm ok das funktioniert zwar soweit doch scheint das irgendwo in ner Struktur nen fehler ist

Code: Alles auswählen

Debug *pFormatCtx\streams[0]\codec\codec_type
Debug *pFormatCtx\streams[1]\codec\codec_type
Wenn ich als Video nen mp4 nehm crashts beim *pFormatCtx\streams[1] nehm ich nen avi schon bei *pFormatCtx\streams[0]
Irgendwie stimmt da was so garnicht :lol:
Nero
Beiträge: 285
Registriert: 08.11.2004 01:50

Re: probleme beim einbinden von libavcodec : gelöst per umwe

Beitrag von Nero »

Ok also ich hab das nun über einen kleinen umweg zum laufen gebracht :lol:

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 :lol:

Ich habe mal die zip geupdatet falls es sich wer anschauen will.
http://www.communityworld.de/libavcodec_test.zip

Mfg Nero
Antworten