Skip to content

Commit

Permalink
USB: eyetoy mirroring
Browse files Browse the repository at this point in the history
  • Loading branch information
Florin9doi authored and refractionpcsx2 committed Feb 21, 2021
1 parent 7801682 commit 7e10e4d
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 48 deletions.
10 changes: 8 additions & 2 deletions pcsx2/USB/usb-eyetoy/cam-linux.cpp
Expand Up @@ -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)
{
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions pcsx2/USB/usb-eyetoy/cam-linux.h
Expand Up @@ -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()
Expand Down
8 changes: 7 additions & 1 deletion pcsx2/USB/usb-eyetoy/cam-windows.cpp
Expand Up @@ -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)
{
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions pcsx2/USB/usb-eyetoy/cam-windows.h
Expand Up @@ -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()
Expand Down
11 changes: 4 additions & 7 deletions pcsx2/USB/usb-eyetoy/jo_mpeg.cpp
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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];
Expand Down
1 change: 1 addition & 0 deletions pcsx2/USB/usb-eyetoy/jo_mpeg.h
Expand Up @@ -5,6 +5,7 @@ extern "C" {
typedef enum {
JO_RGBX,
JO_RGB24,
JO_BGR24,
JO_YUYV,
} jo_mpeg_format_t;

Expand Down
1 change: 1 addition & 0 deletions pcsx2/USB/usb-eyetoy/ov519.h
Expand Up @@ -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
Expand Down
69 changes: 31 additions & 38 deletions pcsx2/USB/usb-eyetoy/usb-eyetoy-webcam.cpp
Expand Up @@ -22,13 +22,6 @@

namespace usb_eyetoy
{

static const USBDescStrings desc_strings = {
"",
"Sony corporation",
"EyeToy USB camera Namtai",
};

typedef struct EYETOYState
{
USBDevice dev;
Expand All @@ -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
Expand All @@ -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 */
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)
{
Expand Down Expand Up @@ -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));

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);
s->mpeg_frame_offset = data_pk;
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(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)
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions pcsx2/USB/usb-eyetoy/videodev.h
Expand Up @@ -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; }
Expand Down

0 comments on commit 7e10e4d

Please sign in to comment.