Go to the documentation of this file.
37 #define LOC ((m_tvrec) ? \
38 QString("DTVRec[%1]: ").arg(m_tvrec->GetInputId()) : \
39 QString("DTVRec(0x%1): ").arg(intptr_t(this),0,16))
93 if (name ==
"recordingtype")
104 if (name ==
"wait_for_seqstart")
106 else if (name ==
"recordmpts")
113 const QString &videodev,
114 const QString& ,
const QString& )
142 LOG(VB_RECORD, LOG_INFO,
LOC +
"ResetForNewFile(void)");
206 LOG(VB_RECORD, LOG_INFO,
LOC +
"Reset(void)");
245 if (atsc && atsc->DesiredMinorChannel())
248 atsc->DesiredMinorChannel());
282 int interval = thresh;
286 .fetchAndStoreRelaxed(thresh * 4 / 5);
291 .fetchAndStoreRelaxed(thresh * 9 / 8);
297 LOG(VB_RECORD, LOG_DEBUG,
LOC +
298 QString(
"Updating timeOfLatestData elapsed(%1) interval(%2)")
299 .arg(elapsed.count()).arg(interval));
324 LOG(VB_GENERAL, LOG_INFO,
LOC +
325 QString(
"BufferedWrite: Writes are failing, "
326 "setting status to %1")
334 const uint8_t *bufptr,
int bytes_left,
int pts_or_dts)
339 bool has_pts = (bufptr[3] & 0x80) != 0;
341 if (((
kExtractPTS == pts_or_dts) && !has_pts) || (offset + 5 > bytes_left))
344 bool has_dts = (bufptr[3] & 0x40) != 0;
349 offset += has_pts ? 5 : 0;
350 if (offset + 5 > bytes_left)
354 return ((uint64_t(bufptr[offset+0] & 0x0e) << 29) |
355 (uint64_t(bufptr[offset+1] ) << 22) |
356 (uint64_t(bufptr[offset+2] & 0xfe) << 14) |
357 (uint64_t(bufptr[offset+3] ) << 7) |
358 (uint64_t(bufptr[offset+4] & 0xfe) >> 1));
362 uint64_t
pts, uint64_t pts_first,
const QDateTime &pts_first_dt)
365 pts += 0x1FFFFFFFFLL;
366 const QDateTime& dt = pts_first_dt;
367 return dt.addMSecs((
pts - pts_first)/90);
421 bool hasFrame =
false;
422 bool hasKeyFrame =
false;
424 uint aspectRatio = 0;
436 const uint8_t *bufptr = tspacket->
data() + tspacket->
AFCOffset();
440 while (bufptr < bufend)
443 int bytes_left = bufend - bufptr;
468 aspectRatio = (bufptr[3] >> 4);
471 height = ((bufptr[1] & 0xf) << 8) | bufptr[2];
472 width = (bufptr[0] <<4) | (bufptr[1]>>4);
480 int ext_type = (bufptr[0] >> 4);
492 int picture_structure = bufptr[2] & 3;
493 int top_field_first = bufptr[3] & (1 << 7);
494 int repeat_first_field = bufptr[3] & (1 << 1);
495 int progressive_frame = bufptr[4] & (1 << 7);
497 LOG(VB_RECORD, LOG_DEBUG,
LOC +
498 QString(
"picture_coding_extension(): (m_progressiveSequence: %1) picture_structure: %2 top_field_first: %3 repeat_first_field: %4 progressive_frame: %5")
500 QString::number(picture_structure , 2),
501 QString::number(top_field_first , 2),
502 QString::number(repeat_first_field , 2),
503 QString::number(progressive_frame , 2)
509 if (picture_structure == 0b00)
513 else if (picture_structure == 0b11)
518 else if (picture_structure < 0b11)
523 if (top_field_first != 0)
525 hasFrame = (picture_structure == 0b01);
529 hasFrame = (picture_structure == 0b10);
536 if (repeat_first_field)
545 else if (progressive_frame)
574 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Music Choice program detected");
580 if (hasFrame && !hasKeyFrame)
594 LOG(VB_RECORD, LOG_DEBUG,
LOC + QString
595 (
"Keyframe @ %1 + %2 = %3")
606 LOG(VB_RECORD, LOG_DEBUG,
LOC + QString
607 (
"Frame @ %1 + %2 = %3")
637 if (frameRate.isNonzero() && frameRate !=
m_frameRate)
640 LOG(VB_RECORD, LOG_INFO,
LOC +
641 QString(
"FindMPEG2Keyframes: frame rate = %1")
642 .arg(frameRate.toDouble() * 1000));
661 LOG(VB_RECORD, LOG_DEBUG,
662 "Switching from dts tracking to pts tracking." +
663 QString(
"TS count is %1").arg(
m_tsCount[stream_id]));
667 int64_t gap_threshold = 90000;
671 gap_threshold = 2*90000LL;
675 gap_threshold = 8*90000LL;
679 int64_t diff = ts -
m_tsLast[stream_id];
682 if (diff < (10 * -90000LL))
684 diff += 0x1ffffffffLL;
701 LOG(VB_RECORD, LOG_DEBUG,
LOC + QString(
"Inserted gap %1 dur %2")
709 LOG(VB_GENERAL, LOG_INFO,
LOC +
710 QString(
"HandleTimestamps: too much damage, "
711 "setting status to %1")
754 LOG(VB_RECORD, LOG_DEBUG,
755 QString(
"count=%1 m_frameRate=%2 tick_frameRate=%3 "
756 "tick_cnt=%4 tick_base=%5 _total_dur=%6")
768 bool hasKeyFrame =
false;
772 static constexpr uint64_t kMsecPerDay { 24ULL * 60 * 60 * 1000 };
774 uint64_t elapsed = 0;
777 auto expected_frame = (uint64_t) ((
double)elapsed / frame_interval);
780 expected_frame += (uint64_t) ((
double)kMsecPerDay / frame_interval);
814 LOG(VB_RECORD, LOG_INFO,
LOC +
"DSMCC - FindOtherKeyframes() - "
815 "generating initial key-frame");
879 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FindH2645Keyframes: No ringbuffer");
885 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FindH2645Keyframes: m_h2645Parser not present");
897 uint aspectRatio = 0;
903 bool hasFrame =
false;
904 bool hasKeyFrame =
false;
916 LOG(VB_GENERAL, LOG_ERR,
LOC +
917 "PES packet start code may overflow to next TS packet, "
918 "aborting keyframe search");
923 if (tspacket->
data()[i ] != 0x00 ||
924 tspacket->
data()[i+1] != 0x00 ||
925 tspacket->
data()[i+2] != 0x01)
930 LOG(VB_GENERAL, LOG_ERR,
LOC +
931 "PES start code not found in TS packet with PUSI set");
942 LOG(VB_GENERAL, LOG_ERR,
LOC +
943 "PES packet headers overflow to next TS packet, "
944 "aborting keyframe search");
954 const unsigned char pes_header_length = tspacket->
data()[i + 5];
959 LOG(VB_GENERAL, LOG_ERR,
LOC +
960 "PES packet headers overflow to next TS packet, "
961 "aborting keyframe search");
968 i += 5 + pes_header_length;
972 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"PES synced");
984 i += (bytes_used - 1);
1006 if (hasFrame && !hasKeyFrame &&
1010 LOG(VB_RECORD, LOG_WARNING,
LOC +
1011 QString(
"FindH2645Keyframes: %1 frames without a keyframe.")
1018 LOG(VB_RECORD, LOG_DEBUG,
LOC + QString
1019 (
"Keyframe @ %1 + %2 = %3 AU %4")
1031 LOG(VB_RECORD, LOG_DEBUG,
LOC + QString
1032 (
"Frame @ %1 + %2 = %3 AU %4")
1063 if (frameRate.isNonzero() && frameRate !=
m_frameRate)
1065 LOG(VB_RECORD, LOG_INFO,
LOC +
1066 QString(
"FindH2645Keyframes: timescale: %1, tick: %2, framerate: %3")
1069 .arg( frameRate.toDouble() * 1000 ) );
1076 LOG(VB_RECORD, LOG_INFO,
LOC +
1077 QString(
"FindH2645Keyframes: scan type: %1")
1079 "Interlaced" :
"Progressive"));
1096 uint64_t startpos = 0;
1126 const uint8_t *bufstart = buffer;
1127 const uint8_t *bufptr = buffer;
1128 const uint8_t *bufend = buffer + len;
1130 uint aspectRatio = 0;
1136 while (bufptr + skip < bufend)
1138 bool hasFrame =
false;
1139 bool hasKeyFrame =
false;
1141 const uint8_t *
tmp = bufptr;
1153 int pes_packet_length = -1;
1154 if ((bufend - bufptr) >= 2)
1155 pes_packet_length = ((bufptr[0]<<8) | bufptr[1]) + 2 + 6;
1162 pes_packet_length = -1;
1163 if (bufend-bufptr >= 4)
1165 uint frmtypei = (bufptr[1]>>3) & 0x7;
1166 if ((1 <= frmtypei) && (frmtypei <= 5))
1176 pes_packet_length = -1;
1182 pes_packet_length = -1;
1187 aspectRatio = (bufptr[3] >> 4);
1190 height = ((bufptr[1] & 0xf) << 8) | bufptr[2];
1191 width = (bufptr[0] <<4) | (bufptr[1]>>4);
1217 if (hasFrame && !hasKeyFrame)
1247 if (height && width &&
1255 if (frameRate.isNonzero() && frameRate !=
m_frameRate)
1258 LOG(VB_RECORD, LOG_INFO,
LOC +
1259 QString(
"FindPSKeyFrames: frame rate = %1")
1260 .arg(frameRate.toDouble() * 1000));
1264 if (hasKeyFrame || hasFrame)
1287 int bytes_skipped = bufend - bufptr;
1288 if (bytes_skipped > 0)
1299 uint64_t rem = (bufend - bufstart);
1303 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1304 QString(
"idx: %1, rem: %2").arg(idx).arg(rem));
1312 LOG(VB_RECORD, LOG_ERR,
LOC +
"SetPAT(NULL)");
1327 int oldProgNum = progNum;
1329 LOG(VB_GENERAL, LOG_INFO,
LOC +
1330 QString(
"Update desired program found in SPTS PAT from %1 to %2")
1331 .arg(oldProgNum).arg(progNum));
1333 pmtpid = _pat->
FindPID(progNum);
1338 LOG(VB_RECORD, LOG_ERR,
LOC +
1339 QString(
"SetPAT(): Ignoring PAT not containing our desired "
1340 "program (%1)...").arg(progNum));
1344 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetPAT(%1 on pid 0x%2)")
1345 .arg(progNum).arg(pmtpid,0,16));
1364 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetPMT(%1, %2)").arg(progNum)
1365 .arg(_pmt ==
nullptr ?
"NULL" :
"valid"));
1370 LOG(VB_RECORD, LOG_INFO,
LOC + QString(
"SetPMT(%1)").arg(progNum));
1376 bool has_no_av =
true;
1394 LOG(VB_RECORD, LOG_ERR,
LOC +
"HandleSingleProgramPAT(NULL)");
1413 LOG(VB_RECORD, LOG_ERR,
LOC +
"HandleSingleProgramPMT(NULL)");
1420 uint bestAudioCodec = 0;
1450 if (avcParser !=
nullptr)
1459 LOG(VB_GENERAL, LOG_INFO,
LOC +
"HEVC detected");
1549 const uint pid = tspacket.
PID();
1559 double erate = v * 100.0 /
m_packetCount.fetchAndAddRelaxed(0);
1560 LOG(VB_RECORD, LOG_WARNING,
LOC +
1561 QString(
"PID 0x%1 discontinuity detected ((%2+1)%16!=%3) %4%")
1562 .arg(pid,0,16).arg(old_cnt,2)
1634 else if (streamType != 0)
1637 LOG(VB_RECORD, LOG_ERR,
LOC +
1638 "ProcessVideoTSPacket: unknown stream type!");
1677 const uint pid = tspacket.
PID();
1687 double erate = v * 100.0 /
m_packetCount.fetchAndAddRelaxed(0);
1688 LOG(VB_RECORD, LOG_WARNING,
LOC +
1689 QString(
"A/V PID 0x%1 discontinuity detected ((%2+1)%16!=%3) %4%")
1691 .arg(erate,5,
'f',2));
1697 LOG(VB_RECORD, LOG_INFO,
LOC +
1698 QString(
"PID 0x%1 Found Payload Start").arg(pid,0,16));
void FindPSKeyFrames(const uint8_t *buffer, uint len) override
void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert) override
std::array< uint8_t, 0x1fff+1 > m_pidStatus
MythTimer m_timeOfLatestDataTimer
uint ProgramPID(uint i) const
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
void SetPositionMapType(MarkTypes type)
Set seektable type.
@ MPEG2ExtensionStartCode
Followed by an extension byte, not documented here.
@ MPEGVideoStreamEnd
Last MPEG-1/2 video stream (w/ext hdr)
@ OpenCableVideo
Always MPEG-2??
QDateTime m_timeOfLatestData
ProgramMapTable * m_inputPmt
PMT on input side.
void VideoCodecChange(AVCodecID vCodec)
Note a change in video codec.
@ MPEGAudioStreamBegin
First MPEG-1/2 audio stream (w/ext hdr)
bool CheckCC(uint pid, uint new_cnt)
uint StreamCount(void) const
void SetDesiredProgram(int p)
unsigned long long m_framesWrittenCount
std::vector< unsigned char > m_payloadBuffer
void AddMPEGSPListener(MPEGSingleProgramStreamListener *val)
static const uint kMaxKeyFrameDistance
If the number of regular frames detected since the last detected keyframe exceeds this value,...
void ResetForNewFile(void) override
QElapsedTimer m_audioTimer
Holds information on a TV Program one might wish to record.
ProgramAssociationTable * m_inputPat
PAT on input side.
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
bool ProcessVideoTSPacket(const TSPacket &tspacket) override
@ MPEG2AudioAmd1
ISO 13818-3/AMD-1 Audio using LATM syntax.
const TSHeader * tsheader() const
bool FindOtherKeyframes(const TSPacket *tspacket)
Non-Audio/Video data.
unsigned int m_videoBytesRemaining
int FindPID(uint pid) const
Locates stream index of pid.
void SetOptionsFromProfile(RecordingProfile *profile, const QString &videodev, const QString &audiodev, const QString &vbidev) override
Sets basic recorder options.
void Reset(void) override
Reset the recorder to the startup state.
uint PCRPID(void) const
stream that contains program clock reference.
void HandlePAT(const ProgramAssociationTable *_pat) override
unsigned long long m_lastGopSeen
void stop(void)
Stops timer, next call to isRunning() will return false and any calls to elapsed() or restart() will ...
unsigned int AFCOffset(void) const
uint pictureWidth(void) const
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
virtual void SetStreamData(MPEGStreamData *data)
void BufferedWrite(const TSPacket &tspacket, bool insert=false)
bool IsVideo(uint i, const QString &sistandard) const
Returns true iff the stream at index i is a video stream.
std::array< uint64_t, 256 > m_tsCount
uint32_t GetUnitsInTick(void) const
void start(void)
starts measuring elapsed time.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
unsigned long long m_framesSeenCount
bool IsDamaged(void) const
uint ProgramCount(void) const
virtual QString GetSIStandard(void) const
void FinishRecording(void) override
Flushes the ringbuffer, and if this is not a live LiveTV recording saves the position map and filesiz...
virtual void SetCAMPMT(const ProgramMapTable *)
std::array< int64_t, 256 > m_tsFirst
QAtomicInt m_timeOfLatestDataPacketInterval
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
static bool IsVideo(uint type)
Returns true iff video is an MPEG1/2/3, H264 or open cable video stream.
MythAVRational m_frameRate
std::array< uint8_t, 0x1fff+1 > m_continuityCounter
static QString toString(RecStatus::Type recstatus, uint id)
Converts "recstatus" into a short (unreadable) string.
static const unsigned char kPayloadStartSeen
virtual bool IsListeningPID(uint pid) const
RecordingInfo * m_curRecording
@ MPEG2AACAudio
ISO 13818-7 Audio w/ADTS syntax.
frm_pos_map_t m_durationMapDelta
@ PrivSec
ISO 13818-1 private tables & ITU H.222.0.
void SetStrOption(RecordingProfile *profile, const QString &name)
Convenience function used to set QString options from a profile.
double m_totalDuration
Total milliseconds that have passed since the start of the recording.
void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert) override
void SetDesiredChannel(int major, int minor)
@ SequenceStartCode
Sequence (SEQ) start code contains frame size, aspect ratio and fps.
RecStatus::Type GetRecordingStatus(void) const
bool ProcessAVTSPacket(const TSPacket &tspacket)
Common code for processing either audio or video packets.
uint ProgramNumber(uint i) const
@ VC1Video
SMPTE 421M video codec (aka VC1) in Blu-Ray.
unsigned long long m_lastKeyframeSeen
void AspectChange(uint aspect, long long frame)
Note a change in aspect ratio in the recordedmark table.
int m_progressiveSequence
uint64_t keyframeAUstreamOffset(void) const
void HandleKeyframe(int64_t extra)
This save the current frame to the position maps and handles ringbuffer switching.
uint64_t m_tdTickCount
Count of the number of equivalent interlaced fields that have passed since m_tdBase.
SCAN_t GetScanType(void) const
static bool IsAudio(uint type)
Returns true iff audio is MPEG1/2, AAC, AC3 or DTS audio stream.
RecordingGaps m_recordingGaps
virtual void ClearStatistics(void)
Used to access the data of a Transport Stream packet.
Encapsulates data about ATSC stream and emits events for most tables.
virtual MythAVRational getFrameRate() const =0
uint StreamType(uint i) const
#define LOC
DTVRecorder – base class for Digital Televison recorders Copyright 2003-2004 by Brandon Beattie,...
virtual RecordingQuality * GetRecordingQuality(const RecordingInfo *ri) const
Returns a report about the current recordings quality.
Encapsulates data about MPEG stream and emits events for each table.
std::chrono::milliseconds restart(void)
Returns milliseconds elapsed since last start() or restart() and resets the count.
bool onFrameStart(void) const
void ResolutionChange(uint width, uint height, long long frame)
Note a change in video size in the recordedmark table.
bool FindAudioKeyframes(const TSPacket *tspacket)
void AudioCodecChange(AVCodecID aCodec)
Note a change in audio codec.
H2645Parser * m_h2645Parser
void HandleH2645Keyframe(void)
This save the current frame to the position maps and handles ringbuffer switching.
MPEGStreamData * GetStreamData(void) const
frm_pos_map_t m_durationMap
@ H264Video
ISO 14492-10 & ITU H.264 (aka MPEG-4-AVC)
std::array< uint8_t, 0x1fff+1 > m_streamId
void SetTotalFrames(uint64_t total_frames)
Note the total frames in the recordedmark table.
@ H265Video
ISO 23008-2 & ITU H.265 (aka HEVC, Ultra HD)
void AddTSStatistics(int continuity_error_count, int packet_count)
void ClearStatistics(void) override
bool ProcessTSPacket(const TSPacket &tspacket) override
@ GOPStartCode
Group of Pictures (GOP) start code.
void SetOption(const QString &name, const QString &value) override
Set an specific option.
MythTimer m_recordMptsTimer
@ MPEGVideoStreamBegin
First MPEG-1/2 video stream (w/ext hdr)
double m_tdBase
Milliseconds from the start to m_tdTickCount = 0.
frm_pos_map_t m_positionMap
MythAVRational m_tdTickFramerate
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
AVContainer m_containerFormat
void SetDuration(std::chrono::milliseconds duration)
Note the total duration in the recordedmark table.
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
@ MPEG4Video
ISO 14492-2 (aka MPEG-4)
void FrameRateChange(uint framerate, uint64_t frame)
Note a change in video frame rate in the recordedmark table.
unsigned long long m_lastSeqSeen
int GetNumSetting(const QString &key, int defaultval=0)
bool IsAudio(uint i, const QString &sistandard) const
Returns true iff the stream at index i is an audio stream.
virtual uint32_t addBytes(const uint8_t *bytes, uint32_t byte_count, uint64_t stream_offset)=0
virtual void FinishRecording(void)
frm_pos_map_t m_positionMapDelta
bool start_code_is_valid(uint32_t start_code)
Test whether a start code found by find_start_code() is valid.
unsigned int m_audioBytesRemaining
virtual void StopRecording(void)
StopRecording() signals to the recorder that it should stop recording and exit cleanly.
bool m_hasWrittenOtherKeyframe
void AddMPEGListener(MPEGStreamListener *val)
unsigned int m_otherBytesRemaining
MythMediaBuffer * m_ringBuffer
bool ProcessAudioTSPacket(const TSPacket &tspacket) override
void AddDVBMainListener(DVBMainStreamListener *val)
bool FindMPEG2Keyframes(const TSPacket *tspacket)
Locates the keyframes and saves them to the position map.
void UpdateFramesWritten(void)
bool m_waitForKeyframeOption
Wait for the a GOP/SEQ-start before sending data.
virtual void SetRecordingStatus(RecStatus::Type status, const QString &file, int line)
MPEGStreamData * m_streamData
QDateTime m_timeOfFirstData
static int64_t extract_timestamp(const uint8_t *bufptr, int bytes_left, int pts_or_dts)
MythAVRational invert() const
int DesiredProgram(void) const
QString m_error
non-empty iff irrecoverable recording error detected
void ClearPositionMap(MarkTypes type) const
@ AC3Audio
A/53 Part 3:2009 6.7.1.
virtual field_type getFieldType(void) const =0
QAtomicInt m_timeOfFirstDataIsSet
static const std::array< const MythAVRational, 16 > frameRateMap
void addMSecs(std::chrono::milliseconds ms)
Adds an offset to the last call to start() or restart().
This is the abstract base class for supporting recorder hardware.
void HandlePMT(uint progNum, const ProgramMapTable *_pmt) override
This is the coordinating class of the Recorder Subsystem.
QAtomicInt m_continuityErrorCount
bool onKeyFrameStart(void) const
AVCodecID m_primaryAudioCodec
uint aspectRatio(void) const
Computes aspect ratio from picture size and sample aspect ratio.
static QDateTime ts_to_qdatetime(uint64_t pts, uint64_t pts_first, const QDateTime &pts_first_dt)
virtual void SetOption(const QString &name, const QString &value)
Set an specific option.
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
AVCodecID m_primaryVideoCodec
std::vector< TSPacket > m_scratch
C++ wrapper for FFmpeg libavutil AVRational.
@ MPEG2Video
ISO 13818-2 & ITU H.262 (aka MPEG-2)
void GetAsTSPackets(std::vector< TSPacket > &output, uint cc) const
Returns payload only PESPacket as series of TSPackets.
void SendMythSystemRecEvent(const QString &msg, const RecordingInfo *pginfo)
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
uint FindPID(uint progNum) const
uint32_t GetTimeScale(void) const
int m_minimumRecordingQuality
static constexpr std::chrono::milliseconds kTimeOfLatestDataIntervalTarget
timeOfLatest update interval target in milliseconds.
QRecursiveMutex m_pidLock
bool FindH2645Keyframes(const TSPacket *tspacket)
uint pictureHeight(void) const
void HandleTimestamps(int stream_id, int64_t pts, int64_t dts)
@ MPEG1Video
ISO 11172-2 (aka MPEG-1)
virtual bool CheckForRingBufferSwitch(void)
If requested, switch to new RingBuffer/ProgramInfo objects.
uint StreamPID(uint i) const
@ MPEGAudioStreamEnd
Last MPEG-1/2 audio stream (w/ext hdr)
RecordingQuality * GetRecordingQuality(const RecordingInfo *r) const override
Returns a report about the current recordings quality.
QAtomicInt m_timeOfLatestDataCount
const MTV_PUBLIC uint8_t * find_start_code_truncated(const uint8_t *p, const uint8_t *end, uint32_t *start_code)
By preserving the start_code value between subsequent calls, the caller can detect start codes across...
@ EAC3Audio
A/53 Part 3:2009 6.7.3.
virtual void InitStreamData(void)
void VideoScanChange(SCAN_t scan, uint64_t frame)
Note a change in video scan type in the recordedmark table.
std::array< int64_t, 256 > m_tsLast
std::array< QDateTime, 256 > m_tsFirstDt
QString GetSetting(const QString &key, const QString &defaultval="")
static constexpr unsigned int kSize
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
bool stateChanged(void) const
void SetIntOption(RecordingProfile *profile, const QString &name)
Convenience function used to set integer options from a profile.