summaryrefslogtreecommitdiff
path: root/test-display.c
diff options
context:
space:
mode:
authorMartin Lucina <mato@kotelna.sk>2010-01-29 17:46:32 +0100
committerMartin Lucina <mato@kotelna.sk>2010-01-29 17:46:32 +0100
commit3c911c00e313641f811e02db8c23f3bf8302a4d5 (patch)
treef37bfde19a2ab58a584053d93fe059920cdf976c /test-display.c
Initial commit
Diffstat (limited to 'test-display.c')
-rw-r--r--test-display.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/test-display.c b/test-display.c
new file mode 100644
index 0000000..11ad9ff
--- /dev/null
+++ b/test-display.c
@@ -0,0 +1,177 @@
+/*
+ Copyright (c) 2010 Martin Lucina
+
+ This file is part of zeromq-examples.
+
+ zeromq-examples 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.
+
+ zeromq-examples 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// Standalone application for testing video capture
+// (without use of 0MQ)
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <unicap.h>
+#include <ucil.h>
+#include <SDL/SDL.h>
+
+#define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a)
+
+int main (void)
+{
+ unicap_handle_t handle;
+ unicap_device_t device;
+ unicap_format_t src_format;
+ unicap_format_t dest_format;
+ unicap_data_buffer_t src_buffer;
+ unicap_data_buffer_t dest_buffer;
+ unicap_data_buffer_t *returned_buffer;
+
+ SDL_Surface *screen;
+ SDL_Surface *rgb_surface;
+
+ int quit = 0;
+ int conversion_found = 0;
+ int index = 0;
+
+ // Open first available video capture device
+ if (!SUCCESS (unicap_enumerate_devices (NULL, &device, 0))) {
+ fprintf (stderr, "Could not enumerate devices\n");
+ exit (1);
+ }
+ if (!SUCCESS (unicap_open (&handle, &device))) {
+ fprintf (stderr, "Failed to open device: %s\n", device.identifier);
+ exit (1);
+ }
+ printf( "Opened video capture device: %s\n", device.identifier );
+
+ // Find a suitable video format that we can convert to RGB24
+ while (SUCCESS (unicap_enumerate_formats (handle, NULL, &src_format, index))) {
+ printf ("Trying video format: %s\n", src_format.identifier);
+ if (ucil_conversion_supported (FOURCC ('R', 'G', 'B', '3'),
+ src_format.fourcc)) {
+ conversion_found = 1;
+ break;
+ }
+ index++;
+ }
+ if (!conversion_found) {
+ fprintf (stderr, "Could not find a suitable video format\n");
+ exit (1);
+ }
+ src_format.buffer_type = UNICAP_BUFFER_TYPE_USER;
+ if (!SUCCESS (unicap_set_format (handle, &src_format))) {
+ fprintf (stderr, "Failed to set video format\n");
+ exit (1);
+ }
+ printf ("Using video format: %s [%dx%d]\n",
+ src_format.identifier,
+ src_format.size.width,
+ src_format.size.height);
+
+ // Clone destination format with equal dimensions, but RGB24 colorspace
+ unicap_copy_format (&dest_format, &src_format);
+ strcpy (dest_format.identifier, "RGB 24bpp");
+ dest_format.fourcc = FOURCC ('R', 'G', 'B', '3');
+ dest_format.bpp = 24;
+ dest_format.buffer_size = dest_format.size.width * dest_format.size.height * 3;
+
+ // Initialise image buffers
+ memset (&src_buffer, 0, sizeof (unicap_data_buffer_t));
+ src_buffer.data = malloc (src_format.buffer_size);
+ src_buffer.buffer_size = src_format.buffer_size;
+ memset (&dest_buffer, 0, sizeof (unicap_data_buffer_t));
+ dest_buffer.data = malloc (dest_format.buffer_size);
+ dest_buffer.buffer_size = dest_format.buffer_size;
+ dest_buffer.format = dest_format;
+
+ // Initialise SDL
+ if (SDL_Init (SDL_INIT_VIDEO) < 0) {
+ fprintf (stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
+ exit (1);
+ }
+ screen = SDL_SetVideoMode (dest_format.size.width, dest_format.size.height, 32, SDL_HWSURFACE);
+ if (screen == NULL) {
+ fprintf (stderr, "Unable to set video mode: %s\n", SDL_GetError ());
+ SDL_Quit ();
+ exit (1);
+ }
+
+ // Start video capture
+ if (!SUCCESS (unicap_start_capture (handle))) {
+ fprintf (stderr, "Failed to start capture on device: %s\n", device.identifier);
+ SDL_Quit ();
+ exit (1);
+ }
+
+ // Display video until user closes window
+ while (!quit)
+ {
+ SDL_Event event;
+
+ // Queue buffer for video capture
+ if (!SUCCESS (unicap_queue_buffer (handle, &src_buffer))) {
+ fprintf (stderr, "Failed to queue a buffer on device: %s\n", device.identifier);
+ SDL_Quit ();
+ exit (1);
+ }
+ // Wait until buffer is ready
+ if (!SUCCESS (unicap_wait_buffer (handle, &returned_buffer))) {
+ fprintf (stderr, "Failed to wait for buffer on device: %s\n", device.identifier);
+ SDL_Quit ();
+ exit (1);
+ }
+ // Convert colorspace
+ if (!SUCCESS (ucil_convert_buffer (&dest_buffer, &src_buffer))) {
+ // XXX This fails sometimes for unknown reasons, just skip the frame for now
+ fprintf (stderr, "Failed to convert video buffer\n");
+ }
+
+ // Create RGB surface
+ rgb_surface = SDL_CreateRGBSurfaceFrom (
+ dest_buffer.data, // Pixel data
+ dest_format.size.width, // Width
+ dest_format.size.height, // Height
+ dest_format.bpp, // Depth
+ dest_format.size.width * 3, // Scanline pitch
+ 0, 0, 0, 0); // TODO RGBA mask
+
+ // Blit surface to screen
+ SDL_BlitSurface (rgb_surface, NULL, screen, NULL);
+ SDL_UpdateRect (screen, 0, 0, 0, 0);
+ SDL_FreeSurface (rgb_surface);
+
+ // Check if user asked to quit
+ while (SDL_PollEvent (&event))
+ {
+ if (event.type == SDL_QUIT)
+ quit = 1;
+ }
+ }
+
+ // Cleanup and quit
+ if (!SUCCESS (unicap_stop_capture (handle)))
+ {
+ fprintf (stderr, "Failed to stop capture on device: %s\n", device.identifier);
+ }
+ if (!SUCCESS (unicap_close (handle)))
+ {
+ fprintf (stderr, "Failed to close the device: %s\n", device.identifier);
+ }
+ SDL_Quit();
+
+ return 0;
+}