mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -05:00
ATV Modulator: camera device handling (no streaming yet)
This commit is contained in:
parent
02328b82ff
commit
2adf6da86d
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user