Tuesday, September 20, 2011

SoMagic EasyCap is no longer a (very small) boat anchor

Success in getting continuous video frames out of the capture device!

I can now stream 720x576 UYVY frames at 25 fps from the unit and pipe the output into mplayer, which can play them.
Obligatory screenshot follows (which doesn't do justice to the fact that it's motion video...but it would seem unfair of Carole Hersee to miss out, now she isn't cut in two!)
One full frame of test card F


I've posted the source code that you need to do this to a public github project easycap-somagic-linux . The code is incredibly rough yet, and there's plenty of to-dos on the list, but they will have to wait until I have more time. It's usable as far as I need it to be, for now.

I'm hoping that someone else will pick it up and turn it into a proper device and video4linux driver.


Friday, September 16, 2011

Vertical Hold

Isochronous problems sorted, using usblib-1.0 and the asynchronous API.

I now have every line of the field.
Just the problem of finding the vertical blanking period so that I can tell where the top of the frame is.
The 7113 indicates there is a bit field called SAV/EAV that should be setting a bit in the data stream to indicate the VBI, but it seems to be acting screwy.

Obligatory status pic:
Try the vertical hold knob...

SoMagic EasyCap - almost two fields

Continuing on with the EasyCap device, I've been able to generate some executables to initialise the device, and capture some video data.

This is the current best result, generated with "mplayer cap.out -demuxer rawvideo -rawvideo "w=724:h=460:format=uyvy"
SoMagic EasyCap capture of Test Ctard F - work in progress

It seems - unless I'm doing it wrong - that you need to manually find the horizontal sync markers in the video data. And the vertical sync, which you can see from the image, I haven't done yet.

The biggest problem I need to overcome is that what you see here is generated from 4 isochronous USB transfers of near 200kbytes each. There seems to be some kind of delay in fetching the data - evidenced by the three "cuts" in the vertical picture ( the second is in the vertical blanking section, so you can't see it)

I'm using libusb, and this is the section that captures the video data:

ret = usb_isochronous_setup(&isourb, 0x00000082, 3072, isobuf, 64 * 3072);
printf("195 isochronous setup returned %d\n", ret);
ret = usb_isochronous_submit(devh, isourb, &isotv);
printf("195 isochronous submit returned %d\n", ret);


ret = usb_isochronous_setup(&isourb1, 0x00000082, 3072, isobuf1, 64 * 3072);
printf("195a isochronous setup returned %d\n", ret);
ret = usb_isochronous_submit(devh, isourb1, &isotv1);
printf("195a isochronous submit returned %d\n", ret);

ret = usb_isochronous_setup(&isourb2, 0x00000082, 3072, isobuf2, 64 * 3072);
printf("195b isochronous setup returned %d\n", ret);
ret = usb_isochronous_submit(devh, isourb2, &isotv2);
printf("195b isochronous submit returned %d\n", ret);

ret = usb_isochronous_setup(&isourb3, 0x00000082, 3072, isobuf3, 64 * 3072);
printf("195c isochronous setup returned %d\n", ret);
ret = usb_isochronous_submit(devh, isourb3, &isotv3);
printf("195c isochronous submit returned %d\n", ret);

int r1,r2,r3,r4;
ret = usb_isochronous_reap(devh, isourb, &isotv, 1000);
//printf("195 isochronous reap returned %d, bytes: ", ret);
r1=ret;

ret = usb_isochronous_reap(devh, isourb1, &isotv1, 1000);
//printf("195a isochronous reap returned %d, bytes: ", ret);
r2=ret;

ret = usb_isochronous_reap(devh, isourb2, &isotv2, 1000);
//printf("195b isochronous reap returned %d, bytes: ", ret);
r3=ret;

ret = usb_isochronous_reap(devh, isourb3, &isotv3, 1000);
//printf("195c isochronous reap returned %d, bytes: ", ret);
r4=ret;

save_bytes(isourb->buffer, r1);
save_bytes(isourb1->buffer, r2);
save_bytes(isourb2->buffer, r3);
save_bytes(isourb3->buffer, r4);
Any clues anyone?



Thursday, September 15, 2011

The SoMagic EasyCap and linux

The short story is...it doesn't work. Yet.

The long story... is quite long. This is part of that story.

The EasyCap is a usb video capture device, or rather, a number of different devices. There exists at least 3 known variants:
1. The Syntek variant, with USB ID 05e1:0408 supported by this driver
2. The so-called DC60+ with an Empia USB bridge and USB ID eb1a:2861, which works with the em28xx driver included in recent Linux kernels
3. And lastly, the SoMagic variant, with USB ID 1c88:0007
All these are sold as "EasyCap", they all look the same, and if you're buying off eBay (where they can be had for less than $10AUD each ) it's a bit of a lucky dip as to which one you get.

I must be unlucky, as I got the one for which there exists no linux driver - the SoMagic.

Looking inside the device, and from the various reports, the unit is almost identical to the Syntek job, except for the USB interface chip.
These are the major chips inside:
  • SMI2021CBE - the usb controller device. Can't find a datasheet for this at all - the only info I've been able to find is this, and actually, that's for the 2020, not 2021. I'm assuming they're very similar
  • GM7113 - the video processing chip. Seems to be a clone of the Philips SAA7113. So this is the part that is the same as the Syntek unit.

An inital lsusb -v -d 1c88:0007 yields this:
Bus 002 Device 005: ID 1c88:0007 Somagic, Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1c88 Somagic, Inc.
  idProduct          0x0007
  bcdDevice            1.00
  iManufacturer           1 Somagic, Inc.
  iProduct                2 SM-USB 007
  iSerial                 3 SMBL007
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           18
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)

So, if I'm reading this right... no defined endpoints. Totally vendor specific.
Interesting, on Windows using the supplied driver, the device doesn't even have that USB id. It's id is 1c88:003c. Clearly, the windows driver is doing some magic.
A usbsnoop and transform to a test program (instructions are here - brilliant! ) later, I can get it to show that device id in linux. Here's the "new" device's lsusb -v -d ...

Bus 002 Device 006: ID 1c88:003c Somagic, Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1c88 Somagic, Inc.
  idProduct          0x003c
  bcdDevice            1.00
  iManufacturer           1  Somagic, Inc. 
  iProduct                2 SMI Grabber DEV
  iSerial                 3 SMIGRABBER9876543210
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           50
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x03ff  1x 1023 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x1400  3x 1024 bytes
        bInterval               1
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)
Aha! Now there are endpoints. I believe that this is closer to what the Syntek presents when it is first plugged in. The SoMagic must require this "firmware" to be uploaded to the initial device before it makes the second device available. There's about 7k of data that is uploaded in usb control messages.

Unfortunately, the Syntek driver doesn't work with the device after this initialisation. Things aren't where the driver expects them to be.

Investigations are continuing....