kopia lustrzana https://github.com/f4exb/sdrangel
ATV Modulator: report video file straming to GUI
rodzic
d642e132d1
commit
5d9a1c7c56
|
@ -24,6 +24,10 @@
|
|||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureATVMod, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureImageFileName, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileName, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileSourceSeek, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureVideoFileSourceStreamTiming, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamTiming, Message)
|
||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message)
|
||||
|
||||
const float ATVMod::m_blackLevel = 0.3f;
|
||||
const float ATVMod::m_spanLevel = 0.7f;
|
||||
|
@ -307,6 +311,30 @@ bool ATVMod::handleMessage(const Message& cmd)
|
|||
openVideo(conf.getFileName());
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureVideoFileSourceSeek::match(cmd))
|
||||
{
|
||||
MsgConfigureVideoFileSourceSeek& conf = (MsgConfigureVideoFileSourceSeek&) cmd;
|
||||
int seekPercentage = conf.getPercentage();
|
||||
seekVideoFileStream(seekPercentage);
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureVideoFileSourceStreamTiming::match(cmd))
|
||||
{
|
||||
int framesCount;
|
||||
|
||||
if (m_videoOK && m_video.isOpened())
|
||||
{
|
||||
framesCount = m_video.get(CV_CAP_PROP_POS_FRAMES);;
|
||||
} else {
|
||||
framesCount = 0;
|
||||
}
|
||||
|
||||
MsgReportVideoFileSourceStreamTiming *report;
|
||||
report = MsgReportVideoFileSourceStreamTiming::create(framesCount);
|
||||
getOutputMessageQueue()->push(report);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
@ -454,15 +482,22 @@ void ATVMod::openVideo(const QString& fileName)
|
|||
m_videoFPS = m_video.get(CV_CAP_PROP_FPS);
|
||||
m_videoWidth = (int) m_video.get(CV_CAP_PROP_FRAME_WIDTH);
|
||||
m_videoHeight = (int) m_video.get(CV_CAP_PROP_FRAME_HEIGHT);
|
||||
m_videoLength = (int) m_video.get(CV_CAP_PROP_FRAME_COUNT);
|
||||
int ex = static_cast<int>(m_video.get(CV_CAP_PROP_FOURCC));
|
||||
char ext[] = {(char)(ex & 0XFF),(char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24),0};
|
||||
qDebug("ATVMod::openVideo: %s FPS: %f size: %d x %d codec: %s",
|
||||
|
||||
qDebug("ATVMod::openVideo: %s FPS: %f size: %d x %d #frames: %d codec: %s",
|
||||
m_video.isOpened() ? "OK" : "KO",
|
||||
m_videoFPS,
|
||||
m_videoWidth,
|
||||
m_videoHeight,
|
||||
m_videoLength,
|
||||
ext);
|
||||
calculateVideoSizes();
|
||||
|
||||
MsgReportVideoFileSourceStreamData *report;
|
||||
report = MsgReportVideoFileSourceStreamData::create(m_videoFPS, m_videoLength);
|
||||
getOutputMessageQueue()->push(report);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -493,3 +528,16 @@ void ATVMod::resizeVideo()
|
|||
cv::resize(m_frameOriginal, m_frame, cv::Size(), m_videoFx, m_videoFy); // resize current frame
|
||||
}
|
||||
}
|
||||
|
||||
void ATVMod::seekVideoFileStream(int seekPercentage)
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_settingsMutex);
|
||||
|
||||
if ((m_videoOK) && m_video.isOpened())
|
||||
{
|
||||
int seekPoint = ((m_videoLength * seekPercentage) / 100);
|
||||
m_video.set(CV_CAP_PROP_POS_FRAMES, seekPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,90 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
class MsgConfigureVideoFileSourceSeek : public Message
|
||||
{
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getPercentage() const { return m_seekPercentage; }
|
||||
|
||||
static MsgConfigureVideoFileSourceSeek* create(int seekPercentage)
|
||||
{
|
||||
return new MsgConfigureVideoFileSourceSeek(seekPercentage);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_seekPercentage; //!< percentage of seek position from the beginning 0..100
|
||||
|
||||
MsgConfigureVideoFileSourceSeek(int seekPercentage) :
|
||||
Message(),
|
||||
m_seekPercentage(seekPercentage)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgConfigureVideoFileSourceStreamTiming : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
|
||||
static MsgConfigureVideoFileSourceStreamTiming* create()
|
||||
{
|
||||
return new MsgConfigureVideoFileSourceStreamTiming();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MsgConfigureVideoFileSourceStreamTiming() :
|
||||
Message()
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportVideoFileSourceStreamTiming : public Message
|
||||
{
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getFrameCount() const { return m_frameCount; }
|
||||
|
||||
static MsgReportVideoFileSourceStreamTiming* create(int frameCount)
|
||||
{
|
||||
return new MsgReportVideoFileSourceStreamTiming(frameCount);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_frameCount;
|
||||
|
||||
MsgReportVideoFileSourceStreamTiming(int frameCount) :
|
||||
Message(),
|
||||
m_frameCount(frameCount)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportVideoFileSourceStreamData : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
int getFrameRate() const { return m_frameRate; }
|
||||
quint32 getVideoLength() const { return m_videoLength; }
|
||||
|
||||
static MsgReportVideoFileSourceStreamData* create(int frameRate,
|
||||
quint32 recordLength)
|
||||
{
|
||||
return new MsgReportVideoFileSourceStreamData(frameRate, recordLength);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_frameRate;
|
||||
int m_videoLength; //!< Video length in frames
|
||||
|
||||
MsgReportVideoFileSourceStreamData(int frameRate,
|
||||
int videoLength) :
|
||||
Message(),
|
||||
m_frameRate(frameRate),
|
||||
m_videoLength(videoLength)
|
||||
{ }
|
||||
};
|
||||
|
||||
ATVMod();
|
||||
~ATVMod();
|
||||
|
||||
|
@ -250,6 +334,7 @@ private:
|
|||
float m_videoFPSq; //!< current video FPS sacaling factor
|
||||
float m_videoFPSCount; //!< current video FPS fractional counter
|
||||
int m_videoPrevFPSCount; //!< current video FPS previous integer counter
|
||||
int m_videoLength; //!< current video length in frames
|
||||
bool m_videoOK;
|
||||
|
||||
static const float m_blackLevel;
|
||||
|
@ -268,6 +353,7 @@ private:
|
|||
void resizeImage();
|
||||
void calculateVideoSizes();
|
||||
void resizeVideo();
|
||||
void seekVideoFileStream(int seekPercentage);
|
||||
|
||||
inline void pullImageLine(Real& sample)
|
||||
{
|
||||
|
|
|
@ -152,7 +152,24 @@ bool ATVModGUI::deserialize(const QByteArray& data)
|
|||
|
||||
bool ATVModGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (ATVMod::MsgReportVideoFileSourceStreamData::match(message))
|
||||
{
|
||||
m_videoFrameRate = ((ATVMod::MsgReportVideoFileSourceStreamData&)message).getFrameRate();
|
||||
m_videoLength = ((ATVMod::MsgReportVideoFileSourceStreamData&)message).getVideoLength();
|
||||
m_frameCount = 0;
|
||||
updateWithStreamData();
|
||||
return true;
|
||||
}
|
||||
else if (ATVMod::MsgReportVideoFileSourceStreamTiming::match(message))
|
||||
{
|
||||
m_frameCount = ((ATVMod::MsgReportVideoFileSourceStreamTiming&)message).getFrameCount();
|
||||
updateWithStreamTime();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ATVModGUI::viewChanged()
|
||||
|
@ -289,9 +306,9 @@ ATVModGUI::ATVModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa
|
|||
m_basicSettingsShown(false),
|
||||
m_doApplySettings(true),
|
||||
m_channelPowerDbAvg(20,0),
|
||||
m_recordLength(0),
|
||||
m_recordSampleRate(48000),
|
||||
m_samplesCount(0),
|
||||
m_videoLength(0),
|
||||
m_videoFrameRate(48000),
|
||||
m_frameCount(0),
|
||||
m_tickCount(0),
|
||||
m_enableNavTime(false)
|
||||
{
|
||||
|
@ -386,4 +403,46 @@ void ATVModGUI::tick()
|
|||
Real powDb = CalcDb::dbPower(m_atvMod->getMagSq());
|
||||
m_channelPowerDbAvg.feed(powDb);
|
||||
ui->channelPower->setText(QString::number(m_channelPowerDbAvg.average(), 'f', 1));
|
||||
|
||||
if (((++m_tickCount & 0xf) == 0) && (ui->inputSelect->currentIndex() == (int) ATVMod::ATVModInputVideo))
|
||||
{
|
||||
ATVMod::MsgConfigureVideoFileSourceStreamTiming* message = ATVMod::MsgConfigureVideoFileSourceStreamTiming::create();
|
||||
m_atvMod->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
void ATVModGUI::updateWithStreamData()
|
||||
{
|
||||
QTime recordLength(0, 0, 0, 0);
|
||||
recordLength = recordLength.addSecs(m_videoLength / m_videoFrameRate);
|
||||
QString s_time = recordLength.toString("hh:mm:ss");
|
||||
ui->recordLengthText->setText(s_time);
|
||||
updateWithStreamTime();
|
||||
}
|
||||
|
||||
void ATVModGUI::updateWithStreamTime()
|
||||
{
|
||||
int t_sec = 0;
|
||||
int t_msec = 0;
|
||||
|
||||
if (m_videoFrameRate > 0.0f)
|
||||
{
|
||||
float secs = m_frameCount / m_videoFrameRate;
|
||||
t_sec = (int) secs;
|
||||
t_msec = (int) ((secs - t_sec) * 1000.0f);
|
||||
}
|
||||
|
||||
QTime t(0, 0, 0, 0);
|
||||
t = t.addSecs(t_sec);
|
||||
t = t.addMSecs(t_msec);
|
||||
QString s_timems = t.toString("hh:mm:ss.zzz");
|
||||
QString s_time = t.toString("hh:mm:ss");
|
||||
ui->relTimeText->setText(s_timems);
|
||||
|
||||
if (!m_enableNavTime)
|
||||
{
|
||||
float posRatio = (t_sec * m_videoFrameRate) / m_videoLength;
|
||||
ui->navTimeSlider->setValue((int) (posRatio * 100.0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,9 +91,9 @@ private:
|
|||
|
||||
QString m_imageFileName;
|
||||
QString m_videoFileName;
|
||||
quint32 m_recordLength;
|
||||
int m_recordSampleRate;
|
||||
int m_samplesCount;
|
||||
quint32 m_videoLength; //!< video file length in seconds
|
||||
float m_videoFrameRate; //!< video file frame rate
|
||||
int m_frameCount;
|
||||
std::size_t m_tickCount;
|
||||
bool m_enableNavTime;
|
||||
|
||||
|
@ -102,6 +102,8 @@ private:
|
|||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings();
|
||||
void updateWithStreamData();
|
||||
void updateWithStreamTime();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(QEvent*);
|
||||
|
|
Ładowanie…
Reference in New Issue