diff --git a/VCamUtils/src/videoformat.cpp b/VCamUtils/src/videoformat.cpp index d6e6541..9792a00 100644 --- a/VCamUtils/src/videoformat.cpp +++ b/VCamUtils/src/videoformat.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include diff --git a/share/config_example.ini b/share/config_example.ini new file mode 100644 index 0000000..d8d4e00 --- /dev/null +++ b/share/config_example.ini @@ -0,0 +1,55 @@ +# Virtual camera configuration file example. +# +# Please, read the instructions to the end. + +[Cameras] +# First at all you must define how many virtual cameras will be created. +cameras/size = 2 + +# Then, define it's properties. +# +# 'formats' is a comma separated list of index in the format list bellow. +cameras/1/description = Virtual Camera +cameras/1/formats = 2 + +cameras/2/description = My Other Virtual Camera +cameras/2/formats = 1, 2 + +[Formats] +# Define how many formats will be supported by the camera. +formats/size = 2 + +# Now define the frame pixel formats, resolutions and frame rates supported by +# the camera. +# YUY2 640x480 is one of the most widely supported formats in webcam capture +# programs. First format defined is the default frame format. +# 'width', 'height' and 'fps' are unsigned integers. +formats/1/format = YUY2 +formats/1/width = 640 +formats/1/height = 480 +formats/1/fps = 30 + +# The parameters can also be specified as a comma separated list, so it's +# possible to combine the parameters to define several formats in one group. +# 'fps' can also be defined as a fraction. +# The following lines will define 4 formats: +# +# RGB24 640x480 20 FPS +# RGB24 640x480 7.5 FPS +# YUY2 640x480 20 FPS +# YUY2 640x480 7.5 FPS +formats/2/format = RGB24, YUY2 +formats/2/width = 640 +formats/2/height = 480 +formats/2/fps = 20/1, 15/2 + +# You can also define a default frame when the device is not receiving any +# input. +# You must give a full path to a picture file, the supported formats for the +# picture are: +# +# BMP (24 bpp and 32 bpp). +# JPG +# PNG +[General] +default_frame = /path/to/default_frame.png diff --git a/share/examples/output_mac.c b/share/examples/output_mac.c new file mode 100644 index 0000000..0bd362a --- /dev/null +++ b/share/examples/output_mac.c @@ -0,0 +1,84 @@ +/* akvirtualcamera, virtual camera for Mac and Windows. + * Copyright (C) 2021 Gonzalo Exequiel Pedone + * + * akvirtualcamera is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * akvirtualcamera is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with akvirtualcamera. If not, see . + * + * Web-Site: http://github.com/webcamoid/akvirtualcamera + */ + +#include +#include +#include + +/* For the sake of simplicity, the program won't print anything to the terminal, + * or do any validation check, you are adviced the check every single value + * returned by each function. + * This program shows the very minimum code required to write frames to the + * plugin. + */ + +// We'll assume this is a valid akvcam output device. +#define VIDEO_OUTPUT "AkVCamVideoDevice0" + +// Send frames for about 30 seconds in a 30 FPS stream. +#define FPS 30 +#define DURATION_SECONDS 30 +#define N_FRAMES (FPS * DURATION_SECONDS) + +int main() +{ + // Set the parameters of the stream. + const char cmd[1024]; + const char format[] = "RGB24"; + int width = 640; + int height = 480; + snprintf(cmd, + 1024, + "AkVCamManager stream %s %s %d %d", + VIDEO_OUTPUT, + format, + width, + height); + + // Start the stream. + proc = popen(cmd, "w"); + + // Allocate the frame buffer. + size_t buffer_size = 3 * width * height; + char *buffer = malloc(buffer_size); + + // Generate some random noise frames. + srand(time(0)); + + for (int i = 0; i < N_FRAMES; i++) { + // Write the frame data to the buffer. + for (size_t byte = 0; byte < buffer_size; byte++) + buffer[byte] = rand() & 0xff; + + fwrite(buffer, buffer_size, 1, proc); + + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 1e9 / FPS; + nanosleep(&ts, &ts); + } + + // Release the frame buffer. + malloc(buffer); + + // Stop the stream. + pclose(proc); + + return 0; +} diff --git a/share/examples/output_windows.c b/share/examples/output_windows.c new file mode 100644 index 0000000..d3f2f47 --- /dev/null +++ b/share/examples/output_windows.c @@ -0,0 +1,140 @@ +/* akvirtualcamera, virtual camera for Mac and Windows. + * Copyright (C) 2021 Gonzalo Exequiel Pedone + * + * akvirtualcamera is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * akvirtualcamera is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with akvirtualcamera. If not, see . + * + * Web-Site: http://github.com/webcamoid/akvirtualcamera + */ + +#include +#include +#include + +/* For the sake of simplicity, the program won't print anything to the terminal, + * or do any validation check, you are adviced the check every single value + * returned by each function. + * This program shows the very minimum code required to write frames to the + * plugin. + */ + +// We'll assume this is a valid akvcam output device. +#define VIDEO_OUTPUT "AkVCamVideoDevice0" + +// Send frames for about 30 seconds in a 30 FPS stream. +#define FPS 30 +#define DURATION_SECONDS 30 +#define N_FRAMES (FPS * DURATION_SECONDS) + +struct StreamProcess +{ + HANDLE stdinReadPipe; + HANDLE stdinWritePipe; + SECURITY_ATTRIBUTES pipeAttributes; + STARTUPINFOA startupInfo; + PROCESS_INFORMATION procInfo; +}; + +int main() +{ + // Set the parameters of the stream. + const char cmd[1024]; + const char format[] = "RGB24"; + int width = 640; + int height = 480; + snprintf(cmd, + 1024, + "AkVCamManager stream %s %s %d %d", + VIDEO_OUTPUT, + format, + width, + height); + + // Get the handles to the standard input and standard output. + struct StreamProcess streamProc; + memset(&streamProc, 0, sizeof(struct StreamProcess)); + streamProc.stdinReadPipe = NULL; + streamProc.stdinWritePipe = NULL; + memset(&streamProc.pipeAttributes, 0, sizeof(struct SECURITY_ATTRIBUTES)); + streamProc.pipeAttributes.nLength = sizeof(struct SECURITY_ATTRIBUTES); + streamProc.pipeAttributes.bInheritHandle = true; + streamProc.pipeAttributes.lpSecurityDescriptor = NULL; + CreatePipe(&streamProc.stdinReadPipe, + &streamProc.stdinWritePipe, + &streamProc.pipeAttributes, + 0); + SetHandleInformation(streamProc.stdinWritePipe, + HANDLE_FLAG_INHERIT, + 0); + + struct STARTUPINFOA startupInfo; + memset(&startupInfo, 0, sizeof(struct STARTUPINFOA)); + startupInfo.cb = sizeof(struct STARTUPINFOA); + startupInfo.hStdInput = streamProc.stdinReadPipe; + startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + startupInfo.wShowWindow = SW_HIDE; + + struct PROCESS_INFORMATION procInfo; + memset(&procInfo, 0, sizeof(struct PROCESS_INFORMATION)); + + // Start the stream. + CreateProcessA(NULL, + cmd, + NULL, + NULL, + true, + 0, + NULL, + NULL, + &startupInfo, + &procInfo); + + // Allocate the frame buffer. + size_t buffer_size = 3 * width; + char *buffer = malloc(buffer_size); + + // Generate some random noise frames. + srand(time(0)); + + for (int i = 0; i < N_FRAMES; i++) { + // Write the frame line by line. + for (int y = 0; y < height; y++) { + for (size_t byte = 0; byte < buffer_size; byte++) + buffer[byte] = rand() & 0xff; + + // Write the frame data to the buffer. + DWORD bytesWritten = 0; + WriteFile(streamProc.stdinWritePipe, + buffer, + DWORD(buffer_size), + &bytesWritten, + NULL); + } + + Sleep(1000 / FPS); + } + + // Release the frame buffer. + malloc(buffer); + + // Close the standard input and standard output handles. + CloseHandle(streamProc.stdinWritePipe); + CloseHandle(streamProc.stdinReadPipe); + + // Stop the stream. + WaitForSingleObject(streamProc.procInfo.hProcess, INFINITE); + CloseHandle(streamProc.procInfo.hProcess); + CloseHandle(streamProc.procInfo.hThread); + + return 0; +}