61 if (!Details.contains(QStringLiteral(
"width")) || !Details.contains(QStringLiteral(
"height")))
64 bool bitrate = Details.contains(QStringLiteral(
"bitrate"));
65 bool framerate = Details.contains(QStringLiteral(
"framerate"));
66 bool video = bitrate && framerate;
67 bool stills = !bitrate && !framerate;
69 if (!video && !stills)
72 m_width = Details.value(QStringLiteral(
"width")).toInt();
73 m_height = Details.value(QStringLiteral(
"height")).toInt();
77 int pitch = (
m_width + 15) & ~15;
80 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Rounding video width up to %1 from %2").arg(pitch).arg(
m_width));
88 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Rounding video height up to %1 from %2").arg(height).arg(
m_height));
101 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video too small - forcing output to %1x%2").arg(
m_width).arg(
m_height));
107 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video too large - forcing output to %1x%2").arg(
m_width).arg(
m_height));
112 m_frameRate = Details.value(QStringLiteral(
"framerate")).toInt();
113 m_bitrate = Details.value(QStringLiteral(
"bitrate")).toInt();
118 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video framerate too low - forcing to %1").arg(
m_frameRate));
123 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video framerate too high - forcing to %1").arg(
m_frameRate));
129 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video bitrate too low - forcing to %1").arg(
m_bitrate));
134 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Video bitrate too high - forcing to %1").arg(
m_bitrate));
146 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Camera stills: %1x%2").arg(
m_width).arg(
m_height));
200 LOG(VB_GENERAL, LOG_ERR, QStringLiteral(
"Error combining camera parameters - %1x%2 != %3x%4")
208 LOG(VB_GENERAL, LOG_WARNING, QStringLiteral(
"Using smaller image size %1x%2").arg(
m_width).arg(
m_height));
222 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Added video to camera parameters"));
228 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Added stills to camera parameters"));
255 m_haveInitSegment(false),
256 m_bufferedPacket(nullptr),
257 m_ringBuffer(nullptr),
258 m_ringBufferLock(QReadWriteLock::Recursive),
356 QFile file(
m_params.
m_contentDir + QDateTime::currentDateTime().toString(QStringLiteral(
"yyyy_MM_dd_hh_mm_ss_zzz")) +
".jpg");
357 if (file.open(QIODevice::ReadWrite | QIODevice::Truncate))
359 QPair<quint32, uint8_t*> pair;
361 file.write((
const char*)pair.second, pair.first);
363 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Saved snapshot as '%1'").arg(file.fileName()));
368 LOG(VB_GENERAL, LOG_ERR, QStringLiteral(
"Failed to open %1 for writing").arg(file.fileName()));
380 if (Length < 1 || !Data)
388 QPair<quint32, uint8_t*> buffer;
396 quint64 now = QDateTime::currentMSecsSinceEpoch();
420 double driftdelta = longaverage - shortaverage;
421 double gradient = driftdelta / timedelta;
422 double timetozero = qAbs(driftdelta) < 1 ? qInf() : drift / gradient;
424 LOG(VB_GENERAL, LOG_INFO, QStringLiteral(
"Drift: %1secs 1min %2 5min %3 timetozero %4")
425 .arg((
double)drift/1000, 0,
'f', 3).arg(shortaverage/1000, 0,
'f', 3).arg(longaverage/1000, 0,
'f', 3).arg(timetozero/1000, 0,
'f', 3));
431 : nextTorcCameraFactory(gTorcCameraFactory)
433 qRegisterMetaType<TorcCameraParams>(
"TorcCameraParams&");
456 result = factory->
Create(Type, Params);
void InitSegmentReady(void)
static TorcCameraFactory * GetTorcCameraFactory(void)
#define VIDEO_FRAMERATE_MIN
void ClearStillsBuffers(void)
TorcAverage< double > m_shortAverage
static TorcCameraDevice * GetCamera(const QString &Type, const TorcCameraParams &Params)
int GetHead(void)
Return the number of the segment at the head of the queue (the newest).
int AddH264Stream(int Width, int Height, int Profile, int Bitrate)
#define VIDEO_H264_PROFILE
QByteArray GetInitSegment(void)
Return a copy of the MP4 'init' segment.
virtual bool CanHandle(const QString &Type, const TorcCameraParams &Params)=0
TorcCameraParams m_params
QByteArray GetInitSegment(void)
TorcCameraFactory * NextFactory(void) const
void SegmentRemoved(int Segment)
QReadWriteLock m_ringBufferLock
TorcAverage< double > m_longAverage
virtual void TakeStills(uint Count)
Tell the camera to take Count number of still images.
AVPacket * m_bufferedPacket
virtual void StartStill(void)=0
virtual bool EnableStills(uint Count)
#define VIDEO_SEGMENT_TARGET
#define VIDEO_DRIFT_SHORT
#define VIDEO_SEGMENT_NUMBER
void SegmentReady(int Segment)
virtual ~TorcCameraDevice()
void SegmentRemoved(int Segment)
#define VIDEO_BITRATE_MIN
virtual TorcCameraDevice * Create(const QString &Type, const TorcCameraParams &Params)=0
bool IsCompatible(const TorcCameraParams &Other) const
static TorcCameraFactory * gTorcCameraFactory
TorcCameraParams & operator=(const TorcCameraParams &Other)
void StillReady(const QString &File)
QByteArray GetSegment(int Segment)
TorcCameraFactory * nextTorcCameraFactory
#define LOG(_MASK_, _LEVEL_, _STRING_)
bool operator==(const TorcCameraParams &Other) const
void InitSegmentReady(void)
#define VIDEO_SEGMENT_MAX
QList< QPair< quint32, uint8_t * > > m_stillsBuffers
TorcCameraParams Combine(const TorcCameraParams &Add)
TorcCameraDevice(const TorcCameraParams &Params)
#define VIDEO_BITRATE_MAX
void SegmentReady(int Segment)
#define VIDEO_GOPDURA_TARGET
TorcSegmentedRingBuffer * m_ringBuffer
void SaveStillBuffer(quint32 Length, uint8_t *Data)
QByteArray GetSegment(int SegmentRef)
Return a copy of the segment identified by SegmentRef.
#define VIDEO_FRAMERATE_MAX