USB: eyetoy mirroring

This commit is contained in:
Florin9doi 2021-02-21 14:48:04 +02:00 committed by refractionpcsx2
parent 7801682377
commit 7e10e4d6eb
9 changed files with 54 additions and 47 deletions

View File

@ -54,6 +54,7 @@ namespace usb_eyetoy
buffer_t mpeg_buffer;
std::mutex mpeg_mutex;
bool mirroring_enabled = true;
static int xioctl(int fh, unsigned long int request, void* arg)
{
@ -78,7 +79,7 @@ namespace usb_eyetoy
if (pixelformat == V4L2_PIX_FMT_YUYV)
{
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
int mpegLen = jo_write_mpeg(mpegData, ptr, 320, 240, JO_YUYV, JO_FLIP_X, JO_NONE);
int mpegLen = jo_write_mpeg(mpegData, ptr, 320, 240, JO_YUYV, mirroring_enabled ? JO_FLIP_X : JO_NONE, JO_NONE);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
}
@ -87,7 +88,7 @@ namespace usb_eyetoy
int width, height, actual_comps;
unsigned char* rgbData = jpgd::decompress_jpeg_image_from_memory(ptr, size, &width, &height, &actual_comps, 3);
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
int mpegLen = jo_write_mpeg(mpegData, rgbData, 320, 240, JO_RGB24, JO_FLIP_X, JO_NONE);
int mpegLen = jo_write_mpeg(mpegData, rgbData, 320, 240, JO_RGB24, mirroring_enabled ? JO_FLIP_X : JO_NONE, JO_NONE);
free(rgbData);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
@ -484,6 +485,11 @@ namespace usb_eyetoy
return len2;
};
void V4L2::SetMirroring(bool state)
{
mirroring_enabled = state;
}
static void deviceChanged(GtkComboBox* widget, gpointer data)
{
*(int*)data = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));

View File

@ -37,6 +37,7 @@ namespace usb_eyetoy
int Open();
int Close();
int GetImage(uint8_t* buf, int len);
void SetMirroring(bool state);
int Reset() { return 0; };
static const TCHAR* Name()

View File

@ -355,6 +355,7 @@ namespace usb_eyetoy
buffer_t mpeg_buffer{};
std::mutex mpeg_mutex;
bool mirroring_enabled = true;
void store_mpeg_frame(unsigned char* data, unsigned int len)
{
@ -369,7 +370,7 @@ namespace usb_eyetoy
if (bitsperpixel == 24)
{
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
int mpegLen = jo_write_mpeg(mpegData, data, 320, 240, JO_RGB24, JO_FLIP_X, JO_FLIP_Y);
int mpegLen = jo_write_mpeg(mpegData, data, 320, 240, JO_BGR24, mirroring_enabled ? JO_FLIP_X : JO_NONE, JO_FLIP_Y);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
}
@ -476,6 +477,11 @@ namespace usb_eyetoy
return len2;
};
void DirectShow::SetMirroring(bool state)
{
mirroring_enabled = state;
}
BOOL CALLBACK DirectShowDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int port;

View File

@ -88,6 +88,7 @@ namespace usb_eyetoy
int Open();
int Close();
int GetImage(uint8_t* buf, int len);
void SetMirroring(bool state);
int Reset() { return 0; };
static const TCHAR* Name()

View File

@ -183,6 +183,7 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
unsigned char *head = mpeg_buf;
jo_bits_t bits = {mpeg_buf};
jo_writeBits(&bits, 0x00, 8);
for (int vblock = 0; vblock < (height+15)/16; vblock++) {
for (int hblock = 0; hblock < (width+15)/16; hblock++) {
if (vblock == 0 && hblock == 0) {
@ -206,11 +207,7 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
if (flipy) y = height - 1 - y;
const unsigned char *c = raw + y*width*4+x*4;
float r, g, b;
if (flipx && flipy) {
r = c[2], g = c[1], b = c[0];
} else {
r = c[0], g = c[1], b = c[2];
}
r = c[0], g = c[1], b = c[2];
Y[i] = (0.299f*r + 0.587f*g + 0.114f*b) * (219.f/255) + 16;
CBx[i] = (-0.299f*r - 0.587f*g + 0.886f*b) * (224.f/255) + 128;
CRx[i] = (0.701f*r - 0.587f*g - 0.114f*b) * (224.f/255) + 128;
@ -222,7 +219,7 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
CR[i] = (CRx[j] + CRx[j+1] + CRx[j+16] + CRx[j+17]) * 0.25f;
}
} else
if (format == JO_RGB24) {
if (format == JO_BGR24 || format == JO_RGB24) {
for (int i=0; i<256; ++i) {
int y = vblock*16+(i/16);
int x = hblock*16+(i&15);
@ -232,7 +229,7 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
if (flipy) y = height - 1 - y;
const unsigned char *c = raw + y*width*3+x*3;
float r, g, b;
if (flipx && flipy) {
if (format == JO_BGR24) {
r = c[2], g = c[1], b = c[0];
} else {
r = c[0], g = c[1], b = c[2];

View File

@ -5,6 +5,7 @@ extern "C" {
typedef enum {
JO_RGBX,
JO_RGB24,
JO_BGR24,
JO_YUYV,
} jo_mpeg_format_t;

View File

@ -32,6 +32,7 @@
#define OV519_R16_DIVIDER 0x16
#define OV519_R20_DFR 0x20
#define OV519_R25_FORMAT 0x25
#define OV519_RA0_FORMAT 0xA0
/* OV519 System Controller register numbers */
#define OV519_R51_RESET1 0x51

View File

@ -22,13 +22,6 @@
namespace usb_eyetoy
{
static const USBDescStrings desc_strings = {
"",
"Sony corporation",
"EyeToy USB camera Namtai",
};
typedef struct EYETOYState
{
USBDevice dev;
@ -51,6 +44,12 @@ namespace usb_eyetoy
static EYETOYState* static_state;
static const USBDescStrings desc_strings = {
"",
"Sony corporation",
"EyeToy USB camera Namtai",
};
/*
Manufacturer: OmniVision Technologies, Inc.
Product ID: 0x8519
@ -61,7 +60,7 @@ namespace usb_eyetoy
Number of Configurations: 1
Manufacturer String: 1 "Sony corporation"
Product String: 2 "EyeToy USB camera Namtai"
*/
*/
static const uint8_t eyetoy_dev_descriptor[] = {
0x12, /* bLength */
@ -80,7 +79,6 @@ namespace usb_eyetoy
0x01, /* bNumConfigurations */
};
/* XXX: patch interrupt size */
static const uint8_t eyetoy_config_descriptor[] = {
0x09, // bLength
0x02, // bDescriptorType (Configuration)
@ -344,22 +342,21 @@ namespace usb_eyetoy
break;
case VendorDeviceOutRequest | 0x1: //Write register
if (!(index >= R51x_I2C_SADDR_3 && index <= R518_I2C_CTL))
{
}
switch (index)
{
case OV519_R51_RESET1:
if (data[0] & 0x8)
case OV519_RA0_FORMAT:
if (data[0] == 0x42)
{
// reset video FIFO
//s->videodev->SetSize(s->regs[OV519_R10_H_SIZE] << 4, s->regs[OV519_R11_V_SIZE] << 3);
Console.WriteLn("EyeToy : configured for MPEG format");
}
else if (data[0] == 0x33)
{
Console.WriteLn("EyeToy : configured for JPEG format; Unimplemented");
}
else
{
Console.WriteLn("EyeToy : configured for unknown format");
}
break;
case OV519_R10_H_SIZE:
break;
case OV519_R11_V_SIZE:
break;
case R518_I2C_CTL:
if (data[0] == 1) // Commit I2C write
@ -376,6 +373,12 @@ namespace usb_eyetoy
{
s->i2c_regs[reg] = val;
}
if (reg == 0x12)
{
const bool mirroring_enabled = val & 0x40;
s->videodev->SetMirroring(mirroring_enabled);
Console.WriteLn("EyeToy : mirroring %s", mirroring_enabled ? "ON" : "OFF");
}
}
else if (s->regs[R518_I2C_CTL] == 0x03 && data[0] == 0x05)
{
@ -416,31 +419,24 @@ namespace usb_eyetoy
case USB_TOKEN_IN:
if (devep == 1)
{
memset(data, 0xff, sizeof(data));
if (s->frame_step == 0)
{
s->mpeg_frame_size = s->videodev->GetImage(s->mpeg_frame_data, 320 * 240 * 2);
if (s->mpeg_frame_size == 0)
{
goto send_packet;
}
s->mpeg_frame_offset = 0;
uint8_t header1[] = {
0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(data, header1, sizeof(header1));
uint8_t header2[] = {
0x69, 0x70, 0x75, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00};
memcpy(data + sizeof(header1), header2, sizeof(header2));
uint8_t header[] = {
0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x69, 0x70, 0x75, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00};
memcpy(data, header, sizeof(header));
int data_pk = max_ep_size - sizeof(header1) - sizeof(header2);
memcpy(data + sizeof(header1) + sizeof(header2), s->mpeg_frame_data + s->mpeg_frame_offset, data_pk);
int data_pk = max_ep_size - sizeof(header);
memcpy(data + sizeof(header), s->mpeg_frame_data, data_pk);
s->mpeg_frame_offset = data_pk;
s->frame_step++;
}
else if (s->mpeg_frame_offset < s->mpeg_frame_size)
@ -450,7 +446,6 @@ namespace usb_eyetoy
data_pk = max_ep_size;
memcpy(data, s->mpeg_frame_data + s->mpeg_frame_offset, data_pk);
s->mpeg_frame_offset += data_pk;
s->frame_step++;
}
else
@ -556,8 +551,6 @@ namespace usb_eyetoy
s->frame_step = 0;
s->mpeg_frame_data = (unsigned char*)calloc(1, 320 * 240 * 4); // TODO: 640x480 ?
s->mpeg_frame_offset = 0;
s->regs[OV519_R10_H_SIZE] = 320 >> 4;
s->regs[OV519_R11_V_SIZE] = 240 >> 3;
static_state = s;
return (USBDevice*)s;

View File

@ -28,6 +28,7 @@ namespace usb_eyetoy
virtual int Open() = 0;
virtual int Close() = 0;
virtual int GetImage(uint8_t* buf, int len) = 0;
virtual void SetMirroring(bool state) = 0;
virtual int Reset() = 0;
virtual int Port() { return mPort; }