3 webcams

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
deify
Beiträge: 141
Registriert: 29.03.2010 22:01
Computerausstattung: Win7 64bit
AMD Phenom II X4 940
NVIDIA GeForce GTS 250
4GB RAM
Kontaktdaten:

Re: 3 webcams

Beitrag von deify »

ja wie gesagt funktioniert leider nicht mit 3mal der selben! dachte mir, dass man dem pc vllt irgendwie vorgauckeln kann dass es eine andere cam ist! ansonsten muss ich eben die avicap oder ähnliches verwenden! wobei ich auch noch am rätseln bin wie ich den buffer als avi speicher! habe auch keinen plan von den callbacks, bzw ich verstehe was es ist aber nicht wie es funktioniert (:
Windows 7 | 64bit | PureBasic 4.51 (x64/x86)
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Re: 3 webcams

Beitrag von - chris - »

@NicTheQuick

Natürlich geht das, ein Thread zweimal aufgerufen:

Code: Alles auswählen


EnableExplicit

IncludeFile "escapi.pbi"

;- escapiOpen
If escapiOpen() = 0
  MessageRequester("Kamera", "DLL 'escapi.dll' nicht vorhanden!")
  End
EndIf

;- Enumerations / DataSections
;- Windows
Enumeration
  #Window_0
EndEnumeration

;- Gadgets
Enumeration
  #Image_0
  #Image_1
EndEnumeration

;- Define
Define Event.l, EventWindow.l, EventGadget.l, EventType.l, EventMenu.l

;- Global
Global quit.i, q1.i, q2.i, capture01TH.i, capture02TH.i
Global mx.i, my.i

Procedure OpenWindow_Window_0()
  Protected res.i
  res = #False
  If OpenWindow(#Window_0, 0, 0, 640, 240, "Kamera", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
    ImageGadget(#Image_0, 0, 0, 320, 240, 0)
    ImageGadget(#Image_1, 320, 0, 320, 240, 0)
    res = #True
  EndIf
  ProcedureReturn res
EndProcedure

Procedure.i gray(color.i, method.i = 0)
  Protected R.i, G.i, B.i, gray.i
  R = Red(color)
  G = Green(color)
  B = Blue(color)
  If method = 1
    gray = (R + G + B) / 3
  Else
    gray = 0.299 * R + 0.587 * G + 0.114 * B
  EndIf
  ProcedureReturn RGB(gray, gray, gray)
EndProcedure

Procedure capture(deviceno.i)

  Structure fps_struc
    fps_soll.i
    fps_delay.i
    fps_counter.i
    fps_timer.i
    fps_res.i
  EndStructure

  Protected width.l, height.l, image.i
  Protected count.l, *namebuffer.i, bufferlength.l, name$
  Protected scp.SimpleCapParams
  Protected y.i, x.i, pixel.i, rgb.i
  Protected t1.q, t2.q, time.q, *fps.fps_struc

  *fps.fps_struc = AllocateMemory(SizeOf(fps_struc))

  If *fps > 0

    width  = 320
    height = 240

    *fps\fps_soll  = 30
    *fps\fps_delay = 1000 / *fps\fps_soll

    image = CreateImage(#PB_Any, width, height, 24)
    SetGadgetState(deviceno, ImageID(image))

    initCOM()

    count = countCaptureDevices()

    Debug "count: " + Str(count)

    If count > 0

      bufferlength = 1000
      *namebuffer  = AllocateMemory(bufferlength)

      If *namebuffer > 0
        getCaptureDeviceName(deviceno, *namebuffer, bufferlength)
        name$ = PeekS(*namebuffer, -1, #PB_Ascii)
        If name$ <> ""
          Debug "name: " + name$
          If deviceno > 0
            name$ = GetWindowTitle(#Window_0) + " | " + name$
          EndIf
          SetWindowTitle(#Window_0, name$)
        EndIf
      EndIf

      scp\mWidth     = width
      scp\mHeight    = height
      scp\mTargetBuf = AllocateMemory(scp\mWidth * scp\mHeight * 4)

      Debug "memory: " + Str(scp\mWidth * scp\mHeight * 4)

      If scp\mTargetBuf > 0

        If initCapture(deviceno, @scp)

          Debug "initCapture"

          Repeat

            t1 = timeGetTime_()

            If *fps\fps_timer < t1
              *fps\fps_res     = *fps\fps_counter
              *fps\fps_timer   = t1 + 1000
              *fps\fps_counter = 0
            Else
              *fps\fps_counter + 1
            EndIf

            doCapture(deviceno)

            ;While isCaptureDone(deviceno) = 0
            ;  If quit = 1
            ;    Break
            ;  EndIf
            ;  Delay(1)
            ;Wend

            If quit = 1
              Break
            EndIf

            If StartDrawing(ImageOutput(image))

              For y = 0 To scp\mHeight - 1
                For x = 0 To scp\mWidth - 1
                  pixel = PeekL(scp\mTargetBuf + (y*scp\mWidth + x) * 4)
                  rgb   = RGB((pixel >> 16) & $FF, (pixel >> 8) & $FF, pixel & $FF)
                  ;rgb   = gray(rgb)
                  Plot(x, y, rgb)
                Next
              Next

              If mx > -1 And my > -1
                If deviceno = 0
                  Circle(mx, my, 10, RGB(255, 0, 0))
                ElseIf deviceno = 1
                  Circle(mx - 320, my, 10, RGB(255, 0, 0))
                EndIf
              EndIf

              DrawText(10, 10, "FPS: " + Str(*fps\fps_res), RGB(255, 0, 0))

              StopDrawing()

              SetGadgetState(deviceno, ImageID(image))

            EndIf

            t2 = timeGetTime_()

            time = t2 - t1

            If time < *fps\fps_delay
              Delay(*fps\fps_delay - time)
            Else
              Delay(1)
            EndIf

          Until quit = 1

          deinitCapture(deviceno)

          Debug "deinitCapture"

        EndIf

      EndIf

    EndIf

  EndIf

  If *fps > 0
    FreeMemory(*fps)
  EndIf

  If *namebuffer > 0
    FreeMemory(*namebuffer)
  EndIf

  If scp\mTargetBuf > 0
    FreeMemory(scp\mTargetBuf)
  EndIf

EndProcedure

If OpenWindow_Window_0()

  StickyWindow(#Window_0, 1)

  capture01TH = CreateThread(@capture(), 0)
  capture02TH = CreateThread(@capture(), 1)

  ;- Event loop
  Repeat

    Event       = WaitWindowEvent(100)
    EventGadget = EventGadget()
    EventType   = EventType()
    EventWindow = EventWindow()

    mx = WindowMouseX(#Window_0)
    my = WindowMouseY(#Window_0)

    Select Event

      Case #PB_Event_Gadget

        If EventGadget = #Image_0
        EndIf

      Case #PB_Event_CloseWindow

        quit = 1

    EndSelect

    q1 = IsThread(capture01TH)
    q2 = IsThread(capture02TH)

  Until quit = 1 And q1 = 0 And q2 = 0

EndIf

;- escapiClose
escapiClose()

End

PB v5.72 x86/x64
Windows 10 Pro 64bit
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Re: 3 webcams

Beitrag von - chris - »

Mit TGA_HEADER und zwei Kameras:

Code: Alles auswählen


EnableExplicit

;- ImageDecoder
UseTGAImageDecoder()

;- IncludeFile
IncludeFile "escapi.pbi"

;- escapiOpen
If escapiOpen() = 0
  MessageRequester("Kamera", "DLL 'escapi.dll' nicht vorhanden!")
  End
EndIf

;- Enumerations / DataSections
;- Windows
Enumeration
  #Window_0
EndEnumeration

;- Gadgets
Enumeration
  #Image_0
  #Image_1
EndEnumeration

;- Image
Enumeration
  #Image_Capture
EndEnumeration

;- Structure
Structure TGA_HEADER
  imageid.a
  colourmaptype.a
  imagetype.a
  colourmapstart.u
  colourmaplength.u
  colourmapbits.a
  xstart.u
  ystart.u
  width.u
  height.u
  pixeldepth.a
  descriptor.a
EndStructure

Structure fps_struc
  fps_soll.i
  fps_delay.i
  fps_counter.i
  fps_timer.i
  fps_res.i
EndStructure

;- Define
Define Event.i, EventWindow.i, EventGadget.i, EventType.i, EventMenu.i

;- Global
Global quit.i, q1.i, q2.i, capture01TH.i, capture02TH.i

Procedure OpenWindow_Window_0()
  Protected res.i
  res = #False
  If OpenWindow(#Window_0, 0, 0, 640, 240, "Kamera", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
    ImageGadget(#Image_0, 0, 0, 320, 240, 0)
    ImageGadget(#Image_1, 320, 0, 320, 240, 0)
    res = #True
  EndIf
  ProcedureReturn res
EndProcedure

Procedure capture(deviceno.i)

  Protected width.l, height.l, image.i, *pImage.i
  Protected count.l, *namebuffer.i, bufferlength.l, name$
  Protected tgaheader.TGA_HEADER, scp.SimpleCapParams
  Protected t1.q, t2.q, time.q

  Protected *fps.fps_struc

  *fps.fps_struc = AllocateMemory(SizeOf(fps_struc))

  If *fps > 0

    width  = 320
    height = 240

    *fps\fps_soll  = 30
    *fps\fps_delay = 1000 / *fps\fps_soll

    image = CreateImage(#PB_Any, width, height, 24)
    SetGadgetState(deviceno, ImageID(image))

    initCOM()

    count = countCaptureDevices()

    Debug "count: " + Str(count)

    If count > 0

      bufferlength = 1000
      *namebuffer  = AllocateMemory(bufferlength)

      If *namebuffer > 0
        getCaptureDeviceName(deviceno, *namebuffer, bufferlength)
        name$ = PeekS(*namebuffer, -1, #PB_Ascii)
        If name$ <> ""
          Debug "name: " + name$
          If deviceno > 0
            name$ = GetWindowTitle(#Window_0) + " | " + name$
          EndIf
          SetWindowTitle(#Window_0, name$)
        EndIf
      EndIf

      tgaHeader\imageid         = 0
      tgaHeader\colourmaptype   = 0
      tgaheader\imagetype       = 2
      tgaHeader\colourmapstart  = 0
      tgaHeader\colourmaplength = 0
      tgaheader\width           = width
      tgaheader\height          = height
      tgaHeader\xstart          = 0
      tgaHeader\ystart          = 0
      tgaheader\pixeldepth      = 32
      tgaheader\descriptor      = % 11110100

      *pImage = AllocateMemory(width * height * 4 + SizeOf(TGA_HEADER))

      If *pImage > 0

        CopyMemory(@tgaheader, *pImage, SizeOf(TGA_HEADER))

        scp\mWidth     = width
        scp\mHeight    = height
        scp\mTargetBuf = *pImage + SizeOf(TGA_HEADER)

        Debug "memory: " + Str(scp\mWidth * scp\mHeight * 4)

        If initCapture(deviceno, @scp)

          Debug "initCapture"

          Repeat

            t1 = timeGetTime_()

            If *fps\fps_timer < t1
              *fps\fps_res     = *fps\fps_counter
              *fps\fps_timer   = t1 + 1000
              *fps\fps_counter = 0
            Else
              *fps\fps_counter + 1
            EndIf

            doCapture(deviceno)

            ;While isCaptureDone(deviceno) = 0
            ;  If quit = 1
            ;    Break
            ;  EndIf
            ;  Delay(1)
            ;Wend

            If quit = 1
              Break
            EndIf

            If CatchImage(deviceno, *pImage)

              StartDrawing(ImageOutput(image))

              DrawImage(ImageID(deviceno), 0, 0)

              DrawText(10, 10, "FPS: " + Str(*fps\fps_res), RGB(255, 0, 0))

              StopDrawing()

              SetGadgetState(deviceno, ImageID(image))

            EndIf

            t2 = timeGetTime_()

            time = t2 - t1

            If time < *fps\fps_delay
              Delay(*fps\fps_delay - time)
            Else
              Delay(1)
            EndIf

          Until quit = 1

          deinitCapture(deviceno)

          Debug "deinitCapture"

        EndIf

      EndIf

    EndIf

  EndIf

  If *fps > 0
    FreeMemory(*fps)
  EndIf

  If *namebuffer > 0
    FreeMemory(*namebuffer)
  EndIf

  If *pImage > 0
    FreeMemory(*pImage)
  EndIf

EndProcedure

If OpenWindow_Window_0()

  StickyWindow(#Window_0, 1)

  capture01TH = CreateThread(@capture(), 0)
  capture02TH = CreateThread(@capture(), 1)

  ;- Event loop
  Repeat

    Event       = WaitWindowEvent(100)
    EventGadget = EventGadget()
    EventType   = EventType()
    EventWindow = EventWindow()

    Select Event

      Case #PB_Event_Gadget

        Select EventGadget

          Case #Image_0
            
          Case #Image_1
                        
        EndSelect

      Case #PB_Event_CloseWindow

        quit = 1

    EndSelect

    q1 = IsThread(capture01TH)
    q1 = IsThread(capture02TH)

  Until quit = 1 And q1 = 0 And q2 = 0

EndIf

;- escapiClose
escapiClose()

End

PB v5.72 x86/x64
Windows 10 Pro 64bit
Benutzeravatar
deify
Beiträge: 141
Registriert: 29.03.2010 22:01
Computerausstattung: Win7 64bit
AMD Phenom II X4 940
NVIDIA GeForce GTS 250
4GB RAM
Kontaktdaten:

Re: 3 webcams

Beitrag von deify »

danke :P an möglichkeiten zum darstellen mangelt es jetzt nichtmehr :P wie gesagt es geht eigentlich mehr um das callback um den buffer in eine avifile zu speichern! da ich ja 2 verschiedene möglichkeiten zum erstellen der bilder nehme muss dieses callback ja auch auf beide anwendbar sein! es sollen nämlich alle 3 bilder gleichzeitig aufgenommen und abgespielt werden
Windows 7 | 64bit | PureBasic 4.51 (x64/x86)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: 3 webcams

Beitrag von NicTheQuick »

- chris - hat geschrieben:@NicTheQuick

Natürlich geht das, ein Thread zweimal aufgerufen:
Ich weiß ja, dass das geht. Und so sind Worker-Threads auch gedacht. Man programmiert ihn einmal und gibt ihm nur das, was er tun soll. Ich hatte nur keine Lust, dass selbst zu machen, weil ihr da grad mehr drin seid und das ganze unter Linux wohl nicht läuft. :wink:
Bild
Benutzeravatar
deify
Beiträge: 141
Registriert: 29.03.2010 22:01
Computerausstattung: Win7 64bit
AMD Phenom II X4 940
NVIDIA GeForce GTS 250
4GB RAM
Kontaktdaten:

Re: 3 webcams

Beitrag von deify »

Hey Leute! Ein gesundes neues Jahr wünsch ich euch Allen!

Wollte nochmal auf meine Frage im "alten" Jahr zurück kommen! Aufnhemen funktioniert jetzt durch 2 verschiedene Methoden, sprich z.B. escapi.dll und avicap.dll.
Jetzt ist die Frage wie ich das bild via CallBack oder sonstigem aus dem Speicher als avi speichern kann!
Hoffe ihr könnt mir da weiter helfen! Habe zwar da bezüglich avicap schoneinmal was gefunden, doch das hat mir ohne erklärung nicht wirklich weit geholfen.


mfg deify
Windows 7 | 64bit | PureBasic 4.51 (x64/x86)
D.J.Peters
Beiträge: 87
Registriert: 28.11.2010 13:07
Computerausstattung: P4 2x3.2GKz.1GB WIXP 32Bit NVIDEA GT240 1GB DDR3, AMD XP 1.8GHz Linux 32Bit NVIDEA GT240 TIi3200
Wohnort: Germany
Kontaktdaten:

Re: 3 webcams

Beitrag von D.J.Peters »

Immer dieser alte Scheiß vom letztem Jahr :lol:

Zum Abspeichern ist die "AVIFIL32.dll" zuständig.

Wie das funktioniert siehst Du in "avi_start(Title$, Width, Height, FPS)"
dort gibst Du den Dateinamen die Videogröße sowie die Framrate an.

if avi_start("KegelCam01.avi",320,200,33)
...

Dann wird mit jedem Aufruf von avi_capture() immer nur ein Frame abgespeichert.
(bei mir waren die Pixel über den globalen Zeiger in avi_lpScreen zu finden)
Du must halt die Pixel von Deinem TGA Bild nehmen oder einen neuen Pointer von eBAY. :lol:

Ganz wichtig ist am Ende die neue AVI Datei mit avi_end() "ordentlich" zu schließen.

Anmerkung avi_capture_gl() macht im Prinzip das gleiche wie avi_capture()
nur das ich dort meine OpenGL Sachen als Video gespeichert habe.

Das kannste wenn Du lust hast z.B. hier sehen dort Rendere ich 3D Autos mit zigtausend Polygonen mit Glas und Spiegelungen
und das ganze speichere ich Frame für Frame als Video in Echtzeit.
http://www.youtube.com/watch?v=WVShauw1pHA

Den Krämpel der Lib muss Du aber selber nach PB portieren.
(wenn das noch keiner gemacht hat)

Aber so viel ist das nicht
bist ja noch ein junger Spunt. :mrgreen:

Grüsse Joshy

Code: Alles auswählen

' AVI Encoder!
' Written by D.J. Peters (Joshy)
Const AVIIF_KEYFRAME = &H10

Enum FILEFLAGS
  OF_WRITE  = &H0001
  OF_CREATE = &H1000
End Enum

Enum AVISAVEFLAGS
  ICMF_CHOOSE_KEYFRAME       = (1 Shl 0)
  ICMF_CHOOSE_DATARATE       = (1 Shl 1)
  ICMF_CHOOSE_PREVIEW        = (1 Shl 2)
  ICMF_CHOOSE_ALLCOMPRESSORS = (1 Shl 3)
End Enum

Type AVIFILEINFO
  As Uinteger dwMaxBytesPerSec
  As Uinteger dwFlags
  As Uinteger dwCaps
  As Uinteger dwStreams
  As Uinteger dwSuggestedBufferSize
  As Uinteger dwWidth
  As Uinteger dwHeight
  As Uinteger dwScale
  As Uinteger dwRate
  As Uinteger dwLength
  As Uinteger dwEditCount
  As String * 63 szFileType
End Type

Type AVISTREAMINFO
  As Uinteger fccType
  As Uinteger fccHandler
  As Uinteger dwFlags
  As Uinteger dwCaps
  As Ushort   wPriority
  As Ushort   wLanguage
  As Uinteger dwScale
  As Uinteger dwRate
  As Uinteger dwStart
  As Uinteger dwLength
  As Uinteger dwInitialFrames
  As Uinteger dwSuggestedBufferSize
  As Uinteger dwQuality
  As Uinteger dwSampleSize
  As Uinteger l,t,w,b
  As Uinteger dwEditCount
  As Uinteger dwFormatChangeCount
  As String * 63 szName
End Type

Type AVICOMPRESSOPTIONS
  As Uinteger fccType
  As Uinteger fccHandler
  As Uinteger dwKeyFrameEvery
  As Uinteger dwQuality
  As Uinteger dwBytesPerSecond
  As Uinteger dwFlags
  As Any Ptr  lpFormat
  As Uinteger cbFormat
  As Any Ptr  lpParms
  As Uinteger cbParms
  As Uinteger dwInterleaveEvery
End Type

Type PAVICOMPRESSOPTIONS As AVICOMPRESSOPTIONS Ptr

Type BITMAPINFOHEADER
  As Integer  biSize
  As Integer  biWidth
  As Integer  biHeight
  As Short    biPlanes
  As Short    biBitCount
  As Integer  biCompression
  As Integer  biSizeImage
  As Integer  biXPelsPerMeter
  As Integer  biYPelsPerMeter
  As Integer  biClrUsed
  As Integer  biClrImportant
End Type

Type AVISaveCallback As Function (Byval nPercent As Integer) As Integer
Type AVIFILE   As Any Ptr
Type AVISTREAM As Any Ptr

Declare Function String2FOURCC       Lib "winmm"    Alias "mmioStringToFOURCCA"  (Byval As String, Byval As Uinteger=0) As Uinteger
Declare Sub      AVIFileInit         Lib "avifil32" Alias "AVIFileInit"
Declare Sub      AVIFileExit         Lib "avifil32" Alias "AVIFileExit"
Declare Function AVIFileOpen         Lib "avifil32" Alias "AVIFileOpenA"         (Byval As AVIFILE Ptr, Byval strfile As String, Byval flag As FILEFLAGS, Byval lpClass As Any Ptr) As Integer
Declare Function AVIFileRelease      Lib "avifil32" Alias "AVIFileRelease"       (Byval As AVIFILE) As Integer
Declare Function AVIFileCreateStream Lib "avifil32" Alias "AVIFileCreateStreamA" (Byval As AVIFILE, Byval As AVISTREAM Ptr, Byval As AVISTREAMINFO Ptr) As Integer
Declare Function AVIStreamRelease    Lib "avifil32" Alias "AVIStreamRelease"     (Byval As AVISTREAM) As Integer
Declare Function AVIMakeCompressedStream Lib "avifil32" Alias "AVIMakeCompressedStream"(Byval As AVISTREAM Ptr, Byval As AVISTREAM , Byval As AVICOMPRESSOPTIONS Ptr, Byval lpClassHandler As Any Ptr) As Integer
Declare Function AVISaveOptions      Lib "avifil32" Alias "AVISaveOptions"       (Byval hParent  As Integer, Byval As AVISAVEFLAGS, Byval nStreams As Uinteger, Byval As AVISTREAM Ptr, Byval As PAVICOMPRESSOPTIONS Ptr) As Integer
Declare Function AVISaveOptionsFree  Lib "avifil32" Alias "AVISaveOptionsFree"   (Byval nStreams As Integer, Byval As PAVICOMPRESSOPTIONS Ptr) As Integer
Declare Function AVIStreamSetFormat  Lib "avifil32" Alias "AVIStreamSetFormat"   (Byval As AVISTREAM, Byval As Integer, Byval As Any Ptr, Byval As Integer) As Integer
Declare Function AVIStreamWrite      Lib "avifil32" Alias "AVIStreamWrite"       (Byval As AVISTREAM, Byval nPos As Integer, Byval nStream As Integer, Byval lpPixel As Any Ptr, Byval bytes As Integer, Byval flag As Integer, Byval swritten As Integer Ptr, Byval bwritten As Integer Ptr) As Integer

Dim Shared As AVIFILE             file
Dim Shared As AVISTREAM           stream
Dim Shared As AVISTREAM           encoderstream
Dim Shared As AVISTREAMINFO       streaminfo
Dim Shared As AVICOMPRESSOPTIONS  compressoptions
Dim Shared As PAVICOMPRESSOPTIONS Ptr ArrayOptions
Dim Shared As BITMAPINFOHEADER    Bitmapformat

Dim Shared As Byte Ptr avi_lpBits, avi_lpScreen
Dim Shared As Integer avi_screen_x, avi_screen_y, avi_frame_rate, avi_frame_count, avi_hWin
Dim Shared As Double avi_timer

ArrayOptions = Callocate(4)
ArrayOptions[0] = @compressoptions

Sub avi_start (file_name  As String, _
               screen_x   As Integer, _
               screen_y   As Integer, _
               frame_rate As Integer)
  Dim As Integer ff = Freefile

  avi_screen_x = screen_x
  avi_screen_y = screen_y
  avi_frame_rate = frame_rate

  Open file_name For Output As ff: Close ff
  ScreenControl fb.GET_WINDOW_HANDLE, avi_hWin
  AVIFileInit

  If AVIFileOpen(@file, file_name, OF_WRITE Or OF_CREATE,0)<>0 Then
    AVIFileExit
    ? "error: AVIFileOpen!"
    Beep: Sleep: End 1
  End If
  With streaminfo
    .fccType = String2FOURCC("vids")
    .dwScale = 1
    .dwRate = avi_frame_rate
    .dwSuggestedBufferSize = avi_screen_x * avi_screen_y * 3 ' RGB
    .l = 0: .t = 0: .w = avi_screen_x:.b = avi_screen_y
  End With
  With BitmapFormat
    .biSize = 40
    .biWidth = avi_screen_x
    .biHeight = avi_screen_y
    .biPlanes = 1
    .biBitCount = 24
    .biCompression = 0 ' raw rgb
    .biSizeImage = avi_screen_x * avi_screen_y * 3 ' rgb
    avi_lpbits = Callocate(.biSizeImage)
  End With
  If AVIFileCreateStream(file, @stream, @streaminfo) Then
    AVIFileRelease(file)
    AVIFileExit
    ? "error: AVIFileCreateStream!": Beep: Sleep: End 1
  End If
  If AVISaveOptions(avi_hWin, &H7, 1, @stream,ArrayOptions) <> 1 Then
    AVIStreamRelease(stream)
    AVIFileRelease(file) 
    AVIFileExit
    ? "error: AVISaveOptions!": Beep: Sleep: End 1
  End If
  If AVIMakeCompressedStream(@encoderstream,stream,ArrayOptions[0], 0) Then
    AVISaveOptionsFree(1, ArrayOptions)
    AVIStreamRelease(stream)
    AVIFileRelease(file)
    AVIFileExit
    ? "error: AVIMakeCompressedStream!": Beep: Sleep: End 1
  End If
  If AVIStreamSetFormat(encoderstream, 0, @BitmapFormat, 40) Then
    AVISaveOptionsFree(1, ArrayOptions)
    AVIStreamRelease(encoderstream)
    AVIStreamRelease(stream)
    AVIFileRelease(file)
    AVIFileExit
    ? "error: AVIStreamSetFormat!": Beep: Sleep: End 1
  End If
End Sub

Sub avi_capture
  Static As Integer x, y, d, s

  If avi_frame_count = 0 Then avi_timer = Timer

  avi_lpScreen = Screenptr
  ' from bottom to top
  avi_lpScreen += (avi_screen_y - 1) * (avi_screen_x * 4)
  For y=0 To avi_screen_y-1
    d = y * avi_screen_x * 3: s = 0
    For x = 0 To avi_screen_x - 1
      ' ARGB32 to RGB24
      avi_lpBits[d + 0] = avi_lpScreen[s + 0]
      avi_lpBits[d + 1] = avi_lpScreen[s + 1]
      avi_lpBits[d + 2] = avi_lpScreen[s + 2]
      d += 3: s += 4
    Next
    avi_lpScreen -= (avi_screen_x * 4)
  Next
  AVIStreamWrite(encoderstream, _
                 avi_frame_count, _
                 1, _
                 avi_lpBits, _
                 BitmapFormat.biSizeImage, 0, 0, 0)
  avi_frame_count += 1

  While avi_frame_count / (Timer - avi_timer) > avi_frame_rate: Wend 'limit FPS
End Sub

' save OpenGL framebuffer as AVI frame
Sub avi_capture_gl
  dim as ubyte tmp
  dim as ubyte ptr lpRGB
  If avi_frame_count = 0 Then avi_timer = Timer
  ' get framebuffer
  glReadPixels(0,0,avi_screen_x,avi_screen_y, _
			         GL_RGB,GL_UNSIGNED_BYTE,avi_lpBits)
  ' swap red and blue 
  lpRGB=avi_lpBits
  for i as integer=0 to avi_screen_x*avi_screen_y-1
    tmp=lpRGB[0]
    lpRGB[0]=lpRGB[2]
    lpRGB[2]=tmp
    lpRGB+=3     
  next
  ' write one AVI frame   
  AVIStreamWrite(encoderstream, avi_frame_count, 1, avi_lpBits, BitmapFormat.biSizeImage, 0, 0, 0)
  avi_frame_count += 1
  While (avi_frame_count / (Timer - avi_timer)) > avi_frame_rate
    sleep 3
  Wend 
End Sub

Sub avi_end
  ' now free saveoptions,release streams,file and dll
  AVISaveOptionsFree(1,ArrayOptions)
  AVIStreamRelease(EncoderStream)
  AVIStreamRelease(Stream)
  AVIFileRelease(File)
  AVIFileExit
End Sub
Zuletzt geändert von D.J.Peters am 06.01.2011 16:49, insgesamt 1-mal geändert.
PS. meine vielen Fehler der Rechtschreibung auf dem Forum könnt Ihr gerne ignorieren.
Benutzeravatar
deify
Beiträge: 141
Registriert: 29.03.2010 22:01
Computerausstattung: Win7 64bit
AMD Phenom II X4 940
NVIDIA GeForce GTS 250
4GB RAM
Kontaktdaten:

Re: 3 webcams

Beitrag von deify »

danke dir (: denke das sollte ich unter umständen hinbekommen :D
sofern ich es schaffe den code sinngemäß zu übersetzen :D
Windows 7 | 64bit | PureBasic 4.51 (x64/x86)
D.J.Peters
Beiträge: 87
Registriert: 28.11.2010 13:07
Computerausstattung: P4 2x3.2GKz.1GB WIXP 32Bit NVIDEA GT240 1GB DDR3, AMD XP 1.8GHz Linux 32Bit NVIDEA GT240 TIi3200
Wohnort: Germany
Kontaktdaten:

Re: 3 webcams

Beitrag von D.J.Peters »

Im grunde neige ich dazu bei Problemlösungen erst einmal eine optimische Haltung einzunehmen
doch bei Deinem Vorhaben sehe ich etwas schwarz.

Drei Videostreams als Vorschaubilder ist eine Sache
aber auch noch gleichzeitig 3 Videostreams zu kompremieren und auf Platte zu "schaufeln"
könnte in die Hose gehen.

Die Streams nicht kompremiert zu Speichern wäre schon mal erheblich schneller
ist aber keine Lösung weil oft bei 2GB schluß ist und das geht bei 3 Streams recht flot.

So eine Kegelsession geht ja vermutlich öfter recht lange.

Ein praktikabler Ansatz wäre die drei Videostreams in nur ein TGA oder besser direkt in ein BMP Bild zu Blitten
und dann nur noch den einen Stream beim Speichern kompremieren zu lassen.
Dann wäre zwar auch bei 2GB schluß mit lustig aber Du schaft mindestens eine doppelt so lange Zeit zu "Recorden".

Wenn es "nur" um eine nachträgliche Bewertung der Kegelsessions geht oder als nachträglichen Beweis herhalten soll
dann wäre auch zu üblegen die drei Videquellen garnicht oder nur einen Stream mit Vorschau zu benutzen.
Zeitlich ist es ein großer Unterschied mit und ohne Livebild auf Platte zu encodieren. (decodieren geht schneller)

Es gibt mit sicherheit auch noch viel bessere Lösungen als diesen "alten" AVI Kram.
Ich könnte mir vorstellen das man den einen Pixelstream von den drei Kameras auch in einen VLC Encoder einspeisen kann
und so z.B. ein viel schlankeres MPEG Video auf Platte zu erzeugen.
(es gibt noch weitere Formate bzw. Encoder ohne die veraltete 2GB Grenze)

Eine sehr elgante Lösung (vermutlich zu viel für einen "Anfänger") wäre es auch wenn Du die Anzahl der Keyframes
dynamisch Verwalten würdest. Gerade Kegeln wäre ein Paradebeispiel dafür.

Im Prinzip sind ja nur die Bilder von interesse wo sich Spieler oder Kugel und natürlich die Kegel bewegen.
In der restlichen Zeit siehst du ja nur eine Kegelbahn auf der sich nichts tut bzw. wo höchstens einige Pixel im Bild "flackern".

Einfach gesprochen wenn auf der Bahn nichts passiert dann brauchst Du nur alle

"N Sekunden einen Keyframe"

und wenn gepielt wird

"N Keyframes pro Sekunde"

Das ist von der Datenmenge her ein gewaltiger Unterschied.
Du muss dabei natürlich wissen das alle Bilder zwischen den Keyframes "nur" Differenzbilder sind
und auf einer Kegelbahn wo nichts passiert sind die Differezbilder (rechteckige grobe Klötze) sehr sehr klein auf Festplatte.

Also bei Deinem "AVI Vorhaben" gibt folgende Möglichkeiten.

Die Anzahl der Vorschaubilder drastisch reduzieren.
Noch besser keine oder nur eine Vorschau wärend der Aufnahme.
Alle drei Streams als einen Stream zu "encoden".

Bin mal gespannt wozu Du hin tendierst.

Jetzt sag nicht Du brauchst auch noch alle drei Audiostreams auf Platte ?

Positive Grüße

Joshy
PS. meine vielen Fehler der Rechtschreibung auf dem Forum könnt Ihr gerne ignorieren.
Benutzeravatar
deify
Beiträge: 141
Registriert: 29.03.2010 22:01
Computerausstattung: Win7 64bit
AMD Phenom II X4 940
NVIDIA GeForce GTS 250
4GB RAM
Kontaktdaten:

Re: 3 webcams

Beitrag von deify »

hey joshy
Ich denke dass es kein Problem wird die 2GB Grenze einzuhalten.
Das aufnehmen gilt nicht für die Bahn und die Kegel, lediglich für den Spieler. Dieser soll aus 3 Perspektiven aufgenommen werden, welche Kegelzahl dabei gefallen ist, ist erstmal unrelevant (so zumindest vom "Auftraggeber" gesagt). Es soll vorerst nur eine Bewegungsanalyse zur verbesserten Ausführung der Schübe werden :). Somit wird also eigentlich maximal 1 oder eben ein paar Schübe gefilmt, und nicht stundenlang auf die leere Bahn gehalten. :lol:

Was das "alte" AVI-Zeug angeht, bin ich gerne offen für andere Möglichkeiten, doch ich denke dass einige davon durchaus zu kompliziert werden könnten (siehe dein encoden aus einem Stream, wo ich nichtmal wüsste, wie ich anfangen soll :o ). Doch ich bin mir sicher dass es auch eine einfachere, bzw. praktischere Methode gibt als die, die ich gerade mache.

Hoffe du kannst mir einen Verbesserungsvorschlag geben :mrgreen:

mfg deify
Windows 7 | 64bit | PureBasic 4.51 (x64/x86)
Antworten