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::MsgReportVideoFileSourceStreamTiming, 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_spanLevel = 0.7f;
@ -46,7 +48,8 @@ ATVMod::ATVMod() :
m_videoFPSCount(0.0f),
m_videoPrevFPSCount(0),
m_videoEOF(false),
m_videoOK(false)
m_videoOK(false),
m_cameraIndex(-1)
{
setObjectName("ATVMod");
scanCameras();
@ -218,7 +221,7 @@ void ATVMod::pullVideo(Real& sample)
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();
}
}
@ -355,6 +358,23 @@ bool ATVMod::handleMessage(const Message& cmd)
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
{
return false;
@ -545,13 +565,34 @@ void ATVMod::calculateVideoSizes()
m_videoFPSCount = m_videoFPSq;
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()
{
if (!m_frameOriginal.empty()) {
cv::resize(m_frameOriginal, m_frame, cv::Size(), m_videoFx, m_videoFy); // resize current frame
if (!m_videoframeOriginal.empty()) {
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_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();
}
}
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()

View File

@ -52,7 +52,8 @@ public:
ATVModInputHGradient,
ATVModInputVGradient,
ATVModInputImage,
ATVModInputVideo
ATVModInputVideo,
ATVModInputCamera
} ATVModInput;
typedef enum
@ -61,12 +62,6 @@ public:
ATVModulationFM
} ATVModulation;
typedef struct
{
cv::VideoCapture m_camera;
int m_cameraNumber;
} ATVCamera;
class MsgConfigureImageFileName : public Message
{
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();
@ -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
{
int m_outputSampleRate; //!< sample rate from channelizer
@ -361,8 +442,8 @@ private:
bool m_imageOK;
cv::VideoCapture m_video; //!< current video capture
cv::Mat m_frameOriginal; //!< current frame from video
cv::Mat m_frame; //!< current displayable video frame
cv::Mat m_videoframeOriginal; //!< current frame from video
cv::Mat m_videoFrame; //!< current displayable video frame
float m_videoFPS; //!< current video FPS rate
int m_videoWidth; //!< current video frame width
int m_videoHeight; //!< current video frame height
@ -376,6 +457,7 @@ private:
bool m_videoOK;
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_spanLevel;
@ -396,6 +478,8 @@ private:
void seekVideoFileStream(int seekPercentage);
void scanCameras();
void releaseCameras();
void calculateCamerasSizes();
void resizeCameras();
inline void pullImageLine(Real& sample)
{
@ -450,7 +534,7 @@ private:
}
break;
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;
}
@ -459,9 +543,9 @@ private:
unsigned char pixv;
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 {
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;

View File

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