comparison x11grab.c @ 1582:754781df8033 libavformat

RFC 1 stage: Improve maintainability of the cursoir painting code - Turned the mouse cursor painting code into a macro for more maintainability - Dropped mouse cursor painting in 8bit mode - Removed log when dropping frames - Free the shared memory segment on close (patch by Edouard Gomez)
author gpoirier
date Wed, 13 Dec 2006 08:47:14 +0000
parents 90a8061c5f83
children 8c0065795c92
comparison
equal deleted inserted replaced
1581:90a8061c5f83 1582:754781df8033
186 break; 186 break;
187 case 32: 187 case 32:
188 #if 0 188 #if 0
189 GetColorInfo (image, &c_info); 189 GetColorInfo (image, &c_info);
190 if ( c_info.alpha_mask == 0xFF000000 && image->green_mask == 0xFF00 ) { 190 if ( c_info.alpha_mask == 0xFF000000 && image->green_mask == 0xFF00 ) {
191 // byte order is relevant here, not endianness 191 /* byte order is relevant here, not endianness
192 // endianness is handled by avcodec, but atm no such thing 192 * endianness is handled by avcodec, but atm no such thing
193 // as having ABGR, instead of ARGB in a word. Since we 193 * as having ABGR, instead of ARGB in a word. Since we
194 // need this for Solaris/SPARC, but need to do the conversion 194 * need this for Solaris/SPARC, but need to do the conversion
195 // for every frame we do it outside of this loop, cf. below 195 * for every frame we do it outside of this loop, cf. below
196 // this matches both ARGB32 and ABGR32 196 * this matches both ARGB32 and ABGR32 */
197 input_pixfmt = PIX_FMT_ARGB32; 197 input_pixfmt = PIX_FMT_ARGB32;
198 } else { 198 } else {
199 av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel); 199 av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel);
200 return AVERROR_IO; 200 return AVERROR_IO;
201 } 201 }
234 fail: 234 fail:
235 av_free(st); 235 av_free(st);
236 return AVERROR_IO; 236 return AVERROR_IO;
237 } 237 }
238 238
239 static const uint16_t mousePointerBlack[] = 239 static uint16_t mousePointerBlack[] =
240 { 240 {
241 0, 49152, 40960, 36864, 34816, 33792, 33280, 33024, 32896, 32832, 241 0, 49152, 40960, 36864, 34816, 33792, 33280, 33024, 32896, 32832,
242 33728, 37376, 43264, 51456, 1152, 1152, 576, 576, 448, 0 242 33728, 37376, 43264, 51456, 1152, 1152, 576, 576, 448, 0
243 }; 243 };
244 244
245 static const uint16_t mousePointerWhite[] = 245 static uint16_t mousePointerWhite[] =
246 { 246 {
247 0, 0, 16384, 24576, 28672, 30720, 31744, 32256, 32512, 32640, 31744, 247 0, 0, 16384, 24576, 28672, 30720, 31744, 32256, 32512, 32640, 31744,
248 27648, 17920, 1536, 768, 768, 384, 384, 0, 0 248 27648, 17920, 1536, 768, 768, 384, 384, 0, 0
249 }; 249 };
250 250
263 av_log(s1, AV_LOG_INFO, "couldn't find mouse pointer\n"); 263 av_log(s1, AV_LOG_INFO, "couldn't find mouse pointer\n");
264 *x = -1; 264 *x = -1;
265 *y = -1; 265 *y = -1;
266 } 266 }
267 } 267 }
268
269 #define DRAW_CURSOR_TEMPLATE(type_t) \
270 do { \
271 type_t *cursor; \
272 int width_cursor; \
273 uint16_t bm_b, bm_w, mask; \
274 \
275 for (line = 0; line < min(20, (y_off + height) - *y); line++ ) { \
276 if (s->mouse_wanted == 1) { \
277 bm_b = mousePointerBlack[line]; \
278 bm_w = mousePointerWhite[line]; \
279 } else { \
280 bm_b = mousePointerWhite[line]; \
281 bm_w = mousePointerBlack[line]; \
282 } \
283 mask = ( 0x0001 << 15 ); \
284 \
285 for (cursor = (type_t*) im_data, width_cursor = 0; \
286 ((width_cursor + *x) < (width + x_off) && width_cursor < 16); \
287 cursor++, width_cursor++) { \
288 if ( ( bm_b & mask ) > 0 ) { \
289 *cursor &= ((~ image->red_mask) & (~ image->green_mask) & (~image->blue_mask )); \
290 } else if ( ( bm_w & mask ) > 0 ) { \
291 *cursor |= (image->red_mask | image->green_mask | image->blue_mask ); \
292 } \
293 mask >>= 1; \
294 } \
295 im_data += image->bytes_per_line; \
296 } \
297 } while (0)
268 298
269 static void 299 static void
270 paintMousePointer(AVFormatContext *s1, X11Grab *s, int *x, int *y, XImage *image) 300 paintMousePointer(AVFormatContext *s1, X11Grab *s, int *x, int *y, XImage *image)
271 { 301 {
272 int x_off = s->x_off; 302 int x_off = s->x_off;
281 311
282 im_data += (image->bytes_per_line * (*y - y_off)); // shift to right line 312 im_data += (image->bytes_per_line * (*y - y_off)); // shift to right line
283 im_data += (image->bits_per_pixel / 8 * (*x - x_off)); // shift to right pixel 313 im_data += (image->bits_per_pixel / 8 * (*x - x_off)); // shift to right pixel
284 314
285 switch(image->bits_per_pixel) { 315 switch(image->bits_per_pixel) {
286 case 32: 316 case 32:
287 { 317 DRAW_CURSOR_TEMPLATE(uint32_t);
288 uint32_t *cursor;
289 int width_cursor;
290 uint16_t bm_b, bm_w, mask;
291
292 for (line = 0; line < min(20, (y_off + height) - *y); line++ ) {
293 if (s->mouse_wanted == 1) {
294 bm_b = mousePointerBlack[line];
295 bm_w = mousePointerWhite[line];
296 } else {
297 bm_b = mousePointerWhite[line];
298 bm_w = mousePointerBlack[line];
299 }
300 mask = (0x0001 << 15);
301
302 for (cursor = (uint32_t*) im_data, width_cursor = 0;
303 ((width_cursor + *x) < (width + x_off) && width_cursor < 16);
304 cursor++, width_cursor++) {
305 // Boolean pointer_b_bit, pointer_w_bit;
306 // pointer_b_bit = ( ( bm_b & mask ) > 0 );
307 // pointer_w_bit = ( ( bm_w & mask ) > 0 );
308 // printf("%i ", pointer_b_bit, pointer_w_bit );
309 if (( bm_b & mask) > 0 ) {
310 *cursor &= ( (~image->red_mask)
311 & (~image->green_mask)
312 & (~image->blue_mask));
313 } else if (( bm_w & mask) > 0 ) {
314 *cursor |= ( image->red_mask
315 | image->green_mask
316 | image->blue_mask );
317 }
318 mask >>= 1;
319 }
320 // printf("\n");
321 im_data += image->bytes_per_line;
322 }
323 }
324 break;
325 #if 0
326 case 24: // not sure this can occur at all ..........
327 av_log(s1, AV_LOG_ERROR, "input image bits_per_pixel %i not implemented with mouse pointer capture ... aborting!\n",
328 image->bits_per_pixel);
329 av_log(s1, AV_LOG_ERROR, "Please file a bug at http://www.sourceforge.net/projects/xvidcap/\n");
330 exit(1);
331 break; 318 break;
332 case 16: 319 case 16:
333 { 320 DRAW_CURSOR_TEMPLATE(uint16_t);
334 uint16_t *cursor;
335 int width;
336 uint16_t bm_b, bm_w, mask;
337
338 for (line = 0; line < 16; line++) {
339 if (mjob->mouseWanted == 1) {
340 bm_b = mousePointerBlack[line];
341 bm_w = mousePointerWhite[line];
342 } else {
343 bm_b = mousePointerWhite[line];
344 bm_w = mousePointerBlack[line];
345 }
346 mask = (0x0001 << 15);
347
348 for (cursor = (uint16_t*) im_data, width = 0;
349 ((width + *x) < (mjob->area->width + mjob->area->x)&&width < 6);
350 cursor++, width++) {
351 // Boolean pointer_b_bit, pointer_w_bit;
352 // pointer_b_bit = ( ( bm_b & mask ) > 0 );
353 // pointer_w_bit = ( ( bm_w & mask ) > 0 );
354 // printf("%i ", pointer_b_bit, pointer_w_bit );
355 if (( bm_b & mask ) > 0 ) {
356 *cursor &= ( (~image->red_mask)
357 & (~image->green_mask)
358 & (~image->blue_mask));
359 } else if (( bm_w & mask ) > 0 ) {
360 *cursor |= ( image->red_mask
361 | image->green_mask
362 | image->blue_mask );
363 }
364 mask >>= 1;
365 }
366 // printf("\n");
367
368 im_data += image->bytes_per_line;
369 }
370 }
371 break;
372 case 8:
373 {
374 uint8_t *cursor;
375 int width;
376 uint16_t bm_b, bm_w, mask;
377
378 for (line = 0; line < 16; line++ ) {
379 if (mjob->mouseWanted == 1) {
380 bm_b = mousePointerBlack[line];
381 bm_w = mousePointerWhite[line];
382 } else {
383 bm_b = mousePointerWhite[line];
384 bm_w = mousePointerBlack[line];
385 }
386 mask = ( 0x0001 << 15 );
387
388 for (cursor = im_data, width = 0;
389 ((width + *x) < (mjob->area->width + mjob->area->x)&&width < 6);
390 cursor++, width++) {
391 // Boolean pointer_b_bit, pointer_w_bit;
392 // pointer_b_bit = ( ( bm_b & mask ) > 0 );
393 // pointer_w_bit = ( ( bm_w & mask ) > 0 );
394 // printf("%i ", pointer_b_bit, pointer_w_bit );
395 if ((bm_b & mask) > 0 ) {
396 *cursor = 0;
397 } else if (( bm_w & mask) > 0 ) {
398 *cursor = 1;
399 }
400 mask >>= 1;
401
402 }
403 // printf("\n");
404
405 im_data += image->bytes_per_line;
406 }
407 }
408 break; 321 break;
409 default: 322 default:
410 av_log(s1, AV_LOG_ERROR, "input image bits_per_pixel %i not supported with mouse pointer capture ... aborting!\n", 323 /* XXX: How do we deal with 24bit and 8bit modes ? */
411 image->bits_per_pixel); 324 break;
412 exit(1);
413
414 #endif
415 } 325 }
416 } 326 }
417 } 327 }
418 328
419 329
476 for(;;) { 386 for(;;) {
477 curtime = av_gettime(); 387 curtime = av_gettime();
478 delay = s->time_frame * s->frame_rate_base / s->frame_rate - curtime; 388 delay = s->time_frame * s->frame_rate_base / s->frame_rate - curtime;
479 if (delay <= 0) { 389 if (delay <= 0) {
480 if (delay < int64_t_C(-1000000) * s->frame_rate_base / s->frame_rate) { 390 if (delay < int64_t_C(-1000000) * s->frame_rate_base / s->frame_rate) {
481 av_log(s1, AV_LOG_DEBUG, "grabbing is %d frames late (dropping)\n", (int) -(delay / 16666));
482 s->time_frame += int64_t_C(1000000); 391 s->time_frame += int64_t_C(1000000);
483 } 392 }
484 break; 393 break;
485 } 394 }
486 ts.tv_sec = delay / 1000000; 395 ts.tv_sec = delay / 1000000;
508 int pointer_x, pointer_y; 417 int pointer_x, pointer_y;
509 getCurrentPointer(s1, s, &pointer_x, &pointer_y); 418 getCurrentPointer(s1, s, &pointer_x, &pointer_y);
510 paintMousePointer(s1, s, &pointer_x, &pointer_y, image); 419 paintMousePointer(s1, s, &pointer_x, &pointer_y, image);
511 } 420 }
512 421
513 #warning FIXME - avoid memcpy 422
514 memcpy(pkt->data, image->data, s->frame_size); 423 /* XXX: avoid memcpy */
424 memcpy(pkt->data, image->data, s->frame_size);
515 return s->frame_size; 425 return s->frame_size;
516 } 426 }
517 427
518 static int x11grab_read_close(AVFormatContext *s1) 428 static int x11grab_read_close(AVFormatContext *s1)
519 { 429 {
520 X11Grab *x11grab = s1->priv_data; 430 X11Grab *x11grab = s1->priv_data;
431
432 /* Free shared mem if necessary */
433 if (x11grab->use_shm) {
434 shmdt(x11grab->shminfo.shmaddr);
435 shmctl(x11grab->shminfo.shmid, IPC_RMID, NULL);
436 }
437
438 /* Free X11 display */
521 XCloseDisplay(x11grab->dpy); 439 XCloseDisplay(x11grab->dpy);
522 return 0; 440 return 0;
523 } 441 }
524 442
525 AVInputFormat x11_grab_device_demuxer = 443 AVInputFormat x11_grab_device_demuxer =
526 { 444 {
527 "x11grab", 445 "x11grab",
528 "X11 frame graber", 446 "X11grab",
529 sizeof(X11Grab), 447 sizeof(X11Grab),
530 NULL, 448 NULL,
531 x11grab_read_header, 449 x11grab_read_header,
532 x11grab_read_packet, 450 x11grab_read_packet,
533 x11grab_read_close, 451 x11grab_read_close,