Skip to content

Commit

Permalink
Add Progressive, MPEG2, HEVC and 4k video properties to VideoProps. U…
Browse files Browse the repository at this point in the history
…pdate program and recordedprogram schemas.

Add HEVC state to osd.xml: <window name="program_info"><statetype name="videocodec">
Add UHD_4k_I and UHD_4k_P states to osd.xml: <window name="program_info"><statetype name="videodescrip">

Add hd1080i, hd1080p, uhd4ki and uhd4kp states to recordings-ui.xml: <window name="watchrecordings"><buttonlist name="recordings"><statetype name="videoprops">
Add hd1080i, hd1080p, uhd4ki and uhd4kp states to recordings-ui.xml: <window name="iconhelp"><buttonlist name="iconlist"><statetype name="icons">

Add <statetype name="codecprops"> with mpeg2, avc and hevc states to <window name="watchrecordings"><buttonlist name="recordings">.
This allows for the codec to be display separately from the video resolution.
  • Loading branch information
jpoet committed Jun 20, 2020
1 parent 7fc5e80 commit e79b8fc
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 74 deletions.
2 changes: 1 addition & 1 deletion mythtv/bindings/perl/MythTV.pm
Expand Up @@ -116,7 +116,7 @@ package MythTV;
# schema version supported in the main code. We need to check that the schema
# version in the database is as expected by the bindings, which are expected
# to be kept in sync with the main code.
our $SCHEMA_VERSION = "1361";
our $SCHEMA_VERSION = "1362";

# NUMPROGRAMLINES is defined in mythtv/libs/libmythtv/programinfo.h and is
# the number of items in a ProgramInfo QStringList group used by
Expand Down
2 changes: 1 addition & 1 deletion mythtv/bindings/python/MythTV/static.py
Expand Up @@ -5,7 +5,7 @@
"""

OWN_VERSION = (32,0,-1,0)
SCHEMA_VERSION = 1361
SCHEMA_VERSION = 1362
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1024
PROTO_VERSION = '91'
Expand Down
36 changes: 36 additions & 0 deletions mythtv/libs/libmyth/programinfo.cpp
Expand Up @@ -4111,6 +4111,31 @@ void ProgramInfo::SaveFrameRate(uint64_t frame, uint framerate)
}


/// \brief Store the Progressive/Interlaced state in the recordedmarkup table
/// \note All frames until the next one with a stored Scan type
/// are assumed to have the same scan type
void ProgramInfo::SaveVideoScanType(uint64_t frame, bool progressive)
{
if (!IsRecording())
return;

MSqlQuery query(MSqlQuery::InitCon());

query.prepare("INSERT INTO recordedmarkup"
" (chanid, starttime, mark, type, data)"
" VALUES"
" ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
query.bindValue(":CHANID", m_chanId);
query.bindValue(":STARTTIME", m_recStartTs);
query.bindValue(":MARK", (quint64)frame);
query.bindValue(":TYPE", MARK_SCAN_PROGRESSIVE);
query.bindValue(":DATA", progressive);

if (!query.exec())
MythDB::DBError("Video scan type insert", query);
}


/// \brief Store the Total Duration at frame 0 in the recordedmarkup table
void ProgramInfo::SaveTotalDuration(int64_t duration)
{
Expand Down Expand Up @@ -4320,6 +4345,17 @@ MarkTypes ProgramInfo::QueryAverageAspectRatio(void ) const
return static_cast<MarkTypes>(query.value(0).toInt());
}

/** \brief If present in recording this loads average video scan type of the
* main video stream from database's stream markup table.
* \note Saves loaded value for future reference by
* QueryAverageScanProgressive().
*/
bool ProgramInfo::QueryAverageScanProgressive(void) const
{
return static_cast<bool>(load_markup_datum(MARK_SCAN_PROGRESSIVE,
m_chanId, m_recStartTs));
}

/** \brief If present this loads the total duration in milliseconds
* of the main video stream from recordedmarkup table in the database
*
Expand Down
8 changes: 5 additions & 3 deletions mythtv/libs/libmyth/programinfo.h
Expand Up @@ -592,6 +592,7 @@ class MPUBLIC ProgramInfo
uint QueryAverageHeight(void) const;
uint QueryAverageFrameRate(void) const;
MarkTypes QueryAverageAspectRatio(void) const;
bool QueryAverageScanProgressive(void) const;
uint32_t QueryTotalDuration(void) const;
int64_t QueryTotalFrames(void) const;
QString QueryRecordingGroup(void) const;
Expand All @@ -616,6 +617,7 @@ class MPUBLIC ProgramInfo
void SaveAspect(uint64_t frame, MarkTypes type, uint customAspect);
void SaveResolution(uint64_t frame, uint width, uint height);
void SaveFrameRate(uint64_t frame, uint framerate);
void SaveVideoScanType(uint64_t frame, bool progressive);
void SaveTotalDuration(int64_t duration);
void SaveTotalFrames(int64_t frames);
void SaveVideoProperties(uint mask, uint video_property_flags);
Expand Down Expand Up @@ -856,10 +858,10 @@ MPUBLIC bool LoadFromOldRecorded(
const MSqlBindings &bindings);

MPUBLIC bool LoadFromOldRecorded(
ProgramList &destination,
const QString &sql,
ProgramList &destination,
const QString &sql,
const MSqlBindings &bindings,
const uint &start,
const uint &start,
const uint &limit,
uint &count);

Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmyth/programtypes.cpp
Expand Up @@ -48,6 +48,7 @@ QString toString(MarkTypes type)
case MARK_ASPECT_16_9: return "ASPECT_16_9";
case MARK_ASPECT_2_21_1:return "ASPECT_2_21_1";
case MARK_ASPECT_CUSTOM:return "ASPECT_CUSTOM";
case MARK_SCAN_PROGRESSIVE: return "PROGRESSIVE";
case MARK_VIDEO_WIDTH: return "VIDEO_WIDTH";
case MARK_VIDEO_HEIGHT: return "VIDEO_HEIGHT";
case MARK_VIDEO_RATE: return "VIDEO_RATE";
Expand Down
27 changes: 16 additions & 11 deletions mythtv/libs/libmyth/programtypes.h
Expand Up @@ -67,6 +67,7 @@ enum MarkTypes {
MARK_ASPECT_16_9 = 12,
MARK_ASPECT_2_21_1 = 13,
MARK_ASPECT_CUSTOM = 14,
MARK_SCAN_PROGRESSIVE = 15,
MARK_VIDEO_WIDTH = 30,
MARK_VIDEO_HEIGHT = 31,
MARK_VIDEO_RATE = 32,
Expand Down Expand Up @@ -182,18 +183,22 @@ enum AudioProps {
/// recordedprogram has to changed accordingly
enum VideoProps {
// For backwards compatibility do not change 0 or 1
VID_UNKNOWN = 0x00,
VID_HDTV = 0x01,
VID_WIDESCREEN = 0x02,
VID_AVC = 0x04,
VID_720 = 0x08,
VID_1080 = 0x10,
VID_DAMAGED = 0x20,
VID_3DTV = 0x40,
}; // has 7 bits in ProgramInfo::properties
#define kVideoPropertyBits 7
VID_UNKNOWN = 0x000,
VID_WIDESCREEN = 0x001,
VID_HDTV = 0x002,
VID_MPEG2 = 0x004,
VID_AVC = 0x008,
VID_HEVC = 0x010,
VID_720 = 0x020,
VID_1080 = 0x040,
VID_4K = 0x080,
VID_3DTV = 0x100,
VID_PROGRESSIVE = 0x200,
VID_DAMAGED = 0x400,
}; // has 11 bits in ProgramInfo::properties
#define kVideoPropertyBits 11
#define kVideoPropertyOffset kAudioPropertyBits
#define kVideoPropertyMask (0x7f<<kVideoPropertyOffset)
#define kVideoPropertyMask (0x7ff<<kVideoPropertyOffset)

/// if SubtitleTypes changes, the subtitletypes column in program and
/// recordedprogram has to changed accordingly
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -75,7 +75,7 @@
* mythtv/bindings/php/MythBackend.php
*/

#define MYTH_DATABASE_VERSION "1361"
#define MYTH_DATABASE_VERSION "1362"

MBASE_PUBLIC const char *GetMythSourceVersion();

Expand Down
14 changes: 14 additions & 0 deletions mythtv/libs/libmythtv/dbcheck.cpp
Expand Up @@ -3681,6 +3681,20 @@ static bool doUpgradeTVDatabaseSchema(void)
if (!UpdateDBVersionNumber("MythTV", "DBSchemaVer", "1361", dbver))
return false;
}
if (dbver == "1361")
{
DBUpdates updates {
"ALTER TABLE program CHANGE COLUMN videoprop videoprop "
" SET('WIDESCREEN', 'HDTV', 'MPEG2', 'AVC', 'HEVC') NOT NULL; ",
"ALTER TABLE recordedprogram CHANGE COLUMN videoprop videoprop "
" SET('WIDESCREEN', 'HDTV', 'MPEG2', 'AVC', 'HEVC', "
" '720', '1080', '4K', '3DTV', 'PROGRESSIVE', "
" 'DAMAGED') NOT NULL; ",
};
if (!performActualUpdate("MythTV", "DBSchemaVer",
updates, "1362", dbver))
return false;
}

return true;
}
Expand Down
20 changes: 10 additions & 10 deletions mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
Expand Up @@ -404,19 +404,19 @@ class ComponentDescriptor : public MPEGDescriptor
}
bool IsSubtitle(void) const { return 0x3 == StreamContent(); }

unsigned char VideoProperties(void) const
uint VideoProperties(void) const
{
if (0x1 == StreamContent())
return MPEG2Properties();
if (0x5 == StreamContent())
return VID_AVC | AVCProperties();
if (0x9 == StreamContent())
return /* VID_HEVC | */ HEVCProperties();
return VID_HEVC | HEVCProperties();

return VID_UNKNOWN;
}

unsigned char MPEG2Properties(void) const
uint MPEG2Properties(void) const
{
switch(ComponentType())
{
Expand All @@ -434,7 +434,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char AVCProperties(void) const
uint AVCProperties(void) const
{
switch(ComponentType())
{
Expand All @@ -452,7 +452,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char HEVCProperties(void) const
uint HEVCProperties(void) const
{
switch(ComponentType())
{
Expand All @@ -467,7 +467,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char AudioProperties(void) const
uint AudioProperties(void) const
{
switch (StreamContent())
{
Expand All @@ -482,7 +482,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char MP2Properties(void) const
uint MP2Properties(void) const
{
switch (ComponentType())
{
Expand All @@ -501,7 +501,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char AC3Properties(void) const
uint AC3Properties(void) const
{
unsigned char properties = AUD_UNKNOWN;

Expand Down Expand Up @@ -530,7 +530,7 @@ class ComponentDescriptor : public MPEGDescriptor
return properties;
}

unsigned char HEAACProperties(void) const
uint HEAACProperties(void) const
{
switch (ComponentType())
{
Expand All @@ -552,7 +552,7 @@ class ComponentDescriptor : public MPEGDescriptor
}
}

unsigned char SubtitleType(void) const
uint SubtitleType(void) const
{
if (!IsSubtitle())
return SUB_UNKNOWN;
Expand Down
9 changes: 6 additions & 3 deletions mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -2111,7 +2111,7 @@ void MythPlayer::DisplayNormalFrame(bool check_prebuffer)
{
if (m_allPaused)
return;

bool ispip = m_playerCtx->IsPIP();
if (ispip)
{
Expand Down Expand Up @@ -4656,13 +4656,16 @@ void MythPlayer::GetCodecDescription(InfoMap &infoMap)
return;

bool interlaced = is_interlaced(m_scan);
if (width == 1920 || height == 1080 || height == 1088)
if (height > 2100)
infoMap["videodescrip"] = interlaced ? "UHD_4K_I" : "UHD_4K_P";
else if (width == 1920 || height == 1080 || height == 1088)
infoMap["videodescrip"] = interlaced ? "HD_1080_I" : "HD_1080_P";
else if ((width == 1280 || height == 720) && !interlaced)
infoMap["videodescrip"] = "HD_720_P";
else if (height >= 720)
infoMap["videodescrip"] = "HD";
else infoMap["videodescrip"] = "SD";
else
infoMap["videodescrip"] = "SD";
}

bool MythPlayer::GetRawAudioState(void) const
Expand Down
14 changes: 13 additions & 1 deletion mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
Expand Up @@ -841,6 +841,7 @@ bool DTVRecorder::FindH2645Keyframes(const TSPacket *tspacket)
uint height = 0;
uint width = 0;
FrameRate frameRate(0);
SCAN_t scantype(SCAN_t::UNKNOWN_SCAN);

bool hasFrame = false;
bool hasKeyFrame = false;
Expand Down Expand Up @@ -912,7 +913,7 @@ bool DTVRecorder::FindH2645Keyframes(const TSPacket *tspacket)
if (!m_pesSynced)
break;

// scan for a NAL unit start code
// scan the NAL units
uint32_t bytes_used = m_h2645Parser->addBytes
(tspacket->data() + i, TSPacket::kSize - i,
m_ringBuffer->GetWritePosition());
Expand All @@ -930,6 +931,7 @@ bool DTVRecorder::FindH2645Keyframes(const TSPacket *tspacket)
width = m_h2645Parser->pictureWidth();
height = m_h2645Parser->pictureHeight();
aspectRatio = m_h2645Parser->aspectRatio();
scantype = m_h2645Parser->GetScanType();
m_h2645Parser->getFrameRate(frameRate);
}
}
Expand Down Expand Up @@ -1005,6 +1007,16 @@ bool DTVRecorder::FindH2645Keyframes(const TSPacket *tspacket)
FrameRateChange(frameRate.toDouble() * 1000, m_framesWrittenCount);
}

if (scantype != SCAN_t::UNKNOWN_SCAN && scantype != m_scanType)
{
LOG(VB_RECORD, LOG_INFO, LOC +
QString("FindH2645Keyframes: scan type: %1")
.arg(scantype == SCAN_t::INTERLACED ?
"Interlaced" : "Progressive"));
m_scanType = scantype;
VideoScanChange(m_scanType, m_framesWrittenCount);
}

return m_seenSps;
}

Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/recorders/dtvrecorder.h
Expand Up @@ -199,6 +199,7 @@ class DTVRecorder :
double m_tdBase {0.0};
uint64_t m_tdTickCount {0};
FrameRate m_tdTickFramerate {0};
SCAN_t m_scanType {SCAN_t::UNKNOWN_SCAN};

// Music Choice
// Comcast Music Choice uses 3 frames every 6 seconds and no key frames
Expand Down
10 changes: 10 additions & 0 deletions mythtv/libs/libmythtv/recorders/recorderbase.cpp
Expand Up @@ -437,6 +437,10 @@ void RecorderBase::FinishRecording(void)
{
if (m_primaryVideoCodec == AV_CODEC_ID_H264)
m_curRecording->SaveVideoProperties(VID_AVC, VID_AVC);
else if (m_primaryVideoCodec == AV_CODEC_ID_H265)
m_curRecording->SaveVideoProperties(VID_HEVC, VID_HEVC);
else if (m_primaryVideoCodec == AV_CODEC_ID_MPEG2VIDEO)
m_curRecording->SaveVideoProperties(VID_MPEG2, VID_MPEG2);

RecordingFile *recFile = m_curRecording->GetRecordingFile();
if (recFile)
Expand Down Expand Up @@ -805,6 +809,12 @@ void RecorderBase::FrameRateChange(uint framerate, uint64_t frame)
}
}

void RecorderBase::VideoScanChange(SCAN_t scan, uint64_t frame)
{
if (m_curRecording)
m_curRecording->SaveVideoScanType(frame, scan != SCAN_t::INTERLACED);
}

void RecorderBase::VideoCodecChange(AVCodecID vCodec)
{
if (m_curRecording && m_curRecording->GetRecordingFile())
Expand Down
5 changes: 5 additions & 0 deletions mythtv/libs/libmythtv/recorders/recorderbase.h
Expand Up @@ -52,6 +52,7 @@ class FrameRate
};

enum class SCAN_t : uint8_t {
UNKNOWN_SCAN,
INTERLACED,
PROGRESSIVE,
VARIABLE
Expand Down Expand Up @@ -288,6 +289,10 @@ class MTV_PUBLIC RecorderBase : public QRunnable
*/
void FrameRateChange(uint framerate, uint64_t frame);

/** \brief Note a change in video scan type in the recordedmark table
*/
void VideoScanChange(SCAN_t scan, uint64_t frame);

/** \brief Note a change in video codec
*/
void VideoCodecChange(AVCodecID vCodec);
Expand Down

0 comments on commit e79b8fc

Please sign in to comment.