1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

ATV Modulator: camera device handling (no streaming yet)

This commit is contained in:
f4exb 2017-03-10 19:06:51 +01:00
parent 02328b82ff
commit 2adf6da86d
3 changed files with 166 additions and 18 deletions

View File

@ -28,6 +28,8 @@ MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileSourceStreamTiming, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileSourceStreamTiming, Message)
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamTiming, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamTiming, Message)
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message) MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message)
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureCameraIndex, Message)
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportCameraData, Message)
const float ATVMod::m_blackLevel = 0.3f; const float ATVMod::m_blackLevel = 0.3f;
const float ATVMod::m_spanLevel = 0.7f; const float ATVMod::m_spanLevel = 0.7f;
@ -46,7 +48,8 @@ ATVMod::ATVMod() :
m_videoFPSCount(0.0f), m_videoFPSCount(0.0f),
m_videoPrevFPSCount(0), m_videoPrevFPSCount(0),
m_videoEOF(false), m_videoEOF(false),
m_videoOK(false) m_videoOK(false),
m_cameraIndex(-1)
{ {
setObjectName("ATVMod"); setObjectName("ATVMod");
scanCameras(); scanCameras();
@ -218,7 +221,7 @@ void ATVMod::pullVideo(Real& sample)
if (!colorFrame.empty()) // some frames may not come out properly if (!colorFrame.empty()) // some frames may not come out properly
{ {
cv::cvtColor(colorFrame, m_frameOriginal, CV_BGR2GRAY); cv::cvtColor(colorFrame, m_videoframeOriginal, CV_BGR2GRAY);
resizeVideo(); resizeVideo();
} }
} }
@ -355,6 +358,23 @@ bool ATVMod::handleMessage(const Message& cmd)
return true; return true;
} }
else if (MsgConfigureCameraIndex::match(cmd))
{
MsgConfigureCameraIndex& cfg = (MsgConfigureCameraIndex&) cmd;
int index = cfg.getIndex();
if (index < m_cameras.size())
{
m_cameraIndex = index;
MsgReportCameraData *report;
report = MsgReportCameraData::create(
m_cameras[m_cameraIndex].m_cameraNumber,
m_cameras[m_cameraIndex].m_videoFPS,
m_cameras[m_cameraIndex].m_videoWidth,
m_cameras[m_cameraIndex].m_videoHeight);
getOutputMessageQueue()->push(report);
}
}
else else
{ {
return false; return false;
@ -545,13 +565,34 @@ void ATVMod::calculateVideoSizes()
m_videoFPSCount = m_videoFPSq; m_videoFPSCount = m_videoFPSq;
m_videoPrevFPSCount = 0; m_videoPrevFPSCount = 0;
qDebug("ATVMod::resizeVideo: factors: %f x %f FPSq: %f", m_videoFx, m_videoFy, m_videoFPSq); qDebug("ATVMod::calculateVideoSizes: factors: %f x %f FPSq: %f", m_videoFx, m_videoFy, m_videoFPSq);
} }
void ATVMod::resizeVideo() void ATVMod::resizeVideo()
{ {
if (!m_frameOriginal.empty()) { if (!m_videoframeOriginal.empty()) {
cv::resize(m_frameOriginal, m_frame, cv::Size(), m_videoFx, m_videoFy); // resize current frame cv::resize(m_videoframeOriginal, m_videoFrame, cv::Size(), m_videoFx, m_videoFy); // resize current frame
}
}
void ATVMod::calculateCamerasSizes()
{
for (std::vector<ATVCamera>::iterator it = m_cameras.begin(); it != m_cameras.end(); ++it)
{
it->m_videoFy = (m_nbImageLines - 2*m_nbBlankLines) / (float) it->m_videoHeight;
it->m_videoFx = m_pointsPerImgLine / (float) it->m_videoWidth;
it->m_videoFPSq = it->m_videoFPS / m_fps;
qDebug("ATVMod::calculateCamerasSizes: [%d] factors: %f x %f FPSq: %f", (int) (it - m_cameras.begin()), it->m_videoFx, it->m_videoFy, it->m_videoFPSq);
}
}
void ATVMod::resizeCameras()
{
for (std::vector<ATVCamera>::iterator it = m_cameras.begin(); it != m_cameras.end(); ++it)
{
if (!it->m_videoframeOriginal.empty()) {
cv::resize(it->m_videoframeOriginal, it->m_videoFrame, cv::Size(), it->m_videoFx, it->m_videoFy); // resize current frame
}
} }
} }
@ -578,11 +619,29 @@ void ATVMod::scanCameras()
m_cameras.back().m_cameraNumber = i; m_cameras.back().m_cameraNumber = i;
m_cameras.back().m_camera.open(i); m_cameras.back().m_camera.open(i);
if (!m_cameras.back().m_camera.isOpened()) if (m_cameras.back().m_camera.isOpened())
{
m_cameras.back().m_videoFPS = m_cameras.back().m_camera.get(CV_CAP_PROP_FPS);
m_cameras.back().m_videoWidth = (int) m_cameras.back().m_camera.get(CV_CAP_PROP_FRAME_WIDTH);
m_cameras.back().m_videoHeight = (int) m_cameras.back().m_camera.get(CV_CAP_PROP_FRAME_HEIGHT);
}
else
{ {
m_cameras.pop_back(); m_cameras.pop_back();
} }
} }
if (m_cameras.size() > 0)
{
m_cameraIndex = 0;
MsgReportCameraData *report;
report = MsgReportCameraData::create(
m_cameras[0].m_cameraNumber,
m_cameras[0].m_videoFPS,
m_cameras[0].m_videoWidth,
m_cameras[0].m_videoHeight);
getOutputMessageQueue()->push(report);
}
} }
void ATVMod::releaseCameras() void ATVMod::releaseCameras()

View File

@ -52,7 +52,8 @@ public:
ATVModInputHGradient, ATVModInputHGradient,
ATVModInputVGradient, ATVModInputVGradient,
ATVModInputImage, ATVModInputImage,
ATVModInputVideo ATVModInputVideo,
ATVModInputCamera
} ATVModInput; } ATVModInput;
typedef enum typedef enum
@ -61,12 +62,6 @@ public:
ATVModulationFM ATVModulationFM
} ATVModulation; } ATVModulation;
typedef struct
{
cv::VideoCapture m_camera;
int m_cameraNumber;
} ATVCamera;
class MsgConfigureImageFileName : public Message class MsgConfigureImageFileName : public Message
{ {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
@ -193,6 +188,68 @@ public:
{ } { }
}; };
class MsgConfigureCameraIndex : public Message
{
MESSAGE_CLASS_DECLARATION
public:
int getIndex() const { return m_index; }
static MsgConfigureCameraIndex* create(int index)
{
return new MsgConfigureCameraIndex(index);
}
private:
int m_index;
MsgConfigureCameraIndex(int index) :
Message(),
m_index(index)
{ }
};
class MsgReportCameraData : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getdeviceNumber() const { return m_deviceNumber; }
int getFPS() const { return m_fps; }
int getWidth() const { return m_width; }
int getHeight() const { return m_height; }
static MsgReportCameraData* create(
int deviceNumber,
int fps,
int width,
int height)
{
return new MsgReportCameraData(
deviceNumber,
fps,
width,
height);
}
protected:
int m_deviceNumber;
int m_fps;
int m_width;
int m_height;
MsgReportCameraData(
int deviceNumber,
int fps,
int width,
int height) :
Message(),
m_deviceNumber(deviceNumber),
m_fps(fps),
m_width(width),
m_height(height)
{ }
};
ATVMod(); ATVMod();
~ATVMod(); ~ATVMod();
@ -292,6 +349,30 @@ private:
{ } { }
}; };
typedef struct ATVCamera
{
cv::VideoCapture m_camera; //!< camera object
cv::Mat m_videoframeOriginal; //!< camera non resized image
cv::Mat m_videoFrame; //!< displayable camera frame
int m_cameraNumber; //!< camera device number
float m_videoFPS; //!< camera FPS rate
int m_videoWidth; //!< camera frame width
int m_videoHeight; //!< camera frame height
float m_videoFx; //!< camera horizontal scaling factor
float m_videoFy; //!< camera vertictal scaling factor
float m_videoFPSq; //!< camera FPS sacaling factor
ATVCamera() :
m_cameraNumber(-1),
m_videoFPS(25),
m_videoWidth(1),
m_videoHeight(1),
m_videoFx(1.0f),
m_videoFy(1.0f),
m_videoFPSq(1.0f)
{}
};
struct Config struct Config
{ {
int m_outputSampleRate; //!< sample rate from channelizer int m_outputSampleRate; //!< sample rate from channelizer
@ -361,8 +442,8 @@ private:
bool m_imageOK; bool m_imageOK;
cv::VideoCapture m_video; //!< current video capture cv::VideoCapture m_video; //!< current video capture
cv::Mat m_frameOriginal; //!< current frame from video cv::Mat m_videoframeOriginal; //!< current frame from video
cv::Mat m_frame; //!< current displayable video frame cv::Mat m_videoFrame; //!< current displayable video frame
float m_videoFPS; //!< current video FPS rate float m_videoFPS; //!< current video FPS rate
int m_videoWidth; //!< current video frame width int m_videoWidth; //!< current video frame width
int m_videoHeight; //!< current video frame height int m_videoHeight; //!< current video frame height
@ -376,6 +457,7 @@ private:
bool m_videoOK; bool m_videoOK;
std::vector<ATVCamera> m_cameras; //!< vector of available cameras std::vector<ATVCamera> m_cameras; //!< vector of available cameras
int m_cameraIndex; //!< curent camera index in list of available cameras
static const float m_blackLevel; static const float m_blackLevel;
static const float m_spanLevel; static const float m_spanLevel;
@ -396,6 +478,8 @@ private:
void seekVideoFileStream(int seekPercentage); void seekVideoFileStream(int seekPercentage);
void scanCameras(); void scanCameras();
void releaseCameras(); void releaseCameras();
void calculateCamerasSizes();
void resizeCameras();
inline void pullImageLine(Real& sample) inline void pullImageLine(Real& sample)
{ {
@ -450,7 +534,7 @@ private:
} }
break; break;
case ATVModInputVideo: case ATVModInputVideo:
if (!m_videoOK || (iLineImage < 0) || m_frame.empty()) if (!m_videoOK || (iLineImage < 0) || m_videoFrame.empty())
{ {
sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel;
} }
@ -459,9 +543,9 @@ private:
unsigned char pixv; unsigned char pixv;
if (m_interlaced) { if (m_interlaced) {
pixv = m_frame.at<unsigned char>(2*iLineImage + oddity, pointIndex); // row (y), col (x) pixv = m_videoFrame.at<unsigned char>(2*iLineImage + oddity, pointIndex); // row (y), col (x)
} else { } else {
pixv = m_frame.at<unsigned char>(iLineImage, pointIndex); // row (y), col (x) pixv = m_videoFrame.at<unsigned char>(iLineImage, pointIndex); // row (y), col (x)
} }
sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel; sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel;

View File

@ -162,6 +162,11 @@ bool ATVModGUI::handleMessage(const Message& message)
updateWithStreamTime(); updateWithStreamTime();
return true; return true;
} }
else if (ATVMod::MsgReportCameraData::match(message))
{
// TODO
return true;
}
else else
{ {
return false; return false;