Revision 3f9bff71

View differences:

libav/grab.c
323 323
    .flags = AVFMT_NOFILE,
324 324
};
325 325

  
326
/*
327
 * Done below so we can register the aiw grabber
328
 * /
329
int video_grab_init(void)
330
{
331
    av_register_input_format(&video_grab_device_format);
332
    return 0;
333
}
334
*/
335

  
336
typedef struct {
337
    int fd;
338
    int frame_format; /* see VIDEO_PALETTE_xxx */
339
    int width, height;
340
    int frame_rate;
341
    INT64 time_frame;
342
    int frame_size;
343
    int deint;
344
    int halfw;
345
    UINT8 *src_mem;
346
    UINT8 *lum_m4_mem;
347
} AIWVideoData;
348

  
349
static int aiw_grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
350
{
351
    AIWVideoData *s = s1->priv_data;
352
    AVStream *st;
353
    int width, height;
354
    int video_fd, frame_size;
355
    int ret, frame_rate;
356
    int desired_palette;
357

  
358
    if (!ap || ap->width <= 0 || ap->height <= 0 || ap->frame_rate <= 0)
359
        return -1;
360
    
361
    width = ap->width;
362
    height = ap->height;
363
    frame_rate = ap->frame_rate;
364

  
365
    st = av_new_stream(s1, 0);
366
    if (!st)
367
        return -ENOMEM;
368

  
369
    s->width = width;
370
    s->height = height;
371
    s->frame_rate = frame_rate;
372

  
373
    video_fd = open(v4l_device, O_RDONLY | O_NONBLOCK);
374
    if (video_fd < 0) {
375
        perror(v4l_device);
376
        goto fail;
377
    }
378
    
379
    if (ioctl(video_fd,VIDIOCGCAP,&video_cap) < 0) {
380
        perror("VIDIOCGCAP");
381
        goto fail;
382
    }
383

  
384
    if (!(video_cap.type & VID_TYPE_CAPTURE)) {
385
        fprintf(stderr, "Fatal: grab device does not handle capture\n");
386
        goto fail;
387
    }
388

  
389
    desired_palette = -1;
390
    if (st->codec.pix_fmt == PIX_FMT_YUV420P) {
391
        desired_palette = VIDEO_PALETTE_YUV420P;
392
    } else if (st->codec.pix_fmt == PIX_FMT_YUV422) {
393
        desired_palette = VIDEO_PALETTE_YUV422;
394
    } else if (st->codec.pix_fmt == PIX_FMT_BGR24) {
395
        desired_palette = VIDEO_PALETTE_RGB24;
396
    }    
397
    
398
    /* unmute audio */
399

  
400
    ret = ioctl(video_fd,VIDIOCGMBUF,&gb_buffers);
401
    if (ret < 0) {
402
        /* try to use read based access */
403
        struct video_window win;
404
        struct video_picture pict;
405
        int val;
406

  
407
        win.x = 0;
408
        win.y = 0;
409
        win.width = width;
410
        win.height = height;
411
        win.chromakey = -1;
412
        win.flags = 0;
413

  
414
        ioctl(video_fd, VIDIOCSWIN, &win);
415

  
416
        ioctl(video_fd, VIDIOCGPICT, &pict);
417
#if 0
418
        printf("v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n",
419
               pict.colour,
420
               pict.hue,
421
               pict.brightness,
422
               pict.contrast,
423
               pict.whiteness);
424
#endif        
425
        /* try to choose a suitable video format */
426
        pict.palette=VIDEO_PALETTE_YUV422;
427
        ret = ioctl(video_fd, VIDIOCSPICT, &pict);
428
        if (ret < 0) {
429
            fprintf(stderr,"Could Not Find YUY2 capture window.\n");
430
            goto fail;
431
        }
432
        if ((width == video_cap.maxwidth && height == video_cap.maxheight) ||
433
            (width == video_cap.maxwidth && height == video_cap.maxheight*2) ||
434
            (width == video_cap.maxwidth/2 && height == video_cap.maxheight)) {
435

  
436
            s->deint=0;
437
            s->halfw=0;
438
            if (height == video_cap.maxheight*2) s->deint=1;
439
            if (width == video_cap.maxwidth/2) s->halfw=1;
440
        } else {
441
            fprintf(stderr,"\nIncorrect Grab Size Supplied - Supported Sizes Are:\n");
442
            fprintf(stderr," %dx%d  %dx%d %dx%d\n\n",
443
                video_cap.maxwidth,video_cap.maxheight,
444
                video_cap.maxwidth,video_cap.maxheight*2,
445
                video_cap.maxwidth/2,video_cap.maxheight);
446
            goto fail;
447
        }
448

  
449
        s->frame_format = pict.palette;
450

  
451
        val = 1;
452
        ioctl(video_fd, VIDIOCCAPTURE, &val);
453

  
454
        s->time_frame = av_gettime();
455
    } else {
456
        fprintf(stderr,"mmap-based capture will not work with this grab.\n");
457
        goto fail;
458
    }
459

  
460
    frame_size = (width * height * 3) / 2;
461
    st->codec.pix_fmt = PIX_FMT_YUV420P;
462
    s->fd = video_fd;
463
    s->frame_size = frame_size;
464
    
465
    st->codec.codec_type = CODEC_TYPE_VIDEO;
466
    st->codec.codec_id = CODEC_ID_RAWVIDEO;
467
    st->codec.width = width;
468
    st->codec.height = height;
469
    st->codec.frame_rate = frame_rate;
470

  
471
    if (s->halfw == 0) {
472
        s->src_mem = av_malloc(s->width*2);
473
    } else {
474
        s->src_mem = av_malloc(s->width*4);
475
    }
476
    if (!s->src_mem) goto fail;
477

  
478
    s->lum_m4_mem = av_malloc(s->width);
479
    if (!s->lum_m4_mem) {
480
        av_free(s->src_mem);
481
        goto fail;
482
    }
483

  
484
    return 0;
485
 fail:
486
    if (video_fd >= 0)
487
        close(video_fd);
488
    av_free(st);
489
    return -EIO;
490
}
491

  
492
//#ifdef HAVE_MMX
493
//#undef HAVE_MMX
494
//#endif
495

  
496
#ifdef HAVE_MMX
497
#include "../libavcodec/i386/mmx.h"
498

  
499
#define LINE_WITH_UV \
500
                    movq_m2r(ptr[0],mm0); \
501
                    movq_m2r(ptr[8],mm1);  \
502
                    movq_r2r(mm0, mm4); \
503
                    punpcklbw_r2r(mm1,mm0); \
504
                    punpckhbw_r2r(mm1,mm4); \
505
                    movq_r2r(mm0,mm5); \
506
                    punpcklbw_r2r(mm4,mm0); \
507
                    punpckhbw_r2r(mm4,mm5); \
508
                    movq_r2r(mm0,mm1); \
509
                    punpcklbw_r2r(mm5,mm1); \
510
                    movq_r2m(mm1,lum[0]); \
511
                    movq_m2r(ptr[16],mm2); \
512
                    movq_m2r(ptr[24],mm1); \
513
                    movq_r2r(mm2,mm4); \
514
                    punpcklbw_r2r(mm1,mm2); \
515
                    punpckhbw_r2r(mm1,mm4); \
516
                    movq_r2r(mm2,mm3); \
517
                    punpcklbw_r2r(mm4,mm2); \
518
                    punpckhbw_r2r(mm4,mm3); \
519
                    movq_r2r(mm2,mm1); \
520
                    punpcklbw_r2r(mm3,mm1); \
521
                    movq_r2m(mm1,lum[8]); \
522
                    punpckhdq_r2r(mm2,mm0); \
523
                    punpckhdq_r2r(mm3,mm5); \
524
                    movq_r2m(mm0,cb[0]); \
525
                    movq_r2m(mm5,cr[0]);
526

  
527
#define LINE_NO_UV \
528
                    movq_m2r(ptr[0],mm0);\
529
                    movq_m2r(ptr[8],mm1);\
530
                    movq_r2r(mm0, mm4);\
531
                    punpcklbw_r2r(mm1,mm0); \
532
                    punpckhbw_r2r(mm1,mm4);\
533
                    movq_r2r(mm0,mm5);\
534
                    punpcklbw_r2r(mm4,mm0);\
535
                    punpckhbw_r2r(mm4,mm5);\
536
                    movq_r2r(mm0,mm1);\
537
                    punpcklbw_r2r(mm5,mm1);\
538
                    movq_r2m(mm1,lum[0]);\
539
                    movq_m2r(ptr[16],mm2);\
540
                    movq_m2r(ptr[24],mm1);\
541
                    movq_r2r(mm2,mm4);\
542
                    punpcklbw_r2r(mm1,mm2);\
543
                    punpckhbw_r2r(mm1,mm4);\
544
                    movq_r2r(mm2,mm3);\
545
                    punpcklbw_r2r(mm4,mm2);\
546
                    punpckhbw_r2r(mm4,mm3);\
547
                    movq_r2r(mm2,mm1);\
548
                    punpcklbw_r2r(mm3,mm1);\
549
                    movq_r2m(mm1,lum[8]);
550

  
551
#define LINE_WITHUV_AVG \
552
                    movq_m2r(ptr[0], mm0);\
553
                    movq_m2r(ptr[8], mm1);\
554
                    movq_r2r(mm0, mm4);\
555
                    punpcklbw_r2r(mm1,mm0);\
556
                    punpckhbw_r2r(mm1,mm4);\
557
                    movq_r2r(mm0,mm5);\
558
                    punpcklbw_r2r(mm4,mm0);\
559
                    punpckhbw_r2r(mm4,mm5);\
560
                    movq_r2r(mm0,mm1);\
561
                    movq_r2r(mm5,mm2);\
562
                    punpcklbw_r2r(mm7,mm1);\
563
                    punpcklbw_r2r(mm7,mm2);\
564
                    paddw_r2r(mm6,mm1);\
565
                    paddw_r2r(mm2,mm1);\
566
                    psraw_i2r(1,mm1);\
567
                    packuswb_r2r(mm7,mm1);\
568
                    movd_r2m(mm1,lum[0]);\
569
                    movq_m2r(ptr[16],mm2);\
570
                    movq_m2r(ptr[24],mm1);\
571
                    movq_r2r(mm2,mm4);\
572
                    punpcklbw_r2r(mm1,mm2);\
573
                    punpckhbw_r2r(mm1,mm4);\
574
                    movq_r2r(mm2,mm3);\
575
                    punpcklbw_r2r(mm4,mm2);\
576
                    punpckhbw_r2r(mm4,mm3);\
577
                    movq_r2r(mm2,mm1);\
578
                    movq_r2r(mm3,mm4);\
579
                    punpcklbw_r2r(mm7,mm1);\
580
                    punpcklbw_r2r(mm7,mm4);\
581
                    paddw_r2r(mm6,mm1);\
582
                    paddw_r2r(mm4,mm1);\
583
                    psraw_i2r(1,mm1);\
584
                    packuswb_r2r(mm7,mm1);\
585
                    movd_r2m(mm1,lum[4]);\
586
                    punpckhbw_r2r(mm7,mm0);\
587
                    punpckhbw_r2r(mm7,mm2);\
588
                    paddw_r2r(mm6,mm0);\
589
                    paddw_r2r(mm2,mm0);\
590
                    psraw_i2r(1,mm0);\
591
                    packuswb_r2r(mm7,mm0);\
592
                    punpckhbw_r2r(mm7,mm5);\
593
                    punpckhbw_r2r(mm7,mm3);\
594
                    paddw_r2r(mm6,mm5);\
595
                    paddw_r2r(mm3,mm5);\
596
                    psraw_i2r(1,mm5);\
597
                    packuswb_r2r(mm7,mm5);\
598
                    movd_r2m(mm0,cb[0]);\
599
                    movd_r2m(mm5,cr[0]);
600

  
601
#define LINE_NOUV_AVG \
602
                    movq_m2r(ptr[0],mm0);\
603
                    movq_m2r(ptr[8],mm1);\
604
                    pand_r2r(mm5,mm0);\
605
                    pand_r2r(mm5,mm1);\
606
                    pmaddwd_r2r(mm6,mm0);\
607
                    pmaddwd_r2r(mm6,mm1);\
608
                    packssdw_r2r(mm1,mm0);\
609
                    paddw_r2r(mm6,mm0);\
610
                    psraw_i2r(1,mm0);\
611
                    movq_m2r(ptr[16],mm2);\
612
                    movq_m2r(ptr[24],mm3);\
613
                    pand_r2r(mm5,mm2);\
614
                    pand_r2r(mm5,mm3);\
615
                    pmaddwd_r2r(mm6,mm2);\
616
                    pmaddwd_r2r(mm6,mm3);\
617
                    packssdw_r2r(mm3,mm2);\
618
                    paddw_r2r(mm6,mm2);\
619
                    psraw_i2r(1,mm2);\
620
                    packuswb_r2r(mm2,mm0);\
621
                    movq_r2m(mm0,lum[0]);
622

  
623
#define DEINT_LINE_LUM(ptroff) \
624
                    movd_m2r(lum_m4[(ptroff)],mm0);\
625
                    movd_m2r(lum_m3[(ptroff)],mm1);\
626
                    movd_m2r(lum_m2[(ptroff)],mm2);\
627
                    movd_m2r(lum_m1[(ptroff)],mm3);\
628
                    movd_m2r(lum[(ptroff)],mm4);\
629
                    punpcklbw_r2r(mm7,mm0);\
630
                    movd_r2m(mm2,lum_m4[(ptroff)]);\
631
                    punpcklbw_r2r(mm7,mm1);\
632
                    punpcklbw_r2r(mm7,mm2);\
633
                    punpcklbw_r2r(mm7,mm3);\
634
                    punpcklbw_r2r(mm7,mm4);\
635
                    psllw_i2r(2,mm1);\
636
                    psllw_i2r(1,mm2);\
637
                    paddw_r2r(mm6,mm1);\
638
                    psllw_i2r(2,mm3);\
639
                    paddw_r2r(mm2,mm1);\
640
                    paddw_r2r(mm4,mm0);\
641
                    paddw_r2r(mm3,mm1);\
642
                    psubusw_r2r(mm0,mm1);\
643
                    psrlw_i2r(3,mm1);\
644
                    packuswb_r2r(mm7,mm1);\
645
                    movd_r2m(mm1,lum_m2[(ptroff)]);
646

  
647
#else
648
#include "../libavcodec/dsputil.h"
649

  
650
#define LINE_WITH_UV \
651
                    lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\
652
                    cb[0]=ptr[1];cb[1]=ptr[5];\
653
                    cr[0]=ptr[3];cr[1]=ptr[7];\
654
                    lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\
655
                    cb[2]=ptr[9];cb[3]=ptr[13];\
656
                    cr[2]=ptr[11];cr[3]=ptr[15];\
657
                    lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\
658
                    cb[4]=ptr[17];cb[5]=ptr[21];\
659
                    cr[4]=ptr[19];cr[5]=ptr[23];\
660
                    lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30];\
661
                    cb[6]=ptr[25];cb[7]=ptr[29];\
662
                    cr[6]=ptr[27];cr[7]=ptr[31];
663

  
664
#define LINE_NO_UV \
665
                    lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\
666
                    lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\
667
                    lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\
668
                    lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30];
669

  
670
#define LINE_WITHUV_AVG \
671
                    sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \
672
                    sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \
673
                    sum=(ptr[1]+ptr[5]+1) >> 1;cb[0]=sum; \
674
                    sum=(ptr[3]+ptr[7]+1) >> 1;cr[0]=sum; \
675
                    sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \
676
                    sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \
677
                    sum=(ptr[9]+ptr[13]+1) >> 1;cb[1]=sum; \
678
                    sum=(ptr[11]+ptr[15]+1) >> 1;cr[1]=sum; \
679
                    sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \
680
                    sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \
681
                    sum=(ptr[17]+ptr[21]+1) >> 1;cb[2]=sum; \
682
                    sum=(ptr[19]+ptr[23]+1) >> 1;cr[2]=sum; \
683
                    sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \
684
                    sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; \
685
                    sum=(ptr[25]+ptr[29]+1) >> 1;cb[3]=sum; \
686
                    sum=(ptr[27]+ptr[31]+1) >> 1;cr[3]=sum; 
687

  
688
#define LINE_NOUV_AVG \
689
                    sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \
690
                    sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \
691
                    sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \
692
                    sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \
693
                    sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \
694
                    sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \
695
                    sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \
696
                    sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; 
697

  
698
#define DEINT_LINE_LUM(ptroff) \
699
                    sum=(-lum_m4[(ptroff)]+(lum_m3[(ptroff)]<<2)+(lum_m2[(ptroff)]<<1)+(lum_m1[(ptroff)]<<2)-lum[(ptroff)]); \
700
                    lum_m4[(ptroff)]=lum_m2[(ptroff)];\
701
                    lum_m2[(ptroff)]=cm[(sum+4)>>3];\
702
                    sum=(-lum_m4[(ptroff)+1]+(lum_m3[(ptroff)+1]<<2)+(lum_m2[(ptroff)+1]<<1)+(lum_m1[(ptroff)+1]<<2)-lum[(ptroff)+1]); \
703
                    lum_m4[(ptroff)+1]=lum_m2[(ptroff)+1];\
704
                    lum_m2[(ptroff)+1]=cm[(sum+4)>>3];\
705
                    sum=(-lum_m4[(ptroff)+2]+(lum_m3[(ptroff)+2]<<2)+(lum_m2[(ptroff)+2]<<1)+(lum_m1[(ptroff)+2]<<2)-lum[(ptroff)+2]); \
706
                    lum_m4[(ptroff)+2]=lum_m2[(ptroff)+2];\
707
                    lum_m2[(ptroff)+2]=cm[(sum+4)>>3];\
708
                    sum=(-lum_m4[(ptroff)+3]+(lum_m3[(ptroff)+3]<<2)+(lum_m2[(ptroff)+3]<<1)+(lum_m1[(ptroff)+3]<<2)-lum[(ptroff)+3]); \
709
                    lum_m4[(ptroff)+3]=lum_m2[(ptroff)+3];\
710
                    lum_m2[(ptroff)+3]=cm[(sum+4)>>3];
711

  
712
#endif
713

  
714

  
715
static int aiw_grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
716
{
717
    AIWVideoData *s = s1->priv_data;
718
    INT64 curtime, delay;
719
    struct timespec ts;
720
    int first;
721
    INT64 per_frame = (INT64_C(1000000) * FRAME_RATE_BASE) / s->frame_rate;
722
    int dropped = 0;
723

  
724
    /* Calculate the time of the next frame */
725
    s->time_frame += per_frame;
726

  
727
    /* wait based on the frame rate */
728
    for(first = 1;; first = 0) {
729
        curtime = av_gettime();
730
        delay = s->time_frame - curtime;
731
        if (delay <= 0) {
732
            if (delay < -per_frame) {
733
                /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */
734
                dropped = 1;
735
                s->time_frame += per_frame;
736
            }
737
            break;
738
        }    
739
        ts.tv_sec = delay / 1000000;
740
        ts.tv_nsec = (delay % 1000000) * 1000;
741
        nanosleep(&ts, NULL);
742
    }
743

  
744
    if (av_new_packet(pkt, s->frame_size) < 0)
745
        return -EIO;
746

  
747
    if (dropped)
748
        pkt->flags |= PKT_FLAG_DROPPED_FRAME;
749

  
750
    /* read fields */
751
    {
752
        UINT8 *ptr, *lum, *cb, *cr;
753
        int h;
754
#ifndef HAVE_MMX
755
        int sum;
756
#endif
757
        UINT8* src = s->src_mem;
758
        UINT8 *ptrend = &src[s->width*2];
759
        lum=&pkt->data[0];
760
        cb=&lum[s->width*s->height];
761
        cr=&cb[(s->width*s->height)/4];
762
        if (s->deint == 0 && s->halfw == 0) {
763
            while (read(s->fd,src,s->width*2) < 0) {
764
                usleep(100);
765
            }
766
            for (h = 0; h < s->height-2; h+=2) {
767
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
768
                    LINE_WITH_UV
769
                }
770
                read(s->fd,src,s->width*2);
771
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) {
772
                    LINE_NO_UV
773
                }
774
                read(s->fd,src,s->width*2);
775
            }
776
/*
777
 * Do last two lines
778
 */
779
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
780
                LINE_WITH_UV
781
            }
782
            read(s->fd,src,s->width*2);
783
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) {
784
                LINE_NO_UV
785
            }
786
            /* drop second field */
787
            while (read(s->fd,src,s->width*2) < 0) {
788
                usleep(100);
789
            }
790
            for (h = 0; h < s->height - 1; h++) {
791
                read(s->fd,src,s->width*2);
792
            }
793
        } else if (s->halfw == 1) {
794
#ifdef HAVE_MMX
795
            mmx_t rounder;
796
            mmx_t masker;
797
            rounder.uw[0]=1;
798
            rounder.uw[1]=1;
799
            rounder.uw[2]=1;
800
            rounder.uw[3]=1;
801
            masker.ub[0]=0xff;
802
            masker.ub[1]=0;
803
            masker.ub[2]=0xff;
804
            masker.ub[3]=0;
805
            masker.ub[4]=0xff;
806
            masker.ub[5]=0;
807
            masker.ub[6]=0xff;
808
            masker.ub[7]=0;
809
            pxor_r2r(mm7,mm7);
810
            movq_m2r(rounder,mm6);
811
#endif
812
            while (read(s->fd,src,s->width*4) < 0) {
813
                usleep(100);
814
            }
815
            ptrend = &src[s->width*4];
816
            for (h = 0; h < s->height-2; h+=2) {
817
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) {
818
                    LINE_WITHUV_AVG
819
                }
820
                read(s->fd,src,s->width*4);
821
#ifdef HAVE_MMX
822
                movq_m2r(masker,mm5);
823
#endif
824
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) {
825
                    LINE_NOUV_AVG
826
                }
827
                read(s->fd,src,s->width*4);
828
            }
829
/*
830
 * Do last two lines
831
 */
832
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) {
833
                LINE_WITHUV_AVG
834
            }
835
            read(s->fd,src,s->width*4);
836
#ifdef HAVE_MMX
837
            movq_m2r(masker,mm5);
838
#endif
839
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) {
840
                LINE_NOUV_AVG
841
            }
842
            /* drop second field */
843
            while (read(s->fd,src,s->width*4) < 0) {
844
                usleep(100);
845
            }
846
            for (h = 0; h < s->height - 1; h++) {
847
                read(s->fd,src,s->width*4);
848
            }
849
        } else {
850
            UINT8 *lum_m1, *lum_m2, *lum_m3, *lum_m4;
851
#ifdef HAVE_MMX
852
            mmx_t rounder;
853
            rounder.uw[0]=4;
854
            rounder.uw[1]=4;
855
            rounder.uw[2]=4;
856
            rounder.uw[3]=4;
857
            movq_m2r(rounder,mm6);
858
            pxor_r2r(mm7,mm7);
859
#else
860
            UINT8 *cm = cropTbl + MAX_NEG_CROP;
861
#endif
862

  
863
            /* read two fields and deinterlace them */
864
            while (read(s->fd,src,s->width*2) < 0) {
865
                usleep(100);
866
            }
867
            for (h = 0; h < (s->height/2)-2; h+=2) {
868
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
869
                    LINE_WITH_UV
870
                }
871
                read(s->fd,src,s->width*2);
872
/* skip a luminance line - will be filled in later */
873
                lum += s->width;
874
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
875
                    LINE_WITH_UV
876
                }
877
/* skip a luminance line - will be filled in later */
878
                lum += s->width;
879
                read(s->fd,src,s->width*2);
880
            }
881
/*
882
 * Do last two lines
883
 */
884
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
885
                LINE_WITH_UV
886
            }
887
/* skip a luminance line - will be filled in later */
888
            lum += s->width;
889
            read(s->fd,src,s->width*2);
890
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) {
891
                LINE_WITH_UV
892
            }
893
/*
894
 *
895
 * SECOND FIELD
896
 *
897
 */
898
            lum=&pkt->data[s->width];
899
            while (read(s->fd,src,s->width*2) < 0) {
900
                usleep(10);
901
            }
902
/* First (and last) two lines not interlaced */
903
            for (h = 0; h < 2; h++) {
904
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) {
905
                    LINE_NO_UV
906
                }
907
                read(s->fd,src,s->width*2);
908
/* skip a luminance line */
909
                lum += s->width;
910
            }
911
            lum_m1=&lum[-s->width];
912
            lum_m2=&lum_m1[-s->width];
913
            lum_m3=&lum_m2[-s->width];
914
            memmove(s->lum_m4_mem,&lum_m3[-s->width],s->width);
915
            for (; h < (s->height/2)-1; h++) {
916
                lum_m4=s->lum_m4_mem;
917
                for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16,lum_m1+=16,lum_m2+=16,lum_m3+=16,lum_m4+=16) {
918
                    LINE_NO_UV
919

  
920
                    DEINT_LINE_LUM(0)
921
                    DEINT_LINE_LUM(4)
922
                    DEINT_LINE_LUM(8)
923
                    DEINT_LINE_LUM(12)
924
                }
925
                read(s->fd,src,s->width*2);
926
/* skip a luminance line */
927
                lum += s->width;
928
                lum_m1 += s->width;
929
                lum_m2 += s->width;
930
                lum_m3 += s->width;
931
//                lum_m4 += s->width;
932
            }
933
/*
934
 * Do last line
935
 */
936
            lum_m4=s->lum_m4_mem;
937
            for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, lum_m1+=16, lum_m2+=16, lum_m3+=16, lum_m4+=16) {
938
                LINE_NO_UV
939

  
940
                DEINT_LINE_LUM(0)
941
                DEINT_LINE_LUM(4)
942
                DEINT_LINE_LUM(8)
943
                DEINT_LINE_LUM(12)
944
            }
945
        }
946
#ifdef HAVE_MMX
947
        emms();
948
#endif
949
    }
950
    return s->frame_size;
951
}
952

  
953
static int aiw_grab_read_close(AVFormatContext *s1)
954
{
955
    AIWVideoData *s = s1->priv_data;
956

  
957
    close(s->fd);
958
    av_free(s->lum_m4_mem);
959
    av_free(s->src_mem);
960

  
961
    return 0;
962
}
963

  
964
AVInputFormat aiw_grab_device_format = {
965
    "aiw_grab_device",
966
    "All-In-Wonder (km read-based) video grab",
967
    sizeof(AIWVideoData),
968
    NULL,
969
    aiw_grab_read_header,
970
    aiw_grab_read_packet,
971
    aiw_grab_read_close,
972
    .flags = AVFMT_NOFILE,
973
};
974

  
326 975
int video_grab_init(void)
327 976
{
328 977
    av_register_input_format(&video_grab_device_format);
978
    av_register_input_format(&aiw_grab_device_format);
329 979
    return 0;
330 980
}

Also available in: Unified diff