Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

dream-alpha / enigma2-plugin-skincomponents-cockpit   deb

Repository URL to install this package:

Version: 5.1.4 

/ usr / lib / enigma2 / python / Components / Converter / COCServiceInfo.py

#!/usr/bin/python
# encoding: utf-8
#
# Copyright (C) 2018-2023 dream-alpha
#
# In case of reuse of this source code please do not remove this copyright.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For more information on the GNU General Public License see:
# <http://www.gnu.org/licenses/>.


from __future__ import division
from __future__ import print_function
from Components.Converter.Converter import Converter
from Components.Element import cached
from enigma import (
	eServiceReference, iServiceInformation, iPlayableService, iAudioType_ENUMS as iAt, CT_MPEG2, CT_H264, CT_MPEG1, CT_MPEG4_PART2, CT_VC1, CT_VC1_SIMPLE_MAIN, CT_H265, CT_DIVX311, CT_DIVX4, CT_SPARK, CT_VP6, CT_VP8, CT_VP9, CT_H263, CT_MJPEG, CT_REAL, CT_AVS, CT_UNKNOWN, iDVBFrontend as FE
)
from Tools.Transponder import ConvertToHumanReadable


class COCServiceInfo(Converter, object):
	HAS_TELETEXT = 0
	IS_MULTICHANNEL = 1
	IS_CRYPTED = 2
	IS_WIDESCREEN = 3
	SUBSERVICES_AVAILABLE = 4
	XRES = 5
	YRES = 6
	APID = 7
	VPID = 8
	PCRPID = 9
	PMTPID = 10
	TXTPID = 11
	TSID = 12
	ONID = 13
	SID = 14
	FRAMERATE = 15
	TRANSFERBPS = 16
	HAS_SUBTITLES = 17
	IS_HDR = 18
	VIDEO_PARAMS = 19
	VIDEO_TYPE = 20
	IS_STREAM = 21
	FREQUENCY = 22
	MODULATION = 23
	TUNERTYPE = 24
	SATPOSITION = 25
	PROVIDER = 26
	VIDEOINFO = 27
	TPDATA = 28
	MULTI = 29

	"""
	Information for skin developers for TPDATA:
	===================================

	Format: TpData,<information>

	Possible values for <information>:
	=====================================================================================================
	| information           | example values                 |    Sat     | Cable | Terrestrial | Code  |
	=====================================================================================================
	| tuner_type            | Satellite, Cable, Terrestrial  |     X      |   X   |      X      |  %T   |
	| tuner_state           | IDLE, TUNING, FAILED           |     X      |   X   |      X      |       |
	| modulation            | QAM256                         |     X      |   X   |             |  %M   |
	| inversion             | Auto, On, Off                  |     X      |   X   |      X      |  %I   |
	| fec_inner             | Auto, 2/3, 5/6                 |     X      |   X   |      X (T2) |  %F   |
	| frequency             | 11111.75 MHz                   |     X      |   X   |      X      |  %FR  |
	| orbital_position      | Name of Satellite              |     X      |       |             |  %O   |
	| polarization          | Horizontal                     |     X      |       |             |  %P   |
	| polarization (short)  | H                              |     X      |       |             |  %PS  |
	| system                | DVB-S2                         |     X      |       |      X      |  %S   |
	| symbol_rate           | 22000                          |     X      |   X   |             |  %SR  |
	| rolloff               | 0.35                           |     X (S2) |       |             |  %R   |
	| pilot                 | Auto, On, Off                  |     X (S2) |       |             |  %p   |
	| is_id                 | ?                              |     X (S2) |       |             |  %i   |
	| pls_mode              | Root, Gold, Combo              |     X (S2) |       |             |       |
	| pls_code              | ?                              |     X (S2) |       |             |       |
	| bandwidth             | 8 Mhz, Auto                    |            |       |      X      |  %B   |
	| constellation         | QPSK, QAM16                    |            |       |      X      |  %C   |
	| transmission_mode     | 2k, 4k, 8k                     |            |       |      X      |  %TM  |
	| guard_interval        | 1/32, 1/16                     |            |       |      X      |  %G   |
	| code_rate_lp          | 1/2, 2/3                       |            |       |      X (T)  |  %L   |
	| code_rate_hp          | 1/2, 2/3                       |            |       |      X (T)  |  %H   |
	| hierarchy_information | 1, 2, 4                        |            |       |      X (T)  |  %HI  |
	| plp_id                | ?                              |            |       |      X (T2) |       |
	=====================================================================================================

	Information for skin developers for MULTI:
	==================================

	Format: Multi,%T %m

	Possible codes see table above. Each code must be separated by a space. Do NOT add quotes.
	"""

	MultiDict = {
		'%T': 'tuner_type',
		'%M': 'modulation',
		'%I': 'inversion',
		'%F': 'fec_inner',
		'%FR' : 'frequency',
		'%O': 'orbital_position',
		'%P': 'polarization',
		'%PS' : 'polarization',
		'%S': 'system',
		'%SR': 'symbol_rate',
		'%R': 'rolloff',
		'%p': 'pilot',
		'%i': 'is_id',
		'%B': 'bandwidth',
		'%C': 'constellation',
		'%TM': 'transmission_mode',
		'%G': 'guard_interval',
		'%L': 'code_rate_lp',
		'%H': 'code_rate_hp',
		'%HI': 'hierarchy_information'
	}

	def __init__(self, atype):
		Converter.__init__(self, atype)

		args = atype.split(',')
		atype = args[0]

		self.info = None
		self.params = None
		if len(args) > 1:
			self.info = args[1]
			if atype == "Multi":
				self.params = self.info.split(' ')

		self.type, self.interesting_events = {
			"HasTelext": (self.HAS_TELETEXT, (iPlayableService.evUpdatedInfo,)),
			"IsMultichannel": (self.IS_MULTICHANNEL, (iPlayableService.evUpdatedInfo,)),
			"IsCrypted": (self.IS_CRYPTED, (iPlayableService.evUpdatedInfo,)),
			"IsWidescreen": (self.IS_WIDESCREEN, (iPlayableService.evVideoSizeChanged,)),
			"IsHdr": (self.IS_HDR, (iPlayableService.evVideoSizeChanged,)),
			"SubservicesAvailable": (self.SUBSERVICES_AVAILABLE, (iPlayableService.evUpdatedEventInfo,)),
			"VideoType": (self.VIDEO_TYPE, (iPlayableService.evVideoTypeReady,)),
			"VideoWidth": (self.XRES, (iPlayableService.evVideoSizeChanged,)),
			"VideoHeight": (self.YRES, (iPlayableService.evVideoSizeChanged,)),
			"VideoParams": (self.VIDEO_PARAMS, (iPlayableService.evVideoSizeChanged, iPlayableService.evVideoProgressiveChanged, iPlayableService.evVideoFramerateChanged)),
			"AudioPid": (self.APID, (iPlayableService.evUpdatedInfo,)),
			"VideoPid": (self.VPID, (iPlayableService.evUpdatedInfo,)),
			"PcrPid": (self.PCRPID, (iPlayableService.evUpdatedInfo,)),
			"PmtPid": (self.PMTPID, (iPlayableService.evUpdatedInfo,)),
			"TxtPid": (self.TXTPID, (iPlayableService.evUpdatedInfo,)),
			"TsId": (self.TSID, (iPlayableService.evUpdatedInfo,)),
			"OnId": (self.ONID, (iPlayableService.evUpdatedInfo,)),
			"Sid": (self.SID, (iPlayableService.evUpdatedInfo,)),
			"Framerate": (self.FRAMERATE, (iPlayableService.evVideoSizeChanged, iPlayableService.evVideoFramerateChanged)),
			"TransferBPS": (self.TRANSFERBPS, (iPlayableService.evUpdatedInfo,)),
			"HasSubtitles": (self.HAS_SUBTITLES, (iPlayableService.evUpdatedInfo, iPlayableService.evSubtitleListChanged)),
			"IsStream": (self.IS_STREAM, (iPlayableService.evUpdatedInfo,)),
			"Frequency": (self.FREQUENCY, (iPlayableService.evStart,)),
			"Modulation": (self.MODULATION, (iPlayableService.evStart,)),
			"TunerType": (self.TUNERTYPE, (iPlayableService.evStart,)),
			"SatPos": (self.SATPOSITION, (iPlayableService.evStart,)),
			"Provider": (self.PROVIDER, (iPlayableService.evStart,)),
			"VideoCodec": (self.VIDEO_TYPE, (iPlayableService.evVideoTypeReady,)),  # compatibility to older enigma2-versions
			"VideoInfo": (self.VIDEOINFO, (iPlayableService.evUpdatedInfo, iPlayableService.evVideoSizeChanged, iPlayableService.evVideoProgressiveChanged, iPlayableService.evVideoFramerateChanged)),
			"TpData": (self.TPDATA, (iPlayableService.evStart,)),
			"Multi": (self.MULTI, (iPlayableService.evStart,)),
		}[atype]
		self.need_wa = iPlayableService.evVideoSizeChanged in self.interesting_events

	def reuse(self):
		self.need_wa = iPlayableService.evVideoSizeChanged in self.interesting_events

	def getServiceInfoString(self, info, what, convert=lambda x: "%d" % x):
		v = info.getInfo(what)
		if v == -1:
			return "N/A"
		if v == -2:
			return info.getInfoString(what)
		return convert(v)

	@cached
	def getBoolean(self):
		service = self.source.service
		if self.type == self.HAS_SUBTITLES:
			subtitle = service and service.subtitleTracks()
			return subtitle and subtitle.getNumberOfSubtitleTracks() > 0

		info = service and service.info()
		if not info:
			return False

		if self.type == self.HAS_TELETEXT:
			tpid = info.getInfo(iServiceInformation.sTXTPID)
			return tpid != -1
		if self.type == self.IS_MULTICHANNEL:
			# FIXME. but currently iAudioTrackInfo doesn't provide more information. pylint: disable=W0511
			audio = service.audioTracks()
			if audio:
				n = audio.getNumberOfTracks()
				idx = 0
				while idx < n:
					i = audio.getTrackInfo(idx)
					if i.getType() in (iAt.atAC3, iAt.atDDP, iAt.atDTS, iAt.atDTSHD):
						return True
					idx += 1
			return False
		if self.type == self.IS_CRYPTED:
			return info.getInfo(iServiceInformation.sIsCrypted) == 1
		if self.type == self.IS_HDR:
			return info.getInfoString(iServiceInformation.sEotf) in ('SMPTE ST 2084 (HDR10)', 'ARIB STD-B67 (HLG)')
		if self.type == self.IS_WIDESCREEN:
			return info.getInfo(iServiceInformation.sAspect) in (3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10)
		if self.type == self.SUBSERVICES_AVAILABLE:
			subservices = service.subServices()
			return subservices.getNumberOfSubservices() > 0 if subservices else False
		if self.type == self.IS_STREAM:
			sref = eServiceReference(info.getInfoString(iServiceInformation.sServiceref))
			path = sref and sref.getPath()
			return path.find("://") != -1 if path else False
		return False

	boolean = property(getBoolean)

	@cached
	def getText(self):
		service = self.source.service
		info = service and service.info()
		if not info:
			return ""

		if self.type == self.XRES:
			return self.getServiceInfoString(info, iServiceInformation.sVideoWidth)
		if self.type == self.YRES:
			return self.getServiceInfoString(info, iServiceInformation.sVideoHeight)
		if self.type == self.APID:
			return self.getServiceInfoString(info, iServiceInformation.sAudioPID)
		if self.type == self.VPID:
			return self.getServiceInfoString(info, iServiceInformation.sVideoPID)
		if self.type == self.PCRPID:
			return self.getServiceInfoString(info, iServiceInformation.sPCRPID)
		if self.type == self.PMTPID:
			return self.getServiceInfoString(info, iServiceInformation.sPMTPID)
		if self.type == self.TXTPID:
			return self.getServiceInfoString(info, iServiceInformation.sTXTPID)
		if self.type == self.TSID:
			return self.getServiceInfoString(info, iServiceInformation.sTSID)
		if self.type == self.ONID:
			return self.getServiceInfoString(info, iServiceInformation.sONID)
		if self.type == self.SID:
			return self.getServiceInfoString(info, iServiceInformation.sSID)
		if self.type == self.FRAMERATE:
			return self.getServiceInfoString(info, iServiceInformation.sFrameRate, lambda x: "%d fps" % ((x + 500) // 1000))
		if self.type == self.TRANSFERBPS:
			return self.getServiceInfoString(info, iServiceInformation.sTransferBPS, lambda x: "%d kB/s" % (x // 1024))
		if self.type == self.VIDEO_PARAMS:
			yres = info.getInfo(iServiceInformation.sVideoHeight)
			frame_rate = info.getInfo(iServiceInformation.sFrameRate)
			progressive = info.getInfo(iServiceInformation.sProgressive)
			print("yres", yres, "frame_rate", frame_rate, "progressive", progressive)
			if not progressive:
				frame_rate *= 2
			frame_rate = (frame_rate + 500) // 1000
			return "%d%s%d" % (yres, 'p' if progressive else 'i', frame_rate)
		if self.type == self.VIDEO_TYPE:
			vtype = info.getInfo(iServiceInformation.sVideoType)
			return {
				CT_MPEG2 : "MPEG2", CT_H264 : "H.264", CT_MPEG1 : "MPEG1", CT_MPEG4_PART2 : "MPEG4",
				CT_VC1 : "VC1", CT_VC1_SIMPLE_MAIN : "WMV3", CT_H265 : "HEVC", CT_DIVX311 : "DIVX3",
				CT_DIVX4 : "DIVX4", CT_SPARK : "SPARK", CT_VP6 : "VP6", CT_VP8 : "VP8",
				CT_VP9 : "VP9", CT_H263 : "H.263", CT_MJPEG : "MJPEG", CT_REAL : "RV",
				CT_AVS : "AVS", CT_UNKNOWN : "UNK"
			}[vtype]
		if self.type in (self.FREQUENCY, self.SATPOSITION, self.TPDATA):
			tp_data = info.getInfoObject(iServiceInformation.sTransponderData)
			if tp_data is not None:
				if self.info:
					tp_info = ConvertToHumanReadable(tp_data)
					return tp_info.get(self.info, "")
				if tp_data["tuner_type"] in (FE.feSatellite, FE.feSatellite2):
					if self.type == self.FREQUENCY:
						return "%d MHz" % (tp_data["frequency"] / 1000)
					if self.type == self.SATPOSITION:
						position = tp_data["orbital_position"]
						if position > 1800:  # west
							return "%.1f " % (float(3600 - position) / 10) + _("W")  # pylint: disable=E0602
						return "%.1f " % (float(position) / 10) + _("E")  # pylint: disable=E0602
					if self.type == self.SYMBOLRATE:
						return "%.2f" % (float(tp_data['symbol_rate']) / 1000)
					if self.type == self.FEC:
						return "%d" % (tp_data['fec_inner'])
				elif tp_data["tuner_type"] == FE.feCable:
					if self.type == self.FREQUENCY:
						return "%d MHz" % (tp_data["frequency"] / 1000)
				elif tp_data["tuner_type"] in (FE.feTerrestrial, FE.feTerrestrial2):
					if self.type == self.FREQUENCY:
						return "%d MHz" % (tp_data["frequency"] / 1000000)
		elif self.type in (self.MODULATION, self.TUNERTYPE):
			tp_data = info.getInfoObject(iServiceInformation.sTransponderData)
			if tp_data:
				isTerrestrial = tp_data["tuner_type"] in (FE.feTerrestrial, FE.feTerrestrial2)
				try:
					tp_data = ConvertToHumanReadable(tp_data)
				except KeyError:
					return ""
				if self.type == self.MODULATION and isTerrestrial is False:
					return str(tp_data["modulation"])
				if self.type == self.TUNERTYPE:
					return str(tp_data["tuner_type"])
		elif self.type == self.VIDEOINFO:
			xres = info.getInfo(iServiceInformation.sVideoWidth)
			yres = info.getInfo(iServiceInformation.sVideoHeight)
			if xres == 0 or yres == 0:
				return ""
			frame_rate = info.getInfo(iServiceInformation.sFrameRate)
			progressive = info.getInfo(iServiceInformation.sProgressive)
			if not progressive:
				frame_rate *= 2
			frame_rate = (frame_rate + 500) / 1000
			return "%sx%s%s%s" % (xres, yres, 'p' if progressive else 'i', frame_rate)
		elif self.type == self.PROVIDER:
			return self.getServiceInfoString(info, iServiceInformation.sProvider)
		elif self.type == self.MULTI:
			tp_data = info.getInfoObject(iServiceInformation.sTransponderData)
			if not tp_data:
				return ""
			if not self.params:
				return ""
			tp_info = ConvertToHumanReadable(tp_data)
			res = ""
			for infoitem in self.params:
				infokey = COCServiceInfo.MultiDict.get(infoitem)
				if not infokey:
					return ""
				infodata = tp_info.get(infokey)
				if not infodata:
					return ""
				if infoitem == '%PS':
					infodata = infodata[0]
				elif infoitem == '%FR':
					infodata = infodata / 1000
					if tp_data["tuner_type"] in (FE.feTerrestrial, FE.feTerrestrial2):
						infodata = infodata / 1000
					infodata = "%d MHz" % infodata
				elif infoitem == '%SR':
					infodata = infodata / 1000
				if res == '':
					res += "%s" % str(infodata)
				else:
					res += " %s" % str(infodata)
			return res
		return ""

	text = property(getText)

	@cached
	def getValue(self):
		service = self.source.service
		info = service and service.info()
		if not info:
			return -1

		if self.type == self.XRES:
			return info.getInfo(iServiceInformation.sVideoWidth)
		if self.type == self.YRES:
			return info.getInfo(iServiceInformation.sVideoHeight)
		if self.type == self.FRAMERATE:
			return info.getInfo(iServiceInformation.sFrameRate)
		if self.type == self.IS_WIDESCREEN:
			return info.getInfo(iServiceInformation.sAspect)
		if self.type == self.VIDEO_PARAMS:
			return -1 if info.getInfo(iServiceInformation.sVideoHeight) < 0 \
				or info.getInfo(iServiceInformation.sFrameRate) < 0 \
				or info.getInfo(iServiceInformation.sProgressive) < 0 \
				else -2
		return -1

	value = property(getValue)

	def changed(self, what):
		if what[0] != self.CHANGED_SPECIFIC or what[1] in self.interesting_events:
			Converter.changed(self, what)
		elif self.need_wa:
			if self.getValue() != -1:
				Converter.changed(self, (self.CHANGED_SPECIFIC, iPlayableService.evVideoSizeChanged))
				self.need_wa = False