ATV Modulator: camera support

This commit is contained in:
f4exb 2017-03-11 08:21:26 +01:00
parent 41fac50526
commit 5baaacb2ed
5 changed files with 126 additions and 8 deletions

View File

@ -84,6 +84,7 @@ void ATVMod::configure(MessageQueue* messageQueue,
ATVModulation atvModulation, ATVModulation atvModulation,
bool videoPlayLoop, bool videoPlayLoop,
bool videoPlay, bool videoPlay,
bool cameraPlay,
bool channelMute) bool channelMute)
{ {
Message* cmd = MsgConfigureATVMod::create( Message* cmd = MsgConfigureATVMod::create(
@ -93,7 +94,8 @@ void ATVMod::configure(MessageQueue* messageQueue,
uniformLevel, uniformLevel,
atvModulation, atvModulation,
videoPlayLoop, videoPlayLoop,
videoPlay); videoPlay,
cameraPlay);
messageQueue->push(cmd); messageQueue->push(cmd);
} }
@ -245,6 +247,44 @@ void ATVMod::pullVideo(Real& sample)
m_videoFPSCount = m_videoFPSq; m_videoFPSCount = m_videoFPSq;
} }
} }
else if ((m_running.m_atvModInput == ATVModInputCamera) && (m_running.m_cameraPlay))
{
ATVCamera& camera = m_cameras[m_cameraIndex]; // currently selected canera
int grabOK;
int fpsIncrement = (int) camera.m_videoFPSCount - camera.m_videoPrevFPSCount;
// move a number of frames according to increment
// use grab to test for EOF then retrieve to preserve last valid frame as the current original frame
// TODO: handle pause (no move)
for (int i = 0; i < fpsIncrement; i++)
{
grabOK = camera.m_camera.grab();
if (!grabOK) break;
}
if (grabOK)
{
cv::Mat colorFrame;
camera.m_camera.retrieve(colorFrame);
if (!colorFrame.empty()) // some frames may not come out properly
{
cv::cvtColor(colorFrame, camera.m_videoframeOriginal, CV_BGR2GRAY);
resizeCamera();
}
if (camera.m_videoFPSCount < camera.m_videoFPS)
{
camera.m_videoPrevFPSCount = (int) camera.m_videoFPSCount;
camera.m_videoFPSCount += camera.m_videoFPSq;
}
else
{
camera.m_videoPrevFPSCount = 0;
camera.m_videoFPSCount = camera.m_videoFPSq;
}
}
}
} }
m_horizontalCount = 0; m_horizontalCount = 0;
@ -308,6 +348,7 @@ bool ATVMod::handleMessage(const Message& cmd)
m_config.m_atvModulation = cfg.getModulation(); m_config.m_atvModulation = cfg.getModulation();
m_config.m_videoPlayLoop = cfg.getVideoPlayLoop(); m_config.m_videoPlayLoop = cfg.getVideoPlayLoop();
m_config.m_videoPlay = cfg.getVideoPlay(); m_config.m_videoPlay = cfg.getVideoPlay();
m_config.m_cameraPlay = cfg.getCameraPlay();
apply(); apply();
@ -318,7 +359,8 @@ bool ATVMod::handleMessage(const Message& cmd)
<< " m_uniformLevel: " << m_config.m_uniformLevel << " m_uniformLevel: " << m_config.m_uniformLevel
<< " m_atvModulation: " << (int) m_config.m_atvModulation << " m_atvModulation: " << (int) m_config.m_atvModulation
<< " m_videoPlayLoop: " << m_config.m_videoPlayLoop << " m_videoPlayLoop: " << m_config.m_videoPlayLoop
<< " m_videoPlay: " << m_config.m_videoPlay; << " m_videoPlay: " << m_config.m_videoPlay
<< " m_cameraPlay: " << m_config.m_cameraPlay;
return true; return true;
} }
@ -424,6 +466,7 @@ void ATVMod::apply(bool force)
m_running.m_atvModulation = m_config.m_atvModulation; m_running.m_atvModulation = m_config.m_atvModulation;
m_running.m_videoPlayLoop = m_config.m_videoPlayLoop; m_running.m_videoPlayLoop = m_config.m_videoPlayLoop;
m_running.m_videoPlay = m_config.m_videoPlay; m_running.m_videoPlay = m_config.m_videoPlay;
m_running.m_cameraPlay = m_config.m_cameraPlay;
} }
int ATVMod::getSampleRateUnits(ATVStd std) int ATVMod::getSampleRateUnits(ATVStd std)
@ -500,6 +543,8 @@ void ATVMod::applyStandard()
calculateVideoSizes(); calculateVideoSizes();
resizeVideo(); resizeVideo();
} }
calculateCamerasSizes();
} }
void ATVMod::openImage(const QString& fileName) void ATVMod::openImage(const QString& fileName)
@ -582,6 +627,9 @@ void ATVMod::calculateCamerasSizes()
it->m_videoFy = (m_nbImageLines - 2*m_nbBlankLines) / (float) it->m_videoHeight; it->m_videoFy = (m_nbImageLines - 2*m_nbBlankLines) / (float) it->m_videoHeight;
it->m_videoFx = m_pointsPerImgLine / (float) it->m_videoWidth; it->m_videoFx = m_pointsPerImgLine / (float) it->m_videoWidth;
it->m_videoFPSq = it->m_videoFPS / m_fps; it->m_videoFPSq = it->m_videoFPS / m_fps;
it->m_videoFPSCount = it->m_videoFPSq;
it->m_videoPrevFPSCount = 0;
qDebug("ATVMod::calculateCamerasSizes: [%d] factors: %f x %f FPSq: %f", (int) (it - m_cameras.begin()), it->m_videoFx, it->m_videoFy, it->m_videoFPSq); qDebug("ATVMod::calculateCamerasSizes: [%d] factors: %f x %f FPSq: %f", (int) (it - m_cameras.begin()), it->m_videoFx, it->m_videoFy, it->m_videoFPSq);
} }
} }
@ -596,6 +644,15 @@ void ATVMod::resizeCameras()
} }
} }
void ATVMod::resizeCamera()
{
ATVCamera& camera = m_cameras[m_cameraIndex];
if (!camera.m_videoframeOriginal.empty()) {
cv::resize(camera.m_videoframeOriginal, camera.m_videoFrame, cv::Size(), camera.m_videoFx, camera.m_videoFy); // resize current frame
}
}
void ATVMod::seekVideoFileStream(int seekPercentage) void ATVMod::seekVideoFileStream(int seekPercentage)
{ {
QMutexLocker mutexLocker(&m_settingsMutex); QMutexLocker mutexLocker(&m_settingsMutex);
@ -641,6 +698,7 @@ void ATVMod::scanCameras()
if (m_cameras.size() > 0) if (m_cameras.size() > 0)
{ {
calculateCamerasSizes();
m_cameraIndex = 0; m_cameraIndex = 0;
} }
} }

View File

@ -261,6 +261,7 @@ public:
ATVModulation atvModulation, ATVModulation atvModulation,
bool videoPlayLoop, bool videoPlayLoop,
bool videoPlay, bool videoPlay,
bool cameraPLay,
bool channelMute); bool channelMute);
virtual void pull(Sample& sample); virtual void pull(Sample& sample);
@ -297,6 +298,7 @@ private:
ATVModulation getModulation() const { return m_atvModulation; } ATVModulation getModulation() const { return m_atvModulation; }
bool getVideoPlayLoop() const { return m_videoPlayLoop; } bool getVideoPlayLoop() const { return m_videoPlayLoop; }
bool getVideoPlay() const { return m_videoPlay; } bool getVideoPlay() const { return m_videoPlay; }
bool getCameraPlay() const { return m_cameraPlay; }
static MsgConfigureATVMod* create( static MsgConfigureATVMod* create(
Real rfBandwidth, Real rfBandwidth,
@ -305,7 +307,8 @@ private:
Real uniformLevel, Real uniformLevel,
ATVModulation atvModulation, ATVModulation atvModulation,
bool videoPlayLoop, bool videoPlayLoop,
bool videoPlay) bool videoPlay,
bool cameraPlay)
{ {
return new MsgConfigureATVMod( return new MsgConfigureATVMod(
rfBandwidth, rfBandwidth,
@ -314,7 +317,8 @@ private:
uniformLevel, uniformLevel,
atvModulation, atvModulation,
videoPlayLoop, videoPlayLoop,
videoPlay); videoPlay,
cameraPlay);
} }
private: private:
@ -325,6 +329,7 @@ private:
ATVModulation m_atvModulation; ATVModulation m_atvModulation;
bool m_videoPlayLoop; bool m_videoPlayLoop;
bool m_videoPlay; bool m_videoPlay;
bool m_cameraPlay;
MsgConfigureATVMod( MsgConfigureATVMod(
Real rfBandwidth, Real rfBandwidth,
@ -333,7 +338,8 @@ private:
Real uniformLevel, Real uniformLevel,
ATVModulation atvModulation, ATVModulation atvModulation,
bool videoPlayLoop, bool videoPlayLoop,
bool videoPlay) : bool videoPlay,
bool cameraPlay) :
Message(), Message(),
m_rfBandwidth(rfBandwidth), m_rfBandwidth(rfBandwidth),
m_atvStd(atvStd), m_atvStd(atvStd),
@ -341,7 +347,8 @@ private:
m_uniformLevel(uniformLevel), m_uniformLevel(uniformLevel),
m_atvModulation(atvModulation), m_atvModulation(atvModulation),
m_videoPlayLoop(videoPlayLoop), m_videoPlayLoop(videoPlayLoop),
m_videoPlay(videoPlay) m_videoPlay(videoPlay),
m_cameraPlay(cameraPlay)
{ } { }
}; };
@ -357,6 +364,8 @@ private:
float m_videoFx; //!< camera horizontal scaling factor float m_videoFx; //!< camera horizontal scaling factor
float m_videoFy; //!< camera vertictal scaling factor float m_videoFy; //!< camera vertictal scaling factor
float m_videoFPSq; //!< camera FPS sacaling factor float m_videoFPSq; //!< camera FPS sacaling factor
float m_videoFPSCount; //!< camera FPS fractional counter
int m_videoPrevFPSCount; //!< camera FPS previous integer counter
ATVCamera() : ATVCamera() :
m_cameraNumber(-1), m_cameraNumber(-1),
@ -365,7 +374,9 @@ private:
m_videoHeight(1), m_videoHeight(1),
m_videoFx(1.0f), m_videoFx(1.0f),
m_videoFy(1.0f), m_videoFy(1.0f),
m_videoFPSq(1.0f) m_videoFPSq(1.0f),
m_videoFPSCount(0.0f),
m_videoPrevFPSCount(0)
{} {}
}; };
@ -380,6 +391,7 @@ private:
ATVModulation m_atvModulation; //!< RF modulation type ATVModulation m_atvModulation; //!< RF modulation type
bool m_videoPlayLoop; //!< Play video in a loop bool m_videoPlayLoop; //!< Play video in a loop
bool m_videoPlay; //!< True to play video and false to pause bool m_videoPlay; //!< True to play video and false to pause
bool m_cameraPlay; //!< True to play camera video and false to pause
Config() : Config() :
m_outputSampleRate(-1), m_outputSampleRate(-1),
@ -390,7 +402,8 @@ private:
m_uniformLevel(0.5f), m_uniformLevel(0.5f),
m_atvModulation(ATVModulationAM), m_atvModulation(ATVModulationAM),
m_videoPlayLoop(false), m_videoPlayLoop(false),
m_videoPlay(false) m_videoPlay(false),
m_cameraPlay(false)
{ } { }
}; };
@ -476,6 +489,7 @@ private:
void releaseCameras(); void releaseCameras();
void calculateCamerasSizes(); void calculateCamerasSizes();
void resizeCameras(); void resizeCameras();
void resizeCamera();
inline void pullImageLine(Real& sample) inline void pullImageLine(Real& sample)
{ {
@ -547,6 +561,33 @@ private:
sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel; sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel;
} }
break; break;
case ATVModInputCamera:
if ((iLineImage < 0) || (m_cameraIndex < 0))
{
sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel;
}
else
{
ATVCamera& camera = m_cameras[m_cameraIndex];
if (camera.m_videoFrame.empty())
{
sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel;
}
else
{
unsigned char pixv;
if (m_interlaced) {
pixv = camera.m_videoFrame.at<unsigned char>(2*iLineImage + oddity, pointIndex); // row (y), col (x)
} else {
pixv = camera.m_videoFrame.at<unsigned char>(iLineImage, pointIndex); // row (y), col (x)
}
sample = (pixv / 256.0f) * m_spanLevel + m_blackLevel;
}
}
break;
case ATVModInputUniform: case ATVModInputUniform:
default: default:
sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel; sample = m_spanLevel * m_running.m_uniformLevel + m_blackLevel;

View File

@ -290,6 +290,16 @@ void ATVModGUI::on_navTimeSlider_valueChanged(int value)
} }
} }
void ATVModGUI::on_playCamera_toggled(bool checked)
{
applySettings();
}
void ATVModGUI::on_camSelect_currentIndexChanged(int index)
{
ATVMod::MsgConfigureCameraIndex* message = ATVMod::MsgConfigureCameraIndex::create(index);
m_atvMod->getInputMessageQueue()->push(message);
}
void ATVModGUI::configureImageFileName() void ATVModGUI::configureImageFileName()
{ {
@ -410,6 +420,7 @@ void ATVModGUI::applySettings()
(ATVMod::ATVModulation) ui->modulation->currentIndex(), (ATVMod::ATVModulation) ui->modulation->currentIndex(),
ui->playLoop->isChecked(), ui->playLoop->isChecked(),
ui->playVideo->isChecked(), ui->playVideo->isChecked(),
ui->playCamera->isChecked(),
ui->channelMute->isChecked()); ui->channelMute->isChecked());
} }
} }

View File

@ -72,6 +72,9 @@ private slots:
void on_playLoop_toggled(bool checked); void on_playLoop_toggled(bool checked);
void on_navTimeSlider_valueChanged(int value); void on_navTimeSlider_valueChanged(int value);
void on_playCamera_toggled(bool checked);
void on_camSelect_currentIndexChanged(int index);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDoubleClicked(); void onMenuDoubleClicked();

View File

@ -363,6 +363,11 @@
<string>Video</string> <string>Video</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>Camera</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item> <item>