begin work on the CameraManager
This commit is contained in:
parent
16d0b05fb5
commit
7d453effb2
|
@ -20,6 +20,7 @@
|
|||
#include <string.h>
|
||||
#include "DSi.h"
|
||||
#include "DSi_Camera.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
namespace DSi_CamModule
|
||||
|
@ -33,10 +34,6 @@ u16 Cnt;
|
|||
|
||||
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
|
||||
u32 DataBuffer[512];
|
||||
u32 BufferReadPos, BufferWritePos;
|
||||
|
@ -77,9 +74,6 @@ void Reset()
|
|||
CropStart = 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));
|
||||
BufferReadPos = 0;
|
||||
BufferWritePos = 0;
|
||||
|
@ -495,6 +489,8 @@ void Camera::StartTransfer()
|
|||
FrameReadMode = 0;
|
||||
FrameFormat = 0;
|
||||
}
|
||||
|
||||
Platform::Camera_CaptureFrame(Num, FrameBuffer, 640, 480, true);
|
||||
}
|
||||
|
||||
bool Camera::TransferDone()
|
||||
|
@ -687,18 +683,30 @@ void Camera::I2C_WriteReg(u16 addr, u16 val)
|
|||
return;
|
||||
case 0x0016:
|
||||
ClocksCnt = val;
|
||||
printf("ClocksCnt=%04X\n", val);
|
||||
//printf("ClocksCnt=%04X\n", val);
|
||||
return;
|
||||
case 0x0018:
|
||||
// TODO: this shouldn't be instant, but uh
|
||||
val &= 0x003F;
|
||||
val |= ((val & 0x0001) << 14);
|
||||
StandbyCnt = val;
|
||||
printf("CAM%d STBCNT=%04X (%04X)\n", Num, StandbyCnt, val);
|
||||
{
|
||||
bool wasactive = IsActivated();
|
||||
// TODO: this shouldn't be instant, but uh
|
||||
val &= 0x003F;
|
||||
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;
|
||||
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;
|
||||
|
||||
case 0x098C:
|
||||
|
|
|
@ -144,6 +144,8 @@ void Mutex_Lock(Mutex* mutex);
|
|||
void Mutex_Unlock(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
|
||||
// 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_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
|
||||
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 <QCameraInfo>
|
||||
#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
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "Platform.h"
|
||||
#include "Config.h"
|
||||
#include "ROMManager.h"
|
||||
#include "CameraManager.h"
|
||||
#include "LAN_Socket.h"
|
||||
#include "LAN_PCap.h"
|
||||
#include <string>
|
||||
|
@ -66,6 +67,8 @@ std::string EmuDirectory;
|
|||
|
||||
void emuStop();
|
||||
|
||||
extern CameraManager* camManager[2];
|
||||
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
|
@ -372,6 +375,11 @@ bool Mutex_TryLock(Mutex* mutex)
|
|||
return ((QMutex*) mutex)->try_lock();
|
||||
}
|
||||
|
||||
void Sleep(u64 usecs)
|
||||
{
|
||||
QThread::usleep(usecs);
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
if (Config::DirectLAN)
|
||||
|
@ -573,9 +580,20 @@ int LAN_RecvPacket(u8* 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 "ArchiveUtil.h"
|
||||
#include "CameraManager.h"
|
||||
|
||||
// TODO: uniform variable spelling
|
||||
|
||||
|
@ -112,6 +113,8 @@ u32 micExtBufferWritePos;
|
|||
u32 micWavLength;
|
||||
s16* micWavBuffer;
|
||||
|
||||
CameraManager* camManager[2];
|
||||
|
||||
const struct { int id; float ratio; const char* label; } aspectRatios[] =
|
||||
{
|
||||
{ 0, 1, "4:3 (native)" },
|
||||
|
@ -325,57 +328,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)
|
||||
{
|
||||
EmuStatus = 0;
|
||||
|
@ -436,7 +388,7 @@ void EmuThread::deinitOpenGL()
|
|||
delete oglContext;
|
||||
delete oglSurface;
|
||||
}
|
||||
#include <QVideoSurfaceFormat>
|
||||
|
||||
void EmuThread::run()
|
||||
{
|
||||
bool hasOGL = mainWindow->hasOGL;
|
||||
|
@ -604,9 +556,6 @@ printf("PROULON\n");
|
|||
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
|
||||
micProcess();
|
||||
|
||||
|
@ -3257,11 +3206,13 @@ int main(int argc, char** argv)
|
|||
|
||||
micDevice = 0;
|
||||
|
||||
|
||||
memset(micExtBuffer, 0, sizeof(micExtBuffer));
|
||||
micExtBufferWritePos = 0;
|
||||
micWavBuffer = nullptr;
|
||||
|
||||
camManager[0] = new CameraManager(0, 640, 480, true);
|
||||
camManager[1] = new CameraManager(1, 640, 480, true);
|
||||
|
||||
ROMManager::EnableCheats(Config::EnableCheats != 0);
|
||||
|
||||
Frontend::Init_Audio(audioFreq);
|
||||
|
@ -3312,6 +3263,9 @@ int main(int argc, char** argv)
|
|||
|
||||
if (micWavBuffer) delete[] micWavBuffer;
|
||||
|
||||
delete camManager[0];
|
||||
delete camManager[1];
|
||||
|
||||
Config::Save();
|
||||
|
||||
SDL_Quit();
|
||||
|
|
|
@ -36,24 +36,8 @@
|
|||
#include <QOpenGLFunctions_3_2_Core>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
#include <QCamera>
|
||||
#include <QCameraInfo>
|
||||
#include <QAbstractVideoSurface>
|
||||
|
||||
#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
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
Loading…
Reference in New Issue