1 /* 2 * next generation[tm] xawtv capture interfaces 3 * 4 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> 5 * 6 */ 7 8 #include <pthread.h> 9 #include <sys/types.h> 10 11 #include "devices.h" 12 #include "list.h" 13 14 extern int ng_debug; 15 extern int ng_chromakey; 16 extern int ng_jpeg_quality; 17 extern int ng_ratio_x; 18 extern int ng_ratio_y; 19 extern char ng_v4l_conf[256]; 20 21 #define BUG_ON(condition,message) if (condition) {\ 22 fprintf(stderr,"BUG: %s [%s:%d]\n",\ 23 message,__FILE__,__LINE__);\ 24 exit(1);} 25 26 #if __STDC_VERSION__ < 199901 27 # define restrict 28 #endif 29 30 #define UNSET (-1U) 31 #define DIMOF(array) (sizeof(array)/sizeof(array[0])) 32 #define SDIMOF(array) ((signed int)(sizeof(array)/sizeof(array[0]))) 33 #define GETELEM(array,index,default) \ 34 (index < sizeof(array)/sizeof(array[0]) ? array[index] : default) 35 36 37 /* --------------------------------------------------------------------- */ 38 /* defines */ 39 40 #define VIDEO_NONE 0 41 #define VIDEO_RGB08 1 /* bt848 dithered */ 42 #define VIDEO_GRAY 2 43 #define VIDEO_RGB15_LE 3 /* 15 bpp little endian */ 44 #define VIDEO_RGB16_LE 4 /* 16 bpp little endian */ 45 #define VIDEO_RGB15_BE 5 /* 15 bpp big endian */ 46 #define VIDEO_RGB16_BE 6 /* 16 bpp big endian */ 47 #define VIDEO_BGR24 7 /* bgrbgrbgrbgr (LE) */ 48 #define VIDEO_BGR32 8 /* bgr-bgr-bgr- (LE) */ 49 #define VIDEO_RGB24 9 /* rgbrgbrgbrgb (BE) */ 50 #define VIDEO_RGB32 10 /* -rgb-rgb-rgb (BE) */ 51 #define VIDEO_LUT2 11 /* lookup-table 2 byte depth */ 52 #define VIDEO_LUT4 12 /* lookup-table 4 byte depth */ 53 #define VIDEO_YUYV 13 /* 4:2:2 */ 54 #define VIDEO_YUV422P 14 /* YUV 4:2:2 (planar) */ 55 #define VIDEO_YUV420P 15 /* YUV 4:2:0 (planar) */ 56 #define VIDEO_MJPEG 16 /* MJPEG (AVI) */ 57 #define VIDEO_JPEG 17 /* JPEG (JFIF) */ 58 #define VIDEO_UYVY 18 /* 4:2:2 */ 59 #define VIDEO_FMT_COUNT 19 60 61 #define AUDIO_NONE 0 62 #define AUDIO_U8_MONO 1 63 #define AUDIO_U8_STEREO 2 64 #define AUDIO_S16_LE_MONO 3 65 #define AUDIO_S16_LE_STEREO 4 66 #define AUDIO_S16_BE_MONO 5 67 #define AUDIO_S16_BE_STEREO 6 68 #define AUDIO_MP3 7 69 #define AUDIO_FMT_COUNT 8 70 71 #if BYTE_ORDER == BIG_ENDIAN 72 # define AUDIO_S16_NATIVE_MONO AUDIO_S16_BE_MONO 73 # define AUDIO_S16_NATIVE_STEREO AUDIO_S16_BE_STEREO 74 # define VIDEO_RGB15_NATIVE VIDEO_RGB15_BE 75 # define VIDEO_RGB16_NATIVE VIDEO_RGB16_BE 76 #endif 77 #if BYTE_ORDER == LITTLE_ENDIAN 78 # define AUDIO_S16_NATIVE_MONO AUDIO_S16_LE_MONO 79 # define AUDIO_S16_NATIVE_STEREO AUDIO_S16_LE_STEREO 80 # define VIDEO_RGB15_NATIVE VIDEO_RGB15_LE 81 # define VIDEO_RGB16_NATIVE VIDEO_RGB16_LE 82 #endif 83 84 #define ATTR_TYPE_INTEGER 1 /* range 0 - 65535 */ 85 #define ATTR_TYPE_CHOICE 2 /* multiple choice */ 86 #define ATTR_TYPE_BOOL 3 /* yes/no */ 87 88 #define ATTR_ID_NORM 1 89 #define ATTR_ID_INPUT 2 90 #define ATTR_ID_VOLUME 3 91 #define ATTR_ID_MUTE 4 92 #define ATTR_ID_AUDIO_MODE 5 93 #define ATTR_ID_COLOR 6 94 #define ATTR_ID_BRIGHT 7 95 #define ATTR_ID_HUE 8 96 #define ATTR_ID_CONTRAST 9 97 #define ATTR_ID_COUNT 10 98 99 #define CAN_OVERLAY 1 100 #define CAN_CAPTURE 2 101 #define CAN_TUNE 4 102 #define NEEDS_CHROMAKEY 8 103 104 /* --------------------------------------------------------------------- */ 105 106 extern const unsigned int ng_vfmt_to_depth[VIDEO_FMT_COUNT]; 107 extern const char* ng_vfmt_to_desc[VIDEO_FMT_COUNT]; 108 109 extern const unsigned int ng_afmt_to_channels[AUDIO_FMT_COUNT]; 110 extern const unsigned int ng_afmt_to_bits[AUDIO_FMT_COUNT]; 111 extern const char* ng_afmt_to_desc[AUDIO_FMT_COUNT]; 112 113 extern const char* ng_attr_to_desc[ATTR_ID_COUNT]; 114 115 /* --------------------------------------------------------------------- */ 116 117 struct STRTAB { 118 long nr; 119 const char *str; 120 }; 121 122 struct OVERLAY_CLIP { 123 int x1,x2,y1,y2; 124 }; 125 126 /* --------------------------------------------------------------------- */ 127 /* video data structures */ 128 129 struct ng_video_fmt { 130 unsigned int fmtid; /* VIDEO_* */ 131 unsigned int width; 132 unsigned int height; 133 unsigned int bytesperline; /* zero for compressed formats */ 134 }; 135 136 struct ng_video_buf { 137 struct ng_video_fmt fmt; 138 size_t size; 139 unsigned char *data; 140 141 /* meta info for frame */ 142 struct { 143 int64_t ts; /* time stamp */ 144 int seq; 145 int twice; 146 } info; 147 148 /* 149 * the lock is for the reference counter. 150 * if the reference counter goes down to zero release() 151 * should be called. priv is for the owner of the 152 * buffer (can be used by the release callback) 153 */ 154 pthread_mutex_t lock; 155 pthread_cond_t cond; 156 int refcount; 157 void (*release)(struct ng_video_buf *buf); 158 void *priv; 159 }; 160 161 void ng_init_video_buf(struct ng_video_buf *buf); 162 void ng_release_video_buf(struct ng_video_buf *buf); 163 struct ng_video_buf* ng_malloc_video_buf(struct ng_video_fmt *fmt, 164 int size); 165 void ng_wakeup_video_buf(struct ng_video_buf *buf); 166 void ng_waiton_video_buf(struct ng_video_buf *buf); 167 168 169 /* --------------------------------------------------------------------- */ 170 /* audio data structures */ 171 172 struct ng_audio_fmt { 173 unsigned int fmtid; /* AUDIO_* */ 174 unsigned int rate; 175 }; 176 177 struct ng_audio_buf { 178 struct ng_audio_fmt fmt; 179 int size; 180 int written; /* for partial writes */ 181 char *data; 182 183 struct { 184 int64_t ts; 185 } info; 186 }; 187 188 struct ng_audio_buf* ng_malloc_audio_buf(struct ng_audio_fmt *fmt, 189 int size); 190 191 /* --------------------------------------------------------------------- */ 192 /* someone who receives video and/or audio data (writeavi, ...) */ 193 194 struct ng_format_list { 195 char *name; 196 char *desc; /* if standard fmtid description doesn't work 197 because it's converted somehow */ 198 char *ext; 199 unsigned int fmtid; 200 void *priv; 201 }; 202 203 struct ng_writer { 204 const char *name; 205 const char *desc; 206 const struct ng_format_list *video; 207 const struct ng_format_list *audio; 208 const int combined; /* both audio + video in one file */ 209 210 void* (*wr_open)(char *moviename, char *audioname, 211 struct ng_video_fmt *video, const void *priv_video, int fps, 212 struct ng_audio_fmt *audio, const void *priv_audio); 213 int (*wr_video)(void *handle, struct ng_video_buf *buf); 214 int (*wr_audio)(void *handle, struct ng_audio_buf *buf); 215 int (*wr_close)(void *handle); 216 217 struct list_head list; 218 }; 219 220 struct ng_reader { 221 const char *name; 222 const char *desc; 223 224 char *magic[4]; 225 int moff[4]; 226 int mlen[4]; 227 228 void* (*rd_open)(char *moviename); 229 struct ng_video_fmt* (*rd_vfmt)(void *handle, int *vfmt, int vn); 230 struct ng_audio_fmt* (*rd_afmt)(void *handle); 231 struct ng_video_buf* (*rd_vdata)(void *handle, unsigned int drop); 232 struct ng_audio_buf* (*rd_adata)(void *handle); 233 int64_t (*frame_time)(void *handle); 234 int (*rd_close)(void *handle); 235 236 struct list_head list; 237 }; 238 239 240 /* --------------------------------------------------------------------- */ 241 /* attributes */ 242 243 struct ng_attribute { 244 int id; 245 const char *name; 246 int type; 247 int defval; 248 struct STRTAB *choices; /* ATTR_TYPE_CHOICE */ 249 int min,max; /* ATTR_TYPE_INTEGER */ 250 int points; /* ATTR_TYPE_INTEGER -- fixed point */ 251 const void *priv; 252 void *handle; 253 int (*read)(struct ng_attribute*); 254 void (*write)(struct ng_attribute*, int val); 255 }; 256 257 struct ng_attribute* ng_attr_byid(struct ng_attribute *attrs, int id); 258 struct ng_attribute* ng_attr_byname(struct ng_attribute *attrs, char *name); 259 const char* ng_attr_getstr(struct ng_attribute *attr, int value); 260 int ng_attr_getint(struct ng_attribute *attr, char *value); 261 void ng_attr_listchoices(struct ng_attribute *attr); 262 int ng_attr_int2percent(struct ng_attribute *attr, int value); 263 int ng_attr_percent2int(struct ng_attribute *attr, int percent); 264 int ng_attr_parse_int(struct ng_attribute *attr, char *str); 265 266 /* --------------------------------------------------------------------- */ 267 268 void ng_ratio_fixup(int *width, int *height, int *xoff, int *yoff); 269 void ng_ratio_fixup2(int *width, int *height, int *xoff, int *yoff, 270 int ratio_x, int ratio_y, int up); 271 272 /* --------------------------------------------------------------------- */ 273 /* device informations */ 274 275 struct ng_devinfo { 276 char device[32]; 277 char name[64]; 278 int flags; 279 }; 280 281 /* --------------------------------------------------------------------- */ 282 /* capture/overlay interface driver */ 283 284 struct ng_vid_driver { 285 const char *name; 286 287 /* open/close */ 288 void* (*open)(char *device, int req_flags); 289 int (*close)(void *handle); 290 291 /* attributes */ 292 char* (*get_devname)(void *handle); 293 int (*capabilities)(void *handle); 294 struct ng_attribute* (*list_attrs)(void *handle); 295 void (*get_min_size)(void *handle, int *min_width, int *min_height); 296 297 /* overlay */ 298 int (*setupfb)(void *handle, struct ng_video_fmt *fmt, void *base); 299 int (*overlay)(void *handle, struct ng_video_fmt *fmt, int x, int y, 300 struct OVERLAY_CLIP *oc, int count, int aspect); 301 302 /* capture */ 303 int (*setformat)(void *handle, struct ng_video_fmt *fmt); 304 int (*startvideo)(void *handle, int fps, unsigned int buffers); 305 void (*stopvideo)(void *handle); 306 struct ng_video_buf* (*nextframe)(void *handle); /* video frame */ 307 struct ng_video_buf* (*getimage)(void *handle); /* single image */ 308 309 /* tuner */ 310 unsigned long (*getfreq)(void *handle); 311 void (*setfreq)(void *handle, unsigned long freq); 312 int (*is_tuned)(void *handle); 313 314 struct list_head list; 315 }; 316 317 318 /* --------------------------------------------------------------------- */ 319 /* sound driver */ 320 321 struct ng_dsp_driver { 322 const char *name; 323 void* (*open)(char *device, struct ng_audio_fmt *fmt, 324 int record); 325 void (*close)(void *handle); 326 int (*fd)(void *handle); 327 int (*startrec)(void *handle); 328 struct ng_audio_buf* (*read)(void *handle, int64_t stopby); 329 struct ng_audio_buf* (*write)(void *handle, struct ng_audio_buf *buf); 330 int64_t (*latency)(void *handle); 331 332 struct list_head list; 333 }; 334 335 struct ng_mix_driver { 336 const char *name; 337 struct ng_devinfo* (*probe)(void); 338 struct ng_devinfo* (*channels)(char *device); 339 void* (*open)(char *device); 340 struct ng_attribute* (*volctl)(void *handle, char *channel); 341 void (*close)(void *handle); 342 343 struct list_head list; 344 }; 345 346 347 /* --------------------------------------------------------------------- */ 348 /* color space converters */ 349 350 struct ng_video_conv { 351 unsigned int fmtid_in; 352 unsigned int fmtid_out; 353 void* (*init)(struct ng_video_fmt *out, 354 void *priv); 355 void (*frame)(void *handle, 356 struct ng_video_buf *out, 357 struct ng_video_buf *in); 358 void (*fini)(void *handle); 359 void *priv; 360 361 struct list_head list; 362 }; 363 364 struct ng_convert_handle { 365 struct ng_video_fmt ifmt; 366 struct ng_video_fmt ofmt; 367 int isize; 368 int osize; 369 struct ng_video_conv *conv; 370 void *chandle; 371 }; 372 373 struct ng_convert_handle* ng_convert_alloc(struct ng_video_conv *conv, 374 struct ng_video_fmt *i, 375 struct ng_video_fmt *o); 376 void ng_convert_init(struct ng_convert_handle *h); 377 struct ng_video_buf* ng_convert_frame(struct ng_convert_handle *h, 378 struct ng_video_buf *dest, 379 struct ng_video_buf *buf); 380 void ng_convert_fini(struct ng_convert_handle *h); 381 struct ng_video_buf* ng_convert_single(struct ng_convert_handle *h, 382 struct ng_video_buf *in); 383 384 /* --------------------------------------------------------------------- */ 385 /* audio converters */ 386 387 struct ng_audio_conv { 388 unsigned int fmtid_in; 389 unsigned int fmtid_out; 390 void* (*init)(void *priv); 391 struct ng_audio_buf* (*frame)(void *handle, 392 struct ng_audio_buf *in); 393 void (*fini)(void *handle); 394 void *priv; 395 396 struct list_head list; 397 }; 398 399 /* --------------------------------------------------------------------- */ 400 /* filters */ 401 402 struct ng_filter { 403 char *name; 404 int fmts; 405 struct ng_attribute* attrs; 406 void* (*init)(struct ng_video_fmt *fmt); 407 struct ng_video_buf* (*frame)(void *handle, 408 struct ng_video_buf *in); 409 void (*fini)(void *handle); 410 411 struct list_head list; 412 }; 413 414 /* --------------------------------------------------------------------- */ 415 416 /* must be changed if we break compatibility */ 417 #define NG_PLUGIN_MAGIC 0x20030129 418 419 extern struct list_head ng_conv; 420 extern struct list_head ng_aconv; 421 extern struct list_head ng_filters; 422 extern struct list_head ng_writers; 423 extern struct list_head ng_readers; 424 extern struct list_head ng_vid_drivers; 425 extern struct list_head ng_dsp_drivers; 426 extern struct list_head ng_mix_drivers; 427 428 int ng_conv_register(int magic, char *plugname, 429 struct ng_video_conv *list, int count); 430 int ng_aconv_register(int magic, char *plugname, 431 struct ng_audio_conv *list, int count); 432 int ng_filter_register(int magic, char *plugname, 433 struct ng_filter *filter); 434 int ng_writer_register(int magic, char *plugname, 435 struct ng_writer *writer); 436 int ng_reader_register(int magic, char *plugname, 437 struct ng_reader *reader); 438 int ng_vid_driver_register(int magic, char *plugname, 439 struct ng_vid_driver *driver); 440 int ng_dsp_driver_register(int magic, char *plugname, 441 struct ng_dsp_driver *driver); 442 int ng_mix_driver_register(int magic, char *plugname, 443 struct ng_mix_driver *driver); 444 445 struct ng_video_conv* ng_conv_find_to(unsigned int out, int *i); 446 struct ng_video_conv* ng_conv_find_from(unsigned int out, int *i); 447 struct ng_video_conv* ng_conv_find_match(unsigned int in, unsigned int out); 448 449 const struct ng_vid_driver* ng_vid_open(char **device, char *driver, 450 struct ng_video_fmt *screen, 451 void *base, void **handle); 452 const struct ng_dsp_driver* ng_dsp_open(char *device, struct ng_audio_fmt *fmt, 453 int record, void **handle); 454 struct ng_attribute* ng_mix_init(char *device, char *channel); 455 struct ng_reader* ng_find_reader(char *filename); 456 457 int64_t ng_tofday_to_timestamp(struct timeval *tv); 458 int64_t ng_get_timestamp(void); 459 void ng_check_clipping(int width, int height, int xadjust, int yadjust, 460 struct OVERLAY_CLIP *oc, int *count); 461 struct ng_video_buf* ng_filter_single(struct ng_filter *filter, 462 struct ng_video_buf *in); 463 464 /* --------------------------------------------------------------------- */ 465 466 void ng_init(void); 467 void ng_lut_init(unsigned long red_mask, unsigned long green_mask, 468 unsigned long blue_mask, unsigned int fmtid, int swap); 469 470 void ng_rgb24_to_lut2(unsigned char *dest, unsigned char *src, int p); 471 void ng_rgb24_to_lut4(unsigned char *dest, unsigned char *src, int p); 472 473 /* --------------------------------------------------------------------- */ 474 /* internal stuff starts here */ 475 476 #ifdef NG_PRIVATE 477 478 /* init functions */ 479 void ng_color_packed_init(void); 480 void ng_color_yuv2rgb_init(void); 481 void ng_writefile_init(void); 482 483 /* for yuv2rgb using lookup tables (color_lut.c, color_yuv2rgb.c) */ 484 extern unsigned long ng_lut_red[256]; 485 extern unsigned long ng_lut_green[256]; 486 extern unsigned long ng_lut_blue[256]; 487 void ng_yuv422_to_lut2(unsigned char *dest, unsigned char *s, int p); 488 void ng_yuv422_to_lut4(unsigned char *dest, unsigned char *s, int p); 489 void ng_yuv420p_to_lut2(void *h, struct ng_video_buf *out, 490 struct ng_video_buf *in); 491 void ng_yuv420p_to_lut4(void *h, struct ng_video_buf *out, 492 struct ng_video_buf *in); 493 void ng_yuv422p_to_lut2(void *h, struct ng_video_buf *out, 494 struct ng_video_buf *in); 495 void ng_yuv422p_to_lut4(void *h, struct ng_video_buf *out, 496 struct ng_video_buf *in); 497 498 /* color_common.c stuff */ 499 void* ng_packed_init(struct ng_video_fmt *out, void *priv); 500 void ng_packed_frame(void *handle, struct ng_video_buf *out, 501 struct ng_video_buf *in); 502 void* ng_conv_nop_init(struct ng_video_fmt *out, void *priv); 503 void ng_conv_nop_fini(void *handle); 504 505 #define NG_GENERIC_PACKED \ 506 .init = ng_packed_init, \ 507 .frame = ng_packed_frame, \ 508 .fini = ng_conv_nop_fini 509 510 #endif /* NG_PRIVATE */ 511 512 /* --------------------------------------------------------------------- */ 513 /* 514 * Local variables: 515 * compile-command: "(cd ..; make)" 516 * End: 517 */ 518