Example #1
0
	def check_relay(self, eit):
		events = eit.events
		if events is None or len(events) < 1:
			return
		# only EITp/f is fed to this func,
		# so just check if the (1st) event exists
		ev = events[0]
		if ev is None or ev.descriptors is None:
			return
		desc = GstMpegts.find_descriptor(ev.descriptors,
			GstMpegts.ISDBDescriptorType.EVENT_GROUP)
		if desc is None:
			return

		eg = desc.parse_event_group()
		if not eg[0]  or eg[1] is None or len(eg[1].events) < 1:
			return
		if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO_INTERNAL or \
		   eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO:
			if eg[1].events[0] is None:
				self.dprint("broken EIT(ev-grp desc. type:2/4) received.")
				return
			self.next_svcid = eg[1].events[0].service_id
			self.next_eid = eg[1].events[0].event_id
			if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO and \
			   eg[1].events[0].transport_stream_id > 0:
				self.next_tsid = eg[1].events[0].transport_stream_id
			else:
				self.next_tsid = None
			self.dprint("will be relayed to ev:{0.next_eid}"
				    "(svc:{0.next_svcid}) ts:{0.next_tsid}".
				    format(self))
		return
Example #2
0
	def check_ev_moved(self, eit, sid):
		events = eit.events
		if events is None or len(events) < 1:
			return
		# only EITp/f is fed to this func,
		# so just check if the (1st) event exists
		ev = events[0]
		if ev is None or ev.descriptors is None:
			return
		desc = GstMpegts.find_descriptor(ev.descriptors,
			GstMpegts.ISDBDescriptorType.EVENT_GROUP)
		if desc is None:
			return

		eg = desc.parse_event_group()
		if not eg[0]  or eg[1] is None or len(eg[1].events) < 1:
			return
		if eg[1].group_type != GstMpegts.EventGroupType.MOVED_FROM_INTERNAL:
			return

		for src in eg[1].events:
			if src.service_id == self.svc_id and src.event_id == self.ev_id:
				self.dprint("the evnet:{0}[svc:{1}] moved."
					" switching...".format(src.event_id, src.service_id))
				self.next_svcid = sid
				self.next_eid = ev.event_id
				self.next_tsid = None
				self.switch_ev(self)
				return
		return
Example #3
0
	def check_relay(self, eit):
		events = eit.events
		if events is None or len(events) < 1:
			return
		# only EITp/f is fed to this func,
		# so just check if the (1st) event exists
		ev = events[0]
		if ev is None or ev.descriptors is None:
			return
		desc = GstMpegts.find_descriptor(ev.descriptors,
			GstMpegts.ISDBDescriptorType.EVENT_GROUP)
		if desc is None:
			return

		eg = desc.parse_event_group()
		if not eg[0]  or eg[1] is None or eg[1].event_count < 1:
			return
		if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO_INTERNAL or \
		   eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO:
			if eg[1].events[0] is None:
				self.dprint("broken EIT(ev-grp desc. type:2/4) received.")
				return
			self.next_svcid = eg[1].events[0].service_id
			self.next_eid = eg[1].events[0].event_id
			if eg[1].group_type == GstMpegts.EventGroupType.RELAED_TO and \
			   eg[1].events[0].transport_stream_id > 0:
				self.next_tsid = eg[1].events[0].transport_stream_id
			else:
				self.next_tsid = None
		return
Example #4
0
	def check_ev_moved(self, eit, sid):
		events = eit.events
		if events is None or len(events) < 1:
			return
		# only EITp/f is fed to this func,
		# so just check if the (1st) event exists
		ev = events[0]
		if ev is None or ev.descriptors is None:
			return
		desc = GstMpegts.find_descriptor(ev.descriptors,
			GstMpegts.ISDBDescriptorType.EVENT_GROUP)
		if desc is None:
			return

		eg = desc.parse_event_group()
		if not eg[0]  or eg[1] is None or eg[1].event_count < 1:
			return
		if eg[1].group_type != GstMpegts.EventGroupType.MOVED_FROM_INTERNAL:
			return

		for i in range(eg.event_count):
			src = eg[1].events[i]
			if src.service_id == self.svc_id and src.event_id == self.ev_id:
				self.dprint("the evnet:{0}[0x{1:04x}] moved."
					" switching...".format(src.event_id, src.service_id))
				self.next_svcid = sid
				self.next_eid = ev.event_id
				self.next_tsid = None
				self.switch_ev(self)
				return
		return
Example #5
0
def proc_msg(message):
	st = message.get_structure()
	if st is None or not st.has_name('eit'):
		return

	try:
		sec = GstMpegts.message_parse_mpegts_section(message)
		eit = sec.get_eit()
		events = eit.events
		if verbose and eit.actual_stream and eit.present_following:
			print("EIT p/f:{} ver:{} eid:{} sid:{}".format(
			sec.section_number, sec.version_number,
			eit.events[0].event_id, sec.subtable_extension))
	except (AttributeError, KeyError):
		sys.stderr.write('******* no events included.\n')
		return

	for ev in events:
		d = GstMpegts.find_descriptor(ev.descriptors,
					      GstMpegts.DVBDescriptorType.SHORT_EVENT)
		try:
			(title, txt) = d.parse_dvb_short_event()[2:4]

			if eit.present_following and \
			   eit.actual_stream and \
			   sec.section_number == 0 and \
			   title is not None:
				print(title)
				print(txt)
				print()
		except (AttributeError, TypeError):
			pass

		d = GstMpegts.find_descriptor(ev.descriptors,
					      GstMpegts.DVBDescriptorType.EXTENDED_EVENT)
		try:
			for desc in d.parse_dvb_extended_event():
				for item in desc.items:
					print(item.item_descripton + ':')
					print(item.item)
					print()
		except AttributeError:
			pass
Example #6
0
def proc_msg(message):
	st = message.get_structure()
	if st is None or not st.has_name('eit'):
		return

	try:
		sec = GstMpegts.message_parse_mpegts_section(message)
		eit = sec.get_eit()
		events = eit.events
	except (AttributeError, KeyError):
		sys.stderr.write('******* no events included.\n')
		return

	for ev in events:
		d = GstMpegts.find_descriptor(ev.descriptors,
					      GstMpegts.DVBDescriptorType.SHORT_EVENT)
		try:
			(title, txt) = d.parse_dvb_short_event()[2:4]

			if eit.present_following and \
			   eit.actual_stream and \
			   sec.section_number == 0 and \
			   title is not None:
				print(title)
				print(txt)
				print()
		except (AttributeError, TypeError):
			pass

		d = GstMpegts.find_descriptor(ev.descriptors,
					      GstMpegts.DVBDescriptorType.EXTENDED_EVENT)
		try:
			for desc in d.parse_dvb_extended_event():
				for item in desc.items:
					print(item.item_descripton + ':')
					print(item.item)
					print()
		except AttributeError:
			pass
Example #7
0
	def proc_eit(self, message):
		sec = GstMpegts.message_parse_mpegts_section(message)
		if sec is None:
			return

		st = message.get_structure()
		if self.watch_pat and st.has_name("pat"):
			self.check_pat(sec)
			return

		if not st.has_name("eit"):
			return
		eit = sec.get_eit()
		if eit is None:
			return

		if not (eit.actual_stream and eit.present_following):
			return

		if sec.subtable_extension != self.svc_id:
			if self.ev_id is not None and not self.found_ev:
				self.check_ev_moved(eit, sec.subtable_extension)
			return

		try:
			event = eit.events[0]

			# NOTE: time in EIT message is adjusted to UTC,
			#       in accordance with the DVB standard.
			tm = event.start_time.to_g_date_time()
			dur = event.duration
			if sec.section_number > 1:
				self.dprint("broken EIT. no/bad section-number.");
				return;

			self.dprint("EIT. ID:%s sec:%s ver:%s" %
					(event.event_id,
					 sec.section_number,
					 sec.version_number))
			if self.ev_id is None and \
			   self.is_target(sec.section_number == 0, tm, dur):
				self.ev_id = event.event_id
				self.dprint("selected event:%s ..." % self.ev_id)

			if sec.section_number == 0:
				# "tsparse" filters out the same-versioned table
				self.eit_ver_present = sec.version_number
				self.eit_eid_present = event.event_id
				evname = None
				desc = GstMpegts.find_descriptor(event.descriptors,
				    GstMpegts.DVBDescriptorType.SHORT_EVENT)
				sh = desc.parse_dvb_short_event()
				if sh[0]:
					evname = sh[2]
				if evname is None or evname == "":
					self.eit_name_present = "???"
				else:
					self.eit_name_present = evname
			else:
				dur_undef = 165 * 3600 + 165 * 60 + 165 # FF:FF:FF as BCD
				if dur == dur_undef and tm.get_year() == 1900:
					return
				# "mpegtsparse" filters out the same-versioned table
				#if eit["version-number"] == self.eit_ver_following:
				#	return
				self.eit_ver_following = sec.version_number
				self.eit_eid_following = event.event_id
				evname = None
				desc = GstMpegts.find_descriptor(event.descriptors,
				    GstMpegts.DVBDescriptorType.SHORT_EVENT)
				sh = desc.parse_dvb_short_event()
				if sh[0]:
					evname = sh[2]
				if evname is None or evname == "":
					self.eit_name_following = "???"
				else:
					self.eit_name_following = evname

			# if event is still not identified, then return & wait subsequent EITs
			if self.ev_id is None:
				return

			if sec.section_number == 0 and \
			   self.ev_id == self.eit_eid_present:
				self.found_ev = True
				if self.ev_start is None and tm.get_year() != 1900:
					self.ev_start = tm.to_unix()
				self.valve(False)
				self.tsid = eit.transport_stream_id
				self.check_relay(eit)
				return
			elif sec.section_number == 1 and \
			     self.ev_id == self.eit_eid_following:
				self.found_ev = True
				if self.ev_start is None and tm.get_year() != 1900:
					self.ev_start = tm.to_unix()
				# check if the next event is close enough
				#  but exclude the case for the starting period of unplanned pause.
				#   in this case, the start time is set to the past.
				# (assert the updated EIT is the "following" one)
				now = time.time()
				if self.ev_start and \
				   self.ev_start >= now and self.ev_start - 5 <= now:
					self.valve(False)
				else:
					self.valve(True)
				self.tsid = eit.transport_stream_id
				self.check_relay(eit)
				return
			else:
				# check if in transient state for unplanned pause/break-ins

				# EITp has been updated first before EITf
				#     to a new event (!self.ev_id).
				# Wait for the EITf update and
				#   check if it == ev_id, i.e. pause/break-in.
				if self.recording and sec.section_number == 0 and \
				   self.eit_ver_present != self.eit_ver_following:
					self.valve(True)
					return

				# check if in state for initial waiting
				if not self.found_ev:
					return

				# EITf has been updated before EITp and
				#    self.ev_id != eid_following (new value) &
				#    self.ev_id != eid_present (old value).
				# Wait for the next EITp updated (to be ev_id).
				if sec.section_number == 1 and \
				   self.eit_ver_present != self.eit_ver_following and \
				   self.ev_id != self.eit_eid_present:
					return

				# wait until next EIT (section) update
				if self.ev_id == self.eit_eid_present or \
				   self.ev_id == self.eit_eid_following:
					return

				# check if a relayed-event exists
				if self.found_ev and self.next_eid:
					self.switch_ev()
					return

				self.valve(True)
				self.dprint("Finished recording.")
				self.quit()
				return
		except TypeError:
			self.dprint("broken EIT?. ignoring...");
			return;
Example #8
0
	def proc_eit(self, message):
		sec = GstMpegts.message_parse_mpegts_section(message)
		if sec is None:
			return

		st = message.get_structure()
		if self.watch_pat and st.has_name("pat"):
			self.check_pat(sec)
			return

		if not st.has_name("eit"):
			return
		eit = sec.get_eit()
		if eit is None:
			return

		if not (eit.actual_stream and eit.present_following):
			return

		if sec.subtable_extension != self.svc_id:
			if self.ev_id is not None and not self.found_ev:
				self.check_ev_moved(eit, sec.subtable_extension)
			return

		try:
			event = eit.events[0]

			# NOTE: time in EIT message is adjusted to UTC,
			#       in accordance with the DVB standard.
			tm = event.start_time.to_g_date_time()
			dur = event.duration
			if sec.section_number > 1:
				self.dprint("broken EIT. no/bad section-number.");
				return;

			if self.ev_id is None and \
			   self.is_target(sec.section_number == 0, tm, dur):
				self.ev_id = event.event_id
				self.dprint("selected event:%s ..." % self.ev_id)

			if sec.section_number == 0:
				# "tsparse" filters out the same-versioned table
				self.eit_ver_present = sec.version_number
				self.eit_eid_present = event.event_id
				evname = None
				desc = GstMpegts.find_descriptor(event.descriptors,
				    GstMpegts.DVBDescriptorType.SHORT_EVENT)
				sh = desc.parse_dvb_short_event()
				if sh[0]:
					evname = sh[2]
				if evname is None or evname == "":
					self.eit_name_present = "???"
				else:
					self.eit_name_present = evname
			else:
				dur_undef = 165 * 3600 + 165 * 60 + 165 # FF:FF:FF as BCD
				if dur == dur_undef and tm.get_year() == 1900:
					return
				# "mpegtsparse" filters out the same-versioned table
				#if eit["version-number"] == self.eit_ver_following:
				#	return
				self.eit_ver_following = sec.version_number
				self.eit_eid_following = event.event_id
				evname = None
				desc = GstMpegts.find_descriptor(event.descriptors,
				    GstMpegts.DVBDescriptorType.SHORT_EVENT)
				sh = desc.parse_dvb_short_event()
				if sh[0]:
					evname = sh[2]
				if evname is None or evname == "":
					self.eit_name_following = "???"
				else:
					self.eit_name_following = evname

			if self.eit_eid_present and self.eit_eid_following and \
			   self.ev_id is None:
				self.ev_id = self.eit_eid_present
				self.dprint("selected event:%s ..." % self.ev_id)

			# if event is still not identified, then return & wait subsequent EITs
			if self.ev_id is None:
				return

			if self.ev_id == self.eit_eid_present:
				self.found_ev = True
				if self.ev_start is None and tm.get_year() != 1900:
					self.ev_start = tm.to_unix()
				self.valve(False)
				self.tsid = eit.transport_stream_id
				self.check_relay(eit)
				return
			elif self.ev_id == self.eit_eid_following:
				self.found_ev = True
				if self.ev_start is None and tm.get_year() != 1900:
					self.ev_start = tm.to_unix()
				# check if the next event is close enough
				#  but exclude the case for the starting period of unplanned pause.
				#   in this case, the start time is set to the past.
				# (assert the updated EIT is the "following" one)
				now = time.time()
				if sec.section_number == 1 and self.ev_start and \
				   self.ev_start >= now and self.ev_start - 5 <= now:
					self.valve(False)
				else:
					self.valve(True)
				self.tsid = eit.transport_stream_id
				self.check_relay(eit)
				return
			else:
				# check if in transient state for unplanned pause/break-ins
				if self.recording and sec.section_number == 0 and \
				   self.eit_ver_present != self.eit_ver_following:
					self.valve(True)
					return

				# check if in state for initial waiting
				if not self.found_ev:
					return

				# check if a relayed-event exists
				if self.recording and self.next_eid:
					self.switch_ev()
					return

				self.valve(True)
				self.dprint("Finished recording.")
				self.quit()
				return
		except TypeError:
			self.dprint("broken EIT?. ignoring...");
			return;