Merge master.
This commit is contained in:
commit
9e4e2be33c
46 changed files with 740 additions and 805 deletions
74
Autobuild.sh
Executable file
74
Autobuild.sh
Executable file
|
@ -0,0 +1,74 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Entry point for the Doozer autobuild system
|
||||
#
|
||||
# (c) Andreas Öman 2011. All rights reserved.
|
||||
#
|
||||
#
|
||||
|
||||
set -eu
|
||||
|
||||
BUILD_API_VERSION=2
|
||||
EXTRA_BUILD_NAME=""
|
||||
JARGS=""
|
||||
JOBSARGS=""
|
||||
TARGET=""
|
||||
RELEASE="--release"
|
||||
WORKINGDIR="/var/tmp/showtime-autobuild"
|
||||
UPLOAD_BUILD_ARTIFACTS=1
|
||||
while getopts "vht:e:j:w:R" OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
v)
|
||||
echo $BUILD_API_VERSION
|
||||
exit 0
|
||||
;;
|
||||
R)
|
||||
UPLOAD_BUILD_ARTIFACTS=0
|
||||
;;
|
||||
h)
|
||||
echo "This script is intended to be used by the autobuild system only"
|
||||
exit 0
|
||||
;;
|
||||
t)
|
||||
TARGET="$OPTARG"
|
||||
;;
|
||||
e)
|
||||
EXTRA_BUILD_NAME="$OPTARG"
|
||||
;;
|
||||
j)
|
||||
JOBSARGS="--jobs=$OPTARG"
|
||||
JARGS="-j$OPTARG"
|
||||
;;
|
||||
w)
|
||||
WORKINGDIR="$OPTARG"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
if [[ -z $TARGET ]]; then
|
||||
echo "target (-t) not specified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#
|
||||
# $1 = local file path
|
||||
# $2 = type
|
||||
# $3 = content-type
|
||||
# $4 = filename
|
||||
#
|
||||
artifact() {
|
||||
if [ $UPLOAD_BUILD_ARTIFACTS -eq 1 ]; then
|
||||
echo "doozer-artifact:$PWD/$1:$2:$3:$4"
|
||||
else
|
||||
echo "Ignoring: $1:$2:$3:$4"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -f Autobuild/${TARGET}.sh ]; then
|
||||
source Autobuild/${TARGET}.sh
|
||||
else
|
||||
echo "target $TARGET not supported"
|
||||
exit 1
|
||||
fi
|
26
Autobuild/debian.sh
Executable file
26
Autobuild/debian.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
CHANGELOG=debian/changelog
|
||||
NOW=`date -R`
|
||||
VER=`git describe | sed "s/\([0-9]*\)\.\([0-9]*\)-\([0-9]*\)-.*/\1.\2.\3/"`
|
||||
echo >${CHANGELOG} "tvheadend (${VER}) unstable; urgency=low"
|
||||
echo >>${CHANGELOG}
|
||||
echo >>${CHANGELOG} " * The full changelog can be found at "
|
||||
echo >>${CHANGELOG} " http://www.lonelycoder.com/tvheadend/download"
|
||||
echo >>${CHANGELOG}
|
||||
echo >>${CHANGELOG} " -- Andreas Öman <andreas@lonelycoder.com> ${NOW}"
|
||||
cat ${CHANGELOG}
|
||||
export JOBSARGS
|
||||
export JARGS
|
||||
dpkg-buildpackage -b -us -uc
|
||||
|
||||
for a in ../tvheadend*${VER}*.deb; do
|
||||
artifact $a deb application/x-deb `basename $a`
|
||||
rm -f $a
|
||||
done
|
||||
|
||||
for a in ../tvheadend*${VER}*.changes; do
|
||||
artifact $a changes text/plain `basename $a`
|
||||
rm -f $a
|
||||
done
|
||||
|
||||
rm -f ${CHANGELOG}
|
||||
dh_clean
|
1
Autobuild/ubuntu-lucid-amd64.sh
Executable file
1
Autobuild/ubuntu-lucid-amd64.sh
Executable file
|
@ -0,0 +1 @@
|
|||
source Autobuild/debian.sh
|
1
Autobuild/ubuntu-lucid-i386.sh
Executable file
1
Autobuild/ubuntu-lucid-i386.sh
Executable file
|
@ -0,0 +1 @@
|
|||
source Autobuild/debian.sh
|
|
@ -1 +0,0 @@
|
|||
debian/changelog
|
41
Makefile
41
Makefile
|
@ -28,6 +28,8 @@ CFLAGS += -Wall -Werror -Wwrite-strings -Wno-deprecated-declarations
|
|||
CFLAGS += -Wmissing-prototypes
|
||||
LDFLAGS += -lrt -ldl
|
||||
|
||||
BUNDLES += docs/html docs/docresources src/webui/static
|
||||
|
||||
#
|
||||
# Core
|
||||
#
|
||||
|
@ -147,23 +149,18 @@ SLIBS += $(SLIBS-yes)
|
|||
OBJS= $(SRCS:%.c=$(BUILDDIR)/%.o)
|
||||
OBJS_EXTRA = $(SRCS_EXTRA:%.c=$(BUILDDIR)/%.so)
|
||||
DEPS= ${OBJS:%.o=%.d}
|
||||
OBJDIRS= $(sort $(dir $(OBJS))) $(sort $(dir $(OBJS_EXTRA)))
|
||||
|
||||
# File bundles
|
||||
BUNDLE_SRCS=$(BUNDLES:%=$(BUILDDIR)/bundles/%.c)
|
||||
BUNDLE_DEPS=$(BUNDLE_SRCS:%.c=%.d)
|
||||
BUNDLE_OBJS=$(BUNDLE_SRCS:%.c=%.o)
|
||||
OBJDIRS+= $(sort $(dir $(BUNDLE_OBJS)))
|
||||
.PRECIOUS: ${BUNDLE_SRCS}
|
||||
|
||||
VERSION=$(shell support/version.sh)
|
||||
CURVERSION=$(shell cat ${BUILDDIR}/ver || echo "0")
|
||||
|
||||
# Common CFLAGS for all files
|
||||
CFLAGS_com = -g -funsigned-char -O2
|
||||
CFLAGS_com += -D_FILE_OFFSET_BITS=64
|
||||
CFLAGS_com += -I${BUILDDIR} -I${CURDIR}/src -I${CURDIR}
|
||||
CFLAGS_com += -DHTS_VERSION=\"$(VERSION)\"
|
||||
|
||||
MKBUNDLE = $(CURDIR)/support/mkbundle
|
||||
|
||||
|
@ -180,31 +177,41 @@ all: ${PROG}
|
|||
|
||||
.PHONY: clean distclean
|
||||
|
||||
${PROG}: $(OBJDIRS) $(OBJS) $(BUNDLE_OBJS) ${OBJS_EXTRA} Makefile
|
||||
$(CC) -o $@ $(OBJS) $(BUNDLE_OBJS) $(LDFLAGS) ${LDFLAGS_cfg}
|
||||
#
|
||||
#
|
||||
#
|
||||
${PROG}: $(OBJS) $(ALLDEPS) support/dataroot/wd.c
|
||||
$(CC) -o $@ $(OBJS) support/dataroot/wd.c $(LDFLAGS) ${LDFLAGS_cfg}
|
||||
|
||||
$(OBJDIRS):
|
||||
@mkdir -p $@
|
||||
${PROG}.bundle: $(OBJS) $(BUNDLE_OBJS) $(ALLDEPS) support/dataroot/bundle.c
|
||||
$(CC) -o $@ $(OBJS) support/dataroot/bundle.c $(BUNDLE_OBJS) $(LDFLAGS) ${LDFLAGS_cfg}
|
||||
|
||||
${PROG}.datadir: $(OBJS) $(ALLDEPS) support/dataroot/datadir.c
|
||||
$(CC) -o $@ $(OBJS) -iquote${BUILDDIR} support/dataroot/datadir.c $(LDFLAGS) ${LDFLAGS_cfg}
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
${BUILDDIR}/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) -MD -MP $(CFLAGS_com) $(CFLAGS) $(CFLAGS_cfg) -c -o $@ $(CURDIR)/$<
|
||||
|
||||
${BUILDDIR}/%.so: ${SRCS_EXTRA}
|
||||
@mkdir -p $(dir $@)
|
||||
${CC} -O -fbuiltin -fomit-frame-pointer -fPIC -shared -o $@ $< -ldl
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILDDIR}/src ${BUILDDIR}/bundles ${BUILDDIR}/ver
|
||||
rm -rf ${BUILDDIR}/src ${BUILDDIR}/bundles
|
||||
find . -name "*~" | xargs rm -f
|
||||
|
||||
distclean: clean
|
||||
rm -rf build.*
|
||||
|
||||
ifneq ($(VERSION), $(CURVERSION))
|
||||
.PHONY: src/version.c
|
||||
$(info Version changed)
|
||||
src/version.c:
|
||||
@echo $(VERSION) >${BUILDDIR}/ver
|
||||
endif
|
||||
# Create buildversion.h
|
||||
src/version.c: $(BUILDDIR)/buildversion.h
|
||||
$(BUILDDIR)/buildversion.h: FORCE
|
||||
@$(CURDIR)/support/version.sh $(CURDIR) $@
|
||||
FORCE:
|
||||
|
||||
|
||||
# Include dependency files if they exist.
|
||||
|
@ -215,7 +222,9 @@ include support/${OSENV}.mk
|
|||
|
||||
# Bundle files
|
||||
$(BUILDDIR)/bundles/%.o: $(BUILDDIR)/bundles/%.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) -I${CURDIR}/src -c -o $@ $<
|
||||
|
||||
$(BUILDDIR)/bundles/%.c: %
|
||||
@mkdir -p $(dir $@)
|
||||
$(MKBUNDLE) -o $@ -s $< -d ${BUILDDIR}/bundles/$<.d -p $< -z
|
||||
|
|
3
README
3
README
|
@ -1,4 +1,3 @@
|
|||
|
||||
Tvheadend TV streaming server
|
||||
=============================
|
||||
|
||||
|
@ -21,7 +20,7 @@ $ make
|
|||
Build the binary, after build the binary resides in 'build.Linux/'.
|
||||
Thus, to start it, just type:
|
||||
|
||||
$ build.Linux/tvheadend
|
||||
$ build.linux/tvheadend
|
||||
|
||||
Settings are stored in $HOME/.hts/tvheadend
|
||||
|
||||
|
|
87
configure
vendored
87
configure
vendored
|
@ -11,14 +11,16 @@
|
|||
# Copyright (c) 2005-2008 Mans Rullgard
|
||||
#
|
||||
|
||||
PLATFORM=`uname`
|
||||
|
||||
PLATFORM=linux
|
||||
source support/configure.inc
|
||||
|
||||
CPU=generic
|
||||
ARCH=`uname -m`
|
||||
OSENV="posix"
|
||||
PREFIX=/usr/local
|
||||
prefix=/usr/local
|
||||
bindir="\${prefix}/bin"
|
||||
mandir="\${prefix}/share/man"
|
||||
datadir="\${prefix}/share/tvheadend"
|
||||
|
||||
show_help(){
|
||||
echo "Usage: configure [options]"
|
||||
|
@ -26,7 +28,11 @@ show_help(){
|
|||
echo
|
||||
echo "Standard options:"
|
||||
echo " --help print this message"
|
||||
echo " --prefix=PREFIX install in PREFIX [$PREFIX]"
|
||||
echo " --prefix=PREFIX Install in PREFIX [$prefix]"
|
||||
echo " --bindir=DIR Install binaries in DIR [$bindir]"
|
||||
echo " --mandir=DIR Install man pages in DIR [$mandir]"
|
||||
echo " --datadir=DIR Install data files in DIR [$datadir]"
|
||||
echo
|
||||
echo " --arch=arch Build for this architecture [$ARCH]"
|
||||
echo " --cpu=cpu Build and optimize for specific CPU"
|
||||
echo " --cc=CC Build using the given compiler"
|
||||
|
@ -42,8 +48,6 @@ enable v4l
|
|||
for opt do
|
||||
optval="${opt#*=}"
|
||||
case "$opt" in
|
||||
--prefix=*) PREFIX="$optval"
|
||||
;;
|
||||
--cpu=*) CPU="$optval"
|
||||
;;
|
||||
--help) show_help
|
||||
|
@ -53,6 +57,33 @@ for opt do
|
|||
;;
|
||||
--cc=*) CC="$optval"
|
||||
;;
|
||||
--prefix=*)
|
||||
prefix="$optval"
|
||||
;;
|
||||
--bindir=*)
|
||||
bindir="$optval"
|
||||
;;
|
||||
--mandir=*)
|
||||
mandir="$optval"
|
||||
;;
|
||||
--datadir=*)
|
||||
datadir="$optval"
|
||||
;;
|
||||
--includedir=*)
|
||||
;;
|
||||
--infodir=*)
|
||||
;;
|
||||
--sysconfdir=*)
|
||||
;;
|
||||
--localstatedir=*)
|
||||
;;
|
||||
--libexecdir=*)
|
||||
;;
|
||||
--disable-maintainer-mode)
|
||||
;;
|
||||
--disable-dependency-tracking)
|
||||
;;
|
||||
|
||||
--enable-?*|--disable-?*)
|
||||
eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g')
|
||||
$action $option
|
||||
|
@ -154,38 +185,32 @@ else
|
|||
die
|
||||
fi
|
||||
|
||||
#
|
||||
# Configure paths, etc
|
||||
#
|
||||
if [ ${RELEASE} != yes ]; then
|
||||
echo NOTE:
|
||||
echo NOTE: Development build.
|
||||
echo NOTE: The generated binary will contained compild-in paths to
|
||||
echo NOTE: the current build tree. If you plan to install or move
|
||||
echo NOTE: the binary, please reconfigure with '--release'.
|
||||
echo NOTE:
|
||||
|
||||
cat >> ${CONFIG_H} << EOF
|
||||
#define TVHEADEND_CONTENT_PATH "${TOPDIR}"
|
||||
EOF
|
||||
|
||||
else
|
||||
|
||||
echo >>${CONFIG_MAK} "BUNDLES += docs/html docs/docresources src/webui/static"
|
||||
|
||||
cat >> ${CONFIG_H} << EOF
|
||||
#define TVHEADEND_CONTENT_PATH NULL
|
||||
EOF
|
||||
fi
|
||||
|
||||
#
|
||||
# Finalize
|
||||
#
|
||||
cat >> ${CONFIG_MAK} << EOF
|
||||
ARCH=$ARCH
|
||||
INSTALLPREFIX=$PREFIX
|
||||
LDFLAGS_cfg += -lpthread
|
||||
EOF
|
||||
|
||||
|
||||
#
|
||||
# Finalize
|
||||
#
|
||||
echo
|
||||
echo "Installation paths:"
|
||||
echo " Prefix: ${prefix}"
|
||||
echo " Binaries: ${bindir}"
|
||||
echo " Man pages: ${mandir}"
|
||||
echo " Data files: ${datadir}"
|
||||
echo
|
||||
echo >>${CONFIG_MAK} "prefix=$prefix"
|
||||
echo >>${CONFIG_MAK} "bindir=\${DESTDIR}$bindir"
|
||||
echo >>${CONFIG_MAK} "mandir=\${DESTDIR}$mandir"
|
||||
echo >>${CONFIG_MAK} "datadir=\${DESTDIR}$datadir"
|
||||
echo >>${CONFIG_MAK} LDFLAGS_cfg += -lpthread -lrt -ldl
|
||||
eval datadirpath=${datadir}
|
||||
echo >>${CONFIG_H} "#define TVHEADEND_DATADIR \"${datadirpath}\""
|
||||
|
||||
|
||||
finalize
|
||||
|
|
472
debian/changelog
vendored
472
debian/changelog
vendored
|
@ -1,472 +0,0 @@
|
|||
tvheadend (2.12.99) hts; urgency=low
|
||||
|
||||
* Debian package has been renamed from hts-tvheadend to tvheadend
|
||||
|
||||
* Add functionality to delete recordings
|
||||
|
||||
* Better support for playing in web clients.
|
||||
Temporary tickets are used instead of username/password authentication
|
||||
|
||||
* Remove lock contention in CWC updates
|
||||
|
||||
* Fix bug in IPTV PAT parser (Ticket #318)
|
||||
|
||||
* Store EPG on disk so it can be reloaded on restart
|
||||
|
||||
* Add support for Viaccess EMM
|
||||
|
||||
* Add support for DRECrypt EMM
|
||||
|
||||
* Depend on OpenSSL for cryptographic features
|
||||
|
||||
* RTSP has been dropped. It was too buggy and noone wanted to maintain it
|
||||
|
||||
* Fix bug in JSON encoder. Ticket #163
|
||||
|
||||
* Fix crash in HTTP service. Ticket #334
|
||||
|
||||
* Added http-streaming of services. Tested and working with mplayer.
|
||||
|
||||
* Add support for building RPM packages
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sat, 19 Feb 2011 12:57:09 +0100
|
||||
|
||||
hts-tvheadend (2.12) hts; urgency=low
|
||||
|
||||
* Add support for IPTV over IPv6
|
||||
|
||||
* Use a native matroska mutiplixer to get better support for metadata, etc
|
||||
|
||||
* Add support for multiple DVR configurations (can be set per recording)
|
||||
|
||||
* Add suport for teletext subtitles
|
||||
|
||||
* Add support for E-AC3
|
||||
|
||||
* Workaround for ITV HD (which has incorrect PMT)
|
||||
Ticket #215
|
||||
|
||||
* Keep track of video width and height and send it over HTSP in
|
||||
subscriptionStart.
|
||||
Ticket #208
|
||||
|
||||
* Add support for Logical Channel Number descriptor (0x83)
|
||||
Ticket #138
|
||||
|
||||
* Maintain the order of PIDs as they appear in the PMT.
|
||||
Ticket #218
|
||||
|
||||
* When there is no video pid (service type is Radio),
|
||||
start the audio stream right away.
|
||||
Ticket #59
|
||||
|
||||
* Add subscriptionChangeWeight HTSP method.
|
||||
|
||||
* psi: Assume that elementary stream type 0x81 is AC3 without
|
||||
relying on any further descriptors
|
||||
Ticket #217
|
||||
|
||||
* Tvheadend no longer depends on FFmpeg so it's not externally updated
|
||||
in svn, nor linked.
|
||||
|
||||
* Added a native matroska muxer.
|
||||
Correctly writes global headers. Ticket #61
|
||||
Add support for recording AAC audio. Ticket #160
|
||||
Improves metadata written to files.
|
||||
|
||||
* Tvheadend no longer tries to fixup lack of PTS/DTS for packets
|
||||
before sending them over HTSP. Rather, those fields will be left
|
||||
out in the message. Currently, all HTSP clients known to mankind
|
||||
handles this.
|
||||
|
||||
* Make error detection in timestamp parsing much more robust. Avoid
|
||||
extracting persistent data (such as video width*height) from
|
||||
received data if we suspect that an error has occured (MPEG-TS TEI
|
||||
or continuity counter errors).
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Mon, 29 Nov 2010 20:06:52 +0100
|
||||
|
||||
hts-tvheadend (2.11) hts; urgency=low
|
||||
|
||||
* Add support for filtering autorecordings based on weekdays.
|
||||
|
||||
* Add circular 10.75 GHz LNB
|
||||
|
||||
* Add a new DVB adapter option that allows the entire DVB Mux to be
|
||||
written to disk as Tvheadend tunes to it. This should aid a lot when
|
||||
it comes to debugging
|
||||
|
||||
* Inject entries in DVR schedule as soon as we know about an EPG
|
||||
entry that matches an autorecording rule. Previously Tvheadend
|
||||
would scan the EPG continously and just grab shows as they neared
|
||||
air time. The drawbacks of this approach was that it's a bit hard
|
||||
to understand what is happening. It also makes (more) correct
|
||||
wakeup from suspend hard to do.
|
||||
|
||||
* Add parsing of episode information from XMLTV and display it in the
|
||||
WebUI EPG
|
||||
|
||||
* A bug caused the 'Automatic Recorder' tab grid not to reload
|
||||
entries upon external change (Such as when a channel got deleted
|
||||
or when a new auto recording was created from the EPG view). This
|
||||
is now fixed.
|
||||
|
||||
* Add support for storing recorded events in a directory named after
|
||||
the event. Ticket #150
|
||||
|
||||
* Add support for appending season and episode numbers to filenames
|
||||
during recording.
|
||||
|
||||
* Prior to this release the color (i.e. connection status) of the
|
||||
CWC entries were not correctly updated when a connection was established
|
||||
or lost. This is now fixed. Ticket #144
|
||||
|
||||
* Add support for prioritized recordings. The user can chose among five
|
||||
different priorities.
|
||||
|
||||
* Fix various issues realted to the Recording Schedule user interface.
|
||||
The UI now includes better visual feedback on what's going on and if
|
||||
there are errors. Also recordings that do not complete successfully
|
||||
are correctly reported as failed entries. Ticket #131
|
||||
|
||||
* Add support for Irdeto and Seca EMM
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sat, 27 Mar 2010 10:03:40 +0100
|
||||
|
||||
hts-tvheadend (2.10) hts; urgency=high
|
||||
|
||||
* Fix a crash in HTSP server.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Thu, 04 Feb 2010 22:21:22 +0100
|
||||
|
||||
hts-tvheadend (2.9) hts; urgency=high
|
||||
|
||||
* A last minute bug slipped in the 2.8 release, causing Tvheadend to read
|
||||
settings and configuration from incorrect path when also switching user
|
||||
during startup. This has now been fixed.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Mon, 25 Jan 2010 21:23:47 +0100
|
||||
|
||||
hts-tvheadend (2.8) hts; urgency=low
|
||||
|
||||
* Added support for AAC audio
|
||||
|
||||
* Added support for manual creation of DVR entries. Prior to this it
|
||||
was only possible to schedule a recording based on EPG entries.
|
||||
|
||||
* It's now possible to enable/disable the signal quality monitor per
|
||||
adapter. This is now default off as it seem to mostly cause problems
|
||||
for people and it's only useful if you have complex setups with
|
||||
multiple adapters, etc.
|
||||
|
||||
* Improve logging when subscriptions fail to start
|
||||
|
||||
* More intelligent arbitration amongst all sources when a subscription
|
||||
is about to start for a channel. If we cannot descramble or if no
|
||||
input is detected, skip to next source.
|
||||
Fixes ticket #89
|
||||
|
||||
* Add option for editing channel icon URL in the channel config tab.
|
||||
|
||||
* Fix support for Irdeto ECM
|
||||
|
||||
* Automatically detect if a connected USB DVB adapter is only Full speed
|
||||
(ie 12Mbit/s), and if so, limit so Tvheadend only can stream one service
|
||||
at the time from the tuned frequency.
|
||||
|
||||
* Add support for extracting provider in the PMT for SECA/Mediaguard
|
||||
|
||||
* Add support for NIT-other tables.
|
||||
In particular useful for Ziggo DVB-C networks in the Netherlands.
|
||||
|
||||
* Fix various bugs related to RTP encapsulated IPTV
|
||||
|
||||
* Tvheadend now support placement of configurations and settings at any path.
|
||||
Use the '-c' command line option for this. By default Tvheadend puts
|
||||
configuration at $HOME/.hts/tvheadend
|
||||
|
||||
* Make it possible to enable debug level log in the web interface.
|
||||
Press the small top-right gear icon in the log console to enable/disable
|
||||
debug log.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Mon, 25 Jan 2010 21:23:47 +0100
|
||||
|
||||
hts-tvheadend (2.7) hts; urgency=low
|
||||
|
||||
* Added support for DVB subtitles. Currently only forwarded over HTSP
|
||||
|
||||
* Add support for reception of RTP encapsulated IPTV
|
||||
|
||||
* Fixed a crash caused by a race condition when starting a subscription
|
||||
|
||||
* Increase maximum packet size for IPTV to 65536 bytes
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sun, 06 Dec 2009 20:40:41 +0100
|
||||
|
||||
hts-tvheadend (2.6) hts; urgency=low
|
||||
|
||||
* Tvheadend's DVB service probe will now make the channel join tags based
|
||||
on the service type and DVB provider name.
|
||||
|
||||
* Add support for tuning on ATSC adapters
|
||||
|
||||
* Add support for sattelite beams with circular polarisation
|
||||
|
||||
* If a user changed the XMLTV source for a channel to 'None', tvheadend
|
||||
would crash. This is now fixed.
|
||||
|
||||
* Add support for copying a selection of muxes from one DVB adapter to
|
||||
another in the web UI.
|
||||
|
||||
* Support for DVB-S2 has been added
|
||||
|
||||
* Default character encoding in DVB is ISO6937, not Latin-1. Ticket #96
|
||||
|
||||
* Add support for DiSEqC 1.1 / 2.1, configured on per-adapter basis.
|
||||
Ticket #99
|
||||
|
||||
* Increase logging and include various stats to XMLTV grab
|
||||
|
||||
* Add support for configuring a per-channel pre/post extra time for
|
||||
scheduled recordings. Ticket #104
|
||||
|
||||
* Autodetect CPU capabilities and choose best mode for CSA descrambler.
|
||||
Ticket #122
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sun, 29 Nov 2009 14:02:36 +0100
|
||||
|
||||
hts-tvheadend (2.5) hts; urgency=low
|
||||
|
||||
* If a previosly detected DVB adapter was not present during startup,
|
||||
Tvheadend would crash. This is now fixed.
|
||||
|
||||
* If XMLTV grabbing was disabled tvheadend would spin in a 100% CPU loop.
|
||||
This is now fixed.
|
||||
|
||||
* The HTSP service is now announced via AVAHI (mDNS service discovery)
|
||||
|
||||
* Support for IPTV has been added. Only RAW TS in UDP is supported
|
||||
at the moment.
|
||||
|
||||
* Add support for setting default extra times to add before and after
|
||||
a recording. Useful if your TV shows never start on time.
|
||||
|
||||
* Use FFmpeg's av_interleaved_write_frame() or some players can't
|
||||
play the recorded content (vlc is one)
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Wed, 19 Aug 2009 22:28:02 +0200
|
||||
|
||||
hts-tvheadend (2.4) hts; urgency=low
|
||||
|
||||
* Due to a bug, the polarisation of DVB-S muxes was not correctly
|
||||
stored internally. This has now been fixed.
|
||||
|
||||
* Fix compilation on 64bit systems
|
||||
|
||||
* Make sure channel <> service mappings are saved when edited from
|
||||
DVB service grid
|
||||
|
||||
* Add support for merging one channel into another.
|
||||
Useful if you have multiple providers offering the same DVB service
|
||||
but with different names.
|
||||
|
||||
* The embedded HTTP server now logs failed requests
|
||||
|
||||
* Use absolute paths when serving static content (the web app itself)
|
||||
This was only a problem when fork()ing a development build
|
||||
|
||||
* Rework the CWC reconnection strategy.
|
||||
If there are active subscription, Tvheadend will attempt to reconnect
|
||||
immediately and then retry every three seconds.
|
||||
If no subscription is active a reconnection attempt is performed
|
||||
every minute.
|
||||
Also, if any CWC configuration changes are made from the UI, Tvheadend
|
||||
will try to reconnect directly.
|
||||
|
||||
* If the EPG receives an updated description for an even that is shorter
|
||||
than the current description it will be ignored.
|
||||
This typically happens if the XMLTV and DVB EIT (Event Information Table)
|
||||
differs. In other words, we assume that a longer description of an
|
||||
event is better than a short.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sun, 26 Jul 2009 13:27:32 +0200
|
||||
|
||||
hts-tvheadend (2.3) hts; urgency=low
|
||||
|
||||
* A simple web interface has been added. To access it, visit
|
||||
|
||||
http://host:9981/simple.html
|
||||
|
||||
This web interface is designed to be really tiny with only
|
||||
a simple search field and options to record found shows.
|
||||
Preferably used from handheld devices.
|
||||
|
||||
* All sensitive information (passwords, etc) are hidden from display
|
||||
in the web ui. The text will still be displayed in cleartext when
|
||||
editing.
|
||||
|
||||
* Redesigned the DVB configuration tab in the web userinterface:
|
||||
- Each adapter have three (or four) tabs
|
||||
o General setup and information
|
||||
o Grid of multiplexes
|
||||
o Grid of services
|
||||
o For sattelite adapters, a sattelite configuration tab.
|
||||
|
||||
* Add support for disabling / enabling an entire DVB multiplex
|
||||
|
||||
* Add support for multiple DiSEqC switchports on a single adapter
|
||||
|
||||
* Add support for different sattelite LNBs
|
||||
|
||||
* Graceful handling of DVB adapters that does not support many
|
||||
table filters in hardware. Tvheadend will rotate among the available
|
||||
ones.
|
||||
|
||||
* Add support for enabling / disabling transports from the DVB configuration
|
||||
|
||||
* Make it possible to remove DVB multiplexes from the web ui
|
||||
|
||||
* Add 'Revert changes' button to all editable grids in the web ui
|
||||
|
||||
* Make it possible to disable the idle scan on per-DVB adapter basis.
|
||||
The idle scan is a process to cycles through all multiplex to check
|
||||
the quality for each mux continously.
|
||||
|
||||
* Hopefully fix some rounding errors in the EPG display. Ticket #69
|
||||
|
||||
* Use a ''livegrid'' (http://www.ext-livegrid.com/) for displaying EPG.
|
||||
|
||||
* Remove configuration and settings (/home/hts/.hts/tvheadend) on a
|
||||
deb package purge operation. Ticket #73
|
||||
|
||||
* If the Program Stream Information changes during a subscription,
|
||||
react and send a subscriptionStop + subscriptionStart.
|
||||
This happens on SVT (in sweden) when the transmission switches
|
||||
from local to nationwide broadcast (AC3 audio is only present
|
||||
in nationwide broadcast)
|
||||
Ticket #78
|
||||
|
||||
* Channel editor has been reworked a bit. It uses an editorGrid, similar
|
||||
to how other grids work in Tvheadend. Tags are mapped inline using
|
||||
a list-of-values combobox (http://lovcombo.extjs.eu/)
|
||||
|
||||
* Added a search IMDB direct link in the EPG window popup.
|
||||
Ticket #79
|
||||
|
||||
* Add support for configuring DVB multiplexes by entering
|
||||
all tuning parameters manually
|
||||
Ticket #37
|
||||
|
||||
* Fix a bug causing channel <> tags mapping not to be restored on load.
|
||||
|
||||
* Add exponential backoff for reconnect attempt in code word client.
|
||||
Ticket #80
|
||||
|
||||
* Try to detect duplicate EPG entries from the DVB feed and adjust
|
||||
EPG accordingly. The EPG code will search for events with the same
|
||||
DVB event ID +- 2 events from the current one. If the event id is
|
||||
equal, the prvious (old) entry will be removed in favor of the new one.
|
||||
Reason for not blindingly trusting the event id is that some networks
|
||||
seem to (incorrectly) reuse IDs.
|
||||
Ticket #65
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sat, 18 Jul 2009 23:19:18 +0200
|
||||
|
||||
hts-tvheadend (2.2) hts; urgency=low
|
||||
|
||||
* Set $HOME so forked processes (XMLTV) will have correct environment
|
||||
and to make the default storage of recorded videos to end up in the
|
||||
correct place.
|
||||
|
||||
* Update built-in DVB mux presets to dvb-apps:1275:9655c8cfeed8
|
||||
|
||||
* Add -h option to display usage.
|
||||
|
||||
* Rewrite the internal streaming pipeline.
|
||||
This is not externally visible, but needed for a future timeshifter.
|
||||
|
||||
* Make it compile on gcc 4.4
|
||||
|
||||
* Send 'source' and 'network' information in HTSP.subscriptionStart message.
|
||||
|
||||
* When deleting a channel any channel-bound autorecording would stay in
|
||||
memory and, sooner or later, cause a crash. This has now been fixed.
|
||||
|
||||
* Add extra scan for XMLTV grabbers in $PATH. Apart from $PATH we also
|
||||
scan in /bin, /usr/bin, /usr/local/bin
|
||||
|
||||
* Search for XMLTV grabbers in /usr/bin/perlbin/vendor (archlinux)
|
||||
|
||||
* Fix a bug causing DVB card which does not implement the
|
||||
FE_READ_UNCORRECTED_BLOCKS operation to report insane amount of
|
||||
forward correction errors.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sun, 07 Jun 2009 19:22:49 +0200
|
||||
|
||||
hts-tvheadend (2.1) hts; urgency=low
|
||||
|
||||
* Add debconf setup scripts to create a superuser account.
|
||||
|
||||
* HTSP server slightly modified. Now also supports the XBMC HTSP client.
|
||||
|
||||
* tvheadend and showtime went separate ways.
|
||||
|
||||
* tvheadend: Record post-processing added again, run command when a
|
||||
recording is done.
|
||||
|
||||
* tvheadend: Fix characterset translation bug introduced in r1902.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Thu, 28 May 2009 21:07:44 +0200
|
||||
|
||||
hts-tvheadend (2.0) unstable; urgency=low
|
||||
|
||||
* tvheadend: All setup and configuration is done from the web user interface.
|
||||
|
||||
* tvheadend: New web user interface based on ExtJS
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Thu, 16 Oct 2008 19:47:23 +0200
|
||||
|
||||
hts-tvheadend (1.4) unstable; urgency=low
|
||||
|
||||
* tvheadend: Add support for DVB-S (still in experimenal state)
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sat, 30 Mar 2008 18:00:00 +0100
|
||||
|
||||
hts-tvheadend (1.3) unstable; urgency=low
|
||||
|
||||
* tvheadend: Add support for executing a post processing script after
|
||||
recording is completed.
|
||||
|
||||
* tvheadend: Mark I-frames as key-frames in recorder (should make seeking
|
||||
work better).
|
||||
|
||||
* tvheadend: Correctly set duration of packets in recorder.
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Thu, 28 Mar 2008 18:00:00 +0100
|
||||
|
||||
hts-tvheadend (1.2) unstable; urgency=low
|
||||
|
||||
* Tvheadend has been rewritten from scratch
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Thu, 28 Feb 2008 17:30:00 +0100
|
||||
|
||||
hts-tvheadend (1.1) unstable; urgency=low
|
||||
|
||||
* Bugfix: Tvheadend: Do not crash if event name is NULL
|
||||
|
||||
* Rewrite tvheadend internals to fix many serious issues
|
||||
|
||||
* tvheadend now correctly supports recording of h264 content
|
||||
|
||||
* RTSP interface added to tvheadend that supports time shifting of live tv
|
||||
|
||||
* Add web interface to tvheadend
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Sat, 24 Nov 2007 08:11:00 +0100
|
||||
|
||||
hts-tvheadend (1.0) unstable; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Andreas Öman <andreas@lonelycoder.com> Tue, 19 Sep 2007 19:20:00 +0200
|
||||
|
30
debian/rules
vendored
30
debian/rules
vendored
|
@ -1,38 +1,18 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -rf build.*
|
||||
dh_clean
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_clean
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_testdir
|
||||
./configure --release --prefix=/usr
|
||||
dh_auto_configure -- ${JOBSARGS}
|
||||
|
||||
override_dh_auto_build:
|
||||
$(MAKE)
|
||||
|
||||
override_dh_install:
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/tvheadend install
|
||||
|
||||
override_dh_installinit:
|
||||
dh_installinit --name tvheadend
|
||||
make ${JARGS}
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip --dbg-package=tvheadend-dbg
|
||||
|
||||
override_dh_autotest:
|
||||
echo "skipped autotest"
|
||||
override_dh_auto_install:
|
||||
dh_auto_install --destdir=debian/tvheadend
|
||||
|
||||
|
|
2
debian/tvheadend.tvheadend.init
vendored
2
debian/tvheadend.tvheadend.init
vendored
|
@ -13,7 +13,7 @@
|
|||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
DESC="HTS Tvheadend"
|
||||
DESC="Tvheadend"
|
||||
NAME=tvheadend
|
||||
DAEMON=/usr/bin/$NAME
|
||||
DAEMON_ARGS="-f -u hts -g video"
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
<dt>Update Card
|
||||
<dd>Forward Entitlement Management Messages (EMMs) to the server.
|
||||
|
||||
<dt>Update One
|
||||
<dd>Forward EMMs only from one channel at a time.
|
||||
|
||||
<dt>Comment
|
||||
<dd>Allows the administrator to set a comment only visible in this editor.
|
||||
It does not serve any active purpose.
|
||||
|
|
|
@ -174,7 +174,7 @@ access_verify(const char *username, const char *password,
|
|||
|
||||
if(ae->ae_username[0] != '*') {
|
||||
/* acl entry requires username to match */
|
||||
if(username == NULL)
|
||||
if(username == NULL || password == NULL)
|
||||
continue; /* Didn't get one */
|
||||
|
||||
if(strcmp(ae->ae_username, username) ||
|
||||
|
@ -391,6 +391,7 @@ access_record_build(access_entry_t *ae)
|
|||
|
||||
htsmsg_add_u32(e, "streaming", ae->ae_rights & ACCESS_STREAMING ? 1 : 0);
|
||||
htsmsg_add_u32(e, "dvr" , ae->ae_rights & ACCESS_RECORDER ? 1 : 0);
|
||||
htsmsg_add_u32(e, "dvrallcfg", ae->ae_rights & ACCESS_RECORDER_ALL ? 1 : 0);
|
||||
htsmsg_add_u32(e, "webui" , ae->ae_rights & ACCESS_WEB_INTERFACE ? 1 : 0);
|
||||
htsmsg_add_u32(e, "admin" , ae->ae_rights & ACCESS_ADMIN ? 1 : 0);
|
||||
|
||||
|
@ -480,6 +481,9 @@ access_record_update(void *opaque, const char *id, htsmsg_t *values,
|
|||
if(!htsmsg_get_u32(values, "dvr", &u32))
|
||||
access_update_flag(ae, ACCESS_RECORDER, u32);
|
||||
|
||||
if(!htsmsg_get_u32(values, "dvrallcfg", &u32))
|
||||
access_update_flag(ae, ACCESS_RECORDER_ALL, u32);
|
||||
|
||||
if(!htsmsg_get_u32(values, "admin", &u32))
|
||||
access_update_flag(ae, ACCESS_ADMIN, u32);
|
||||
|
||||
|
|
|
@ -58,7 +58,8 @@ typedef struct access_ticket {
|
|||
#define ACCESS_STREAMING 0x1
|
||||
#define ACCESS_WEB_INTERFACE 0x2
|
||||
#define ACCESS_RECORDER 0x4
|
||||
#define ACCESS_ADMIN 0x8
|
||||
#define ACCESS_RECORDER_ALL 0x8
|
||||
#define ACCESS_ADMIN 0x10
|
||||
#define ACCESS_FULL 0x3f
|
||||
|
||||
/**
|
||||
|
|
294
src/cwc.c
294
src/cwc.c
|
@ -47,7 +47,7 @@
|
|||
#define TVHEADEND_PROTOCOL_ID 0x6502
|
||||
#define CWC_KEEPALIVE_INTERVAL 30
|
||||
|
||||
#define CWS_NETMSGSIZE 272
|
||||
#define CWS_NETMSGSIZE 362
|
||||
#define CWS_FIRSTCMDNO 0xe0
|
||||
|
||||
/**
|
||||
|
@ -61,6 +61,8 @@ typedef enum {
|
|||
CARD_VIACCESS,
|
||||
CARD_NAGRA,
|
||||
CARD_NDS,
|
||||
CARD_CRYPTOWORKS,
|
||||
CARD_BULCRYPT,
|
||||
CARD_UNKNOWN
|
||||
} card_type_t;
|
||||
|
||||
|
@ -150,7 +152,8 @@ typedef struct cwc_service {
|
|||
enum {
|
||||
CS_UNKNOWN,
|
||||
CS_RESOLVED,
|
||||
CS_FORBIDDEN
|
||||
CS_FORBIDDEN,
|
||||
CS_IDLE
|
||||
} cs_keystate;
|
||||
|
||||
void *cs_keys;
|
||||
|
@ -242,7 +245,13 @@ typedef struct cwc {
|
|||
int shared_toggle;
|
||||
int shared_len;
|
||||
uint8_t * shared_emm;
|
||||
void *ca_update_id;
|
||||
} cwc_viaccess_emm;
|
||||
#define cwc_cryptoworks_emm cwc_viaccess_emm
|
||||
|
||||
/* one update id */
|
||||
int64_t cwc_update_time;
|
||||
void *cwc_update_id;
|
||||
|
||||
/* Card type */
|
||||
card_type_t cwc_card_type;
|
||||
|
@ -258,6 +267,7 @@ typedef struct cwc {
|
|||
int cwc_port;
|
||||
char *cwc_id;
|
||||
int cwc_emm;
|
||||
int cwc_emmex;
|
||||
|
||||
const char *cwc_errtxt;
|
||||
|
||||
|
@ -280,6 +290,8 @@ void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len);
|
|||
void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len);
|
||||
void cwc_emm_nagra(cwc_t *cwc, uint8_t *data, int len);
|
||||
void cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len);
|
||||
void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len);
|
||||
void cwc_emm_bulcrypt(cwc_t *cwc, uint8_t *data, int len);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -469,7 +481,7 @@ cwc_send_msg(cwc_t *cwc, const uint8_t *msg, size_t len, int sid, int enq)
|
|||
buf[4] = sid >> 8;
|
||||
buf[5] = sid;
|
||||
|
||||
if((len = des_encrypt(buf, len, cwc)) < 0) {
|
||||
if((len = des_encrypt(buf, len, cwc)) <= 0) {
|
||||
free(buf);
|
||||
free(cm);
|
||||
return -1;
|
||||
|
@ -581,10 +593,10 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
|
|||
|
||||
memcpy(cwc->cwc_ua, &msg[6], 8);
|
||||
|
||||
tvhlog(LOG_INFO, "cwc", "%s: Connected as user 0x%02x "
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: Connected as user 0x%02x "
|
||||
"to a %s-card [0x%04x : %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x] "
|
||||
"with %d providers",
|
||||
cwc->cwc_hostname,
|
||||
cwc->cwc_hostname, cwc->cwc_port,
|
||||
msg[3], n, cwc->cwc_caid,
|
||||
cwc->cwc_ua[0], cwc->cwc_ua[1], cwc->cwc_ua[2], cwc->cwc_ua[3], cwc->cwc_ua[4], cwc->cwc_ua[5], cwc->cwc_ua[6], cwc->cwc_ua[7],
|
||||
nprov);
|
||||
|
@ -607,8 +619,8 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
|
|||
cwc->cwc_providers[i].sa[6] = msg[9];
|
||||
cwc->cwc_providers[i].sa[7] = msg[10];
|
||||
|
||||
tvhlog(LOG_INFO, "cwc", "%s: Provider ID #%d: 0x%06x %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
|
||||
cwc->cwc_hostname, i + 1,
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: Provider ID #%d: 0x%06x %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
|
||||
cwc->cwc_hostname, cwc->cwc_port, i + 1,
|
||||
cwc->cwc_providers[i].id,
|
||||
cwc->cwc_providers[i].sa[0],
|
||||
cwc->cwc_providers[i].sa[1],
|
||||
|
@ -631,16 +643,16 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
|
|||
|
||||
if (!emm_allowed) {
|
||||
tvhlog(LOG_INFO, "cwc",
|
||||
"%s: Will not forward EMMs (not allowed by server)",
|
||||
cwc->cwc_hostname);
|
||||
"%s:%i: Will not forward EMMs (not allowed by server)",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
} else if (cwc->cwc_card_type != CARD_UNKNOWN) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: Will forward EMMs",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
cwc->cwc_forward_emm = 1;
|
||||
} else {
|
||||
tvhlog(LOG_INFO, "cwc",
|
||||
"%s: Will not forward EMMs (unsupported CA system)",
|
||||
cwc->cwc_hostname);
|
||||
"%s:%i: Will not forward EMMs (unsupported CA system)",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -658,43 +670,57 @@ static void
|
|||
cwc_detect_card_type(cwc_t *cwc)
|
||||
{
|
||||
uint8_t c_sys = cwc->cwc_caid >> 8;
|
||||
|
||||
switch(cwc->cwc_caid) {
|
||||
case 0x5581:
|
||||
case 0x4aee:
|
||||
cwc->cwc_card_type = CARD_BULCRYPT;
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: bulcrypt card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(c_sys) {
|
||||
case 0x17:
|
||||
case 0x06:
|
||||
cwc->cwc_card_type = CARD_IRDETO;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: irdeto card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: irdeto card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x05:
|
||||
cwc->cwc_card_type = CARD_VIACCESS;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: viaccess card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: viaccess card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x0b:
|
||||
cwc->cwc_card_type = CARD_CONAX;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: conax card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: conax card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x01:
|
||||
cwc->cwc_card_type = CARD_SECA;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: seca card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: seca card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x4a:
|
||||
cwc->cwc_card_type = CARD_DRE;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: dre card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: dre card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x18:
|
||||
cwc->cwc_card_type = CARD_NAGRA;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: nagra card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: nagra card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x09:
|
||||
cwc->cwc_card_type = CARD_NDS;
|
||||
tvhlog(LOG_INFO, "cwc", "%s: nds card",
|
||||
cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: nds card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
case 0x0d:
|
||||
cwc->cwc_card_type = CARD_CRYPTOWORKS;
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: cryptoworks card",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
break;
|
||||
default:
|
||||
cwc->cwc_card_type = CARD_UNKNOWN;
|
||||
|
@ -728,6 +754,8 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
int len, int seq)
|
||||
{
|
||||
service_t *t = ct->cs_service;
|
||||
cwc_service_t *ct2;
|
||||
cwc_t *cwc2;
|
||||
ecm_pid_t *ep;
|
||||
char chaninfo[32];
|
||||
int i;
|
||||
|
@ -748,20 +776,48 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
if(ct->cs_okchannel == es->es_channel)
|
||||
ct->cs_okchannel = -1;
|
||||
|
||||
if (es->es_nok < 3)
|
||||
es->es_nok++;
|
||||
|
||||
if(ct->cs_keystate == CS_FORBIDDEN)
|
||||
return; // We already know it's bad
|
||||
|
||||
es->es_nok = 1;
|
||||
if (es->es_nok > 2) {
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"Too many NOKs for service \"%s\"%s from %s:%i",
|
||||
t->s_svcname, chaninfo, ct->cs_cwc->cwc_hostname,
|
||||
ct->cs_cwc->cwc_port);
|
||||
goto forbid;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
|
||||
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
|
||||
if (ct != ct2 && ct2->cs_service == t &&
|
||||
ct2->cs_keystate == CS_RESOLVED) {
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"NOK from %s:%i: Already has a key for service \"%s\", from %s:%i",
|
||||
ct->cs_cwc->cwc_hostname, ct->cs_cwc->cwc_port,
|
||||
t->s_svcname, ct2->cs_cwc->cwc_hostname, ct2->cs_cwc->cwc_port);
|
||||
es->es_nok = 3; /* do not send more ECM requests */
|
||||
goto forbid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tvhlog(LOG_DEBUG, "cwc", "Received NOK for service \"%s\"%s (seqno: %d "
|
||||
"Req delay: %lld ms)", t->s_svcname, chaninfo, seq, delay);
|
||||
|
||||
forbid:
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
|
||||
for(i = 0; i <= ep->ep_last_section; i++)
|
||||
if(ep->ep_sections[i] == NULL ||
|
||||
ep->ep_sections[i]->es_pending ||
|
||||
ep->ep_sections[i]->es_nok == 0)
|
||||
return;
|
||||
if(ep->ep_sections[i] == NULL) {
|
||||
if(es->es_nok < 2) /* only first hit is allowed */
|
||||
return;
|
||||
} else {
|
||||
if(ep->ep_sections[i]->es_pending ||
|
||||
ep->ep_sections[i]->es_nok == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
tvhlog(LOG_ERR, "cwc",
|
||||
"Can not descramble service \"%s\", access denied (seqno: %d "
|
||||
|
@ -786,12 +842,26 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
msg[3 + 5], msg[3 + 6], msg[3 + 7], msg[3 + 8], msg[3 + 9],
|
||||
msg[3 + 10],msg[3 + 11],msg[3 + 12],msg[3 + 13],msg[3 + 14],
|
||||
msg[3 + 15], seq, delay);
|
||||
|
||||
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
|
||||
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
|
||||
if (ct != ct2 && ct2->cs_service == t &&
|
||||
ct2->cs_keystate == CS_RESOLVED) {
|
||||
ct->cs_keystate = CS_IDLE;
|
||||
tvhlog(LOG_DEBUG, "cwc",
|
||||
"Already has a key for service \"%s\", from %s:%i",
|
||||
t->s_svcname, ct2->cs_cwc->cwc_hostname, ct2->cs_cwc->cwc_port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ct->cs_keystate != CS_RESOLVED)
|
||||
tvhlog(LOG_INFO, "cwc",
|
||||
"Obtained key for for service \"%s\" in %lld ms, from %s",
|
||||
t->s_svcname, delay, ct->cs_cwc->cwc_hostname);
|
||||
|
||||
"Obtained key for service \"%s\" in %lld ms, from %s:%i",
|
||||
t->s_svcname, delay, ct->cs_cwc->cwc_hostname,
|
||||
ct->cs_cwc->cwc_port);
|
||||
|
||||
ct->cs_keystate = CS_RESOLVED;
|
||||
memcpy(ct->cs_cw, msg + 3, 16);
|
||||
ct->cs_pending_cw_update = 1;
|
||||
|
@ -877,15 +947,15 @@ cwc_read_message(cwc_t *cwc, const char *state, int timeout)
|
|||
int msglen, r;
|
||||
|
||||
if((r = cwc_read(cwc, buf, 2, timeout))) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: %s: Read error (header): %s",
|
||||
cwc->cwc_hostname, state, strerror(r));
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: %s: Read error (header): %s",
|
||||
cwc->cwc_hostname, cwc->cwc_port, state, strerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
msglen = (buf[0] << 8) | buf[1];
|
||||
if(msglen >= CWS_NETMSGSIZE) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: %s: Invalid message size: %d",
|
||||
cwc->cwc_hostname, state, msglen);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: %s: Invalid message size: %d",
|
||||
cwc->cwc_hostname, cwc->cwc_port, state, msglen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -893,14 +963,14 @@ cwc_read_message(cwc_t *cwc, const char *state, int timeout)
|
|||
so just wait 1 second here */
|
||||
|
||||
if((r = cwc_read(cwc, cwc->cwc_buf + 2, msglen, 1000))) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: %s: Read error: %s",
|
||||
cwc->cwc_hostname, state, strerror(r));
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: %s: Read error: %s",
|
||||
cwc->cwc_hostname, cwc->cwc_port, state, strerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((msglen = des_decrypt(cwc->cwc_buf, msglen + 2, cwc)) < 15) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: %s: Decrypt failed",
|
||||
state, cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: %s: Decrypt failed",
|
||||
cwc->cwc_hostname, cwc->cwc_port, state);
|
||||
return -1;
|
||||
}
|
||||
return msglen;
|
||||
|
@ -962,8 +1032,8 @@ cwc_session(cwc_t *cwc)
|
|||
* Get login key
|
||||
*/
|
||||
if((r = cwc_read(cwc, cwc->cwc_buf, 14, 5000))) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: No login key received: %s",
|
||||
cwc->cwc_hostname, strerror(r));
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: No login key received: %s",
|
||||
cwc->cwc_hostname, cwc->cwc_port, strerror(r));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -978,7 +1048,8 @@ cwc_session(cwc_t *cwc)
|
|||
return;
|
||||
|
||||
if(cwc->cwc_buf[12] != MSG_CLIENT_2_SERVER_LOGIN_ACK) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: Login failed", cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: Login failed",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -992,7 +1063,8 @@ cwc_session(cwc_t *cwc)
|
|||
return;
|
||||
|
||||
if(cwc->cwc_buf[12] != MSG_CARD_DATA) {
|
||||
tvhlog(LOG_INFO, "cwc", "%s: Card data request failed", cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i: Card data request failed",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1166,8 @@ cwc_thread(void *aux)
|
|||
cwc->cwc_caid = 0;
|
||||
cwc->cwc_connected = 0;
|
||||
cwc_comet_status_update(cwc);
|
||||
tvhlog(LOG_INFO, "cwc", "Disconnected from %s", cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "Disconnected from %s:%i",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
}
|
||||
|
||||
if(subscriptions_active()) {
|
||||
|
@ -1109,13 +1182,14 @@ cwc_thread(void *aux)
|
|||
ts.tv_nsec = 0;
|
||||
|
||||
tvhlog(LOG_INFO, "cwc",
|
||||
"%s: Automatic connection attempt in in %d seconds",
|
||||
cwc->cwc_hostname, d);
|
||||
"%s:%i: Automatic connection attempt in in %d seconds",
|
||||
cwc->cwc_hostname, cwc->cwc_port, d);
|
||||
|
||||
pthread_cond_timedwait(&cwc_config_changed, &cwc_mutex, &ts);
|
||||
}
|
||||
|
||||
tvhlog(LOG_INFO, "cwc", "%s destroyed", cwc->cwc_hostname);
|
||||
tvhlog(LOG_INFO, "cwc", "%s:%i destroyed",
|
||||
cwc->cwc_hostname, cwc->cwc_port);
|
||||
|
||||
while((ct = LIST_FIRST(&cwc->cwc_services)) != NULL) {
|
||||
t = ct->cs_service;
|
||||
|
@ -1180,14 +1254,24 @@ cwc_emm_cache_lookup(cwc_t *cwc, uint32_t crc)
|
|||
*
|
||||
*/
|
||||
void
|
||||
cwc_emm(uint8_t *data, int len)
|
||||
cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id)
|
||||
{
|
||||
cwc_t *cwc;
|
||||
|
||||
pthread_mutex_lock(&cwc_mutex);
|
||||
|
||||
TAILQ_FOREACH(cwc, &cwcs, cwc_link) {
|
||||
if(cwc->cwc_forward_emm && cwc->cwc_writer_running) {
|
||||
if(cwc->cwc_caid == caid &&
|
||||
cwc->cwc_forward_emm && cwc->cwc_writer_running) {
|
||||
if (cwc->cwc_emmex) {
|
||||
if (cwc->cwc_update_id != ca_update_id) {
|
||||
int64_t delta = getmonoclock() - cwc->cwc_update_time;
|
||||
if (delta < 25000000UL) /* 25 seconds */
|
||||
continue;
|
||||
}
|
||||
cwc->cwc_update_time = getmonoclock();
|
||||
}
|
||||
cwc->cwc_update_id = ca_update_id;
|
||||
switch (cwc->cwc_card_type) {
|
||||
case CARD_CONAX:
|
||||
cwc_emm_conax(cwc, data, len);
|
||||
|
@ -1210,6 +1294,12 @@ cwc_emm(uint8_t *data, int len)
|
|||
case CARD_NDS:
|
||||
cwc_emm_nds(cwc, data, len);
|
||||
break;
|
||||
case CARD_CRYPTOWORKS:
|
||||
cwc_emm_cryptoworks(cwc, data, len);
|
||||
break;
|
||||
case CARD_BULCRYPT:
|
||||
cwc_emm_bulcrypt(cwc, data, len);
|
||||
break;
|
||||
case CARD_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
@ -1402,13 +1492,15 @@ cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen)
|
|||
if (cwc->cwc_viaccess_emm.shared_emm) {
|
||||
cwc->cwc_viaccess_emm.shared_len = len;
|
||||
memcpy(cwc->cwc_viaccess_emm.shared_emm, data, len);
|
||||
cwc->cwc_viaccess_emm.ca_update_id = cwc->cwc_update_id;
|
||||
}
|
||||
cwc->cwc_viaccess_emm.shared_toggle = data[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x8e:
|
||||
if (cwc->cwc_viaccess_emm.shared_emm) {
|
||||
if (cwc->cwc_viaccess_emm.shared_emm &&
|
||||
cwc->cwc_viaccess_emm.ca_update_id == cwc->cwc_update_id) {
|
||||
int match = 0;
|
||||
int i;
|
||||
/* Match SA and provider in shared */
|
||||
|
@ -1490,6 +1582,9 @@ cwc_table_input(struct th_descrambler *td, struct service *t,
|
|||
char chaninfo[32];
|
||||
caid_t *c;
|
||||
|
||||
if (ct->cs_keystate == CS_IDLE)
|
||||
return;
|
||||
|
||||
if(len > 4096)
|
||||
return;
|
||||
|
||||
|
@ -1541,6 +1636,9 @@ cwc_table_input(struct th_descrambler *td, struct service *t,
|
|||
|
||||
es = ep->ep_sections[section];
|
||||
|
||||
if (es->es_nok > 2)
|
||||
break; /* too many NOK responses in a row */
|
||||
|
||||
if(es->es_ecmsize == len && !memcmp(es->es_ecm, data, len))
|
||||
break; /* key already sent */
|
||||
|
||||
|
@ -1654,6 +1752,90 @@ cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len)
|
|||
cwc_send_msg(cwc, data, len, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len)
|
||||
{
|
||||
int match = 0;
|
||||
|
||||
switch (data[0]) {
|
||||
case 0x82: /* unique */
|
||||
match = len >= 10 && memcmp(data + 5, cwc->cwc_ua + 3, 5) == 0;
|
||||
break;
|
||||
case 0x84: /* emm-sh */
|
||||
if (len >= 9 && memcmp(data + 5, cwc->cwc_ua + 3, 4) == 0) {
|
||||
if (cwc->cwc_cryptoworks_emm.shared_emm) {
|
||||
free(cwc->cwc_cryptoworks_emm.shared_emm);
|
||||
cwc->cwc_cryptoworks_emm.shared_len = 0;
|
||||
cwc->cwc_cryptoworks_emm.shared_emm = (uint8_t *)malloc(len);
|
||||
}
|
||||
cwc->cwc_cryptoworks_emm.shared_emm = malloc(len);
|
||||
if (cwc->cwc_cryptoworks_emm.shared_emm) {
|
||||
cwc->cwc_cryptoworks_emm.shared_len = len;
|
||||
memcpy(cwc->cwc_cryptoworks_emm.shared_emm, data, len);
|
||||
cwc->cwc_cryptoworks_emm.ca_update_id = cwc->cwc_update_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x86: /* emm-sb */
|
||||
if (cwc->cwc_cryptoworks_emm.shared_emm &&
|
||||
cwc->cwc_cryptoworks_emm.ca_update_id == cwc->cwc_update_id) {
|
||||
/* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */
|
||||
uint32_t elen = len - 5 + cwc->cwc_cryptoworks_emm.shared_len - 12;
|
||||
uint8_t *tmp = malloc(elen);
|
||||
uint8_t *composed = tmp ? malloc(elen + 12) : NULL;
|
||||
if (composed) {
|
||||
memcpy(tmp, data + 5, len - 5);
|
||||
memcpy(tmp + len - 5, cwc->cwc_cryptoworks_emm.shared_emm + 12,
|
||||
cwc->cwc_cryptoworks_emm.shared_len - 12);
|
||||
memcpy(composed, cwc->cwc_cryptoworks_emm.shared_emm, 12);
|
||||
sort_nanos(composed + 12, tmp, elen);
|
||||
composed[1] = ((elen + 9) >> 8) | 0x70;
|
||||
composed[2] = (elen + 9) & 0xff;
|
||||
cwc_send_msg(cwc, composed, elen + 12, 0, 1);
|
||||
free(composed);
|
||||
free(tmp);
|
||||
}
|
||||
cwc->cwc_cryptoworks_emm.shared_emm = NULL;
|
||||
cwc->cwc_cryptoworks_emm.shared_len = 0;
|
||||
}
|
||||
break;
|
||||
case 0x88: /* global */
|
||||
case 0x89: /* global */
|
||||
match = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (match)
|
||||
cwc_send_msg(cwc, data, len, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
cwc_emm_bulcrypt(cwc_t *cwc, uint8_t *data, int len)
|
||||
{
|
||||
int match = 0;
|
||||
|
||||
switch (data[0]) {
|
||||
case 0x82: /* unique */
|
||||
case 0x85: /* unique */
|
||||
match = len >= 10 && memcmp(data + 3, cwc->cwc_ua + 2, 3) == 0;
|
||||
break;
|
||||
case 0x84: /* shared */
|
||||
match = len >= 10 && memcmp(data + 3, cwc->cwc_ua + 2, 2) == 0;
|
||||
break;
|
||||
case 0x8b: /* shared-unknown */
|
||||
match = len >= 10 && memcmp(data + 4, cwc->cwc_ua + 2, 2) == 0;
|
||||
break;
|
||||
case 0x8a: /* global */
|
||||
match = len >= 10 && memcmp(data + 4, cwc->cwc_ua + 2, 1) == 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (match)
|
||||
cwc_send_msg(cwc, data, len, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -1924,6 +2106,7 @@ cwc_record_build(cwc_t *cwc)
|
|||
|
||||
htsmsg_add_str(e, "deskey", buf);
|
||||
htsmsg_add_u32(e, "emm", cwc->cwc_emm);
|
||||
htsmsg_add_u32(e, "emmex", cwc->cwc_emmex);
|
||||
htsmsg_add_str(e, "comment", cwc->cwc_comment ?: "");
|
||||
|
||||
return e;
|
||||
|
@ -2010,6 +2193,9 @@ cwc_entry_update(void *opaque, const char *id, htsmsg_t *values, int maycreate)
|
|||
if(!htsmsg_get_u32(values, "emm", &u32))
|
||||
cwc->cwc_emm = u32;
|
||||
|
||||
if(!htsmsg_get_u32(values, "emmex", &u32))
|
||||
cwc->cwc_emmex = u32;
|
||||
|
||||
cwc->cwc_reconfigure = 1;
|
||||
|
||||
if(cwc->cwc_fd != -1)
|
||||
|
|
|
@ -23,6 +23,6 @@ void cwc_init(void);
|
|||
|
||||
void cwc_service_start(struct service *t);
|
||||
|
||||
void cwc_emm(uint8_t *data, int len);
|
||||
void cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id);
|
||||
|
||||
#endif /* CWC_H_ */
|
||||
|
|
|
@ -265,7 +265,8 @@ th_dvb_mux_instance_t *dvb_mux_create(th_dvb_adapter_t *tda,
|
|||
const struct dvb_mux_conf *dmc,
|
||||
uint16_t tsid, const char *network,
|
||||
const char *logprefix, int enabled,
|
||||
int initialscan, const char *identifier);
|
||||
int initialscan, const char *identifier,
|
||||
dvb_satconf_t *satconf);
|
||||
|
||||
void dvb_mux_set_networkname(th_dvb_mux_instance_t *tdmi, const char *name);
|
||||
|
||||
|
@ -295,7 +296,8 @@ const char *dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
|||
int polarisation,
|
||||
const char *satconf);
|
||||
|
||||
int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src);
|
||||
int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src,
|
||||
dvb_satconf_t *satconf);
|
||||
|
||||
/**
|
||||
* DVB Transport (aka DVB service)
|
||||
|
|
|
@ -458,7 +458,7 @@ dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src)
|
|||
dvb_mux_destroy(tdmi_dst);
|
||||
|
||||
LIST_FOREACH(tdmi_src, &src->tda_muxes, tdmi_adapter_link)
|
||||
dvb_mux_copy(dst, tdmi_src);
|
||||
dvb_mux_copy(dst, tdmi_src, NULL);
|
||||
|
||||
tda_save(dst);
|
||||
}
|
||||
|
|
|
@ -150,7 +150,8 @@ tdmi_compare_conf(int adapter_type,
|
|||
th_dvb_mux_instance_t *
|
||||
dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
||||
uint16_t tsid, const char *network, const char *source,
|
||||
int enabled, int initialscan, const char *identifier)
|
||||
int enabled, int initialscan, const char *identifier,
|
||||
dvb_satconf_t *satconf)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi, *c;
|
||||
unsigned int hash;
|
||||
|
@ -225,8 +226,9 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
|||
|
||||
snprintf(buf, sizeof(buf), "%s%d%s%s%s",
|
||||
tda->tda_identifier, dmc->dmc_fe_params.frequency, qpsktxt,
|
||||
dmc->dmc_satconf ? "_satconf_" : "",
|
||||
dmc->dmc_satconf ? dmc->dmc_satconf->sc_id : "");
|
||||
(satconf || dmc->dmc_satconf) ? "_satconf_" : "",
|
||||
(satconf ? satconf->sc_id :
|
||||
(dmc->dmc_satconf ? dmc->dmc_satconf->sc_id : "")));
|
||||
|
||||
tdmi->tdmi_identifier = strdup(buf);
|
||||
} else {
|
||||
|
@ -259,6 +261,8 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc,
|
|||
|
||||
|
||||
memcpy(&tdmi->tdmi_conf, dmc, sizeof(struct dvb_mux_conf));
|
||||
if(satconf)
|
||||
tdmi->tdmi_conf.dmc_satconf = satconf;
|
||||
if(tdmi->tdmi_conf.dmc_satconf != NULL) {
|
||||
LIST_INSERT_HEAD(&tdmi->tdmi_conf.dmc_satconf->sc_tdmis,
|
||||
tdmi, tdmi_satconf_link);
|
||||
|
@ -708,7 +712,7 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m, const char *identifier)
|
|||
|
||||
tdmi = dvb_mux_create(tda, &dmc,
|
||||
tsid, htsmsg_get_str(m, "network"), NULL, enabled, 1,
|
||||
identifier);
|
||||
identifier, NULL);
|
||||
if(tdmi != NULL) {
|
||||
|
||||
if((s = htsmsg_get_str(m, "status")) != NULL)
|
||||
|
@ -1058,7 +1062,7 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
|||
}
|
||||
dmc.dmc_polarisation = polarisation;
|
||||
|
||||
tdmi = dvb_mux_create(tda, &dmc, 0xffff, NULL, NULL, 1, 1, NULL);
|
||||
tdmi = dvb_mux_create(tda, &dmc, 0xffff, NULL, NULL, 1, 1, NULL, NULL);
|
||||
|
||||
if(tdmi == NULL)
|
||||
return "Mux already exist";
|
||||
|
@ -1071,7 +1075,8 @@ dvb_mux_add_by_params(th_dvb_adapter_t *tda,
|
|||
*
|
||||
*/
|
||||
int
|
||||
dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src)
|
||||
dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src,
|
||||
dvb_satconf_t *satconf)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi_dst;
|
||||
service_t *t_src, *t_dst;
|
||||
|
@ -1083,7 +1088,7 @@ dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src)
|
|||
tdmi_src->tdmi_transport_stream_id,
|
||||
tdmi_src->tdmi_network,
|
||||
"copy operation", tdmi_src->tdmi_enabled,
|
||||
1, NULL);
|
||||
1, NULL, satconf);
|
||||
|
||||
if(tdmi_dst == NULL)
|
||||
return -1; // Already exist
|
||||
|
|
|
@ -64,9 +64,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const struct mux *m, int num,
|
|||
break;
|
||||
|
||||
case FE_QPSK:
|
||||
#ifdef SYS_DVBS
|
||||
dmc.dmc_fe_delsys = SYS_DVBS;
|
||||
#endif
|
||||
dmc.dmc_fe_delsys = SYS_DVBS;
|
||||
dmc.dmc_fe_params.u.qpsk.symbol_rate = m->symrate;
|
||||
dmc.dmc_fe_params.u.qpsk.fec_inner = m->fec;
|
||||
|
||||
|
@ -102,7 +100,7 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const struct mux *m, int num,
|
|||
|
||||
dmc.dmc_satconf = dvb_satconf_entry_find(tda, satconf, 0);
|
||||
|
||||
dvb_mux_create(tda, &dmc, 0xffff, NULL, source, 1, 1, NULL);
|
||||
dvb_mux_create(tda, &dmc, 0xffff, NULL, source, 1, 1, NULL, NULL);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
#define TDT_CRC 0x1
|
||||
#define TDT_QUICKREQ 0x2
|
||||
#define TDT_INC_TABLE_HDR 0x4
|
||||
#define TDT_CA 0x4
|
||||
|
||||
static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
|
||||
|
||||
|
@ -214,8 +214,9 @@ dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec,
|
|||
ptr = &sec[3];
|
||||
if(chkcrc) len -= 4; /* Strip trailing CRC */
|
||||
|
||||
if(tdt->tdt_flags & TDT_INC_TABLE_HDR)
|
||||
ret = tdt->tdt_callback(tdmi, sec, len + 3, tableid, tdt->tdt_opaque);
|
||||
if(tdt->tdt_flags & TDT_CA)
|
||||
ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
|
||||
sec, len + 3, tableid, tdt->tdt_opaque);
|
||||
else
|
||||
ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque);
|
||||
|
||||
|
@ -412,9 +413,13 @@ dvb_desc_extended_event(uint8_t *ptr, int len,
|
|||
if ((desclen - strlen(desc)) > 2)
|
||||
{
|
||||
/* get description -> append to desc if space left */
|
||||
strncat(desc, "\n", 1);
|
||||
strncat(desc, (char*)(items+1),
|
||||
items[0] > (desclen - strlen(desc)) ? (desclen - strlen(desc)) : items[0]);
|
||||
if (desc[0] != '\0')
|
||||
strncat(desc, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(desc + strlen(desc),
|
||||
desclen - strlen(desc),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
items += 1 + items[0];
|
||||
|
@ -423,9 +428,13 @@ dvb_desc_extended_event(uint8_t *ptr, int len,
|
|||
if ((itemlen - strlen(item)) > 2)
|
||||
{
|
||||
/* get item -> append to item if space left */
|
||||
strncat(item, "\n", 1);
|
||||
strncat(item, (char*)(items+1),
|
||||
items[0] > (itemlen - strlen(item)) ? (itemlen - strlen(item)) : items[0]);
|
||||
if (item[0] != '\0')
|
||||
strncat(item, "\n", 1);
|
||||
if((r = dvb_get_string_with_len(item + strlen(item),
|
||||
itemlen - strlen(item),
|
||||
items, (localptr + count) - items,
|
||||
dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* go to next item */
|
||||
|
@ -824,7 +833,7 @@ static int
|
|||
dvb_ca_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque)
|
||||
{
|
||||
cwc_emm(ptr, len);
|
||||
cwc_emm(ptr, len, (uintptr_t)opaque, (void *)tdmi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -837,6 +846,7 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
{
|
||||
int tag, tlen;
|
||||
uint16_t pid;
|
||||
uintptr_t caid;
|
||||
|
||||
if((ptr[2] & 1) == 0) {
|
||||
/* current_next_indicator == next, skip this */
|
||||
|
@ -852,14 +862,14 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
len -= 2;
|
||||
switch(tag) {
|
||||
case DVB_DESC_CA:
|
||||
// caid = ( ptr[0] << 8) | ptr[1];
|
||||
caid = ( ptr[0] << 8) | ptr[1];
|
||||
pid = ((ptr[2] & 0x1f) << 8) | ptr[3];
|
||||
|
||||
if(pid == 0)
|
||||
break;
|
||||
|
||||
tdt_add(tdmi, NULL, dvb_ca_callback, NULL, "CA",
|
||||
TDT_INC_TABLE_HDR, pid, NULL);
|
||||
tdt_add(tdmi, NULL, dvb_ca_callback, (void *)caid, "CA",
|
||||
TDT_CA, pid, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -942,7 +952,7 @@ dvb_table_cable_delivery(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x07];
|
||||
|
||||
dvb_mux_create(tdmi->tdmi_adapter, &dmc, tsid, NULL,
|
||||
"automatic mux discovery", 1, 1, NULL);
|
||||
"automatic mux discovery", 1, 1, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1037,7 @@ dvb_table_sat_delivery(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
|
||||
#endif
|
||||
dvb_mux_create(tdmi->tdmi_adapter, &dmc, tsid, NULL,
|
||||
"automatic mux discovery", 1, 1, NULL);
|
||||
"automatic mux discovery", 1, 1, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -143,14 +143,13 @@ static htsbuf_queue_t *
|
|||
mk_build_segment_info(mk_mux_t *mkm)
|
||||
{
|
||||
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
|
||||
extern char *htsversion_full;
|
||||
char app[128];
|
||||
|
||||
snprintf(app, sizeof(app), "HTS Tvheadend %s", htsversion_full);
|
||||
snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version);
|
||||
|
||||
ebml_append_bin(q, 0x73a4, mkm->uuid, sizeof(mkm->uuid));
|
||||
ebml_append_string(q, 0x7ba9, mkm->title);
|
||||
ebml_append_string(q, 0x4d80, "HTS Tvheadend Matroska muxer");
|
||||
ebml_append_string(q, 0x4d80, "Tvheadend Matroska muxer");
|
||||
ebml_append_string(q, 0x5741, app);
|
||||
ebml_append_uint(q, 0x2ad7b1, MATROSKA_TIMESCALE);
|
||||
|
||||
|
@ -822,10 +821,13 @@ mk_write_frame_i(mk_mux_t *mkm, mk_track *t, th_pkt_t *pkt)
|
|||
int skippable = pkt->pkt_frametype == PKT_B_FRAME;
|
||||
int vkeyframe = SCT_ISVIDEO(t->type) && keyframe;
|
||||
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
uint8_t *data = pktbuf_ptr(pkt->pkt_payload);
|
||||
size_t len = pktbuf_len(pkt->pkt_payload);
|
||||
const int clusersizemax = 2000000;
|
||||
|
||||
if(!data || len <= 0)
|
||||
return;
|
||||
|
||||
if(pts == PTS_UNSET)
|
||||
// This is our best guess, it might be wrong but... oh well
|
||||
pts = t->nextpts;
|
||||
|
@ -875,10 +877,6 @@ mk_write_frame_i(mk_mux_t *mkm, mk_track *t, th_pkt_t *pkt)
|
|||
addcue(mkm, pts, t->tracknum);
|
||||
}
|
||||
|
||||
|
||||
data = pktbuf_ptr(pkt->pkt_payload);
|
||||
len = pktbuf_len(pkt->pkt_payload);
|
||||
|
||||
if(t->type == SCT_AAC || t->type == SCT_MP4A) {
|
||||
// Skip ADTS header
|
||||
if(len < 7)
|
||||
|
|
|
@ -50,7 +50,6 @@ static void *htsp_server;
|
|||
|
||||
#define HTSP_PRIV_MASK (ACCESS_STREAMING)
|
||||
|
||||
extern const char *htsversion;
|
||||
extern char *dvr_storage;
|
||||
|
||||
LIST_HEAD(htsp_connection_list, htsp_connection);
|
||||
|
@ -1047,7 +1046,7 @@ htsp_method_hello(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
|
||||
htsmsg_add_u32(r, "htspversion", HTSP_PROTO_VERSION);
|
||||
htsmsg_add_str(r, "servername", "HTS Tvheadend");
|
||||
htsmsg_add_str(r, "serverversion", htsversion);
|
||||
htsmsg_add_str(r, "serverversion", tvheadend_version);
|
||||
htsmsg_add_bin(r, "challenge", htsp->htsp_challenge, 32);
|
||||
|
||||
htsp_update_logname(htsp);
|
||||
|
@ -1541,7 +1540,7 @@ const static char frametypearray[PKT_NTYPES] = {
|
|||
static void
|
||||
htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt)
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create_map(), *n;
|
||||
htsmsg_t *m, *n;
|
||||
htsp_msg_t *hm;
|
||||
htsp_connection_t *htsp = hs->hs_htsp;
|
||||
int64_t ts;
|
||||
|
@ -1557,6 +1556,8 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt)
|
|||
pkt_ref_dec(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
m = htsmsg_create_map();
|
||||
|
||||
htsmsg_add_str(m, "method", "muxpkt");
|
||||
htsmsg_add_u32(m, "subscriptionId", hs->hs_sid);
|
||||
|
|
14
src/main.c
14
src/main.c
|
@ -60,8 +60,6 @@
|
|||
#include "ffdecsa/FFdecsa.h"
|
||||
|
||||
int running;
|
||||
extern const char *htsversion;
|
||||
extern const char *htsversion_full;
|
||||
time_t dispatch_clock;
|
||||
static LIST_HEAD(, gtimer) gtimers;
|
||||
pthread_mutex_t global_lock;
|
||||
|
@ -150,7 +148,7 @@ gtimer_disarm(gtimer_t *gti)
|
|||
static void
|
||||
usage(const char *argv0)
|
||||
{
|
||||
printf("HTS Tvheadend %s\n", htsversion_full);
|
||||
printf("HTS Tvheadend %s\n", tvheadend_version);
|
||||
printf("usage: %s [options]\n", argv0);
|
||||
printf("\n");
|
||||
printf(" -a <adapters> Use only DVB adapters specified (csv)\n");
|
||||
|
@ -386,7 +384,7 @@ main(int argc, char **argv)
|
|||
#endif
|
||||
http_server_init();
|
||||
|
||||
webui_init(TVHEADEND_CONTENT_PATH);
|
||||
webui_init(tvheadend_dataroot());
|
||||
|
||||
serviceprobe_init();
|
||||
|
||||
|
@ -433,9 +431,11 @@ main(int argc, char **argv)
|
|||
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||
|
||||
tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
|
||||
"running as PID:%d UID:%d GID:%d, settings located in '%s'",
|
||||
htsversion_full,
|
||||
getpid(), getuid(), getgid(), hts_settings_get_root());
|
||||
"running as PID:%d UID:%d GID:%d, settings located in '%s', "
|
||||
"dataroot: %s",
|
||||
tvheadend_version,
|
||||
getpid(), getuid(), getgid(), hts_settings_get_root(),
|
||||
tvheadend_dataroot() ?: "<Embedded file system>");
|
||||
|
||||
if(crash)
|
||||
abort();
|
||||
|
|
|
@ -71,6 +71,9 @@ read_audio_specific_config(elementary_stream_t *st, latm_private_t *latm,
|
|||
else
|
||||
sr = sri_to_rate(latm->sample_rate_index);
|
||||
|
||||
if(sr == 0)
|
||||
return;
|
||||
|
||||
st->es_frame_duration = 1024 * 90000 / sr;
|
||||
|
||||
latm->channel_config = read_bits(bs, 4);
|
||||
|
|
22
src/psi.c
22
src/psi.c
|
@ -307,8 +307,10 @@ psi_desc_ca(service_t *t, const uint8_t *buffer, int size)
|
|||
}
|
||||
break;
|
||||
case 0x4a00://DRECrypt
|
||||
provid = size < 4 ? 0 : buffer[4];
|
||||
break;
|
||||
if (caid != 0x4aee) { // Bulcrypt
|
||||
provid = size < 4 ? 0 : buffer[4];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
provid = 0;
|
||||
break;
|
||||
|
@ -834,13 +836,23 @@ static struct strtab caidnametab[] = {
|
|||
{ "Irdeto", 0x0600 },
|
||||
{ "Irdeto", 0x0602 },
|
||||
{ "Irdeto", 0x0604 },
|
||||
{ "Irdeto", 0x0624 },
|
||||
{ "Irdeto", 0x0666 },
|
||||
{ "Jerroldgi", 0x0700 },
|
||||
{ "Matra", 0x0800 },
|
||||
{ "NDS", 0x0900 },
|
||||
{ "Nokia", 0x0A00 },
|
||||
{ "Conax", 0x0B00 },
|
||||
{ "NTL", 0x0C00 },
|
||||
{ "CryptoWorks", 0x0D00 },
|
||||
{ "CryptoWorks", 0x0D00 },
|
||||
{ "CryptoWorks", 0x0D01 },
|
||||
{ "CryptoWorks", 0x0D02 },
|
||||
{ "CryptoWorks", 0x0D03 },
|
||||
{ "CryptoWorks", 0x0D05 },
|
||||
{ "CryptoWorks", 0x0D0F },
|
||||
{ "CryptoWorks", 0x0D70 },
|
||||
{ "CryptoWorks ICE", 0x0D96 },
|
||||
{ "CryptoWorks ICE", 0x0D97 },
|
||||
{ "PowerVu", 0x0E00 },
|
||||
{ "Sony", 0x0F00 },
|
||||
{ "Tandberg", 0x1000 },
|
||||
|
@ -866,7 +878,9 @@ static struct strtab caidnametab[] = {
|
|||
{ "GI", 0x4700 },
|
||||
{ "Telemann", 0x4800 },
|
||||
{ "DRECrypt", 0x4ae0 },
|
||||
{ "DRECrypt2", 0x4ae1 }
|
||||
{ "DRECrypt2", 0x4ae1 },
|
||||
{ "Bulcrypt", 0x4aee },
|
||||
{ "Bulcrypt", 0x5581 },
|
||||
};
|
||||
|
||||
const char *
|
||||
|
|
|
@ -184,7 +184,7 @@ got_pat(const uint8_t *ptr, size_t len, void *opaque)
|
|||
len -= 8;
|
||||
ptr += 8;
|
||||
|
||||
if(len < 0)
|
||||
if(len <= 0)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
*/
|
||||
typedef struct tt_mag {
|
||||
int ttm_curpage;
|
||||
int ttm_inactive;
|
||||
int64_t ttm_current_pts;
|
||||
uint8_t ttm_lang;
|
||||
uint8_t ttm_page[23*40 + 1];
|
||||
|
@ -397,8 +396,7 @@ tt_decode_line(service_t *t, elementary_stream_t *st, uint8_t *buf)
|
|||
case 0:
|
||||
if(ttm->ttm_curpage != 0) {
|
||||
|
||||
if(ttm->ttm_inactive == 0)
|
||||
tt_subtitle_deliver(t, st, ttm);
|
||||
tt_subtitle_deliver(t, st, ttm);
|
||||
|
||||
if(ttm->ttm_curpage == 192)
|
||||
teletext_rundown_copy(ttp, ttm);
|
||||
|
@ -429,11 +427,9 @@ tt_decode_line(service_t *t, elementary_stream_t *st, uint8_t *buf)
|
|||
teletext_rundown_scan(t, ttp);
|
||||
|
||||
ttm->ttm_current_pts = t->s_current_pts;
|
||||
ttm->ttm_inactive = 0;
|
||||
break;
|
||||
|
||||
case 1 ... 23:
|
||||
ttm->ttm_inactive = 0;
|
||||
for(i = 0; i < 40; i++) {
|
||||
c = buf[i + 2] & 0x7f;
|
||||
ttm->ttm_page[i + 40 * (line - 1)] = c;
|
||||
|
@ -446,30 +442,6 @@ tt_decode_line(service_t *t, elementary_stream_t *st, uint8_t *buf)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
teletext_scan_stream(service_t *t, elementary_stream_t *st)
|
||||
{
|
||||
tt_private_t *ttp = st->es_priv;
|
||||
tt_mag_t *ttm;
|
||||
int i;
|
||||
|
||||
if(ttp == NULL)
|
||||
return;
|
||||
for(i = 0; i < 8; i++) {
|
||||
ttm = &ttp->ttp_mags[i];
|
||||
ttm->ttm_inactive++;
|
||||
if(ttm->ttm_inactive == 2) {
|
||||
tt_subtitle_deliver(t, st, ttm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -489,7 +461,6 @@ teletext_input(service_t *t, elementary_stream_t *st, const uint8_t *tsb)
|
|||
}
|
||||
x += 46;
|
||||
}
|
||||
teletext_scan_stream(t, st);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -220,9 +220,6 @@ callback(struct dl_phdr_info *info, size_t size, void *data)
|
|||
}
|
||||
|
||||
|
||||
extern const char *htsversion_full;
|
||||
|
||||
|
||||
void
|
||||
trap_init(const char *ver)
|
||||
{
|
||||
|
@ -259,7 +256,7 @@ trap_init(const char *ver)
|
|||
"PRG: %s (%s) "
|
||||
"[%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x] "
|
||||
"CWD: %s ", ver, htsversion_full,
|
||||
"CWD: %s ", ver, tvheadend_version,
|
||||
digest[0],
|
||||
digest[1],
|
||||
digest[2],
|
||||
|
|
|
@ -142,8 +142,6 @@ ts_extract_pcr(service_t *t, elementary_stream_t *st, const uint8_t *tsb,
|
|||
pcr |= (uint64_t)tsb[9] << 1;
|
||||
pcr |= ((uint64_t)tsb[10] >> 7) & 0x01;
|
||||
|
||||
pcr = pcr;
|
||||
|
||||
if(pcrp != NULL)
|
||||
*pcrp = pcr;
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TVHEADEND_H
|
||||
#define TVHEADEND_H
|
||||
|
||||
|
@ -34,6 +33,9 @@
|
|||
|
||||
#include "redblack.h"
|
||||
|
||||
extern const char *tvheadend_version;
|
||||
extern const char *tvheadend_dataroot();
|
||||
|
||||
#define PTS_UNSET INT64_C(0x8000000000000000)
|
||||
|
||||
extern pthread_mutex_t global_lock;
|
||||
|
@ -400,7 +402,7 @@ extern void scopedunlock(pthread_mutex_t **mtxp);
|
|||
#define scopedlock(mtx) \
|
||||
pthread_mutex_t *scopedlock ## __LINE__ \
|
||||
__attribute__((cleanup(scopedunlock))) = mtx; \
|
||||
pthread_mutex_lock(mtx);
|
||||
pthread_mutex_lock(scopedlock ## __LINE__);
|
||||
|
||||
#define scopedgloballock() scopedlock(&global_lock)
|
||||
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
#include "buildversion.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HTS_RELEASE_TAG
|
||||
const char *htsversion=HTS_RELEASE_TAG;
|
||||
const char *htsversion_full=HTS_RELEASE_TAG " (" HTS_VERSION ")";
|
||||
#else
|
||||
const char *htsversion=HTS_VERSION;
|
||||
const char *htsversion_full=HTS_VERSION;
|
||||
#endif
|
||||
const char *tvheadend_version = BUILD_VERSION;
|
||||
|
|
|
@ -43,9 +43,6 @@
|
|||
#include "epg.h"
|
||||
#include "iptv_input.h"
|
||||
|
||||
extern const char *htsversion;
|
||||
extern const char *htsversion_full;
|
||||
|
||||
static void
|
||||
extjs_load(htsbuf_queue_t *hq, const char *script)
|
||||
{
|
||||
|
@ -166,7 +163,7 @@ extjs_root(http_connection_t *hc, const char *remain, void *opaque)
|
|||
"<body>\n"
|
||||
"<div id=\"systemlog\"></div>\n"
|
||||
"</body></html>\n",
|
||||
htsversion);
|
||||
tvheadend_version);
|
||||
http_output_html(hc);
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,7 +182,7 @@ page_about(http_connection_t *hc, const char *remain, void *opaque)
|
|||
"<div class=\"about-title\">"
|
||||
"HTS Tvheadend %s"
|
||||
"</div><br>"
|
||||
"© 2006 - 2010 Andreas \303\226man, et al.<br><br>"
|
||||
"© 2006 - 2012 Andreas \303\226man, et al.<br><br>"
|
||||
"<img src=\"docresources/tvheadendlogo.png\"><br>"
|
||||
"<a href=\"http://www.lonelycoder.com/hts\">"
|
||||
"http://www.lonelycoder.com/hts</a><br><br>"
|
||||
|
@ -197,8 +194,8 @@ page_about(http_connection_t *hc, const char *remain, void *opaque)
|
|||
"<br><br>"
|
||||
"Build: %s"
|
||||
"</center>",
|
||||
htsversion,
|
||||
htsversion_full);
|
||||
tvheadend_version,
|
||||
tvheadend_version);
|
||||
|
||||
http_output_html(hc);
|
||||
return 0;
|
||||
|
@ -634,6 +631,9 @@ extjs_confignames(http_connection_t *hc, const char *remain, void *opaque)
|
|||
out = htsmsg_create_map();
|
||||
array = htsmsg_create_list();
|
||||
|
||||
if (http_access_verify(hc, ACCESS_RECORDER_ALL))
|
||||
goto skip;
|
||||
|
||||
LIST_FOREACH(cfg, &dvrconfigs, config_link) {
|
||||
e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "identifier", cfg->dvr_config_name);
|
||||
|
@ -644,6 +644,7 @@ extjs_confignames(http_connection_t *hc, const char *remain, void *opaque)
|
|||
htsmsg_add_msg(array, NULL, e);
|
||||
}
|
||||
|
||||
skip:
|
||||
htsmsg_add_msg(out, "entries", array);
|
||||
|
||||
} else {
|
||||
|
@ -890,6 +891,19 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
return HTTP_STATUS_BAD_REQUEST;
|
||||
}
|
||||
|
||||
if (http_access_verify(hc, ACCESS_RECORDER_ALL)) {
|
||||
config_name = NULL;
|
||||
LIST_FOREACH(cfg, &dvrconfigs, config_link) {
|
||||
if (cfg->dvr_config_name && hc->hc_username &&
|
||||
strcmp(cfg->dvr_config_name, hc->hc_username) == 0) {
|
||||
config_name = cfg->dvr_config_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (config_name == NULL && hc->hc_username)
|
||||
tvhlog(LOG_INFO,"dvr","User '%s' has no dvr config with identical name, using default...", hc->hc_username);
|
||||
}
|
||||
|
||||
dvr_entry_create_by_event(config_name,
|
||||
e, hc->hc_representative, NULL, DVR_PRIO_NORMAL);
|
||||
#endif
|
||||
|
@ -961,6 +975,19 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if(stop < start)
|
||||
stop += 86400;
|
||||
|
||||
if (http_access_verify(hc, ACCESS_RECORDER_ALL)) {
|
||||
config_name = NULL;
|
||||
LIST_FOREACH(cfg, &dvrconfigs, config_link) {
|
||||
if (cfg->dvr_config_name && hc->hc_username &&
|
||||
strcmp(cfg->dvr_config_name, hc->hc_username) == 0) {
|
||||
config_name = cfg->dvr_config_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (config_name == NULL && hc->hc_username)
|
||||
tvhlog(LOG_INFO,"dvr","User '%s' has no dvr config with identical name, using default...", hc->hc_username);
|
||||
}
|
||||
|
||||
dvr_entry_create(config_name,
|
||||
ch, start, stop, title, NULL, hc->hc_representative,
|
||||
NULL, NULL, 0, dvr_pri2val(pri));
|
||||
|
|
|
@ -454,11 +454,14 @@ extjs_dvbsatconf(http_connection_t *hc, const char *remain, void *opaque)
|
|||
htsbuf_queue_t *hq = &hc->hc_reply;
|
||||
th_dvb_adapter_t *tda;
|
||||
htsmsg_t *out;
|
||||
const char *adapter = http_arg_get(&hc->hc_req_args, "adapter");
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
|
||||
if(remain == NULL ||
|
||||
(tda = dvb_adapter_find_by_identifier(remain)) == NULL) {
|
||||
if((remain == NULL ||
|
||||
(tda = dvb_adapter_find_by_identifier(remain)) == NULL) &&
|
||||
(adapter == NULL ||
|
||||
(tda = dvb_adapter_find_by_identifier(adapter)) == NULL)) {
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
return 404;
|
||||
}
|
||||
|
@ -582,9 +585,11 @@ extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
th_dvb_adapter_t *tda;
|
||||
htsmsg_t *in;
|
||||
const char *entries = http_arg_get(&hc->hc_req_args, "entries");
|
||||
const char *satconf = http_arg_get(&hc->hc_req_args, "satconf");
|
||||
const char *id;
|
||||
htsmsg_field_t *f;
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
dvb_satconf_t *sc = NULL;
|
||||
|
||||
in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL;
|
||||
|
||||
|
@ -599,13 +604,20 @@ extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
return 404;
|
||||
}
|
||||
|
||||
if (satconf) {
|
||||
sc = dvb_satconf_entry_find(tda, satconf, 0);
|
||||
if (sc == NULL) {
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(f, &in->hm_fields, hmf_link) {
|
||||
if((id = htsmsg_field_get_string(f)) != NULL &&
|
||||
(tdmi = dvb_mux_find_by_identifier(id)) != NULL &&
|
||||
tda != tdmi->tdmi_adapter) {
|
||||
|
||||
if(dvb_mux_copy(tda, tdmi)) {
|
||||
if(dvb_mux_copy(tda, tdmi, sc)) {
|
||||
char buf[100];
|
||||
dvb_mux_nicename(buf, sizeof(buf), tdmi);
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#endif
|
||||
|
||||
extern char tvh_binshasum[20];
|
||||
extern char *htsversion_full;
|
||||
|
||||
int page_statedump(http_connection_t *hc, const char *remain, void *opaque);
|
||||
|
||||
|
@ -159,7 +158,7 @@ page_statedump(http_connection_t *hc, const char *remain, void *opaque)
|
|||
htsbuf_qprintf(hq, "Tvheadend %s Binary SHA1: "
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
htsversion_full,
|
||||
tvheadend_version,
|
||||
tvh_binshasum[0],
|
||||
tvh_binshasum[1],
|
||||
tvh_binshasum[2],
|
||||
|
|
|
@ -20,6 +20,12 @@ tvheadend.acleditor = function() {
|
|||
width: 100
|
||||
});
|
||||
|
||||
var dvrallcfgColumn = new Ext.grid.CheckColumn({
|
||||
header: "All Configs (VR)",
|
||||
dataIndex: 'dvrallcfg',
|
||||
width: 100
|
||||
});
|
||||
|
||||
var webuiColumn = new Ext.grid.CheckColumn({
|
||||
header: "Web Interface",
|
||||
dataIndex: 'webui',
|
||||
|
@ -52,6 +58,7 @@ tvheadend.acleditor = function() {
|
|||
},
|
||||
streamingColumn,
|
||||
dvrColumn,
|
||||
dvrallcfgColumn,
|
||||
webuiColumn,
|
||||
adminColumn,
|
||||
{
|
||||
|
@ -63,14 +70,14 @@ tvheadend.acleditor = function() {
|
|||
]);
|
||||
|
||||
var UserRecord = Ext.data.Record.create([
|
||||
'enabled','streaming','dvr','admin','webui','username',
|
||||
'enabled','streaming','dvr','dvrallcfg','admin','webui','username',
|
||||
'prefix','password','comment'
|
||||
]);
|
||||
|
||||
return new tvheadend.tableEditor('Access control', 'accesscontrol', cm,
|
||||
UserRecord,
|
||||
[enabledColumn, streamingColumn,
|
||||
dvrColumn, webuiColumn,
|
||||
dvrColumn, dvrallcfgColumn, webuiColumn,
|
||||
adminColumn],
|
||||
null,
|
||||
'config_access.html', 'group');
|
||||
|
|
|
@ -14,6 +14,12 @@ tvheadend.cwceditor = function() {
|
|||
width: 100
|
||||
});
|
||||
|
||||
var emmexColumn = new Ext.grid.CheckColumn({
|
||||
header: "Update One",
|
||||
dataIndex: 'emmex',
|
||||
width: 100
|
||||
});
|
||||
|
||||
function setMetaAttr(meta, record){
|
||||
var enabled = record.get('enabled');
|
||||
if(!enabled) return;
|
||||
|
@ -72,6 +78,7 @@ tvheadend.cwceditor = function() {
|
|||
editor: new fm.TextField({allowBlank: false})
|
||||
},
|
||||
emmColumn,
|
||||
emmexColumn,
|
||||
{
|
||||
header: "Comment",
|
||||
dataIndex: 'comment',
|
||||
|
@ -86,7 +93,7 @@ tvheadend.cwceditor = function() {
|
|||
|
||||
var rec = Ext.data.Record.create([
|
||||
'enabled', 'connected', 'hostname', 'port', 'username',
|
||||
'password', 'deskey', 'emm', 'comment'
|
||||
'password', 'deskey', 'emm', 'emmex', 'comment'
|
||||
]);
|
||||
|
||||
var store = new Ext.data.JsonStore({
|
||||
|
@ -99,7 +106,7 @@ tvheadend.cwceditor = function() {
|
|||
});
|
||||
|
||||
var grid = new tvheadend.tableEditor('Code Word Client', 'cwc', cm, rec,
|
||||
[enabledColumn, emmColumn], store,
|
||||
[enabledColumn, emmColumn, emmexColumn], store,
|
||||
'config_cwc.html', 'key');
|
||||
|
||||
tvheadend.comet.on('cwcStatus', function(msg) {
|
||||
|
|
|
@ -169,14 +169,24 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
|
|||
var selectedKeys = grid.selModel.selections.keys;
|
||||
var target = panel.getForm().getValues('targetID').targetID;
|
||||
|
||||
if(adapterData.satConf) {
|
||||
var satconf = panel.getForm().getValues('targetSatConfID').targetSatConfID;
|
||||
var mparams = {
|
||||
entries:Ext.encode(selectedKeys),
|
||||
satconf:satconf
|
||||
};
|
||||
} else {
|
||||
var mparams = {
|
||||
entries:Ext.encode(selectedKeys)
|
||||
};
|
||||
}
|
||||
|
||||
Ext.Ajax.request({
|
||||
url: "dvb/copymux/" + target,
|
||||
params: {
|
||||
entries:Ext.encode(selectedKeys)
|
||||
},
|
||||
failure:function(response,options) {
|
||||
params: mparams,
|
||||
failure:function(response,options) {
|
||||
Ext.MessageBox.alert('Server Error','Unable to copy');
|
||||
},
|
||||
},
|
||||
success: function() {
|
||||
win.close();
|
||||
}
|
||||
|
@ -191,30 +201,71 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
|
|||
'name'],
|
||||
baseParams: {sibling: adapterId}
|
||||
});
|
||||
if(adapterData.satConf) {
|
||||
targetSatConfStore = new Ext.data.JsonStore({
|
||||
root:'entries',
|
||||
id: 'identifier',
|
||||
url:'dvb/satconf',
|
||||
fields: ['identifier',
|
||||
'name'],
|
||||
baseParams: {adapter: adapterId}
|
||||
});
|
||||
satConf = new Ext.form.ComboBox({
|
||||
store: targetSatConfStore,
|
||||
fieldLabel: 'Target Satellite config',
|
||||
name: 'targetsatconf',
|
||||
hiddenName: 'targetSatConfID',
|
||||
editable: false,
|
||||
allowBlank: false,
|
||||
triggerAction: 'all',
|
||||
mode: 'remote',
|
||||
displayField:'name',
|
||||
valueField:'identifier',
|
||||
emptyText: 'Select target adapter first...'
|
||||
});
|
||||
} else {
|
||||
satConf = null;
|
||||
}
|
||||
|
||||
var mitems = [
|
||||
new Ext.form.ComboBox({
|
||||
store: targetStore,
|
||||
fieldLabel: 'Target adapter',
|
||||
name: 'targetadapter',
|
||||
hiddenName: 'targetID',
|
||||
editable: false,
|
||||
allowBlank: false,
|
||||
triggerAction: 'all',
|
||||
mode: 'remote',
|
||||
displayField:'name',
|
||||
valueField:'identifier',
|
||||
emptyText: 'Select target adapter...',
|
||||
listeners: {
|
||||
'select': function(combo, value) {
|
||||
if (satConf) {
|
||||
satConf.emptyText = 'Select satellite configuration...';
|
||||
satConf.clearValue();
|
||||
targetSatConfStore.baseParams = {adapter: combo.value};
|
||||
targetSatConfStore.load();
|
||||
satConf.focus();
|
||||
satConf.expand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
if (satConf)
|
||||
mitems.push(satConf);
|
||||
|
||||
var panel = new Ext.FormPanel({
|
||||
frame:true,
|
||||
border:true,
|
||||
bodyStyle:'padding:5px',
|
||||
labelAlign: 'right',
|
||||
labelWidth: 110,
|
||||
labelWidth: 150,
|
||||
defaultType: 'textfield',
|
||||
items: [
|
||||
|
||||
new Ext.form.ComboBox({
|
||||
store: targetStore,
|
||||
fieldLabel: 'Target adapter',
|
||||
name: 'targetadapter',
|
||||
hiddenName: 'targetID',
|
||||
editable: false,
|
||||
allowBlank: false,
|
||||
triggerAction: 'all',
|
||||
mode: 'remote',
|
||||
displayField:'name',
|
||||
valueField:'identifier',
|
||||
emptyText: 'Select target adapter...'
|
||||
})
|
||||
],
|
||||
items: mitems,
|
||||
buttons: [{
|
||||
text: 'Copy',
|
||||
handler: doCopy
|
||||
|
@ -225,7 +276,7 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) {
|
|||
title: 'Copy multiplex configuration',
|
||||
layout: 'fit',
|
||||
width: 500,
|
||||
height: 120,
|
||||
height: 150,
|
||||
modal: true,
|
||||
plain: true,
|
||||
items: panel
|
||||
|
|
|
@ -156,10 +156,12 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, th_subscription_t
|
|||
|
||||
//Check socket status
|
||||
getsockopt(hc->hc_fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
|
||||
|
||||
//Abort upon socket error, or after 20 seconds of silence
|
||||
if(err || timeouts >= 20){
|
||||
run = 0;
|
||||
if(err) {
|
||||
tvhlog(LOG_DEBUG, "webui", "Client hung up, exit streaming");
|
||||
run = 0;
|
||||
}else if(timeouts >= 20) {
|
||||
tvhlog(LOG_WARNING, "webui", "Timeout waiting for packets");
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&sq->sq_mutex);
|
||||
|
@ -168,13 +170,13 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, th_subscription_t
|
|||
|
||||
timeouts = 0; //Reset timeout counter
|
||||
TAILQ_REMOVE(&sq->sq_queue, sm, sm_link);
|
||||
pthread_mutex_unlock(&sq->sq_mutex);
|
||||
|
||||
switch(sm->sm_type) {
|
||||
case SMT_PACKET: {
|
||||
if(!mkm)
|
||||
break;
|
||||
|
||||
pkt_ref_inc(sm->sm_data);
|
||||
run = !mk_mux_write_pkt(mkm, sm->sm_data);
|
||||
sm->sm_data = NULL;
|
||||
|
||||
|
@ -221,7 +223,6 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, th_subscription_t
|
|||
break;
|
||||
}
|
||||
streaming_msg_free(sm);
|
||||
pthread_mutex_unlock(&sq->sq_mutex);
|
||||
}
|
||||
|
||||
if(mkm)
|
||||
|
@ -378,11 +379,12 @@ http_stream_service(http_connection_t *hc, service_t *service)
|
|||
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
http_stream_run(hc, &sq, s);
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
if(s) {
|
||||
http_stream_run(hc, &sq, s);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
}
|
||||
|
||||
globalheaders_destroy(gh);
|
||||
tsfix_destroy(tsfix);
|
||||
|
@ -413,11 +415,12 @@ http_stream_channel(http_connection_t *hc, channel_t *ch)
|
|||
0);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
http_stream_run(hc, &sq, s);
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
if(s) {
|
||||
http_stream_run(hc, &sq, s);
|
||||
pthread_mutex_lock(&global_lock);
|
||||
subscription_unsubscribe(s);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
}
|
||||
|
||||
globalheaders_destroy(gh);
|
||||
tsfix_destroy(tsfix);
|
||||
|
@ -656,10 +659,9 @@ webui_static_content(const char *content_path, const char *http_path,
|
|||
}
|
||||
|
||||
tvhlog(LOG_ERR, "webui",
|
||||
"No source path providing HTTP content: \"%s\"."
|
||||
"No source path providing HTTP content: \"%s\". "
|
||||
"Checked in \"%s\" and in the binary's embedded file system. "
|
||||
"If you need to move or install the binary, "
|
||||
"reconfigure with --release", http_path, content_path);
|
||||
, http_path, content_path);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ BUILDDIR=build.${PLATFORM}
|
|||
DEFAULT_THEME="new"
|
||||
RELEASE=no
|
||||
|
||||
RELEASENAME=`head -n1 ${TOPDIR}/ChangeLog | awk '{print $2}' | sed s/\(// | sed s/\)//`
|
||||
|
||||
CONFIG_LIST="
|
||||
cwc
|
||||
avahi
|
||||
|
@ -125,12 +123,6 @@ EOF
|
|||
|
||||
finalize() {
|
||||
|
||||
if [ ${RELEASE} = yes ]; then
|
||||
echo Release build: ${RELEASENAME}
|
||||
echo >>${CONFIG_H} "#define TVHEADEND_RELEASE_TAG \"${RELEASENAME}\""
|
||||
fi
|
||||
|
||||
|
||||
cat >> ${CONFIG_MAK} << EOF
|
||||
OSENV=${OSENV}
|
||||
LDFLAGS_cfg += -lm
|
||||
|
|
4
support/dataroot/bundle.c
Normal file
4
support/dataroot/bundle.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
const char *tvheadend_dataroot(void)
|
||||
{
|
||||
return (void *)0;
|
||||
}
|
7
support/dataroot/datadir.c
Normal file
7
support/dataroot/datadir.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "config.h"
|
||||
|
||||
const char *tvheadend_dataroot(void)
|
||||
{
|
||||
return TVHEADEND_DATADIR;
|
||||
}
|
||||
|
4
support/dataroot/wd.c
Normal file
4
support/dataroot/wd.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
const char *tvheadend_dataroot(void)
|
||||
{
|
||||
return "./";
|
||||
}
|
8
support/getver.sh
Executable file
8
support/getver.sh
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
revision=`cd "$1" && git describe --dirty --abbrev=5 2>/dev/null | sed -e 's/-/./g'`
|
||||
|
||||
if ! test $revision; then
|
||||
test $revision || revision=`cd "$1" && git describe --abbrev=5 2>/dev/null | sed -e 's/-/./g'`
|
||||
fi
|
||||
|
||||
echo $revision
|
|
@ -1,22 +1,19 @@
|
|||
MAN = man/tvheadend.1
|
||||
ICON = support/gnome/tvheadend.svg
|
||||
|
||||
INSTBIN= ${DESTDIR}${INSTALLPREFIX}/bin
|
||||
INSTMAN= ${DESTDIR}${INSTALLPREFIX}/share/man/man1
|
||||
INSTDBG= ${DESTDIR}${INSTALLPREFIX}/lib/debug/bin
|
||||
MAN=man/tvheadend.1
|
||||
INSTICON= ${DESTDIR}$(prefix)/share/icons/hicolor/scalable/apps
|
||||
|
||||
install: ${PROG} ${MAN}
|
||||
mkdir -p ${INSTBIN}
|
||||
install -T ${PROG} ${INSTBIN}/tvheadend
|
||||
mkdir -p ${INSTMAN}
|
||||
install ${MAN} ${INSTMAN}
|
||||
|
||||
install-debug: ${PROG}
|
||||
mkdir -p ${INSTDBG}
|
||||
objcopy --only-keep-debug ${INSTBIN}/tvheadend ${INSTDBG}/tvheadend.debug
|
||||
strip -g ${INSTBIN}/tvheadend
|
||||
objcopy --add-gnu-debuglink=${INSTDBG}/tvheadend.debug ${INSTBIN}/tvheadend
|
||||
install: ${PROG}.datadir ${MAN}
|
||||
install -D ${PROG}.datadir ${bindir}/tvheadend
|
||||
install -D ${MAN} ${mandir}/tvheadend.1
|
||||
|
||||
for bundle in ${BUNDLES}; do \
|
||||
mkdir -p ${datadir}/$$bundle ;\
|
||||
cp -r $$bundle/* ${datadir}/$$bundle ;\
|
||||
done
|
||||
|
||||
|
||||
uninstall:
|
||||
rm -f ${INSTBIN}/tvheadend
|
||||
rm -f ${INSTDBG}/tvheadend.debug
|
||||
rm -f ${INSTMAN}/tvheadend.1
|
||||
rm -f ${bindir)/tvheadend
|
||||
rm -f ${mandir)/tvheadend.1
|
||||
|
|
|
@ -1,23 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
# check for SVN revision number
|
||||
revision=`cd "$1" && LC_ALL=C svn info 2> /dev/null | grep Revision | cut -d' ' -f2`
|
||||
test $revision || revision=`cd "$1" && grep revision .svn/entries 2>/dev/null | cut -d '"' -f2`
|
||||
test $revision || revision=`cd "$1" && sed -n -e '/^dir$/{n;p;q}' .svn/entries 2>/dev/null`
|
||||
test $revision && revision=SVN-r$revision
|
||||
revision=`$1/support/getver.sh`
|
||||
|
||||
# check for git short hash
|
||||
if ! test $revision; then
|
||||
revision=`cd "$1" && git log -1 --pretty=format:%h`
|
||||
test $revision && revision=git-$revision
|
||||
NEW_REVISION="#define BUILD_VERSION \"$revision\""
|
||||
OLD_REVISION=`cat $2 2> /dev/null`
|
||||
|
||||
# Update version.h only on revision changes to avoid spurious rebuilds
|
||||
if test "$NEW_REVISION" != "$OLD_REVISION"; then
|
||||
echo "$NEW_REVISION" > "$2"
|
||||
fi
|
||||
|
||||
# check for debian changelog
|
||||
if ! test $revision; then
|
||||
revision=`cd "$1" && cat debian/changelog |head -1|cut -f2 -d' '|sed s/\(//|sed s/\)//`
|
||||
fi
|
||||
|
||||
# no version number found
|
||||
test $revision || revision=UNKNOWN
|
||||
|
||||
echo $revision
|
||||
|
|
Loading…
Add table
Reference in a new issue