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")
160 else if (name ==
"videodevice")
164 else if (name ==
"tvformat")
167 if (value.toLower() ==
"ntsc" || value.toLower() ==
"ntsc-jp")
172 else if (value.toLower() ==
"pal-m")
176 else if (value.toLower() ==
"atsc")
195 LOG(VB_GENERAL, LOG_WARNING,
LOC +
196 QString(
"SetOption(%1,%2): Option not recognized")
203 LOG(VB_GENERAL, LOG_ERR,
LOC +
204 QString(
"SetOption(): Unknown int option: %1: %2")
205 .arg(name).arg(value));
214 LOG(VB_GENERAL, LOG_WARNING,
LOC +
215 QString(
"SetIntOption(...%1): Option not in profile.").arg(name));
224 LOG(VB_GENERAL, LOG_WARNING,
LOC +
225 QString(
"SetStrOption(...%1): Option not in profile.").arg(name));
243 LOG(VB_GENERAL, LOG_ERR,
LOC +
244 "Programmer Error: Recorder started while we were in "
315 std::chrono::milliseconds wait =
timeout -
t.elapsed();
362 bool did_switch =
false;
405 const QString&
file,
int line)
409 LOG(VB_RECORD, LOG_INFO,
410 QString(
"Modifying recording status from %1 to %2 at %3:%4")
414 QString::number(line)));
424 MythEvent me(QString(
"UPDATE_RECORDING_STATUS %1 %2 %3 %4 %5")
494 LOG(VB_GENERAL, LOG_CRIT,
"RecordingFile object is NULL. No video file metadata can be stored");
503 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Finished Recording: "
505 "Video Codec: %1 (%2x%3 A/R: %4 %5fps) "
539 frm_pos_map_t::const_iterator it =
m_positionMap.lowerBound(desired);
542 if (it.key() == desired)
561 frm_pos_map_t::const_iterator it =
m_positionMap.lowerBound(start);
562 end = (end < 0) ? INT64_MAX : end;
564 (it.key() <= end); ++it)
567 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
568 QString(
"GetKeyframePositions(%1,%2,#%3) out of %4")
569 .arg(start).arg(end).arg(map.size()).arg(
m_positionMap.size()));
583 frm_pos_map_t::const_iterator it =
m_durationMap.lowerBound(start);
584 end = (end < 0) ? INT64_MAX : end;
586 (it.key() <= end); ++it)
589 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
590 QString(
"GetKeyframeDurations(%1,%2,#%3) out of %4")
591 .arg(start).arg(end).arg(map.size()).arg(
m_durationMap.size()));
606 bool needToSave =
force;
615 has_delta && (pm_elapsed >= 1.5s);
617 needToSave |= has_delta && (pm_elapsed >= 10s);
665 LOG(VB_RECORD, LOG_WARNING,
LOC +
666 "Ringbuffer was switched due to timeout instead of keyframe.");
676 LOG(VB_RECORD, LOG_DEBUG,
677 QString(
"No progstart mark needed because delta=%1")
681 frm_pos_map_t::const_iterator first_it = durationDeltaCopy.begin();
682 if (first_it == durationDeltaCopy.end())
684 LOG(VB_RECORD, LOG_DEBUG,
"No progstart mark because map is empty");
687 frm_pos_map_t::const_iterator last_it = durationDeltaCopy.end();
689 long long bookmarkFrame = 0;
690 long long first_time { first_it.value() };
691 long long last_time { last_it.value() };
692 LOG(VB_RECORD, LOG_DEBUG,
693 QString(
"durationDeltaCopy.begin() = (%1,%2)")
695 .arg(first_it.value()));
699 LOG(VB_RECORD, LOG_DEBUG,
700 QString(
"No progstart mark yet because estimatedProgStartMS=%1 "
708 LOG(VB_RECORD, LOG_DEBUG,
709 QString(
"Set progstart mark=%1 because %2<=%3<%4")
717 frm_pos_map_t::const_iterator upper_it = first_it;
718 for (; upper_it != durationDeltaCopy.end(); ++upper_it)
724 LOG(VB_RECORD, LOG_DEBUG,
725 QString(
"Set progstart mark=%1 because "
726 "estimatedProgStartMS=%2 and upper_it.value()=%3")
728 .arg(upper_it.value()));
729 bookmarkFrame = upper_it.key();
737 LOG(VB_RECORD, LOG_DEBUG,
"No progstart mark due to fallthrough");
747 LOG(VB_RECORD, LOG_DEBUG,
748 QString(
"Setting lastSavedKeyframe=%1 lastSavedDuration=%2 "
749 "for progstart mark calculations")
756 uint customAspect = 0;
760 customAspect = aspect;
992 QString msg =
"Need %1 recorder, but compiled without %2 support!";
994 LOG(VB_GENERAL, LOG_ERR,
995 "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.