begin work on the CameraManager
This commit is contained in:
parent
c761feee6a
commit
5363d3bf0c
|
@ -20,6 +20,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
#include "DSi_Camera.h"
|
#include "DSi_Camera.h"
|
||||||
|
#include "Platform.h"
|
||||||
|
|
||||||
|
|
||||||
namespace DSi_CamModule
|
namespace DSi_CamModule
|
||||||
|
@ -33,10 +34,6 @@ u16 Cnt;
|
||||||
|
|
||||||
u32 CropStart, CropEnd;
|
u32 CropStart, CropEnd;
|
||||||
|
|
||||||
/*u8 FrameBuffer[640*480*4];
|
|
||||||
u32 FrameLength;
|
|
||||||
u32 TransferPos;*/
|
|
||||||
|
|
||||||
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
|
// pixel data buffer holds a maximum of 512 words, regardless of how long scanlines are
|
||||||
u32 DataBuffer[512];
|
u32 DataBuffer[512];
|
||||||
u32 BufferReadPos, BufferWritePos;
|
u32 BufferReadPos, BufferWritePos;
|
||||||
|
@ -77,9 +74,6 @@ void Reset()
|
||||||
CropStart = 0;
|
CropStart = 0;
|
||||||
CropEnd = 0;
|
CropEnd = 0;
|
||||||
|
|
||||||
/*memset(FrameBuffer, 0, 640*480*4);
|
|
||||||
TransferPos = 0;
|
|
||||||
FrameLength = 256*192*2;*/ // TODO: make it check frame size, data type, etc
|
|
||||||
memset(DataBuffer, 0, 512*sizeof(u32));
|
memset(DataBuffer, 0, 512*sizeof(u32));
|
||||||
BufferReadPos = 0;
|
BufferReadPos = 0;
|
||||||
BufferWritePos = 0;
|
BufferWritePos = 0;
|
||||||
|
@ -495,6 +489,8 @@ void Camera::StartTransfer()
|
||||||
FrameReadMode = 0;
|
FrameReadMode = 0;
|
||||||
FrameFormat = 0;
|
FrameFormat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::TransferDone()
|
bool Camera::TransferDone()
|
||||||
|
@ -687,18 +683,30 @@ void Camera::I2C_WriteReg(u16 addr, u16 val)
|
||||||
return;
|
return;
|
||||||
case 0x0016:
|
case 0x0016:
|
||||||
ClocksCnt = val;
|
ClocksCnt = val;
|
||||||
printf("ClocksCnt=%04X\n", val);
|
//printf("ClocksCnt=%04X\n", val);
|
||||||
return;
|
return;
|
||||||
case 0x0018:
|
case 0x0018:
|
||||||
// TODO: this shouldn't be instant, but uh
|
{
|
||||||
val &= 0x003F;
|
bool wasactive = IsActivated();
|
||||||
val |= ((val & 0x0001) << 14);
|
// TODO: this shouldn't be instant, but uh
|
||||||
StandbyCnt = val;
|
val &= 0x003F;
|
||||||
printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
|
val |= ((val & 0x0001) << 14);
|
||||||
|
StandbyCnt = val;
|
||||||
|
//printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
|
||||||
|
bool isactive = IsActivated();
|
||||||
|
if (isactive && !wasactive) Platform::Camera_Start(Num);
|
||||||
|
else if (wasactive && !isactive) Platform::Camera_Stop(Num);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 0x001A:
|
case 0x001A:
|
||||||
MiscCnt = val & 0x0B7B;
|
{
|
||||||
printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val);
|
bool wasactive = IsActivated();
|
||||||
|
MiscCnt = val & 0x0B7B;
|
||||||
|
//printf("CAM%d MISCCNT=%04X (%04X)\n", Num, MiscCnt, val);
|
||||||
|
bool isactive = IsActivated();
|
||||||
|
if (isactive && !wasactive) Platform::Camera_Start(Num);
|
||||||
|
else if (wasactive && !isactive) Platform::Camera_Stop(Num);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x098C:
|
case 0x098C:
|
||||||
|
|
|
@ -144,6 +144,8 @@ void Mutex_Lock(Mutex* mutex);
|
||||||
void Mutex_Unlock(Mutex* mutex);
|
void Mutex_Unlock(Mutex* mutex);
|
||||||
bool Mutex_TryLock(Mutex* mutex);
|
bool Mutex_TryLock(Mutex* mutex);
|
||||||
|
|
||||||
|
void Sleep(u64 usecs);
|
||||||
|
|
||||||
|
|
||||||
// functions called when the NDS or GBA save files need to be written back to storage
|
// functions called when the NDS or GBA save files need to be written back to storage
|
||||||
// savedata and savelen are always the entire save memory buffer and its full length
|
// savedata and savelen are always the entire save memory buffer and its full length
|
||||||
|
@ -166,7 +168,15 @@ void LAN_DeInit();
|
||||||
int LAN_SendPacket(u8* data, int len);
|
int LAN_SendPacket(u8* data, int len);
|
||||||
int LAN_RecvPacket(u8* data);
|
int LAN_RecvPacket(u8* data);
|
||||||
|
|
||||||
void Sleep(u64 usecs);
|
|
||||||
|
// interface for camera emulation
|
||||||
|
// camera numbers:
|
||||||
|
// 0 = DSi outer camera
|
||||||
|
// 1 = DSi inner camera
|
||||||
|
// other values reserved for future camera addon emulation
|
||||||
|
void Camera_Start(int num);
|
||||||
|
void Camera_Stop(int num);
|
||||||
|
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,123 @@
|
||||||
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
||||||
with melonDS. If not, see http://www.gnu.org/licenses/.
|
with melonDS. If not, see http://www.gnu.org/licenses/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "CameraManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
CameraFrameDumper::CameraFrameDumper(QObject* parent) : QAbstractVideoSurface(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CameraFrameDumper::present(const QVideoFrame& _frame)
|
||||||
|
{
|
||||||
|
QVideoFrame frame(_frame);
|
||||||
|
if (!frame.map(QAbstractVideoBuffer::ReadOnly))
|
||||||
|
return false;
|
||||||
|
printf("FRAMEZORZ!! %d %d %d\n", frame.pixelFormat(), frame.isMapped(), frame.isReadable());
|
||||||
|
//NDS::CamInputFrame(0, (u32*)frame.bits(), frame.width(), frame.height(), false);
|
||||||
|
|
||||||
|
frame.unmap();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QVideoFrame::PixelFormat> CameraFrameDumper::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
|
||||||
|
{
|
||||||
|
QList<QVideoFrame::PixelFormat> ret;
|
||||||
|
|
||||||
|
ret.append(QVideoFrame::Format_RGB32);
|
||||||
|
ret.append(QVideoFrame::Format_YUYV);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CameraManager::CameraManager(int num, int width, int height, bool yuv)
|
||||||
|
{
|
||||||
|
Num = num;
|
||||||
|
|
||||||
|
FrameWidth = width;
|
||||||
|
FrameHeight = height;
|
||||||
|
FrameFormatYUV = yuv;
|
||||||
|
|
||||||
|
int fbsize = FrameWidth * FrameHeight;
|
||||||
|
if (yuv) fbsize /= 2;
|
||||||
|
FrameBuffer = new u32[fbsize];
|
||||||
|
|
||||||
|
InputType = -1;
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraManager::~CameraManager()
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
|
||||||
|
// save settings here?
|
||||||
|
|
||||||
|
delete[] FrameBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::Init()
|
||||||
|
{
|
||||||
|
if (InputType != -1)
|
||||||
|
DeInit();
|
||||||
|
|
||||||
|
// TODO: load settings from config!!
|
||||||
|
InputType = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
// fill the framebuffer with black
|
||||||
|
|
||||||
|
int total = FrameWidth * FrameHeight;
|
||||||
|
u32 fill = 0;
|
||||||
|
if (FrameFormatYUV)
|
||||||
|
{
|
||||||
|
total /= 2;
|
||||||
|
fill = 0x80008000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < total; i++)
|
||||||
|
FrameBuffer[i] = fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputType == 1)
|
||||||
|
{
|
||||||
|
// still image
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::DeInit()
|
||||||
|
{
|
||||||
|
InputType = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::Start()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::Stop()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraManager::CaptureFrame(u32* frame, int width, int height, bool yuv)
|
||||||
|
{
|
||||||
|
FrameMutex.lock();
|
||||||
|
|
||||||
|
if (width == FrameWidth && height == FrameHeight && yuv == FrameFormatYUV)
|
||||||
|
{
|
||||||
|
int len = width * height;
|
||||||
|
if (yuv) len /= 2;
|
||||||
|
memcpy(frame, FrameBuffer, len * sizeof(u32));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameMutex.unlock();
|
||||||
|
}
|
||||||
|
|
|
@ -22,5 +22,47 @@
|
||||||
#include <QCamera>
|
#include <QCamera>
|
||||||
#include <QCameraInfo>
|
#include <QCameraInfo>
|
||||||
#include <QAbstractVideoSurface>
|
#include <QAbstractVideoSurface>
|
||||||
|
#include <QVideoSurfaceFormat>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class CameraFrameDumper : public QAbstractVideoSurface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CameraFrameDumper(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
bool present(const QVideoFrame& frame) override;
|
||||||
|
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CameraManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CameraManager(int num, int width, int height, bool yuv);
|
||||||
|
~CameraManager();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void DeInit();
|
||||||
|
|
||||||
|
void Start();
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
void CaptureFrame(u32* frame, int width, int height, bool yuv);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int Num;
|
||||||
|
|
||||||
|
int InputType;
|
||||||
|
QString ImagePath;
|
||||||
|
QString CamDeviceName;
|
||||||
|
|
||||||
|
int FrameWidth, FrameHeight;
|
||||||
|
bool FrameFormatYUV;
|
||||||
|
u32* FrameBuffer;
|
||||||
|
QMutex FrameMutex;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // CAMERAMANAGER_H
|
#endif // CAMERAMANAGER_H
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "ROMManager.h"
|
#include "ROMManager.h"
|
||||||
|
#include "CameraManager.h"
|
||||||
#include "LAN_Socket.h"
|
#include "LAN_Socket.h"
|
||||||
#include "LAN_PCap.h"
|
#include "LAN_PCap.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -66,6 +67,8 @@ std::string EmuDirectory;
|
||||||
|
|
||||||
void emuStop();
|
void emuStop();
|
||||||
|
|
||||||
|
extern CameraManager* camManager[2];
|
||||||
|
|
||||||
|
|
||||||
namespace Platform
|
namespace Platform
|
||||||
{
|
{
|
||||||
|
@ -372,6 +375,11 @@ bool Mutex_TryLock(Mutex* mutex)
|
||||||
return ((QMutex*) mutex)->try_lock();
|
return ((QMutex*) mutex)->try_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sleep(u64 usecs)
|
||||||
|
{
|
||||||
|
QThread::usleep(usecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
|
||||||
{
|
{
|
||||||
|
@ -529,7 +537,6 @@ int MP_RecvPacket(u8* data, bool block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool LAN_Init()
|
bool LAN_Init()
|
||||||
{
|
{
|
||||||
if (Config::DirectLAN)
|
if (Config::DirectLAN)
|
||||||
|
@ -573,9 +580,20 @@ int LAN_RecvPacket(u8* data)
|
||||||
return LAN_Socket::RecvPacket(data);
|
return LAN_Socket::RecvPacket(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sleep(u64 usecs)
|
|
||||||
|
void Camera_Start(int num)
|
||||||
{
|
{
|
||||||
QThread::usleep(usecs);
|
return camManager[num]->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera_Stop(int num)
|
||||||
|
{
|
||||||
|
return camManager[num]->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv)
|
||||||
|
{
|
||||||
|
return camManager[num]->CaptureFrame(frame, width, height, yuv);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
|
|
||||||
#include "ROMManager.h"
|
#include "ROMManager.h"
|
||||||
#include "ArchiveUtil.h"
|
#include "ArchiveUtil.h"
|
||||||
|
#include "CameraManager.h"
|
||||||
|
|
||||||
// TODO: uniform variable spelling
|
// TODO: uniform variable spelling
|
||||||
|
|
||||||
|
@ -112,6 +113,8 @@ u32 micExtBufferWritePos;
|
||||||
u32 micWavLength;
|
u32 micWavLength;
|
||||||
s16* micWavBuffer;
|
s16* micWavBuffer;
|
||||||
|
|
||||||
|
CameraManager* camManager[2];
|
||||||
|
|
||||||
void micCallback(void* data, Uint8* stream, int len);
|
void micCallback(void* data, Uint8* stream, int len);
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,57 +319,6 @@ void micProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void camOpen()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void camClose()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void camProcess()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraFrameDumper::CameraFrameDumper(QObject* parent) : QAbstractVideoSurface(parent)
|
|
||||||
{
|
|
||||||
printf("BAKA!!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*CameraFrameDumper::~CameraFrameDumper()
|
|
||||||
{
|
|
||||||
printf("SAYONARA\n");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool CameraFrameDumper::present(const QVideoFrame& _frame)
|
|
||||||
{
|
|
||||||
//printf("FRAMEZORZ!! %d %d %d\n", frame.pixelFormat(), frame.isMapped(), frame.isReadable());
|
|
||||||
|
|
||||||
QVideoFrame frame(_frame);
|
|
||||||
if (!frame.map(QAbstractVideoBuffer::ReadOnly))
|
|
||||||
return false;
|
|
||||||
printf("FRAMEZORZ!! %d %d %d\n", frame.pixelFormat(), frame.isMapped(), frame.isReadable());
|
|
||||||
NDS::CamInputFrame(0, (u32*)frame.bits(), frame.width(), frame.height(), false);
|
|
||||||
|
|
||||||
frame.unmap();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QVideoFrame::PixelFormat> CameraFrameDumper::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const
|
|
||||||
{
|
|
||||||
QList<QVideoFrame::PixelFormat> ret;
|
|
||||||
printf("PENIS. %d\n", type);
|
|
||||||
ret.append(QVideoFrame::Format_RGB32);
|
|
||||||
ret.append(QVideoFrame::Format_YUYV);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EmuThread::EmuThread(QObject* parent) : QThread(parent)
|
EmuThread::EmuThread(QObject* parent) : QThread(parent)
|
||||||
{
|
{
|
||||||
EmuStatus = 0;
|
EmuStatus = 0;
|
||||||
|
@ -427,7 +379,7 @@ void EmuThread::deinitOpenGL()
|
||||||
delete oglContext;
|
delete oglContext;
|
||||||
delete oglSurface;
|
delete oglSurface;
|
||||||
}
|
}
|
||||||
#include <QVideoSurfaceFormat>
|
|
||||||
void EmuThread::run()
|
void EmuThread::run()
|
||||||
{
|
{
|
||||||
bool hasOGL = mainWindow->hasOGL;
|
bool hasOGL = mainWindow->hasOGL;
|
||||||
|
@ -595,9 +547,6 @@ printf("PROULON\n");
|
||||||
OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened");
|
OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened");
|
||||||
}
|
}
|
||||||
|
|
||||||
// camera input test
|
|
||||||
//NDS::CamInputFrame(0, (u32*)testimg_conv.bits(), testimg_conv.width(), testimg_conv.height(), true);
|
|
||||||
|
|
||||||
// microphone input
|
// microphone input
|
||||||
micProcess();
|
micProcess();
|
||||||
|
|
||||||
|
@ -3229,11 +3178,13 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
micDevice = 0;
|
micDevice = 0;
|
||||||
|
|
||||||
|
|
||||||
memset(micExtBuffer, 0, sizeof(micExtBuffer));
|
memset(micExtBuffer, 0, sizeof(micExtBuffer));
|
||||||
micExtBufferWritePos = 0;
|
micExtBufferWritePos = 0;
|
||||||
micWavBuffer = nullptr;
|
micWavBuffer = nullptr;
|
||||||
|
|
||||||
|
camManager[0] = new CameraManager(0, 640, 480, true);
|
||||||
|
camManager[1] = new CameraManager(1, 640, 480, true);
|
||||||
|
|
||||||
ROMManager::EnableCheats(Config::EnableCheats != 0);
|
ROMManager::EnableCheats(Config::EnableCheats != 0);
|
||||||
|
|
||||||
Frontend::Init_Audio(audioFreq);
|
Frontend::Init_Audio(audioFreq);
|
||||||
|
@ -3284,6 +3235,9 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
if (micWavBuffer) delete[] micWavBuffer;
|
if (micWavBuffer) delete[] micWavBuffer;
|
||||||
|
|
||||||
|
delete camManager[0];
|
||||||
|
delete camManager[1];
|
||||||
|
|
||||||
Config::Save();
|
Config::Save();
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
|
@ -36,24 +36,8 @@
|
||||||
#include <QOpenGLFunctions_3_2_Core>
|
#include <QOpenGLFunctions_3_2_Core>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
|
|
||||||
#include <QCamera>
|
|
||||||
#include <QCameraInfo>
|
|
||||||
#include <QAbstractVideoSurface>
|
|
||||||
|
|
||||||
#include "FrontendUtil.h"
|
#include "FrontendUtil.h"
|
||||||
|
|
||||||
class CameraFrameDumper : public QAbstractVideoSurface
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
CameraFrameDumper(QObject* parent = nullptr);
|
|
||||||
//~CameraFrameDumper();
|
|
||||||
|
|
||||||
bool present(const QVideoFrame& frame) override;
|
|
||||||
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EmuThread : public QThread
|
class EmuThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
Loading…
Reference in New Issue