diff options
author | Frank Schaefer <fschaefer.oss@googlemail.com> | 2012-12-08 09:31:31 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-22 17:57:17 -0500 |
commit | 227b7c90671624e0d143e324a3015726282981df (patch) | |
tree | b0d88cf25c16adeb45441575b614398aadb3145e /drivers/media | |
parent | e04c00d985c62a6e1cc6c8048308f3216442f708 (diff) |
[media] em28xx: move the em2710/em2750/em28xx specific frame data processing code to a separate function
em28xx_urb_data_copy() actually consists of two parts:
USB urb processing (checks, data extraction) and frame data packet processing.
Move the latter to a separate function and call it from em28xx_urb_data_copy()
for each data packet.
The em25xx, em2760, em2765 (and likely em277x) chip variants are using a
different frame data format, for which support will be added later with
another function.
This reduces the size of em28xx_urb_data_copy() and makes the code much more
readable. While we're at it, clean up the code a bit (rename some variables to
something more meaningful, improve some comments etc.)
Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-video.c | 170 |
1 files changed, 90 insertions, 80 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index a1f6de0f1b3b..133e6b0a5c7d 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -379,15 +379,90 @@ finish_field_prepare_next(struct em28xx *dev, | |||
379 | return buf; | 379 | return buf; |
380 | } | 380 | } |
381 | 381 | ||
382 | /* Processes and copies the URB data content (video and VBI data) */ | 382 | /* |
383 | static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | 383 | * Process data packet according to the em2710/em2750/em28xx frame data format |
384 | */ | ||
385 | static inline void process_frame_data_em28xx(struct em28xx *dev, | ||
386 | unsigned char *data_pkt, | ||
387 | unsigned int data_len) | ||
384 | { | 388 | { |
385 | struct em28xx_buffer *buf, *vbi_buf; | 389 | struct em28xx_buffer *buf = dev->usb_ctl.vid_buf; |
390 | struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf; | ||
386 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 391 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
387 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | 392 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; |
388 | int xfer_bulk, num_packets, i, rc = 1; | 393 | |
389 | unsigned int actual_length, len = 0; | 394 | /* capture type 0 = vbi start |
390 | unsigned char *p; | 395 | capture type 1 = vbi in progress |
396 | capture type 2 = video start | ||
397 | capture type 3 = video in progress */ | ||
398 | if (data_len >= 4) { | ||
399 | /* NOTE: Headers are always 4 bytes and | ||
400 | * never split across packets */ | ||
401 | if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 && | ||
402 | data_pkt[2] == 0x88 && data_pkt[3] == 0x88) { | ||
403 | /* Continuation */ | ||
404 | data_pkt += 4; | ||
405 | data_len -= 4; | ||
406 | } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) { | ||
407 | /* Field start (VBI mode) */ | ||
408 | dev->capture_type = 0; | ||
409 | dev->vbi_read = 0; | ||
410 | em28xx_isocdbg("VBI START HEADER !!!\n"); | ||
411 | dev->top_field = !(data_pkt[2] & 1); | ||
412 | data_pkt += 4; | ||
413 | data_len -= 4; | ||
414 | } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) { | ||
415 | /* Field start (VBI disabled) */ | ||
416 | dev->capture_type = 2; | ||
417 | em28xx_isocdbg("VIDEO START HEADER !!!\n"); | ||
418 | dev->top_field = !(data_pkt[2] & 1); | ||
419 | data_pkt += 4; | ||
420 | data_len -= 4; | ||
421 | } | ||
422 | } | ||
423 | /* NOTE: With bulk transfers, intermediate data packets | ||
424 | * have no continuation header */ | ||
425 | |||
426 | if (dev->capture_type == 0) { | ||
427 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); | ||
428 | dev->usb_ctl.vbi_buf = vbi_buf; | ||
429 | dev->capture_type = 1; | ||
430 | } | ||
431 | |||
432 | if (dev->capture_type == 1) { | ||
433 | int vbi_size = dev->vbi_width * dev->vbi_height; | ||
434 | int vbi_data_len = ((dev->vbi_read + data_len) > vbi_size) ? | ||
435 | (vbi_size - dev->vbi_read) : data_len; | ||
436 | |||
437 | /* Copy VBI data */ | ||
438 | if (vbi_buf != NULL) | ||
439 | em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); | ||
440 | dev->vbi_read += vbi_data_len; | ||
441 | |||
442 | if (vbi_data_len < data_len) { | ||
443 | /* Continue with copying video data */ | ||
444 | dev->capture_type = 2; | ||
445 | data_pkt += vbi_data_len; | ||
446 | data_len -= vbi_data_len; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (dev->capture_type == 2) { | ||
451 | buf = finish_field_prepare_next(dev, buf, dma_q); | ||
452 | dev->usb_ctl.vid_buf = buf; | ||
453 | dev->capture_type = 3; | ||
454 | } | ||
455 | |||
456 | if (dev->capture_type == 3 && buf != NULL && data_len > 0) | ||
457 | em28xx_copy_video(dev, buf, data_pkt, data_len); | ||
458 | } | ||
459 | |||
460 | /* Processes and copies the URB data content (video and VBI data) */ | ||
461 | static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | ||
462 | { | ||
463 | int xfer_bulk, num_packets, i; | ||
464 | unsigned char *usb_data_pkt; | ||
465 | unsigned int usb_data_len; | ||
391 | 466 | ||
392 | if (!dev) | 467 | if (!dev) |
393 | return 0; | 468 | return 0; |
@@ -400,9 +475,6 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | |||
400 | 475 | ||
401 | xfer_bulk = usb_pipebulk(urb->pipe); | 476 | xfer_bulk = usb_pipebulk(urb->pipe); |
402 | 477 | ||
403 | buf = dev->usb_ctl.vid_buf; | ||
404 | vbi_buf = dev->usb_ctl.vbi_buf; | ||
405 | |||
406 | if (xfer_bulk) /* bulk */ | 478 | if (xfer_bulk) /* bulk */ |
407 | num_packets = 1; | 479 | num_packets = 1; |
408 | else /* isoc */ | 480 | else /* isoc */ |
@@ -410,9 +482,9 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | |||
410 | 482 | ||
411 | for (i = 0; i < num_packets; i++) { | 483 | for (i = 0; i < num_packets; i++) { |
412 | if (xfer_bulk) { /* bulk */ | 484 | if (xfer_bulk) { /* bulk */ |
413 | actual_length = urb->actual_length; | 485 | usb_data_len = urb->actual_length; |
414 | 486 | ||
415 | p = urb->transfer_buffer; | 487 | usb_data_pkt = urb->transfer_buffer; |
416 | } else { /* isoc */ | 488 | } else { /* isoc */ |
417 | if (urb->iso_frame_desc[i].status < 0) { | 489 | if (urb->iso_frame_desc[i].status < 0) { |
418 | print_err_status(dev, i, | 490 | print_err_status(dev, i, |
@@ -421,87 +493,25 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | |||
421 | continue; | 493 | continue; |
422 | } | 494 | } |
423 | 495 | ||
424 | actual_length = urb->iso_frame_desc[i].actual_length; | 496 | usb_data_len = urb->iso_frame_desc[i].actual_length; |
425 | if (actual_length > dev->max_pkt_size) { | 497 | if (usb_data_len > dev->max_pkt_size) { |
426 | em28xx_isocdbg("packet bigger than packet size"); | 498 | em28xx_isocdbg("packet bigger than packet size"); |
427 | continue; | 499 | continue; |
428 | } | 500 | } |
429 | 501 | ||
430 | p = urb->transfer_buffer + | 502 | usb_data_pkt = urb->transfer_buffer + |
431 | urb->iso_frame_desc[i].offset; | 503 | urb->iso_frame_desc[i].offset; |
432 | } | 504 | } |
433 | 505 | ||
434 | if (actual_length == 0) { | 506 | if (usb_data_len == 0) { |
435 | /* NOTE: happens very often with isoc transfers */ | 507 | /* NOTE: happens very often with isoc transfers */ |
436 | /* em28xx_usbdbg("packet %d is empty",i); - spammy */ | 508 | /* em28xx_usbdbg("packet %d is empty",i); - spammy */ |
437 | continue; | 509 | continue; |
438 | } | 510 | } |
439 | 511 | ||
440 | /* capture type 0 = vbi start | 512 | process_frame_data_em28xx(dev, usb_data_pkt, usb_data_len); |
441 | capture type 1 = vbi in progress | ||
442 | capture type 2 = video start | ||
443 | capture type 3 = video in progress */ | ||
444 | len = actual_length; | ||
445 | if (len >= 4) { | ||
446 | /* NOTE: headers are always 4 bytes and | ||
447 | * never split across packets */ | ||
448 | if (p[0] == 0x33 && p[1] == 0x95) { | ||
449 | dev->capture_type = 0; | ||
450 | dev->vbi_read = 0; | ||
451 | em28xx_isocdbg("VBI START HEADER!!!\n"); | ||
452 | dev->top_field = !(p[2] & 1); | ||
453 | p += 4; | ||
454 | len -= 4; | ||
455 | } else if (p[0] == 0x88 && p[1] == 0x88 && | ||
456 | p[2] == 0x88 && p[3] == 0x88) { | ||
457 | /* continuation */ | ||
458 | p += 4; | ||
459 | len -= 4; | ||
460 | } else if (p[0] == 0x22 && p[1] == 0x5a) { | ||
461 | /* start video */ | ||
462 | dev->capture_type = 2; | ||
463 | dev->top_field = !(p[2] & 1); | ||
464 | p += 4; | ||
465 | len -= 4; | ||
466 | } | ||
467 | } | ||
468 | /* NOTE: with bulk transfers, intermediate data packets | ||
469 | * have no continuation header */ | ||
470 | |||
471 | if (dev->capture_type == 0) { | ||
472 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); | ||
473 | dev->usb_ctl.vbi_buf = vbi_buf; | ||
474 | dev->capture_type = 1; | ||
475 | } | ||
476 | |||
477 | if (dev->capture_type == 1) { | ||
478 | int vbi_size = dev->vbi_width * dev->vbi_height; | ||
479 | int vbi_data_len = ((dev->vbi_read + len) > vbi_size) ? | ||
480 | (vbi_size - dev->vbi_read) : len; | ||
481 | |||
482 | /* Copy VBI data */ | ||
483 | if (vbi_buf != NULL) | ||
484 | em28xx_copy_vbi(dev, vbi_buf, p, vbi_data_len); | ||
485 | dev->vbi_read += vbi_data_len; | ||
486 | |||
487 | if (vbi_data_len < len) { | ||
488 | /* Continue with copying video data */ | ||
489 | dev->capture_type = 2; | ||
490 | p += vbi_data_len; | ||
491 | len -= vbi_data_len; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | if (dev->capture_type == 2) { | ||
496 | buf = finish_field_prepare_next(dev, buf, dma_q); | ||
497 | dev->usb_ctl.vid_buf = buf; | ||
498 | dev->capture_type = 3; | ||
499 | } | ||
500 | |||
501 | if (buf != NULL && dev->capture_type == 3 && len > 0) | ||
502 | em28xx_copy_video(dev, buf, p, len); | ||
503 | } | 513 | } |
504 | return rc; | 514 | return 1; |
505 | } | 515 | } |
506 | 516 | ||
507 | 517 | ||