Skip to content

Commit

Permalink
webcam
Browse files Browse the repository at this point in the history
  • Loading branch information
sechshelme committed Aug 5, 2023
1 parent 639b137 commit 8ebb670
Show file tree
Hide file tree
Showing 12 changed files with 5,634 additions and 49 deletions.
1,293 changes: 1,293 additions & 0 deletions Webcam/Webcam-SDL2-master/Lazarus/C-Header/ext.tmp

Large diffs are not rendered by default.

Empty file.
1,600 changes: 1,600 additions & 0 deletions Webcam/Webcam-SDL2-master/Lazarus/C-Header/ext3.tmp

Large diffs are not rendered by default.

2,441 changes: 2,441 additions & 0 deletions Webcam/Webcam-SDL2-master/Lazarus/C-Header/videodev2.h

Large diffs are not rendered by default.

34 changes: 30 additions & 4 deletions Webcam/Webcam-SDL2-master/Lazarus/project1.lpr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
program project1;

uses
BaseUnix,
unixtype,
SDL2,
ctypes,
v4l2_driver;
Expand All @@ -25,12 +27,15 @@ TStreamHandle = record
video_fildes: longint;
sH: TStreamHandle;

var
sdlTexture: PSDL_Texture;
sdlRenderer: PSDL_Renderer;
sdlRect: TSDL_Rect;
sdlScreen: PSDL_Window;
quit: boolean = False;
fds: TFDSet;

tv: TTimeVal = (tv_sec: 1; tv_usec: 0);
buf:Tv4l2_buffer;

procedure frame_handler(pframe: Pointer; len: cint);
begin
Expand Down Expand Up @@ -92,12 +97,33 @@ TStreamHandle = record
Write('Kann Renderer nicht öffnen');
end;

sdlTexture:= SDL_CreateTexture( sdlRenderer,SDL_PIXELFORMAT_YUY2, SDL_TEXTUREACCESS_STREAMING,640,480);
sdlTexture := SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_YUY2, SDL_TEXTUREACCESS_STREAMING, 640, 480);

sdlRect.w := 640;
sdlRect.h := 480;

// #define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
// #define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer)
// #define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)

sdlRect.w:=640;
sdlRect.h:=480;

repeat
fpFD_ZERO(fds);
fpFD_SET(video_fildes, fds);

fpSelect(video_fildes + 1, @fds, nil, nil, @tv);

buf._type:=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory:=V4L2_MEMORY_MMAP;
FpIOCtl(video_fildes, VIDIOC_DQBUF, @buf);

buf._type:=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory:=V4L2_MEMORY_MMAP;
FpIOCtl(video_fildes, VIDIOC_QBUF, @buf);

//////////////77


until quit;


Expand Down
93 changes: 88 additions & 5 deletions Webcam/Webcam-SDL2-master/Lazarus/v4l2_driver.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

interface

{$L v4l2_driver.o}
{$LinkLib c}
uses
BaseUnix;

{$IFDEF FPC}
{$PACKRECORDS C}
{$ENDIF}
{$L v4l2_driver.o}
{$LinkLib c}

{$IFDEF FPC}
{$PACKRECORDS C}
{$ENDIF}

const
BUF_NUM = 4;
Expand All @@ -16,6 +19,86 @@ interface
IMAGE_WIDTH: longint; cvar;external;
IMAGE_HEIGHT: longint; cvar;external;

// ---- von /usr/include/linux/videodev2.h

const
V4L2_BUF_TYPE_VIDEO_CAPTURE = 1;
V4L2_BUF_TYPE_VIDEO_OUTPUT = 2;
V4L2_BUF_TYPE_VIDEO_OVERLAY = 3;
V4L2_BUF_TYPE_VBI_CAPTURE = 4;
V4L2_BUF_TYPE_VBI_OUTPUT = 5;
V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6;
V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7;
V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8;
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9;
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10;
V4L2_BUF_TYPE_SDR_CAPTURE = 11;
V4L2_BUF_TYPE_SDR_OUTPUT = 12;
V4L2_BUF_TYPE_META_CAPTURE = 13;
V4L2_BUF_TYPE_META_OUTPUT = 14;
//* Deprecated; do not use */
V4L2_BUF_TYPE_PRIVATE = $80;

const
V4L2_MEMORY_MMAP = 1;
V4L2_MEMORY_USERPTR = 2;
V4L2_MEMORY_OVERLAY = 3;
V4L2_MEMORY_DMABUF = 4;

type
Pv4l2_plane = ^Tv4l2_plane;

Tv4l2_plane = record
bytesused: uint32;
length: uint32;
m: record
mem_offset: uint32;
userptr: culong;
fd: uint32;
end;
data_offset: uint32;
reserved: array [0..10] of uint32;
end;

Tv4l2_timecode = record
_type: uint32;
flags: uint32;
frames: uint8;
seconds: uint8;
minutes: uint8;
hours: uint8;
userbits: array[0..3] of uint8;
end;

Tv4l2_buffer = record
index: uint32;
_type: uint32;
bytesused: uint32;
flags: uint32;
field: uint32;
timestamp: TTimeVal;
timecode: Tv4l2_timecode;
sequence: uint32;

// memory location
memory: uint32;
m: record
offset: uint32;
userptr: culong;
planes: pv4l2_plane;
fd: int32;
end;
length: uint32;
reserved2: uint32;
u: record
request_fd: int32;
reserved: uint32;
end;
end;

// -------------------------------------------


type
Pv4l2_ubuffer = ^Tv4l2_ubuffer;

Expand Down
164 changes: 164 additions & 0 deletions Webcam/Webcam-SDL2-master/src/main (Kopie).c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include "v4l2_driver.h"
#include <SDL2/SDL.h>
#include <linux/videodev2.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>

#define SAVE_EVERY_FRAME 0

pthread_t thread_stream;
SDL_Window *sdlScreen;
SDL_Renderer *sdlRenderer;
SDL_Texture *sdlTexture;
SDL_Rect sdlRect;


struct streamHandler {
int fd;
void (*framehandler)(void *pframe, int length);
};

static void frame_handler(void *pframe, int length) {
SDL_UpdateTexture(sdlTexture, &sdlRect, pframe, IMAGE_WIDTH * 2);
// SDL_UpdateYUVTexture
SDL_RenderClear(sdlRenderer);
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent(sdlRenderer);

}

static void *v4l2_streaming(void *arg) {
// SDL2 begins
memset(&sdlRect, 0, sizeof(sdlRect));
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return NULL;
}

sdlScreen = SDL_CreateWindow("Simple YUV Window", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, IMAGE_WIDTH,
IMAGE_HEIGHT, SDL_WINDOW_SHOWN);

if (!sdlScreen) {
fprintf(stderr, "SDL: could not create window - exiting:%s\n",
SDL_GetError());
return NULL;
}

sdlRenderer = SDL_CreateRenderer(
sdlScreen, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (sdlRenderer == NULL) {
fprintf(stderr, "SDL_CreateRenderer Error\n");
return NULL;
}
sdlTexture =
SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_YUY2,
SDL_TEXTUREACCESS_STREAMING, IMAGE_WIDTH, IMAGE_HEIGHT);
sdlRect.w = IMAGE_WIDTH;
sdlRect.h = IMAGE_HEIGHT;

int fd = ((struct streamHandler *)(arg))->fd;

void (*handlerXXX)(void *pframe, int length) = ((struct streamHandler *)(arg))->framehandler;

fd_set fds;
struct v4l2_buffer buf;

while (1) {
int ret;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {.tv_sec = 1, .tv_usec = 0};
ret = select(fd + 1, &fds, NULL, NULL, &tv);

if (FD_ISSET(fd, &fds)) {
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_DQBUF, &buf);

(*handlerXXX)(v4l2_ubuffers[buf.index].start, v4l2_ubuffers[buf.index].length);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ioctl(fd, VIDIOC_QBUF, &buf);
}
}
return NULL;
}

int main(int argc, char const *argv[]) {
const char *device = "/dev/video0";

int video_fildes = v4l2_open(device);
if (video_fildes == -1) {
fprintf(stderr, "can't open %s\n", device);
exit(-1);
}

if (v4l2_querycap(video_fildes, device) == -1) {
perror("v4l2_querycap");
goto exit_;
}

printf("----- %d\n", V4L2_PIX_FMT_YUYV);

// most of devices support YUYV422 packed.
if (v4l2_sfmt(video_fildes, V4L2_PIX_FMT_YUYV) == -1) {
perror("v4l2_sfmt");
goto exit_;
}

if (v4l2_gfmt(video_fildes) == -1) {
perror("v4l2_gfmt");
goto exit_;
}

if (v4l2_sfps(video_fildes, 30) == -1) { // no fatal error
perror("v4l2_sfps");
}

if (v4l2_mmap(video_fildes) == -1) {
perror("v4l2_mmap");
goto exit_;
}

if (v4l2_streamon(video_fildes) == -1) {
perror("v4l2_streamon");
goto exit_;
}

// create a thread that will update frame int the buffer
struct streamHandler sH = {video_fildes, frame_handler};

v4l2_streaming( (void *)(&sH));

int quit = 0;
SDL_Event e;
while (!quit) {
usleep(250);
}


if (v4l2_streamoff(video_fildes) == -1) {
perror("v4l2_streamoff");
goto exit_;
}

if (v4l2_munmap() == -1) {
perror("v4l2_munmap");
goto exit_;
}

exit_:
if (v4l2_close(video_fildes) == -1) {
perror("v4l2_close");
};
SDL_Quit();
return 0;
}
Loading

0 comments on commit 8ebb670

Please sign in to comment.