4#include "libmythbase/mythconfig.h"
41#define TVREC_CARDNUM \
42 ((m_tvrec != nullptr) ? QString::number(m_tvrec->GetInputId()) : "NULL")
44#define LOC QString("RecBase[%1](%2): ") \
45 .arg(TVREC_CARDNUM, m_videodevice)
80 msg =
" '" +
Buffer->GetFilename() +
"'";
81 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetRingBuffer(0x%1)")
82 .arg((uint64_t)
Buffer,0,16) + msg);
92 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetRecording(0x%1) title(%2)")
93 .arg((uint64_t)pginfo,0,16).arg(pginfo->GetTitle()));
97 LOG(VB_RECORD, LOG_INFO,
LOC +
"SetRecording(0x0)");
127 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetNextRecording(0x%1, 0x%2)")
128 .arg(
reinterpret_cast<intptr_t
>(ri),0,16)
129 .arg(
reinterpret_cast<intptr_t
>(
Buffer),0,16));
156 if (name ==
"videocodec")
158 else if (name ==
"videodevice")
160 else if (name ==
"tvformat")
163 if (value.toLower() ==
"ntsc" || value.toLower() ==
"ntsc-jp")
168 else if (value.toLower() ==
"pal-m")
172 else if (value.toLower() ==
"atsc")
191 LOG(VB_GENERAL, LOG_WARNING,
LOC +
192 QString(
"SetOption(%1,%2): Option not recognized")
199 LOG(VB_GENERAL, LOG_ERR,
LOC +
200 QString(
"SetOption(): Unknown int option: %1: %2")
201 .arg(name).arg(value));
210 LOG(VB_GENERAL, LOG_ERR,
LOC +
211 QString(
"SetIntOption(...%1): Option not in profile.").arg(name));
220 LOG(VB_GENERAL, LOG_ERR,
LOC +
221 QString(
"SetStrOption(...%1): Option not in profile.").arg(name));
239 LOG(VB_GENERAL, LOG_ERR,
LOC +
240 "Programmer Error: Recorder started while we were in "
311 std::chrono::milliseconds wait =
timeout -
t.elapsed();
358 bool did_switch =
false;
401 const QString&
file,
int line)
405 LOG(VB_RECORD, LOG_INFO,
406 QString(
"Modifying recording status from %1 to %2 at %3:%4")
410 QString::number(line)));
420 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
490 LOG(VB_GENERAL, LOG_CRIT,
"RecordingFile object is NULL. No video file metadata can be stored");
499 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Finished Recording: "
501 "Video Codec: %1 (%2x%3 A/R: %4 %5fps) "
535 frm_pos_map_t::const_iterator it =
m_positionMap.lowerBound(desired);
538 if (it.key() == desired)
557 frm_pos_map_t::const_iterator it =
m_positionMap.lowerBound(start);
558 end = (end < 0) ? INT64_MAX : end;
560 (it.key() <= end); ++it)
563 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
564 QString(
"GetKeyframePositions(%1,%2,#%3) out of %4")
565 .arg(start).arg(end).arg(map.size()).arg(
m_positionMap.size()));
579 frm_pos_map_t::const_iterator it =
m_durationMap.lowerBound(start);
580 end = (end < 0) ? INT64_MAX : end;
582 (it.key() <= end); ++it)
585 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
586 QString(
"GetKeyframeDurations(%1,%2,#%3) out of %4")
587 .arg(start).arg(end).arg(map.size()).arg(
m_durationMap.size()));
602 bool needToSave =
force;
611 has_delta && (pm_elapsed >= 1.5s);
613 needToSave |= has_delta && (pm_elapsed >= 10s);
661 LOG(VB_RECORD, LOG_WARNING,
LOC +
662 "Ringbuffer was switched due to timeout instead of keyframe.");
672 LOG(VB_RECORD, LOG_DEBUG,
673 QString(
"No progstart mark needed because delta=%1")
677 frm_pos_map_t::const_iterator first_it = durationDeltaCopy.begin();
678 if (first_it == durationDeltaCopy.end())
680 LOG(VB_RECORD, LOG_DEBUG,
"No progstart mark because map is empty");
683 frm_pos_map_t::const_iterator last_it = durationDeltaCopy.end();
685 long long bookmarkFrame = 0;
686 long long first_time { first_it.value() };
687 long long last_time { last_it.value() };
688 LOG(VB_RECORD, LOG_DEBUG,
689 QString(
"durationDeltaCopy.begin() = (%1,%2)")
691 .arg(first_it.value()));
695 LOG(VB_RECORD, LOG_DEBUG,
696 QString(
"No progstart mark yet because estimatedProgStartMS=%1 "
704 LOG(VB_RECORD, LOG_DEBUG,
705 QString(
"Set progstart mark=%1 because %2<=%3<%4")
713 frm_pos_map_t::const_iterator upper_it = first_it;
714 for (; upper_it != durationDeltaCopy.end(); ++upper_it)
720 LOG(VB_RECORD, LOG_DEBUG,
721 QString(
"Set progstart mark=%1 because "
722 "estimatedProgStartMS=%2 and upper_it.value()=%3")
724 .arg(upper_it.value()));
725 bookmarkFrame = upper_it.key();
733 LOG(VB_RECORD, LOG_DEBUG,
"No progstart mark due to fallthrough");
743 LOG(VB_RECORD, LOG_DEBUG,
744 QString(
"Setting lastSavedKeyframe=%1 lastSavedDuration=%2 "
745 "for progstart mark calculations")
752 uint customAspect = 0;
756 customAspect = aspect;
988 QString msg =
"Need %1 recorder, but compiled without %2 support!";
990 LOG(VB_GENERAL, LOG_ERR,
991 "RecorderBase::CreateRecorder() Error, " + msg);
This is a specialization of DTVRecorder used to handle streams from ASI drivers.
Abstract class providing a generic interface to tuning hardware.
Provides interface to the tuning hardware when using DVB drivers.
This is a specialization of DTVRecorder used to handle streams from DVB drivers.
This is a specialization of DTVRecorder used to handle streams from External 'blackbox' recorders.
FirewireChannel Copyright (c) 2005 by Jim Westfall and Dave Abrahams Distributed as part of MythTV un...
This is a specialization of DTVRecorder used to handle DVB and ATSC streams from a firewire input.
ImportRecorder imports files, creating a seek map and other stuff that MythTV likes to have for recor...
C++ wrapper for FFmpeg libavutil AVRational.
void dispatch(const MythEvent &event)
This class is used as a container for messages.
A QElapsedTimer based timer to replace use of QTime as a timer.
std::chrono::milliseconds restart(void)
Returns milliseconds elapsed since last start() or restart() and resets the count.
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
void start(void)
starts measuring elapsed time.
Holds information on recordings and videos.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
void SetRecordingStatus(RecStatus::Type status)
void SaveVideoScanType(uint64_t frame, bool progressive)
Store the Progressive/Interlaced state in the recordedmarkup table.
void SaveTotalDuration(std::chrono::milliseconds duration)
Store the Total Duration at frame 0 in the recordedmarkup table.
void SaveResolution(uint64_t frame, uint width, uint height)
Store the Resolution at frame in the recordedmarkup table.
void SaveFrameRate(uint64_t frame, uint framerate)
Store the Frame Rate at frame in the recordedmarkup table.
void SaveAspect(uint64_t frame, MarkTypes type, uint customAspect)
Store aspect ratio of a frame in the recordedmark table.
uint QueryAverageWidth(void) const
If present in recording this loads average width of the main video stream from database's stream mark...
void SaveVideoProperties(uint mask, uint video_property_flags)
uint QueryAverageHeight(void) const
If present in recording this loads average height of the main video stream from database's stream mar...
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
uint QueryAverageFrameRate(void) const
If present in recording this loads average frame rate of the main video stream from database's stream...
MarkTypes QueryAverageAspectRatio(void) const
void SaveTotalFrames(int64_t frames)
Store the Total Frames at frame 0 in the recordedmarkup table.
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
void SavePositionMapDelta(frm_pos_map_t &posMap, MarkTypes type) const
uint GetInputID(void) const
RecStatus::Type GetRecordingStatus(void) const
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
void SaveMarkupMap(const frm_dir_map_t &marks, MarkTypes type=MARK_ALL, int64_t min_frame=-1, int64_t max_frame=-1) const
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
This is the abstract base class for supporting recorder hardware.
qint64 m_estimatedProgStartMS
virtual bool IsRecording(void)
Tells whether the StartRecorder() loop is running.
virtual void StartNewFile(void)
QAtomicInt m_timeOfLatestDataPacketInterval
virtual void Pause(bool clear=true)
Pause tells recorder to pause, it should not block.
virtual void ResetForNewFile(void)=0
AVContainer m_containerFormat
void SetFrameRate(double rate)
Sets the video frame rate.
QMutex m_nextRingBufferLock
virtual void Unpause(void)
Unpause tells recorder to unpause.
virtual bool CheckForRingBufferSwitch(void)
If requested, switch to new RingBuffer/ProgramInfo objects.
frm_pos_map_t m_positionMap
AVCodecID m_primaryAudioCodec
frm_pos_map_t m_durationMapDelta
MarkTypes m_positionMapType
long long m_lastSavedDuration
QDateTime m_timeOfLatestData
void FrameRateChange(uint framerate, uint64_t frame)
Note a change in video frame rate in the recordedmark table.
void SetTotalFrames(uint64_t total_frames)
Note the total frames in the recordedmark table.
QDateTime m_timeOfFirstData
void SetRecording(const RecordingInfo *pginfo)
Changes the Recording from the one set initially with SetOptionsFromProfile().
double GetFrameRate(void) const
Returns the latest frame rate.
bool GetKeyframePositions(long long start, long long end, frm_pos_map_t &map) const
virtual bool IsRecordingRequested(void)
Tells us if StopRecording() has been called.
void VideoCodecChange(AVCodecID vCodec)
Note a change in video codec.
void SetNextRecording(const RecordingInfo *ri, MythMediaBuffer *Buffer)
Sets next recording info, to be applied as soon as practical.
virtual void StopRecording(void)
StopRecording() signals to the recorder that it should stop recording and exit cleanly.
MythTimer m_ringBufferCheckTimer
frm_pos_map_t m_positionMapDelta
virtual void FinishRecording(void)
void ResolutionChange(uint width, uint height, long long frame)
Note a change in video size in the recordedmark table.
virtual RecordingQuality * GetRecordingQuality(const RecordingInfo *ri) const
Returns a report about the current recordings quality.
void AspectChange(uint aspect, long long frame)
Note a change in aspect ratio in the recordedmark table.
virtual bool PauseAndWait(std::chrono::milliseconds timeout=100ms)
If m_requestPause is true, sets pause and blocks up to timeout milliseconds or until unpaused,...
AVCodecID m_primaryVideoCodec
bool m_recording
True while recording is actually being performed.
bool GetKeyframeDurations(long long start, long long end, frm_pos_map_t &map) const
virtual void SetRecordingStatus(RecStatus::Type status, const QString &file, int line)
frm_pos_map_t m_durationMap
QWaitCondition m_pauseWait
long long GetKeyframePosition(long long desired) const
Returns closest keyframe position before the desired frame.
long long m_lastSavedKeyframe
void SetStrOption(RecordingProfile *profile, const QString &name)
Convenience function used to set QString options from a profile.
MythMediaBuffer * m_ringBuffer
RecordingGaps m_recordingGaps
virtual bool IsPaused(bool holding_lock=false) const
Returns true iff recorder is paused.
void SetDuration(std::chrono::milliseconds duration)
Note the total duration in the recordedmark table.
MythAVRational m_frameRate
virtual bool WaitForPause(std::chrono::milliseconds timeout=1s)
WaitForPause blocks until recorder is actually paused, or timeout milliseconds elapse.
MythTimer m_positionMapTimer
QAtomicInt m_timeOfLatestDataCount
void VideoScanChange(SCAN_t scan, uint64_t frame)
Note a change in video scan type in the recordedmark table.
QAtomicInt m_timeOfFirstDataIsSet
bool m_requestRecording
True if API call has requested a recording be [re]started.
void SavePositionMap(bool force=false, bool finished=false)
Save the seektable to the DB.
virtual void SetOption(const QString &name, const QString &value)
Set an specific option.
MythMediaBuffer * m_nextRingBuffer
void AudioCodecChange(AVCodecID aCodec)
Note a change in audio codec.
void TryWriteProgStartMark(const frm_pos_map_t &durationDeltaCopy)
RecordingInfo * m_curRecording
static RecorderBase * CreateRecorder(TVRec *tvrec, ChannelBase *channel, RecordingProfile &profile, const GeneralDBOptions &genOpt)
QWaitCondition m_unpauseWait
virtual void ClearStatistics(void)
RecordingInfo * m_nextRecording
QWaitCondition m_recordingWait
void SetIntOption(RecordingProfile *profile, const QString &name)
Convenience function used to set integer options from a profile.
void SetRingBuffer(MythMediaBuffer *Buffer)
Tells recorder to use an externally created ringbuffer.
Holds information on a recording file and it's video and audio streams.
AVContainer m_containerFormat
static QString AVContainerToString(AVContainer format)
double m_videoAspectRatio
Holds information on a TV Program one might wish to record.
void SaveFilesize(uint64_t fsize) override
Sets recording file size in database, and sets "filesize" field.
void SetDesiredStartTime(const QDateTime &dt)
QDateTime GetDesiredEndTime(void) const
void SetDesiredEndTime(const QDateTime &dt)
QDateTime GetDesiredStartTime(void) const
RecordingFile * GetRecordingFile() const
virtual QString getValue(void) const
This is the coordinating class of the Recorder Subsystem.
void RecorderPaused(void)
This is a callback, called by the "recorder" instance when it has actually paused.
void RingBufferChanged(MythMediaBuffer *Buffer, RecordingInfo *pginfo, RecordingQuality *recq)
This is a specialization of DTVRecorder used to handle streams from V4L2 recorders.
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static void clear(SettingsMap &cache, SettingsMap &overrides, const QString &myKey)
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void SendMythSystemRecEvent(const QString &msg, const RecordingInfo *pginfo)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
def scan(profile, smoonURL, gate)
@ MARK_ASPECT_1_1
deprecated, it is only 1:1 sample aspect ratio
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
QMap< long long, long long > frm_pos_map_t
Frame # -> File offset map.