aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/pac207.c
diff options
context:
space:
mode:
authorHans de Goede <j.w.r.degoede@hhs.nl>2008-07-04 17:29:32 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:17:02 -0400
commitab8f12cf8e3d33adec382585f9f60f8686a372c3 (patch)
tree5e788581199b1a8ddeaba222d958a8a77ba84a02 /drivers/media/video/gspca/pac207.c
parent24c530b4abb979f9e79298f0b4c4e83781a0e4c3 (diff)
V4L/DVB (8197): gspca: pac207 frames no more decoded in the subdriver.
videodev2: New pixfmt pac207: Remove the specific decoding. main: get_buff_size operation added for the subdriver. Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl> Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/pac207.c')
-rw-r--r--drivers/media/video/gspca/pac207.c353
1 files changed, 43 insertions, 310 deletions
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 7e067456e62b..0135ba599e81 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -58,34 +58,10 @@ MODULE_LICENSE("GPL");
58 before doing any other adjustments */ 58 before doing any other adjustments */
59#define PAC207_AUTOGAIN_IGNORE_FRAMES 3 59#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
60 60
61enum pac207_line_state {
62 LINE_HEADER1,
63 LINE_HEADER2,
64 LINE_UNCOMPRESSED,
65 LINE_COMPRESSED,
66};
67
68struct pac207_decoder_state {
69 /* generic state */
70 u16 line_read;
71 u16 line_marker;
72 u8 line_state;
73 u8 header_read;
74 /* compression state */
75 u16 processed_bytes;
76 u8 remaining_bits;
77 s8 no_remaining_bits;
78 u8 get_abs;
79 u8 discard_byte;
80 u8 line_decode_buf[352];
81};
82
83/* specific webcam descriptor */ 61/* specific webcam descriptor */
84struct sd { 62struct sd {
85 struct gspca_dev gspca_dev; /* !! must be the first item */ 63 struct gspca_dev gspca_dev; /* !! must be the first item */
86 64
87 struct pac207_decoder_state decoder_state;
88
89 u8 mode; 65 u8 mode;
90 66
91 u8 brightness; 67 u8 brightness;
@@ -94,6 +70,7 @@ struct sd {
94 u8 gain; 70 u8 gain;
95 71
96 u8 sof_read; 72 u8 sof_read;
73 u8 header_read;
97 u8 autogain_ignore_frames; 74 u8 autogain_ignore_frames;
98 75
99 atomic_t avg_lum; 76 atomic_t avg_lum;
@@ -173,8 +150,8 @@ static struct ctrl sd_ctrls[] = {
173}; 150};
174 151
175static struct cam_mode sif_mode[] = { 152static struct cam_mode sif_mode[] = {
176 {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, 153 {V4L2_PIX_FMT_PAC207, 176, 144, 1},
177 {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, 154 {V4L2_PIX_FMT_PAC207, 352, 288, 0},
178}; 155};
179 156
180static const __u8 pac207_sensor_init[][8] = { 157static const __u8 pac207_sensor_init[][8] = {
@@ -361,68 +338,17 @@ static void sd_close(struct gspca_dev *gspca_dev)
361{ 338{
362} 339}
363 340
364/* -- convert pixart frames to Bayer -- */ 341static int sd_get_buff_size_op(struct gspca_dev *gspca_dev, int mode)
365/* Sonix decompressor struct B.S.(2004) */
366static struct {
367 u8 is_abs;
368 u8 len;
369 s8 val;
370} table[256];
371
372void init_pixart_decoder(void)
373{ 342{
374 int i, is_abs, val, len; 343 switch (gspca_dev->cam.cam_mode[mode].width) {
375 344 case 176: /* 176x144 */
376 for (i = 0; i < 256; i++) { 345 /* uncompressed, add 2 bytes / line for line header */
377 is_abs = 0; 346 return (176 + 2) * 144;
378 val = 0; 347 case 352: /* 352x288 */
379 len = 0; 348 /* compressed */
380 if ((i & 0xC0) == 0) { 349 return 352 * 288 / 2;
381 /* code 00 */
382 val = 0;
383 len = 2;
384 } else if ((i & 0xC0) == 0x40) {
385 /* code 01 */
386 val = -5;
387 len = 2;
388 } else if ((i & 0xC0) == 0x80) {
389 /* code 10 */
390 val = 5;
391 len = 2;
392 } else if ((i & 0xF0) == 0xC0) {
393 /* code 1100 */
394 val = -10;
395 len = 4;
396 } else if ((i & 0xF0) == 0xD0) {
397 /* code 1101 */
398 val = 10;
399 len = 4;
400 } else if ((i & 0xF8) == 0xE0) {
401 /* code 11100 */
402 val = -15;
403 len = 5;
404 } else if ((i & 0xF8) == 0xE8) {
405 /* code 11101 */
406 val = 15;
407 len = 5;
408 } else if ((i & 0xFC) == 0xF0) {
409 /* code 111100 */
410 val = -20;
411 len = 6;
412 } else if ((i & 0xFC) == 0xF4) {
413 /* code 111101 */
414 val = 20;
415 len = 6;
416 } else if ((i & 0xF8) == 0xF8) {
417 /* code 11111xxxxxx */
418 is_abs = 1;
419 val = 0;
420 len = 5;
421 }
422 table[i].is_abs = is_abs;
423 table[i].val = val;
424 table[i].len = len;
425 } 350 }
351 return -EIO; /* should never happen */
426} 352}
427 353
428/* auto gain and exposure algorithm based on the knee algorithm described here: 354/* auto gain and exposure algorithm based on the knee algorithm described here:
@@ -517,245 +443,52 @@ static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
517 return NULL; 443 return NULL;
518} 444}
519 445
520static int pac207_decompress_row(struct gspca_dev *gspca_dev,
521 struct gspca_frame *f,
522 __u8 *cdata,
523 int len)
524{
525 struct sd *sd = (struct sd *) gspca_dev;
526 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
527 unsigned char *outp = decoder_state->line_decode_buf +
528 decoder_state->line_read;
529 int val, bitlen, bitpos = -decoder_state->no_remaining_bits;
530 u8 code;
531
532 /* first two pixels are stored as raw 8-bit */
533 while (decoder_state->line_read < 2) {
534 *outp++ = *cdata++;
535 decoder_state->line_read++;
536 len--;
537 if (len == 0)
538 return 0;
539 }
540
541 while (decoder_state->line_read < gspca_dev->width) {
542 if (bitpos < 0) {
543 code = decoder_state->remaining_bits << (8 + bitpos) |
544 cdata[0] >> -bitpos;
545 } else {
546 u8 *addr = cdata + bitpos / 8;
547 code = addr[0] << (bitpos & 7) |
548 addr[1] >> (8 - (bitpos & 7));
549 }
550
551 bitlen = decoder_state->get_abs ?
552 6 : table[code].len;
553
554 /* Stop decompressing if we're out of input data */
555 if ((bitpos + bitlen) > (len * 8))
556 break;
557
558 if (decoder_state->get_abs) {
559 *outp++ = code & 0xFC;
560 decoder_state->line_read++;
561 decoder_state->get_abs = 0;
562 } else {
563 if (table[code].is_abs) {
564 decoder_state->get_abs = 1;
565 } else {
566 /* relative to left pixel */
567 val = outp[-2] +
568 table[code].val;
569 if (val > 0xff)
570 val = 0xff;
571 else if (val < 0)
572 val = 0;
573 *outp++ = val;
574 decoder_state->line_read++;
575 }
576 }
577 bitpos += bitlen;
578 }
579
580 if (decoder_state->line_read == gspca_dev->width) {
581 int compressed_line_len;
582
583 gspca_frame_add(gspca_dev, INTER_PACKET, f,
584 decoder_state->line_decode_buf,
585 gspca_dev->width);
586
587 /* completely decompressed line, round pos to nearest word */
588 compressed_line_len = ((decoder_state->processed_bytes * 8 +
589 bitpos + 15) / 16) * 2;
590
591 len -= compressed_line_len - decoder_state->processed_bytes;
592 if (len < 0) {
593 decoder_state->discard_byte = 1;
594 len = 0;
595 }
596 } else {
597 decoder_state->processed_bytes += len;
598 decoder_state->remaining_bits = cdata[bitpos/8];
599 decoder_state->no_remaining_bits = (8 - bitpos) & 7;
600 len = 0;
601 }
602
603 return len;
604}
605
606static void pac207_decode_line_init(struct gspca_dev *gspca_dev)
607{
608 struct sd *sd = (struct sd *) gspca_dev;
609 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
610
611 decoder_state->line_read = 0;
612 decoder_state->line_state = LINE_HEADER1;
613 decoder_state->processed_bytes = 0;
614 decoder_state->no_remaining_bits = 0;
615 decoder_state->get_abs = 0;
616}
617
618static void pac207_decode_frame_init(struct gspca_dev *gspca_dev)
619{
620 struct sd *sd = (struct sd *) gspca_dev;
621 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
622
623 decoder_state->header_read = 0;
624 decoder_state->discard_byte = 0;
625
626 pac207_decode_line_init(gspca_dev);
627}
628
629static int pac207_decode_frame_data(struct gspca_dev *gspca_dev,
630 struct gspca_frame *f, unsigned char *data, int len)
631{
632 struct sd *sd = (struct sd *) gspca_dev;
633 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
634 int needed = 0;
635
636 /* first 11 bytes after sof marker: frame header */
637 if (decoder_state->header_read < 11) {
638 /* get average lumination from frame header (byte 5) */
639 if (decoder_state->header_read < 5) {
640 needed = 5 - decoder_state->header_read;
641 if (len >= needed)
642 atomic_set(&sd->avg_lum, data[needed-1]);
643 }
644 /* skip the rest of the header */
645 needed = 11 - decoder_state->header_read;
646 if (len <= needed) {
647 decoder_state->header_read += len;
648 return 0;
649 }
650 data += needed;
651 len -= needed;
652 decoder_state->header_read = 11;
653 }
654
655 while (len) {
656 if (decoder_state->discard_byte) {
657 data++;
658 len--;
659 decoder_state->discard_byte = 0;
660 continue;
661 }
662
663 switch (decoder_state->line_state) {
664 case LINE_HEADER1:
665 decoder_state->line_marker = data[0] << 8;
666 decoder_state->line_state = LINE_HEADER2;
667 needed = 1;
668 break;
669 case LINE_HEADER2:
670 decoder_state->line_marker |= data[0];
671 switch (decoder_state->line_marker) {
672 case 0x0ff0:
673 decoder_state->line_state = LINE_UNCOMPRESSED;
674 break;
675 case 0x1ee1:
676 decoder_state->line_state = LINE_COMPRESSED;
677 break;
678 default:
679 PDEBUG(D_STREAM,
680 "Error unknown line-header %04X",
681 (int) decoder_state->line_marker);
682 gspca_dev->last_packet_type = DISCARD_PACKET;
683 return 0;
684 }
685 needed = 1;
686 break;
687 case LINE_UNCOMPRESSED:
688 needed = gspca_dev->width - decoder_state->line_read;
689 if (needed > len)
690 needed = len;
691 gspca_frame_add(gspca_dev, INTER_PACKET, f, data,
692 needed);
693 decoder_state->line_read += needed;
694 break;
695 case LINE_COMPRESSED:
696 needed = len -
697 pac207_decompress_row(gspca_dev, f, data, len);
698 break;
699 }
700
701 data += needed;
702 len -= needed;
703
704 if (decoder_state->line_read == gspca_dev->width) {
705 if ((f->data_end - f->data) ==
706 (gspca_dev->width * gspca_dev->height)) {
707 /* eureka we've got a frame */
708 return 1;
709 }
710 pac207_decode_line_init(gspca_dev);
711 }
712 }
713
714 return 0;
715}
716
717static void sd_pkt_scan(struct gspca_dev *gspca_dev, 446static void sd_pkt_scan(struct gspca_dev *gspca_dev,
718 struct gspca_frame *frame, 447 struct gspca_frame *frame,
719 __u8 *data, 448 __u8 *data,
720 int len) 449 int len)
721{ 450{
451 struct sd *sd = (struct sd *) gspca_dev;
722 unsigned char *sof; 452 unsigned char *sof;
723 int n;
724 453
725 sof = pac207_find_sof(gspca_dev, data, len); 454 sof = pac207_find_sof(gspca_dev, data, len);
726
727 if (sof) { 455 if (sof) {
456 int n;
457
728 /* finish decoding current frame */ 458 /* finish decoding current frame */
729 if (gspca_dev->last_packet_type == INTER_PACKET) { 459 n = sof - data;
730 n = sof - data; 460 if (n > sizeof pac207_sof_marker)
731 if (n > sizeof(pac207_sof_marker)) 461 n -= sizeof pac207_sof_marker;
732 n -= sizeof(pac207_sof_marker); 462 else
733 else 463 n = 0;
734 n = 0; 464 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
735 n = pac207_decode_frame_data(gspca_dev, frame, 465 data, n);
736 data, n); 466 sd->header_read = 0;
737 if (n)
738 frame = gspca_frame_add(gspca_dev,
739 LAST_PACKET,
740 frame,
741 NULL,
742 0);
743 else
744 PDEBUG(D_STREAM, "Incomplete frame");
745 }
746 pac207_decode_frame_init(gspca_dev);
747 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); 467 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
748 len -= sof - data; 468 len -= sof - data;
749 data = sof; 469 data = sof;
750 } 470 }
471 if (sd->header_read < 11) {
472 int needed;
751 473
752 if (gspca_dev->last_packet_type == DISCARD_PACKET) 474 /* get average lumination from frame header (byte 5) */
753 return; 475 if (sd->header_read < 5) {
476 needed = 5 - sd->header_read;
477 if (len >= needed)
478 atomic_set(&sd->avg_lum, data[needed - 1]);
479 }
480 /* skip the rest of the header */
481 needed = 11 - sd->header_read;
482 if (len <= needed) {
483 sd->header_read += len;
484 return;
485 }
486 data += needed;
487 len -= needed;
488 sd->header_read = 11;
489 }
754 490
755 n = pac207_decode_frame_data(gspca_dev, frame, data, len); 491 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
756 if (n)
757 gspca_frame_add(gspca_dev, LAST_PACKET,
758 frame, NULL, 0);
759} 492}
760 493
761static void setbrightness(struct gspca_dev *gspca_dev) 494static void setbrightness(struct gspca_dev *gspca_dev)
@@ -891,6 +624,7 @@ static const struct sd_desc sd_desc = {
891 .close = sd_close, 624 .close = sd_close,
892 .dq_callback = pac207_do_auto_gain, 625 .dq_callback = pac207_do_auto_gain,
893 .pkt_scan = sd_pkt_scan, 626 .pkt_scan = sd_pkt_scan,
627 .get_buff_size = sd_get_buff_size_op,
894}; 628};
895 629
896/* -- module initialisation -- */ 630/* -- module initialisation -- */
@@ -927,7 +661,6 @@ static struct usb_driver sd_driver = {
927/* -- module insert / remove -- */ 661/* -- module insert / remove -- */
928static int __init sd_mod_init(void) 662static int __init sd_mod_init(void)
929{ 663{
930 init_pixart_decoder();
931 if (usb_register(&sd_driver) < 0) 664 if (usb_register(&sd_driver) < 0)
932 return -1; 665 return -1;
933 PDEBUG(D_PROBE, "v%s registered", version); 666 PDEBUG(D_PROBE, "v%s registered", version);