aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/gspca/ov534.c115
1 files changed, 57 insertions, 58 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index ea2245626d53..647c448f492f 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -46,9 +46,9 @@ MODULE_LICENSE("GPL");
46/* specific webcam descriptor */ 46/* specific webcam descriptor */
47struct sd { 47struct sd {
48 struct gspca_dev gspca_dev; /* !! must be the first item */ 48 struct gspca_dev gspca_dev; /* !! must be the first item */
49 __u32 last_fid;
50 __u32 last_pts; 49 __u32 last_pts;
51 int frame_rate; 50 u16 last_fid;
51 u8 frame_rate;
52}; 52};
53 53
54/* V4L2 controls supported by the driver */ 54/* V4L2 controls supported by the driver */
@@ -428,76 +428,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
428{ 428{
429 struct sd *sd = (struct sd *) gspca_dev; 429 struct sd *sd = (struct sd *) gspca_dev;
430 __u32 this_pts; 430 __u32 this_pts;
431 int this_fid; 431 u16 this_fid;
432 int remaining_len = len; 432 int remaining_len = len;
433 __u8 *next_data = data;
434 433
435scan_next: 434 do {
436 if (remaining_len <= 0) 435 len = min(remaining_len, 2040); /*fixme: was 2048*/
437 return;
438
439 data = next_data;
440 len = min(remaining_len, 2048);
441 remaining_len -= len;
442 next_data += len;
443
444 /* Payloads are prefixed with a UVC-style header. We
445 consider a frame to start when the FID toggles, or the PTS
446 changes. A frame ends when EOF is set, and we've received
447 the correct number of bytes. */
448
449 /* Verify UVC header. Header length is always 12 */
450 if (data[0] != 12 || len < 12) {
451 PDEBUG(D_PACK, "bad header");
452 goto discard;
453 }
454 436
455 /* Check errors */ 437 /* Payloads are prefixed with a UVC-style header. We
456 if (data[1] & UVC_STREAM_ERR) { 438 consider a frame to start when the FID toggles, or the PTS
457 PDEBUG(D_PACK, "payload error"); 439 changes. A frame ends when EOF is set, and we've received
458 goto discard; 440 the correct number of bytes. */
459 }
460 441
461 /* Extract PTS and FID */ 442 /* Verify UVC header. Header length is always 12 */
462 if (!(data[1] & UVC_STREAM_PTS)) { 443 if (data[0] != 12 || len < 12) {
463 PDEBUG(D_PACK, "PTS not present"); 444 PDEBUG(D_PACK, "bad header");
464 goto discard; 445 goto discard;
465 } 446 }
466 this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
467 this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
468
469 /* If PTS or FID has changed, start a new frame. */
470 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
471 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
472 sd->last_pts = this_pts;
473 sd->last_fid = this_fid;
474 }
475
476 /* Add the data from this payload */
477 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
478 data + 12, len - 12);
479 447
480 /* If this packet is marked as EOF, end the frame */ 448 /* Check errors */
481 if (data[1] & UVC_STREAM_EOF) { 449 if (data[1] & UVC_STREAM_ERR) {
482 sd->last_pts = 0; 450 PDEBUG(D_PACK, "payload error");
451 goto discard;
452 }
483 453
484 if ((frame->data_end - frame->data) != 454 /* Extract PTS and FID */
485 (gspca_dev->width * gspca_dev->height * 2)) { 455 if (!(data[1] & UVC_STREAM_PTS)) {
486 PDEBUG(D_PACK, "short frame"); 456 PDEBUG(D_PACK, "PTS not present");
487 goto discard; 457 goto discard;
488 } 458 }
459 this_pts = (data[5] << 24) | (data[4] << 16)
460 | (data[3] << 8) | data[2];
461 this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
489 462
490 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 463 /* If PTS or FID has changed, start a new frame. */
464 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
465 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
491 NULL, 0); 466 NULL, 0);
467 sd->last_pts = this_pts;
468 sd->last_fid = this_fid;
469 }
470
471 /* Add the data from this payload */
472 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
473 data + 12, len - 12);
474
475 /* If this packet is marked as EOF, end the frame */
476 if (data[1] & UVC_STREAM_EOF) {
477 sd->last_pts = 0;
478
479 if (frame->data_end - frame->data !=
480 gspca_dev->width * gspca_dev->height * 2) {
481 PDEBUG(D_PACK, "short frame");
482 goto discard;
483 }
484
485 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
486 NULL, 0);
492 } 487 }
493 488
494 /* Done this payload */ 489 /* Done this payload */
495 goto scan_next; 490 goto scan_next;
496 491
497discard: 492discard:
498 /* Discard data until a new frame starts. */ 493 /* Discard data until a new frame starts. */
499 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 494 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
500 goto scan_next; 495
496scan_next:
497 remaining_len -= len;
498 data += len;
499 } while (remaining_len > 0);
501} 500}
502 501
503/* get stream parameters (framerate) */ 502/* get stream parameters (framerate) */