sdl_rgb_display.c
Upload User: shyika
Upload Date: 2017-11-25
Package Size: 1227k
Code Size: 8k
Category:

Video Capture

Development Platform:

Unix_Linux

  1. /*
  2.     unicap
  3.     Copyright (C) 2004  Arne Caspari
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15. */
  16. /**
  17.    sdl_display.c
  18.    This example demonstrates how to display a live video stream using libSDL
  19.  **/
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <unicap.h>
  23. #include <status.h>
  24. #include <linux/types.h>
  25. #include <SDL.h>
  26. #define UYVY 0x59565955 /* UYVY (packed, 16 bits) */
  27. #define FOURCC(a,b,c,d) (unsigned int)((((unsigned int)d)<<24)+(((unsigned int)c)<<16)+(((unsigned int)b)<<8)+a)
  28. size_t y4112rgb24( __u8 *dest, __u8 *source, size_t dest_size, size_t source_size )
  29. {
  30. int i;
  31. int dest_offset = 0;
  32. /*  if( dest_size < ( source_size *2 ) ) */
  33. /*  { */
  34. /*  return 0; */
  35. /*  } */
  36. for( i = 0; i < source_size; i+=6 )
  37. {
  38. __u8 *r, *b, *g;
  39. __u8 *y1, *y2, *y3, *y4, *u, *v;
  40. float fr, fg, fb;
  41. float fy1, fy2, fy3, fy4, fu, fv;
  42. r = dest + dest_offset;
  43. g = r + 1;
  44. b = g + 1;
  45. u = source + i;
  46. y1 = u + 1;
  47. y2 = y1 + 1;
  48. v = y2 + 1;
  49. y3 = v + 1;
  50. y4 = y3 + 1;
  51. fu = *u;
  52. fv = *v;
  53. fy1= *y1;
  54. fy2= *y2;
  55. fy3= *y3;
  56. fy4= *y4;
  57. fr = fy1 - 0.0009267 * ( fu - 128 ) + 1.4016868 * ( fv - 128 );
  58. fg = fy1 - 0.3436954 * ( fu - 128 ) - 0.7141690 * ( fv - 128 );
  59. fb = fy1 + 1.7721604 * ( fu - 128 ) + 0.0009902 * ( fv - 128 );
  60. *r = (__u8) ( fr > 255 ? 255 : ( fr < 0 ? 0 : fr ) );
  61. *g = (__u8) ( fg > 255 ? 255 : ( fg < 0 ? 0 : fg ) );
  62. *b = (__u8) ( fb > 255 ? 255 : ( fb < 0 ? 0 : fb ) );
  63. dest_offset += 3;
  64. r = dest + dest_offset;
  65. g = r + 1;
  66. b = g + 1;
  67. fr = 255;//fy2 - 0.0009267 * ( fu - 128 ) + 1.4016868 * ( fv - 128 );
  68. fg = 255;//fy2 - 0.3436954 * ( fu - 128 ) - 0.7141690 * ( fv - 128 );
  69. fb = fy2 + 1.7721604 * ( fu - 128 ) + 0.0009902 * ( fv - 128 );
  70. *r = (__u8) ( fr > 255 ? 255 : ( fr < 0 ? 0 : fr ) );
  71. *g = (__u8) ( fg > 255 ? 255 : ( fg < 0 ? 0 : fg ) );
  72. *b = (__u8) ( fb > 255 ? 255 : ( fb < 0 ? 0 : fb ) );
  73. dest_offset += 3;
  74. r = dest + dest_offset;
  75. g = r + 1;
  76. b = g + 1;
  77. fr = fy3 - 0.0009267 * ( fu - 128 ) + 1.4016868 * ( fv - 128 );
  78. fg = fy3 - 0.3436954 * ( fu - 128 ) - 0.7141690 * ( fv - 128 );
  79. fb = fy3 + 1.7721604 * ( fu - 128 ) + 0.0009902 * ( fv - 128 );
  80. *r = (__u8) ( fr > 255 ? 255 : ( fr < 0 ? 0 : fr ) );
  81. *g = (__u8) ( fg > 255 ? 255 : ( fg < 0 ? 0 : fg ) );
  82. *b = (__u8) ( fb > 255 ? 255 : ( fb < 0 ? 0 : fb ) );
  83. dest_offset += 3;
  84. r = dest + dest_offset;
  85. g = r + 1;
  86. b = g + 1;
  87. fr = fy4 - 0.0009267 * ( fu - 128 ) + 1.4016868 * ( fv - 128 );
  88. fg = fy4 - 0.3436954 * ( fu - 128 ) - 0.7141690 * ( fv - 128 );
  89. fb = fy4 + 1.7721604 * ( fu - 128 ) + 0.0009902 * ( fv - 128 );
  90. *r = (__u8) ( fr > 255 ? 255 : ( fr < 0 ? 0 : fr ) );
  91. *g = (__u8) ( fg > 255 ? 255 : ( fg < 0 ? 0 : fg ) );
  92. *b = (__u8) ( fb > 255 ? 255 : ( fb < 0 ? 0 : fb ) );
  93. dest_offset += 3;
  94. }
  95. // From SciLab : This is the good one.
  96. //r = 1 * y -  0.0009267*(u-128)  + 1.4016868*(v-128);^M
  97. //g = 1 * y -  0.3436954*(u-128)  - 0.7141690*(v-128);^M
  98. //b = 1 * y +  1.7721604*(u-128)  + 0.0009902*(v-128);^M
  99. // YUV->RGB
  100. // r = 1.164 * (y-16) + 1.596*(v-128);
  101. // g = 1.164 * (y-16) + 0.813*(v-128) - 0.391*(u-128);
  102. // b = 1.164 * (y-16) + 2.018*(u-128);
  103. return source_size * 2;
  104. }
  105. int main( int argc, char **argv )
  106. {
  107. unicap_handle_t handle;
  108. unicap_device_t device;
  109. unicap_format_t format_spec;
  110. unicap_format_t format;
  111. unicap_data_buffer_t buffer;
  112. unicap_data_buffer_t *returned_buffer;
  113. int i;
  114. SDL_Surface *screen;
  115. SDL_Surface *rgb_surface;
  116. Uint32 rmask, gmask, bmask, amask;
  117. int quit=0;
  118. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  119. rmask = 0xff000000;
  120. gmask = 0x00ff0000;
  121. bmask = 0x0000ff00;
  122. amask = 0x000000ff;
  123. #else
  124. rmask = 0x000000ff;
  125. gmask = 0x0000ff00;
  126. bmask = 0x00ff0000;
  127. amask = 0xff000000;
  128. #endif
  129. printf( "select video devicen" );
  130. for( i = 0; SUCCESS( unicap_enumerate_devices( NULL, &device, i ) ); i++ )
  131. {
  132. printf( "%i: %sn", i, device.identifier );
  133. }
  134. if( --i > 0 )
  135. {
  136. printf( "Select video capture device: %d" );
  137. scanf( "%d", &i );
  138. }
  139. if( !SUCCESS( unicap_enumerate_devices( NULL, &device, i ) ) )
  140. {
  141. fprintf( stderr, "Failed to get info for device '%s'n", device.identifier );
  142. exit( 1 );
  143. }
  144. /*
  145.   Acquire a handle to this device
  146.  */
  147. if( !SUCCESS( unicap_open( &handle, &device ) ) )
  148. {
  149. fprintf( stderr, "Failed to open device: %sn", device.identifier );
  150. exit( 1 );
  151. }
  152. printf( "Opened video capture device: %sn", device.identifier );
  153. /*
  154.   Create a format specification to limit the list of formats returned by 
  155.   unicap_enumerate_formats to the ones with the color format 'UYVY'
  156.  */
  157. unicap_void_format( &format_spec );
  158. format_spec.fourcc = FOURCC('Y','4','1','1');
  159. /*
  160.   Get the list of video formats of the colorformat UYVY
  161.  */
  162. for( i = 0; SUCCESS( unicap_enumerate_formats( handle, &format_spec, &format, i ) ); i++ )
  163. {
  164. printf( "%d: %s [%dx%d]n", 
  165. i,
  166. format.identifier, 
  167. format.size.width, 
  168. format.size.height );
  169. }
  170. if( --i > 0 )
  171. {
  172. printf( "Select video format: " );
  173. scanf( "%d", &i );
  174. }
  175. if( !SUCCESS( unicap_enumerate_formats( handle, &format_spec, &format, i ) ) )
  176. {
  177. fprintf( stderr, "Failed to get video formatn" );
  178. exit( 1 );
  179. }
  180. format.size.width = 640;
  181. format.size.height = 480;
  182. /*
  183.   Set this video format
  184.  */
  185. if( !SUCCESS( unicap_set_format( handle, &format ) ) )
  186. {
  187. fprintf( stderr, "Failed to set video formatn" );
  188. exit( 1 );
  189. }
  190. /*
  191.   Initialize the image buffer
  192.  */
  193. memset( &buffer, 0x0, sizeof( unicap_data_buffer_t ) );
  194. /**
  195.    Init SDL & SDL_Overlay
  196.  **/
  197. if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
  198. {
  199.    fprintf(stderr, "Failed to initialize SDL:  %sn", SDL_GetError());
  200.    exit(1);
  201. }
  202. atexit(SDL_Quit);
  203. screen = SDL_SetVideoMode( format.size.width, format.size.height, 32, SDL_HWSURFACE);
  204. if ( screen == NULL ) {
  205.    fprintf(stderr, "Unable to set video mode: %sn", SDL_GetError());
  206.    exit(1);
  207. }
  208. rgb_surface = SDL_CreateRGBSurface( SDL_SWSURFACE, 
  209. format.size.width, 
  210. format.size.height, 
  211. 24, 
  212. 0, 
  213. 0, 
  214. 0, 
  215. 0 );
  216. /*
  217.   Pass the pointer to the overlay to the unicap data buffer. 
  218.  */
  219. buffer.data = malloc( 640 * 480 * 2 );
  220. /*
  221.   Start the capture process on the device
  222.  */
  223. if( !SUCCESS( unicap_start_capture( handle ) ) )
  224. {
  225. fprintf( stderr, "Failed to start capture on device: %sn", device.identifier );
  226. exit( 1 );
  227. }
  228. while( !quit )
  229. {
  230. SDL_Rect rect;
  231. SDL_Event event;
  232. rect.x = rect.y = 0;
  233. rect.w = format.size.width;
  234. rect.h = format.size.height;
  235. /*
  236.   Queue the buffer
  237.   
  238.   The buffer now gets filled with image data by the capture device
  239. */
  240. if( !SUCCESS( unicap_queue_buffer( handle, &buffer ) ) )
  241. {
  242. fprintf( stderr, "Failed to queue a buffer on device: %sn", device.identifier );
  243. exit( 1 );
  244. }
  245. /*
  246.   Wait until the image buffer is ready
  247. */
  248. if( !SUCCESS( unicap_wait_buffer( handle, &returned_buffer ) ) )
  249. {
  250. fprintf( stderr, "Failed to wait for buffer on device: %sn", device.identifier );
  251. }
  252. SDL_LockSurface( rgb_surface );
  253. y4112rgb24( rgb_surface->pixels,
  254. buffer.data,
  255. buffer.format.size.width * buffer.format.size.height * 3,
  256. buffer.buffer_size );
  257. SDL_UnlockSurface( rgb_surface );
  258. SDL_BlitSurface( rgb_surface, NULL, screen, NULL );
  259. SDL_UpdateRect( screen, 0, 0, 0, 0 );
  260. /*
  261.   Display the video data
  262.  */
  263. while( SDL_PollEvent( &event ) )
  264. {
  265. if( event.type == SDL_QUIT )
  266. {
  267. quit=1;
  268. }
  269. }
  270. }
  271. /*
  272.   Stop the device
  273.  */
  274. if( !SUCCESS( unicap_stop_capture( handle ) ) )
  275. {
  276. fprintf( stderr, "Failed to stop capture on device: %sn", device.identifier );
  277. }
  278. /*
  279.   Close the device 
  280.   This invalidates the handle
  281.  */
  282. if( !SUCCESS( unicap_close( handle ) ) )
  283. {
  284. fprintf( stderr, "Failed to close the device: %sn", device.identifier );
  285. }
  286. SDL_Quit();
  287. return 0;
  288. }