include make/drivers.mk
include make/flashimage.mk
include make/cleantargets.mk
+include make/ffmpeg.mk
############################################################################
# a print out of environment variables
@echo " later, you might find those useful:"
@echo " * make update-self - update the build system"
@echo " * make update-neutrino - update the neutrino source"
- @echo " * make update-git - update the coolstream git"
+ @echo " * make update-git - update the coolstream/armbox git"
@echo " * make update-git-target - copy updated git into \$$TARGETPREFIX"
@echo ""
@echo " cleantargets:"
update-neutrino:
$(MAKE) $(SOURCE_DIR)/neutrino-hd
-update-git:
+update-git-coolstream:
$(MAKE) $(GIT_BOOTLOADER)
$(MAKE) $(GIT_DRIVERS_THIRDPARTY)
$(MAKE) $(GIT_DRIVERS)
$(MAKE) $(GIT_KERNEL)
$(MAKE) $(GIT_PLUGINS)
+update-git-armbox:
+ $(MAKE) $(GIT_LIBSTB_HAL)
+# $(MAKE) $(GIT_BOOTLOADER)
+# $(MAKE) $(GIT_DRIVERS)
+# $(MAKE) $(GIT_KERNEL_HD51)
+ $(MAKE) $(GIT_PLUGINS)
+
+update-git: update-git-$(BOXTYPE)
+
update-git-target:
$(MAKE) modules includes-and-libs
@echo ""
# prerequisites.mk
-prerequisites:
- $(MAKE) $(SOURCE_DIR)/neutrino-hd $(GIT_BOOTLOADER) $(GIT_DRIVERS_THIRDPARTY) $(GIT_DRIVERS) $(GIT_KERNEL) $(GIT_PLUGINS)
+prerequisites-coolstream:
+ $(MAKE) $(SOURCE_DIR)/neutrino-hd
+ $(MAKE) $(GIT_BOOTLOADER)
+ $(MAKE) $(GIT_DRIVERS_THIRDPARTY)
+ $(MAKE) $(GIT_DRIVERS)
+ $(MAKE) $(GIT_KERNEL)
+ $(MAKE) $(GIT_PLUGINS)
+
+prerequisites-armbox:
+ $(MAKE) $(SOURCE_DIR)/neutrino-hd
+# $(MAKE) $(GIT_BOOTLOADER)
+# $(MAKE) $(GIT_DRIVERS_THIRDPARTY)
+# $(MAKE) $(GIT_DRIVERS)
+# $(MAKE) $(GIT_KERNEL)
+ $(MAKE) $(GIT_PLUGINS)
+
+prerequisites: prerequisites-$(BOXTYPE)
# bootstrap.mk
BOOTSTRAP = targetprefix $(BUILD_TMP) $(CROSS_BASE) $(HOSTPREFIX)/bin
# neutrino.mk
neutrino:
$(MAKE) $(D)/neutrino-hd
+
neutrino-libs:
$(MAKE) $(D)/neutrino-hd-libs
PHONY += applications
PHONY += multimedia
PHONY += plugins
-PHONY += kernel
-PHONY += bootloader
-PHONY += drivers
+#PHONY += kernel
+#PHONY += bootloader
+#PHONY += drivers
.PHONY: $(PHONY)
--- /dev/null
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -421,7 +421,7 @@ clean-libLTLIBRARIES:
+ rm -f $${locs}; \
+ }
+ libasound.la: $(libasound_la_OBJECTS) $(libasound_la_DEPENDENCIES) $(EXTRA_libasound_la_DEPENDENCIES)
+- $(AM_V_CCLD)$(libasound_la_LINK) -rpath $(libdir) $(libasound_la_OBJECTS) $(libasound_la_LIBADD) $(LIBS)
++ $(AM_V_CCLD)$(libasound_la_LINK) -rpath $(DESTDIR)$(libdir) $(libasound_la_OBJECTS) $(libasound_la_LIBADD) $(LIBS)
+
+ mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+--- a/src/pcm/scopes/Makefile.in
++++ b/src/pcm/scopes/Makefile.in
+@@ -348,7 +348,7 @@ clean-pkglibLTLIBRARIES:
+ rm -f $${locs}; \
+ }
+ scope-level.la: $(scope_level_la_OBJECTS) $(scope_level_la_DEPENDENCIES) $(EXTRA_scope_level_la_DEPENDENCIES)
+- $(AM_V_CCLD)$(scope_level_la_LINK) -rpath $(pkglibdir) $(scope_level_la_OBJECTS) $(scope_level_la_LIBADD) $(LIBS)
++ $(AM_V_CCLD)$(scope_level_la_LINK) -rpath $(DESTDIR)$(pkglibdir) $(scope_level_la_OBJECTS) $(scope_level_la_LIBADD) $(LIBS)
+
+ mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
--- /dev/null
+--- a/utils/alsa.pc.in
++++ b/utils/alsa.pc.in
+@@ -1,7 +1,7 @@
+ prefix=@prefix@
+-exec_prefix=@exec_prefix@
+-libdir=@libdir@
+-includedir=@includedir@
++exec_prefix=${prefix}
++libdir=${exec_prefix}/lib
++includedir=${prefix}/include
+
+ Name: alsa
+ Description: Advanced Linux Sound Architecture (ALSA) - Library
--- /dev/null
+--- ffmpeg-3.2.2/configure
++++ ffmpeg-3.2.2/configure
+@@ -3033,10 +3033,8 @@
+ # protocols
+ async_protocol_deps="threads"
+ bluray_protocol_deps="libbluray"
+-ffrtmpcrypt_protocol_deps="!librtmp_protocol"
+ ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl"
+ ffrtmpcrypt_protocol_select="tcp_protocol"
+-ffrtmphttp_protocol_deps="!librtmp_protocol"
+ ffrtmphttp_protocol_select="http_protocol"
+ ftp_protocol_select="tcp_protocol"
+ gopher_protocol_select="network"
+@@ -3053,14 +3051,12 @@
+ libssh_protocol_deps="libssh"
+ mmsh_protocol_select="http_protocol"
+ mmst_protocol_select="network"
+-rtmp_protocol_deps="!librtmp_protocol"
+-rtmp_protocol_select="tcp_protocol"
+-rtmpe_protocol_select="ffrtmpcrypt_protocol"
+-rtmps_protocol_deps="!librtmp_protocol"
+-rtmps_protocol_select="tls_protocol"
+-rtmpt_protocol_select="ffrtmphttp_protocol"
+-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
+-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
++ffrtmp_protocol_select="tcp_protocol"
++ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
++ffrtmps_protocol_select="tls_protocol"
++ffrtmpt_protocol_select="ffrtmphttp_protocol"
++ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
++ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
+ rtp_protocol_select="udp_protocol"
+ sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
+ sctp_protocol_select="network"
+--- ffmpeg-3.2.2/libavformat/rtmpproto.c
++++ ffmpeg-3.2.2/libavformat/rtmpproto.c
+@@ -2612,7 +2612,7 @@
+ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
+ {
+ RTMPContext *rt = s->priv_data;
+- char proto[8], hostname[256], path[1024], auth[100], *fname;
++ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
+ char *old_app, *qmark, *n, fname_buffer[1024];
+ uint8_t buf[2048];
+ int port;
+@@ -2623,7 +2623,7 @@
+
+ rt->is_input = !(flags & AVIO_FLAG_WRITE);
+
+- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
++ memset(tmpProto, 0, sizeof(tmpProto)); proto = &tmpProto[2]; av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
+ path, sizeof(path), s->filename);
+
+@@ -3157,9 +3157,9 @@
+ };
+
+
+-RTMP_PROTOCOL(rtmp)
+-RTMP_PROTOCOL(rtmpe)
+-RTMP_PROTOCOL(rtmps)
+-RTMP_PROTOCOL(rtmpt)
+-RTMP_PROTOCOL(rtmpte)
+-RTMP_PROTOCOL(rtmpts)
++RTMP_PROTOCOL(ffrtmp)
++RTMP_PROTOCOL(ffrtmpe)
++RTMP_PROTOCOL(ffrtmps)
++RTMP_PROTOCOL(ffrtmpt)
++RTMP_PROTOCOL(ffrtmpte)
++RTMP_PROTOCOL(ffrtmpts)
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -566,12 +566,12 @@
+ OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
+ OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+ OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
+-OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o
+ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o
+ OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
+ OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
+--- a/libavformat/protocols.c
++++ b/libavformat/protocols.c
+@@ -44,12 +44,12 @@
+ extern const URLProtocol ff_md5_protocol;
+ extern const URLProtocol ff_pipe_protocol;
+ extern const URLProtocol ff_prompeg_protocol;
+-extern const URLProtocol ff_rtmp_protocol;
+-extern const URLProtocol ff_rtmpe_protocol;
+-extern const URLProtocol ff_rtmps_protocol;
+-extern const URLProtocol ff_rtmpt_protocol;
+-extern const URLProtocol ff_rtmpte_protocol;
+-extern const URLProtocol ff_rtmpts_protocol;
++extern const URLProtocol ff_ffrtmp_protocol;
++extern const URLProtocol ff_ffrtmpe_protocol;
++extern const URLProtocol ff_ffrtmps_protocol;
++extern const URLProtocol ff_ffrtmpt_protocol;
++extern const URLProtocol ff_ffrtmpte_protocol;
++extern const URLProtocol ff_ffrtmpts_protocol;
+ extern const URLProtocol ff_rtp_protocol;
+ extern const URLProtocol ff_sctp_protocol;
+ extern const URLProtocol ff_srtp_protocol;
--- /dev/null
+--- a/libavcodec/aacdec_template.c
++++ b/libavcodec/aacdec_template.c
+@@ -2453,7 +2453,7 @@
+ * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
+ * @param coef spectral coefficients
+ */
+-static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
++static __attribute__((optimize(0))) void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
+ IndividualChannelStream *ics, int decode)
+ {
+ const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
+--- a/libavcodec/mdct_template.c
++++ b/libavcodec/mdct_template.c
+@@ -102,7 +102,7 @@ av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
+ * @param output N/2 samples
+ * @param input N/2 samples
+ */
+-void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
++void __attribute__((optimize(0))) ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
+ {
+ int k, n8, n4, n2, n, j;
+ const uint16_t *revtab = s->revtab;
+--- a/libavcodec/aacps.c
++++ b/libavcodec/aacps.c
+@@ -659,7 +659,7 @@
+ par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
+ }
+
+-static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
++static void __attribute__((optimize(0))) decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
+ {
+ LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
+ LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
+--- a/libavcodec/fft_template.c
++++ b/libavcodec/fft_template.c
+@@ -536,7 +536,7 @@
+ pass(z,FFT_NAME(ff_cos_##n),n4/2);\
+ }
+
+-static void fft4(FFTComplex *z)
++static void __attribute__((optimize(0))) fft4(FFTComplex *z)
+ {
+ FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
+
+@@ -550,7 +550,7 @@
+ BF(z[2].im, z[0].im, t2, t5);
+ }
+
+-static void fft8(FFTComplex *z)
++static void __attribute__((optimize(0))) fft8(FFTComplex *z)
+ {
+ FFTDouble t1, t2, t3, t4, t5, t6;
+
--- /dev/null
+diff -uNr ffmpeg-3.4.2/configure ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/configure
+--- ffmpeg-3.4.2/configure 2018-02-12 01:29:18.000000000 +0100
++++ ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/configure 2018-02-14 21:07:28.278640757 +0100
+@@ -3128,10 +3128,8 @@
+ # protocols
+ async_protocol_deps="threads"
+ bluray_protocol_deps="libbluray"
+-ffrtmpcrypt_protocol_conflict="librtmp_protocol"
+ ffrtmpcrypt_protocol_deps_any="gcrypt gmp openssl"
+ ffrtmpcrypt_protocol_select="tcp_protocol"
+-ffrtmphttp_protocol_conflict="librtmp_protocol"
+ ffrtmphttp_protocol_select="http_protocol"
+ ftp_protocol_select="tcp_protocol"
+ gopher_protocol_select="network"
+@@ -3148,14 +3146,12 @@
+ libssh_protocol_deps="libssh"
+ mmsh_protocol_select="http_protocol"
+ mmst_protocol_select="network"
+-rtmp_protocol_conflict="librtmp_protocol"
+-rtmp_protocol_select="tcp_protocol"
+-rtmpe_protocol_select="ffrtmpcrypt_protocol"
+-rtmps_protocol_conflict="librtmp_protocol"
+-rtmps_protocol_select="tls_protocol"
+-rtmpt_protocol_select="ffrtmphttp_protocol"
+-rtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
+-rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
++ffrtmp_protocol_select="tcp_protocol"
++ffrtmpe_protocol_select="ffrtmpcrypt_protocol"
++ffrtmps_protocol_select="tls_protocol"
++ffrtmpt_protocol_select="ffrtmphttp_protocol"
++ffrtmpte_protocol_select="ffrtmpcrypt_protocol ffrtmphttp_protocol"
++ffrtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
+ rtp_protocol_select="udp_protocol"
+ sctp_protocol_deps="struct_sctp_event_subscribe struct_msghdr_msg_flags"
+ sctp_protocol_select="network"
+diff -uNr ffmpeg-3.4.2/libavformat/Makefile ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/Makefile
+--- ffmpeg-3.4.2/libavformat/Makefile 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/Makefile 2018-02-14 20:10:19.763205912 +0100
+@@ -575,12 +575,12 @@
+ OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
+ OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+ OBJS-$(CONFIG_PROMPEG_PROTOCOL) += prompeg.o
+-OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o
+-OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMP_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o
++OBJS-$(CONFIG_FFRTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o
+ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o
+ OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o
+ OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o
+diff -uNr ffmpeg-3.4.2/libavformat/protocols.c ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/protocols.c
+--- ffmpeg-3.4.2/libavformat/protocols.c 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/protocols.c 2018-02-14 20:12:01.235570344 +0100
+@@ -44,12 +44,12 @@
+ extern const URLProtocol ff_md5_protocol;
+ extern const URLProtocol ff_pipe_protocol;
+ extern const URLProtocol ff_prompeg_protocol;
+-extern const URLProtocol ff_rtmp_protocol;
+-extern const URLProtocol ff_rtmpe_protocol;
+-extern const URLProtocol ff_rtmps_protocol;
+-extern const URLProtocol ff_rtmpt_protocol;
+-extern const URLProtocol ff_rtmpte_protocol;
+-extern const URLProtocol ff_rtmpts_protocol;
++extern const URLProtocol ff_ffrtmp_protocol;
++extern const URLProtocol ff_ffrtmpe_protocol;
++extern const URLProtocol ff_ffrtmps_protocol;
++extern const URLProtocol ff_ffrtmpt_protocol;
++extern const URLProtocol ff_ffrtmpte_protocol;
++extern const URLProtocol ff_ffrtmpts_protocol;
+ extern const URLProtocol ff_rtp_protocol;
+ extern const URLProtocol ff_sctp_protocol;
+ extern const URLProtocol ff_srtp_protocol;
+diff -uNr ffmpeg-3.4.2/libavformat/rtmpproto.c ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/rtmpproto.c
+--- ffmpeg-3.4.2/libavformat/rtmpproto.c 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_allow_to_choose_rtmp_impl_at_runtime/libavformat/rtmpproto.c 2018-02-14 20:21:41.701280041 +0100
+@@ -2626,7 +2626,7 @@
+ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
+ {
+ RTMPContext *rt = s->priv_data;
+- char proto[8], hostname[256], path[1024], auth[100], *fname;
++ char *proto, tmpProto[10], hostname[256], path[1024], auth[100], *fname;
+ char *old_app, *qmark, *n, fname_buffer[1024];
+ uint8_t buf[2048];
+ int port;
+@@ -2637,7 +2637,9 @@
+
+ rt->is_input = !(flags & AVIO_FLAG_WRITE);
+
+- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
++ memset(tmpProto, 0, sizeof(tmpProto));
++ proto = &tmpProto[2];
++ av_url_split(tmpProto, sizeof(tmpProto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
+ path, sizeof(path), s->filename);
+
+@@ -3171,9 +3173,9 @@
+ };
+
+
+-RTMP_PROTOCOL(rtmp)
+-RTMP_PROTOCOL(rtmpe)
+-RTMP_PROTOCOL(rtmps)
+-RTMP_PROTOCOL(rtmpt)
+-RTMP_PROTOCOL(rtmpte)
+-RTMP_PROTOCOL(rtmpts)
++RTMP_PROTOCOL(ffrtmp)
++RTMP_PROTOCOL(ffrtmpe)
++RTMP_PROTOCOL(ffrtmps)
++RTMP_PROTOCOL(ffrtmpt)
++RTMP_PROTOCOL(ffrtmpte)
++RTMP_PROTOCOL(ffrtmpts)
--- /dev/null
+--- a/libavformat/avio.h
++++ b/libavformat/avio.h
+@@ -291,12 +291,6 @@
+ */
+ int writeout_count;
+
+- /**
+- * Original buffer size
+- * used internally after probing and ensure seekback to reset the buffer size
+- * This field is internal to libavformat and access from outside is not allowed.
+- */
+- int orig_buffer_size;
+
+ /**
+ * Threshold to favor readahead over seek.
+--- a/libavformat/aviobuf.c
++++ b/libavformat/aviobuf.c
+@@ -33,7 +33,7 @@
+ #include "url.h"
+ #include <stdarg.h>
+
+-#define IO_BUFFER_SIZE 32768
++#define IO_BUFFER_SIZE 262144
+
+ /**
+ * Do seeks within this distance ahead of the current buffer by skipping
+@@ -88,7 +88,6 @@
+ int64_t (*seek)(void *opaque, int64_t offset, int whence))
+ {
+ s->buffer = buffer;
+- s->orig_buffer_size =
+ s->buffer_size = buffer_size;
+ s->buf_ptr = buffer;
+ s->buf_ptr_max = buffer;
+@@ -557,16 +556,16 @@
+ }
+
+ /* make buffer smaller in case it ended up large after probing */
+- if (s->read_packet && s->orig_buffer_size && s->buffer_size > s->orig_buffer_size) {
++ if (s->read_packet && s->buffer_size > max_buffer_size) {
+ if (dst == s->buffer && s->buf_ptr != dst) {
+- int ret = ffio_set_buf_size(s, s->orig_buffer_size);
++ int ret = ffio_set_buf_size(s, max_buffer_size);
+ if (ret < 0)
+ av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
+
+ s->checksum_ptr = dst = s->buffer;
+ }
+- av_assert0(len >= s->orig_buffer_size);
+- len = s->orig_buffer_size;
++ av_assert0(len >= max_buffer_size);
++ len = max_buffer_size;
+ }
+
+ if (s->read_packet)
+@@ -1009,7 +1008,6 @@
+
+ av_free(s->buffer);
+ s->buffer = buffer;
+- s->orig_buffer_size =
+ s->buffer_size = buf_size;
+ s->buf_ptr = s->buf_ptr_max = buffer;
+ url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
+--- a/libavformat/utils.c
++++ b/libavformat/utils.c
+@@ -118,6 +118,25 @@
+ MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb)
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
++
++void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
++{
++ if (min_size < *size)
++ return ptr;
++
++ min_size = FFMAX(17 * min_size / 16 + 32, min_size);
++
++ ptr = av_realloc(ptr, min_size);
++ /* we could set this to the unmodified min_size but this is safer
++ * if the user lost the ptr and uses NULL now
++ */
++ if (!ptr)
++ min_size = 0;
++
++ *size = min_size;
++
++ return ptr;
++}
+
+ int64_t av_stream_get_end_pts(const AVStream *st)
+ {
--- /dev/null
+diff -uNr ffmpeg-3.4.2/libavformat/http.c ffmpeg-3.4.2_chunked_transfer_fix_eof/libavformat/http.c
+--- ffmpeg-3.4.2/libavformat/http.c 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_chunked_transfer_fix_eof/libavformat/http.c 2018-02-14 19:56:02.371892777 +0100
+@@ -1296,8 +1296,11 @@
+ "Chunked encoding data size: %"PRIu64"'\n",
+ s->chunksize);
+
+- if (!s->chunksize)
++ if (!s->chunksize) {
++ /* we need to remember endof*/
++ s->chunksize = UINT64_MAX;
+ return 0;
++ }
+ else if (s->chunksize == UINT64_MAX) {
+ av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
+ s->chunksize);
--- /dev/null
+diff -uNr ffmpeg-3.4.2/libavformat/dashdec.c ffmpeg-3.4.2_dashdec/libavformat/dashdec.c
+--- ffmpeg-3.4.2/libavformat/dashdec.c 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_dashdec/libavformat/dashdec.c 2018-02-15 19:43:08.889757019 +0100
+@@ -39,7 +39,7 @@
+ /*
+ * reference to : ISO_IEC_23009-1-DASH-2012
+ * Section: 5.3.9.6.2
+- * Table: Table 17 — Semantics of SegmentTimeline element
++ * Table: Table 17 — Semantics of SegmentTimeline element
+ * */
+ struct timeline {
+ /* starttime: Element or Attribute Name
+@@ -80,10 +80,13 @@
+ AVFormatContext *ctx;
+ AVPacket pkt;
+ int rep_idx;
+- int rep_count;
+ int stream_index;
+
+ enum AVMediaType type;
++ char id[20];
++ int bandwidth;
++ AVRational framerate;
++ AVStream *assoc_stream; /* demuxer stream associated with this representation */
+
+ int n_fragments;
+ struct fragment **fragments; /* VOD list of fragment for profile */
+@@ -113,13 +116,32 @@
+ uint32_t init_sec_buf_read_offset;
+ int64_t cur_timestamp;
+ int is_restart_needed;
++
++ /* used for live stream were each fragment starts with
++ * 0 pts, so we need to
++ */
++ int64_t pkt_start_time_offset;
++ int is_first_pkt;
+ };
+
+ typedef struct DASHContext {
+ const AVClass *class;
+ char *base_url;
+- struct representation *cur_video;
+- struct representation *cur_audio;
++
++ int n_videos;
++ struct representation **videos;
++ int n_audios;
++ struct representation **audios;
++
++ /* Temporary variables used during manifest parsing */
++ int tmp_video_rep_idx;
++ int tmp_audio_rep_idx;
++
++ /* Used to force using selected representation */
++ int video_rep_index;
++ int audio_rep_index;
++
++ int64_t last_load_time;
+
+ /* MediaPresentationDescription Attribute */
+ uint64_t media_presentation_duration;
+@@ -141,8 +163,34 @@
+ char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
+ char *allowed_extensions;
+ AVDictionary *avio_opts;
++ int max_url_size;
+ } DASHContext;
+
++static int sleep_ms(DASHContext *c, uint32_t time_ms)
++{
++ int ret = 0;
++ int64_t start_time = av_gettime_relative();
++ do {
++ if (ff_check_interrupt(c->interrupt_callback)) {
++ ret = 1;
++ break;
++ }
++ av_usleep(100*1000);
++ } while (av_gettime_relative() - start_time < (time_ms*1000));
++ return ret;
++}
++
++static int ishttp(char *url)
++{
++ const char *proto_name = avio_find_protocol_name(url);
++ return av_strstart(proto_name, "http", NULL);
++}
++
++static int aligned(int val)
++{
++ return ((val + 0x3F) >> 6) << 6;
++}
++
+ static uint64_t get_current_time_in_sec(void)
+ {
+ return av_gettime() / 1000000;
+@@ -328,17 +376,39 @@
+ }
+
+ av_freep(&pls->url_template);
+- av_freep(pls);
++ av_freep(&pls);
++}
++
++static void free_video_list(DASHContext *c)
++{
++ int i;
++ for (i = 0; i < c->n_videos; i++) {
++ struct representation *pls = c->videos[i];
++ free_representation(pls);
++ }
++ av_freep(&c->videos);
++ c->n_videos = 0;
+ }
+
+-static void set_httpheader_options(DASHContext *c, AVDictionary *opts)
++static void free_audio_list(DASHContext *c)
++{
++ int i;
++ for (i = 0; i < c->n_audios; i++) {
++ struct representation *pls = c->audios[i];
++ free_representation(pls);
++ }
++ av_freep(&c->audios);
++ c->n_audios = 0;
++}
++
++static void set_httpheader_options(DASHContext *c, AVDictionary **opts)
+ {
+ // broker prior HTTP options that should be consistent across requests
+- av_dict_set(&opts, "user-agent", c->user_agent, 0);
+- av_dict_set(&opts, "cookies", c->cookies, 0);
+- av_dict_set(&opts, "headers", c->headers, 0);
++ av_dict_set(opts, "user-agent", c->user_agent, 0);
++ av_dict_set(opts, "cookies", c->cookies, 0);
++ av_dict_set(opts, "headers", c->headers, 0);
+ if (c->is_live) {
+- av_dict_set(&opts, "seekable", "0", 0);
++ av_dict_set(opts, "seekable", "0", 0);
+ }
+ }
+ static void update_options(char **dest, const char *name, void *src)
+@@ -392,7 +462,8 @@
+ else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5))
+ return AVERROR_INVALIDDATA;
+
+- ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
++ av_freep(pb);
++ ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+ if (ret >= 0) {
+ // update cookies on http response with setcookies.
+ char *new_cookies = NULL;
+@@ -418,6 +489,7 @@
+
+ static char *get_content_url(xmlNodePtr *baseurl_nodes,
+ int n_baseurl_nodes,
++ int max_url_size,
+ char *rep_id_val,
+ char *rep_bandwidth_val,
+ char *val)
+@@ -425,10 +497,12 @@
+ int i;
+ char *text;
+ char *url = NULL;
+- char tmp_str[MAX_URL_SIZE];
+- char tmp_str_2[MAX_URL_SIZE];
++ char *tmp_str = av_mallocz(max_url_size);
++ char *tmp_str_2 = av_mallocz(max_url_size);
+
+- memset(tmp_str, 0, sizeof(tmp_str));
++ if (!tmp_str || !tmp_str_2) {
++ return NULL;
++ }
+
+ for (i = 0; i < n_baseurl_nodes; ++i) {
+ if (baseurl_nodes[i] &&
+@@ -436,32 +510,36 @@
+ baseurl_nodes[i]->children->type == XML_TEXT_NODE) {
+ text = xmlNodeGetContent(baseurl_nodes[i]->children);
+ if (text) {
+- memset(tmp_str, 0, sizeof(tmp_str));
+- memset(tmp_str_2, 0, sizeof(tmp_str_2));
+- ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text);
+- av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str));
++ memset(tmp_str, 0, max_url_size);
++ memset(tmp_str_2, 0, max_url_size);
++ ff_make_absolute_url(tmp_str_2, max_url_size, tmp_str, text);
++ av_strlcpy(tmp_str, tmp_str_2, max_url_size);
+ xmlFree(text);
+ }
+ }
+ }
+
+ if (val)
+- av_strlcat(tmp_str, (const char*)val, sizeof(tmp_str));
++ av_strlcat(tmp_str, (const char*)val, max_url_size);
+
+ if (rep_id_val) {
+ url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val);
+ if (!url) {
+- return NULL;
++ goto end;
+ }
+- av_strlcpy(tmp_str, url, sizeof(tmp_str));
+- av_free(url);
++ av_strlcpy(tmp_str, url, max_url_size);
+ }
+ if (rep_bandwidth_val && tmp_str[0] != '\0') {
++ // free any previously assigned url before reassigning
++ av_free(url);
+ url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val);
+ if (!url) {
+- return NULL;
++ goto end;
+ }
+ }
++end:
++ av_free(tmp_str);
++ av_free(tmp_str_2);
+ return url;
+ }
+
+@@ -522,55 +600,85 @@
+ return type;
+ }
+
++static struct fragment * get_Fragment(char *range)
++{
++ struct fragment * seg = av_mallocz(sizeof(struct fragment));
++
++ if (!seg)
++ return NULL;
++
++ seg->size = -1;
++ if (range) {
++ char *str_end_offset;
++ char *str_offset = av_strtok(range, "-", &str_end_offset);
++ seg->url_offset = strtoll(str_offset, NULL, 10);
++ seg->size = strtoll(str_end_offset, NULL, 10) - seg->url_offset;
++ }
++
++ return seg;
++}
++
+ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representation *rep,
+ xmlNodePtr fragmenturl_node,
+ xmlNodePtr *baseurl_nodes,
+ char *rep_id_val,
+ char *rep_bandwidth_val)
+ {
++ DASHContext *c = s->priv_data;
+ char *initialization_val = NULL;
+ char *media_val = NULL;
++ char *range_val = NULL;
++ int max_url_size = c ? c->max_url_size: MAX_URL_SIZE;
+
+ if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) {
+ initialization_val = xmlGetProp(fragmenturl_node, "sourceURL");
+- if (initialization_val) {
+- rep->init_section = av_mallocz(sizeof(struct fragment));
++ range_val = xmlGetProp(fragmenturl_node, "range");
++ if (initialization_val || range_val) {
++ rep->init_section = get_Fragment(range_val);
+ if (!rep->init_section) {
+ xmlFree(initialization_val);
++ xmlFree(range_val);
+ return AVERROR(ENOMEM);
+ }
+ rep->init_section->url = get_content_url(baseurl_nodes, 4,
++ max_url_size,
+ rep_id_val,
+ rep_bandwidth_val,
+ initialization_val);
++
+ if (!rep->init_section->url) {
+ av_free(rep->init_section);
+ xmlFree(initialization_val);
++ xmlFree(range_val);
+ return AVERROR(ENOMEM);
+ }
+- rep->init_section->size = -1;
+ xmlFree(initialization_val);
++ xmlFree(range_val);
+ }
+ } else if (!av_strcasecmp(fragmenturl_node->name, (const char *)"SegmentURL")) {
+ media_val = xmlGetProp(fragmenturl_node, "media");
+- if (media_val) {
+- struct fragment *seg = av_mallocz(sizeof(struct fragment));
++ range_val = xmlGetProp(fragmenturl_node, "mediaRange");
++ if (media_val || range_val) {
++ struct fragment *seg = get_Fragment(range_val);
+ if (!seg) {
+ xmlFree(media_val);
++ xmlFree(range_val);
+ return AVERROR(ENOMEM);
+ }
+ seg->url = get_content_url(baseurl_nodes, 4,
++ max_url_size,
+ rep_id_val,
+ rep_bandwidth_val,
+ media_val);
+ if (!seg->url) {
+ av_free(seg);
+ xmlFree(media_val);
++ xmlFree(range_val);
+ return AVERROR(ENOMEM);
+ }
+- seg->size = -1;
+ dynarray_add(&rep->fragments, &rep->n_fragments, seg);
+ xmlFree(media_val);
++ xmlFree(range_val);
+ }
+ }
+
+@@ -613,26 +721,155 @@
+ return 0;
+ }
+
++static int fill_timelines(AVFormatContext *s, struct representation *rep, xmlNodePtr *nodes, const int n_nodes)
++{
++ xmlNodePtr fragment_timeline_node;
++ int ret = 0;
++ int i = 0;
++ for (; i < n_nodes; ++i) {
++ if (nodes[i]) {
++
++ fragment_timeline_node = find_child_node_by_name(nodes[i], "SegmentTimeline");
++ if (fragment_timeline_node) {
++ fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
++ while (fragment_timeline_node) {
++ ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
++ if (ret < 0) {
++ return ret;
++ }
++ fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
++ }
++ }
++ }
++ }
++
++ return ret;
++}
++
++static int resolve_content_path(AVFormatContext *s, const char *url, int *max_url_size, xmlNodePtr *baseurl_nodes, int n_baseurl_nodes) {
++
++ char *tmp_str = NULL;
++ char *path = NULL;
++ char *mpdName = NULL;
++ xmlNodePtr node = NULL;
++ char *baseurl = NULL;
++ char *root_url = NULL;
++ char *text = NULL;
++
++ int isRootHttp = 0;
++ char token ='/';
++ int start = 0;
++ int rootId = 0;
++ int updated = 0;
++ int size = 0;
++ int i;
++ int tmp_max_url_size = strlen(url);
++
++ for (i = n_baseurl_nodes-1; i >= 0 ; i--) {
++ text = xmlNodeGetContent(baseurl_nodes[i]);
++ if (!text)
++ continue;
++ tmp_max_url_size += strlen(text);
++ if (ishttp(text)) {
++ xmlFree(text);
++ break;
++ }
++ xmlFree(text);
++ }
++
++ tmp_max_url_size = aligned(tmp_max_url_size);
++ text = av_mallocz(tmp_max_url_size);
++ if (!text) {
++ updated = AVERROR(ENOMEM);
++ goto end;
++ }
++ av_strlcpy(text, url, strlen(url)+1);
++ while (mpdName = av_strtok(text, "/", &text)) {
++ size = strlen(mpdName);
++ }
++
++ path = av_mallocz(tmp_max_url_size);
++ tmp_str = av_mallocz(tmp_max_url_size);
++ if (!tmp_str || !path) {
++ updated = AVERROR(ENOMEM);
++ goto end;
++ }
++
++ av_strlcpy (path, url, strlen(url) - size + 1);
++ for (rootId = n_baseurl_nodes - 1; rootId > 0; rootId --) {
++ if (!(node = baseurl_nodes[rootId])) {
++ continue;
++ }
++ if (ishttp(xmlNodeGetContent(node))) {
++ break;
++ }
++ }
++
++ node = baseurl_nodes[rootId];
++ baseurl = xmlNodeGetContent(node);
++ root_url = (av_strcasecmp(baseurl, "")) ? baseurl : path;
++ if (node) {
++ xmlNodeSetContent(node, root_url);
++ updated = 1;
++ }
++
++ size = strlen(root_url);
++ isRootHttp = ishttp(root_url);
++
++ if (root_url[size - 1] != token) {
++ av_strlcat(root_url, "/", size + 2);
++ size += 2;
++ }
++
++ for (i = 0; i < n_baseurl_nodes; ++i) {
++ if (i == rootId) {
++ continue;
++ }
++ text = xmlNodeGetContent(baseurl_nodes[i]);
++ if (text) {
++ memset(tmp_str, 0, strlen(tmp_str));
++ if (!ishttp(text) && isRootHttp) {
++ av_strlcpy(tmp_str, root_url, size + 1);
++ }
++ start = (text[0] == token);
++ av_strlcat(tmp_str, text + start, tmp_max_url_size);
++ xmlNodeSetContent(baseurl_nodes[i], tmp_str);
++ updated = 1;
++ xmlFree(text);
++ }
++ }
++
++end:
++ if (tmp_max_url_size > *max_url_size) {
++ *max_url_size = tmp_max_url_size;
++ }
++ av_free(path);
++ av_free(tmp_str);
++ return updated;
++
++}
++
+ static int parse_manifest_representation(AVFormatContext *s, const char *url,
+ xmlNodePtr node,
+ xmlNodePtr adaptionset_node,
+ xmlNodePtr mpd_baseurl_node,
+ xmlNodePtr period_baseurl_node,
++ xmlNodePtr period_segmenttemplate_node,
++ xmlNodePtr period_segmentlist_node,
+ xmlNodePtr fragment_template_node,
+ xmlNodePtr content_component_node,
+- xmlNodePtr adaptionset_baseurl_node)
++ xmlNodePtr adaptionset_baseurl_node,
++ xmlNodePtr adaptionset_segmentlist_node)
+ {
+ int32_t ret = 0;
+- int32_t audio_rep_idx = 0;
+- int32_t video_rep_idx = 0;
+ DASHContext *c = s->priv_data;
+ struct representation *rep = NULL;
+ struct fragment *seg = NULL;
+ xmlNodePtr representation_segmenttemplate_node = NULL;
+ xmlNodePtr representation_baseurl_node = NULL;
+ xmlNodePtr representation_segmentlist_node = NULL;
+- xmlNodePtr fragment_timeline_node = NULL;
+- xmlNodePtr fragment_templates_tab[2];
++ xmlNodePtr segmentlists_tab[3];
++ xmlNodePtr fragment_templates_tab[5];
+ char *duration_val = NULL;
+ char *presentation_timeoffset_val = NULL;
+ char *startnumber_val = NULL;
+@@ -643,6 +880,7 @@
+ xmlNodePtr representation_node = node;
+ char *rep_id_val = xmlGetProp(representation_node, "id");
+ char *rep_bandwidth_val = xmlGetProp(representation_node, "bandwidth");
++ char *rep_framerate_val = xmlGetProp(representation_node, "frameRate");
+ enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
+
+ // try get information from representation
+@@ -656,7 +894,7 @@
+ type = get_content_type(adaptionset_node);
+ if (type == AVMEDIA_TYPE_UNKNOWN) {
+ av_log(s, AV_LOG_VERBOSE, "Parsing '%s' - skipp not supported representation type\n", url);
+- } else if ((type == AVMEDIA_TYPE_VIDEO && !c->cur_video) || (type == AVMEDIA_TYPE_AUDIO && !c->cur_audio)) {
++ } else if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO) {
+ // convert selected representation to our internal struct
+ rep = av_mallocz(sizeof(struct representation));
+ if (!rep) {
+@@ -672,17 +910,24 @@
+ baseurl_nodes[2] = adaptionset_baseurl_node;
+ baseurl_nodes[3] = representation_baseurl_node;
+
+- if (representation_segmenttemplate_node || fragment_template_node) {
+- fragment_timeline_node = NULL;
++ ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4);
++ c->max_url_size = aligned(c->max_url_size + strlen(rep_id_val) + strlen(rep_bandwidth_val));
++ if (ret == AVERROR(ENOMEM) || ret == 0) {
++ goto end;
++ }
++ if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) {
+ fragment_templates_tab[0] = representation_segmenttemplate_node;
+- fragment_templates_tab[1] = fragment_template_node;
+-
+- presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "presentationTimeOffset");
+- duration_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "duration");
+- startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "startNumber");
+- timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "timescale");
+- initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "initialization");
+- media_val = get_val_from_nodes_tab(fragment_templates_tab, 2, "media");
++ fragment_templates_tab[1] = adaptionset_segmentlist_node;
++ fragment_templates_tab[2] = fragment_template_node;
++ fragment_templates_tab[3] = period_segmenttemplate_node;
++ fragment_templates_tab[4] = period_segmentlist_node;
++
++ presentation_timeoffset_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset");
++ duration_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "duration");
++ startnumber_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "startNumber");
++ timescale_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "timescale");
++ initialization_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "initialization");
++ media_val = get_val_from_nodes_tab(fragment_templates_tab, 4, "media");
+
+ if (initialization_val) {
+ rep->init_section = av_mallocz(sizeof(struct fragment));
+@@ -691,7 +936,8 @@
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+- rep->init_section->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, initialization_val);
++ c->max_url_size = aligned(c->max_url_size + strlen(initialization_val));
++ rep->init_section->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, initialization_val);
+ if (!rep->init_section->url) {
+ av_free(rep->init_section);
+ av_free(rep);
+@@ -703,7 +949,8 @@
+ }
+
+ if (media_val) {
+- rep->url_template = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, media_val);
++ c->max_url_size = aligned(c->max_url_size + strlen(media_val));
++ rep->url_template = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, media_val);
+ xmlFree(media_val);
+ }
+
+@@ -719,32 +966,27 @@
+ rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10);
+ xmlFree(timescale_val);
+ }
++
++ ret = fill_timelines(s, rep, fragment_templates_tab, 5);
++ if (ret < 0) {
++ return ret;
++ }
++
+ if (startnumber_val) {
+- rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10);
++ if (rep->n_timelines)
++ rep->start_number = (int64_t) strtoll(startnumber_val, NULL, 10);
++ else
++ rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10);
+ xmlFree(startnumber_val);
+ }
+
+- fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline");
+-
+- if (!fragment_timeline_node)
+- fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline");
+- if (fragment_timeline_node) {
+- fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
+- while (fragment_timeline_node) {
+- ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
+- if (ret < 0) {
+- return ret;
+- }
+- fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
+- }
+- }
+ } else if (representation_baseurl_node && !representation_segmentlist_node) {
+ seg = av_mallocz(sizeof(struct fragment));
+ if (!seg) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+- seg->url = get_content_url(baseurl_nodes, 4, rep_id_val, rep_bandwidth_val, NULL);
++ seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
+ if (!seg->url) {
+ av_free(seg);
+ ret = AVERROR(ENOMEM);
+@@ -756,8 +998,14 @@
+ // TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html
+ // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full
+ xmlNodePtr fragmenturl_node = NULL;
+- duration_val = xmlGetProp(representation_segmentlist_node, "duration");
+- timescale_val = xmlGetProp(representation_segmentlist_node, "timescale");
++ segmentlists_tab[0] = representation_segmentlist_node;
++ segmentlists_tab[1] = adaptionset_segmentlist_node;
++ segmentlists_tab[2] = period_segmentlist_node;
++
++ duration_val = get_val_from_nodes_tab(segmentlists_tab, 3, "duration");
++ timescale_val = get_val_from_nodes_tab(segmentlists_tab, 3, "timescale");
++ startnumber_val = get_val_from_nodes_tab(segmentlists_tab, 3, "startNumber");
++
+ if (duration_val) {
+ rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10);
+ xmlFree(duration_val);
+@@ -766,6 +1014,10 @@
+ rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10);
+ xmlFree(timescale_val);
+ }
++ if (startnumber_val) {
++ rep->start_number = (int64_t) strtoll(startnumber_val, NULL, 10);
++ xmlFree(startnumber_val);
++ }
+ fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node);
+ while (fragmenturl_node) {
+ ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node,
+@@ -778,19 +1030,9 @@
+ fragmenturl_node = xmlNextElementSibling(fragmenturl_node);
+ }
+
+- fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline");
+-
+- if (!fragment_timeline_node)
+- fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline");
+- if (fragment_timeline_node) {
+- fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
+- while (fragment_timeline_node) {
+- ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
+- if (ret < 0) {
+- return ret;
+- }
+- fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
+- }
++ ret = fill_timelines(s, rep, segmentlists_tab, 3);
++ if (ret < 0) {
++ return ret;
+ }
+ } else {
+ free_representation(rep);
+@@ -801,24 +1043,37 @@
+ if (rep) {
+ if (rep->fragment_duration > 0 && !rep->fragment_timescale)
+ rep->fragment_timescale = 1;
+- if (type == AVMEDIA_TYPE_VIDEO) {
+- rep->rep_idx = video_rep_idx;
+- c->cur_video = rep;
++ rep->bandwidth = rep_bandwidth_val ? atoi(rep_bandwidth_val) : 0;
++ strncpy(rep->id, rep_id_val ? rep_id_val : "", sizeof(rep->id));
++ rep->framerate = av_make_q(0, 0);
++ if (type == AVMEDIA_TYPE_VIDEO && rep_framerate_val) {
++ ret = av_parse_video_rate(&rep->framerate, rep_framerate_val);
++ if (ret < 0)
++ av_log(s, AV_LOG_VERBOSE, "Ignoring invalid frame rate '%s'\n", rep_framerate_val);
++ }
++ if (type == AVMEDIA_TYPE_VIDEO && (c->video_rep_index == -1 || c->video_rep_index == c->tmp_video_rep_idx)) {
++ rep->rep_idx = c->tmp_video_rep_idx;
++ dynarray_add(&c->videos, &c->n_videos, rep);
++ } else if (type == AVMEDIA_TYPE_AUDIO && (c->audio_rep_index == -1 || c->audio_rep_index == c->tmp_audio_rep_idx)) {
++ rep->rep_idx = c->tmp_audio_rep_idx;
++ dynarray_add(&c->audios, &c->n_audios, rep);
+ } else {
+- rep->rep_idx = audio_rep_idx;
+- c->cur_audio = rep;
++ free_representation(rep);
++ rep = NULL;
+ }
+ }
+ }
+-
+- video_rep_idx += type == AVMEDIA_TYPE_VIDEO;
+- audio_rep_idx += type == AVMEDIA_TYPE_AUDIO;
++
++ c->tmp_video_rep_idx += type == AVMEDIA_TYPE_VIDEO;
++ c->tmp_audio_rep_idx += type == AVMEDIA_TYPE_AUDIO;
+
+ end:
+ if (rep_id_val)
+ xmlFree(rep_id_val);
+ if (rep_bandwidth_val)
+ xmlFree(rep_bandwidth_val);
++ if (rep_framerate_val)
++ xmlFree(rep_framerate_val);
+
+ return ret;
+ }
+@@ -826,12 +1081,15 @@
+ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url,
+ xmlNodePtr adaptionset_node,
+ xmlNodePtr mpd_baseurl_node,
+- xmlNodePtr period_baseurl_node)
++ xmlNodePtr period_baseurl_node,
++ xmlNodePtr period_segmenttemplate_node,
++ xmlNodePtr period_segmentlist_node)
+ {
+ int ret = 0;
+ xmlNodePtr fragment_template_node = NULL;
+ xmlNodePtr content_component_node = NULL;
+ xmlNodePtr adaptionset_baseurl_node = NULL;
++ xmlNodePtr adaptionset_segmentlist_node = NULL;
+ xmlNodePtr node = NULL;
+
+ node = xmlFirstElementChild(adaptionset_node);
+@@ -842,14 +1100,19 @@
+ content_component_node = node;
+ } else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) {
+ adaptionset_baseurl_node = node;
++ } else if (!av_strcasecmp(node->name, (const char *)"SegmentList")) {
++ adaptionset_segmentlist_node = node;
+ } else if (!av_strcasecmp(node->name, (const char *)"Representation")) {
+ ret = parse_manifest_representation(s, url, node,
+ adaptionset_node,
+ mpd_baseurl_node,
+ period_baseurl_node,
++ period_segmenttemplate_node,
++ period_segmentlist_node,
+ fragment_template_node,
+ content_component_node,
+- adaptionset_baseurl_node);
++ adaptionset_baseurl_node,
++ adaptionset_segmentlist_node);
+ if (ret < 0) {
+ return ret;
+ }
+@@ -874,18 +1137,21 @@
+ xmlNodePtr period_node = NULL;
+ xmlNodePtr mpd_baseurl_node = NULL;
+ xmlNodePtr period_baseurl_node = NULL;
++ xmlNodePtr period_segmenttemplate_node = NULL;
++ xmlNodePtr period_segmentlist_node = NULL;
+ xmlNodePtr adaptionset_node = NULL;
+ xmlAttrPtr attr = NULL;
+ char *val = NULL;
+ uint32_t perdiod_duration_sec = 0;
+ uint32_t perdiod_start_sec = 0;
+- int32_t audio_rep_idx = 0;
+- int32_t video_rep_idx = 0;
++
++ c->tmp_audio_rep_idx = 0;
++ c->tmp_video_rep_idx = 0;
+
+ if (!in) {
+ close_in = 1;
+
+- set_httpheader_options(c, opts);
++ set_httpheader_options(c, &opts);
+ ret = avio_open2(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts);
+ av_dict_free(&opts);
+ if (ret < 0)
+@@ -967,6 +1233,9 @@
+ }
+
+ mpd_baseurl_node = find_child_node_by_name(node, "BaseURL");
++ if (!mpd_baseurl_node) {
++ mpd_baseurl_node = xmlNewNode(NULL, "BaseURL");
++ }
+
+ // at now we can handle only one period, with the longest duration
+ node = xmlFirstElementChild(node);
+@@ -989,7 +1258,7 @@
+ period_node = node;
+ c->period_duration = perdiod_duration_sec;
+ c->period_start = perdiod_start_sec;
+- if (c->period_start > 0)
++ if (c->period_duration > 0)
+ c->media_presentation_duration = c->period_duration;
+ }
+ }
+@@ -1005,19 +1274,15 @@
+ while (adaptionset_node) {
+ if (!av_strcasecmp(adaptionset_node->name, (const char *)"BaseURL")) {
+ period_baseurl_node = adaptionset_node;
++ } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentTemplate")) {
++ period_segmenttemplate_node = adaptionset_node;
++ } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentList")) {
++ period_segmentlist_node = adaptionset_node;
+ } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"AdaptationSet")) {
+- parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node);
++ parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node);
+ }
+ adaptionset_node = xmlNextElementSibling(adaptionset_node);
+ }
+- if (c->cur_video) {
+- c->cur_video->rep_count = video_rep_idx;
+- av_log(s, AV_LOG_VERBOSE, "rep_idx[%d]\n", (int)c->cur_video->rep_idx);
+- av_log(s, AV_LOG_VERBOSE, "rep_count[%d]\n", (int)video_rep_idx);
+- }
+- if (c->cur_audio) {
+- c->cur_audio->rep_count = audio_rep_idx;
+- }
+ cleanup:
+ /*free the document */
+ xmlFreeDoc(doc);
+@@ -1029,6 +1294,7 @@
+ if (close_in) {
+ avio_close(in);
+ }
++ c->last_load_time = av_gettime_relative();
+ return ret;
+ }
+
+@@ -1042,15 +1308,17 @@
+ if (pls->n_fragments) {
+ num = pls->first_seq_no;
+ } else if (pls->n_timelines) {
++
+ start_time_offset = get_segment_start_time_based_on_timeline(pls, 0xFFFFFFFF) - pls->timelines[pls->first_seq_no]->starttime; // total duration of playlist
+- if (start_time_offset < 60 * pls->fragment_timescale)
++ if (start_time_offset < 60*pls->fragment_timescale)
+ start_time_offset = 0;
+ else
+ start_time_offset = start_time_offset - 60 * pls->fragment_timescale;
+-
++
+ num = calc_next_seg_no_from_timelines(pls, pls->timelines[pls->first_seq_no]->starttime + start_time_offset);
+ if (num == -1)
+ num = pls->first_seq_no;
++
+ } else if (pls->fragment_duration){
+ if (pls->presentation_timeoffset) {
+ num = pls->presentation_timeoffset * pls->fragment_timescale / pls->fragment_duration;
+@@ -1079,9 +1347,8 @@
+ return num;
+ }
+
+-static int64_t calc_max_seg_no(struct representation *pls)
++static int64_t calc_max_seg_no(struct representation *pls, DASHContext *c)
+ {
+- DASHContext *c = pls->parent->priv_data;
+ int64_t num = 0;
+
+ if (pls->n_fragments) {
+@@ -1101,83 +1368,119 @@
+ return num;
+ }
+
+-static void move_timelines(struct representation *rep_src, struct representation *rep_dest)
++static void move_timelines(struct representation *rep_src, struct representation *rep_dest, DASHContext *c)
+ {
+ if (rep_dest && rep_src ) {
+ free_timelines_list(rep_dest);
+ rep_dest->timelines = rep_src->timelines;
+ rep_dest->n_timelines = rep_src->n_timelines;
+ rep_dest->first_seq_no = rep_src->first_seq_no;
+- rep_dest->last_seq_no = calc_max_seg_no(rep_dest);
++ rep_dest->last_seq_no = calc_max_seg_no(rep_dest, c);
++ rep_dest->start_number = rep_src->start_number;
+ rep_src->timelines = NULL;
+ rep_src->n_timelines = 0;
+ rep_dest->cur_seq_no = rep_src->cur_seq_no;
+ }
+ }
+
+-static void move_segments(struct representation *rep_src, struct representation *rep_dest)
++static void move_segments(struct representation *rep_src, struct representation *rep_dest, DASHContext *c)
+ {
+- if (rep_dest && rep_src ) {
++ if (rep_dest && rep_src) {
+ free_fragment_list(rep_dest);
+- if (rep_src->start_number > (rep_dest->start_number + rep_dest->n_fragments))
++ if (rep_src->start_number > (rep_dest->start_number + rep_dest->cur_seq_no))
+ rep_dest->cur_seq_no = 0;
+ else
+- rep_dest->cur_seq_no += rep_src->start_number - rep_dest->start_number;
++ rep_dest->cur_seq_no = rep_src->n_fragments - ((rep_src->start_number + rep_src->n_fragments) - (rep_dest->start_number + rep_dest->cur_seq_no));
+ rep_dest->fragments = rep_src->fragments;
+ rep_dest->n_fragments = rep_src->n_fragments;
+ rep_dest->parent = rep_src->parent;
+- rep_dest->last_seq_no = calc_max_seg_no(rep_dest);
++ rep_dest->start_number = rep_src->start_number;
++ rep_dest->last_seq_no = calc_max_seg_no(rep_dest, c);
+ rep_src->fragments = NULL;
+ rep_src->n_fragments = 0;
+ }
+ }
+
++static int64_t default_reload_interval_us(AVFormatContext *s)
++{
++ return 2000 * 1000;
++}
+
+ static int refresh_manifest(AVFormatContext *s)
+ {
+
+- int ret = 0;
++ int ret = 0, i;
+ DASHContext *c = s->priv_data;
+
+ // save current context
+- struct representation *cur_video = c->cur_video;
+- struct representation *cur_audio = c->cur_audio;
++ int n_videos = c->n_videos;
++ struct representation **videos = c->videos;
++ int n_audios = c->n_audios;
++ struct representation **audios = c->audios;
+ char *base_url = c->base_url;
++ int64_t reload_interval_us = 0;
+
+ c->base_url = NULL;
+- c->cur_video = NULL;
+- c->cur_audio = NULL;
++ c->n_videos = 0;
++ c->videos = NULL;
++ c->n_audios = 0;
++ c->audios = NULL;
++
++ reload_interval_us = default_reload_interval_us(s);
++ while (av_gettime_relative() - c->last_load_time < reload_interval_us) {
++ if (ff_check_interrupt(c->interrupt_callback))
++ return AVERROR_EXIT;
++ av_usleep(100*1000);
++ }
++
+ ret = parse_manifest(s, s->filename, NULL);
+ if (ret)
+ goto finish;
+
+- if (cur_video && cur_video->timelines || cur_audio && cur_audio->timelines) {
+- // calc current time
+- int64_t currentVideoTime = 0;
+- int64_t currentAudioTime = 0;
+- if (cur_video && cur_video->timelines)
+- currentVideoTime = get_segment_start_time_based_on_timeline(cur_video, cur_video->cur_seq_no) / cur_video->fragment_timescale;
+- if (cur_audio && cur_audio->timelines)
+- currentAudioTime = get_segment_start_time_based_on_timeline(cur_audio, cur_audio->cur_seq_no) / cur_audio->fragment_timescale;
+- // update segments
+- if (cur_video && cur_video->timelines) {
+- c->cur_video->cur_seq_no = calc_next_seg_no_from_timelines(c->cur_video, currentVideoTime * cur_video->fragment_timescale - 1);
+- if (c->cur_video->cur_seq_no >= 0) {
+- move_timelines(c->cur_video, cur_video);
+- }
+- }
+- if (cur_audio && cur_audio->timelines) {
+- c->cur_audio->cur_seq_no = calc_next_seg_no_from_timelines(c->cur_audio, currentAudioTime * cur_audio->fragment_timescale - 1);
+- if (c->cur_audio->cur_seq_no >= 0) {
+- move_timelines(c->cur_audio, cur_audio);
+- }
+- }
++ if (c->n_videos != n_videos) {
++ av_log(c, AV_LOG_ERROR,
++ "new manifest has mismatched no. of video representations, %d -> %d\n",
++ n_videos, c->n_videos);
++ return AVERROR_INVALIDDATA;
+ }
+- if (cur_video && cur_video->fragments) {
+- move_segments(c->cur_video, cur_video);
++ if (c->n_audios != n_audios) {
++ av_log(c, AV_LOG_ERROR,
++ "new manifest has mismatched no. of audio representations, %d -> %d\n",
++ n_audios, c->n_audios);
++ return AVERROR_INVALIDDATA;
+ }
+- if (cur_audio && cur_audio->fragments) {
+- move_segments(c->cur_audio, cur_audio);
++
++ for (i = 0; i < n_videos; i++) {
++ struct representation *cur_video = videos[i];
++ struct representation *ccur_video = c->videos[i];
++ if (cur_video->timelines) {
++ // calc current time
++ int64_t current_time = get_segment_start_time_based_on_timeline(cur_video, cur_video->cur_seq_no) / cur_video->fragment_timescale;
++ // update segments
++ ccur_video->cur_seq_no = calc_next_seg_no_from_timelines(ccur_video, current_time * cur_video->fragment_timescale - 1);
++ if (ccur_video->cur_seq_no >= 0) {
++ move_timelines(ccur_video, cur_video, c);
++ }
++ }
++ if (cur_video->fragments) {
++ move_segments(ccur_video, cur_video, c);
++ }
++ }
++ for (i = 0; i < n_audios; i++) {
++ struct representation *cur_audio = audios[i];
++ struct representation *ccur_audio = c->audios[i];
++ if (cur_audio->timelines) {
++ // calc current time
++ int64_t current_time = get_segment_start_time_based_on_timeline(cur_audio, cur_audio->cur_seq_no) / cur_audio->fragment_timescale;
++ // update segments
++ ccur_audio->cur_seq_no = calc_next_seg_no_from_timelines(ccur_audio, current_time * cur_audio->fragment_timescale - 1);
++ if (ccur_audio->cur_seq_no >= 0) {
++ move_timelines(ccur_audio, cur_audio, c);
++ }
++ }
++ if (cur_audio->fragments) {
++ move_segments(ccur_audio, cur_audio, c);
++ }
+ }
+
+ finish:
+@@ -1186,12 +1489,14 @@
+ av_free(base_url);
+ else
+ c->base_url = base_url;
+- if (c->cur_audio)
+- free_representation(c->cur_audio);
+- if (c->cur_video)
+- free_representation(c->cur_video);
+- c->cur_audio = cur_audio;
+- c->cur_video = cur_video;
++ if (c->audios)
++ free_audio_list(c);
++ if (c->videos)
++ free_video_list(c);
++ c->n_audios = n_audios;
++ c->audios = audios;
++ c->n_videos = n_videos;
++ c->videos = videos;
+ return ret;
+ }
+
+@@ -1225,17 +1530,29 @@
+ }
+ }
+ if (c->is_live) {
+- min_seq_no = calc_min_seg_no(pls->parent, pls);
+- max_seq_no = calc_max_seg_no(pls);
+-
+- if (pls->timelines || pls->fragments) {
+- refresh_manifest(pls->parent);
+- }
+- if (pls->cur_seq_no <= min_seq_no) {
+- av_log(pls->parent, AV_LOG_VERBOSE, "old fragment: cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"], playlist %d\n", (int64_t)pls->cur_seq_no, min_seq_no, max_seq_no, (int)pls->rep_idx);
+- pls->cur_seq_no = calc_cur_seg_no(pls->parent, pls);
+- } else if (pls->cur_seq_no > max_seq_no) {
+- av_log(pls->parent, AV_LOG_VERBOSE, "new fragment: min[%"PRId64"] max[%"PRId64"], playlist %d\n", min_seq_no, max_seq_no, (int)pls->rep_idx);
++ while (!ff_check_interrupt(c->interrupt_callback)) {
++ min_seq_no = calc_min_seg_no(pls->parent, pls);
++ max_seq_no = calc_max_seg_no(pls, c);
++
++ if (pls->cur_seq_no <= min_seq_no) {
++ av_log(pls->parent, AV_LOG_VERBOSE, "to old fragment: cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"], playlist %d\n", (int64_t)pls->cur_seq_no, min_seq_no, max_seq_no, (int)pls->rep_idx);
++ if (pls->timelines || pls->fragments) {
++ refresh_manifest(pls->parent);
++ }
++ pls->cur_seq_no = calc_cur_seg_no(pls->parent, pls);
++ } else if (pls->cur_seq_no > max_seq_no) {
++ av_log(pls->parent, AV_LOG_VERBOSE, "wait for new fragment:cur[%"PRId64"] min[%"PRId64"] max[%"PRId64"], playlist %d\n", pls->cur_seq_no, min_seq_no, max_seq_no, (int)pls->rep_idx);
++ if (pls->timelines || pls->fragments) {
++ refresh_manifest(pls->parent);
++ } else {
++ /* maybe the better solution will be to sleep based on pls->fragment_duration
++ * for example: 1000 * pls->fragment_duration / pls->fragment_timescale ???
++ */
++ sleep_ms(c, 2000);
++ }
++ continue;
++ }
++ break;
+ }
+ seg = av_mallocz(sizeof(struct fragment));
+ if (!seg) {
+@@ -1248,19 +1565,22 @@
+ }
+ }
+ if (seg) {
+- char tmpfilename[MAX_URL_SIZE];
+-
+- ff_dash_fill_tmpl_params(tmpfilename, sizeof(tmpfilename), pls->url_template, 0, pls->cur_seq_no, 0, get_segment_start_time_based_on_timeline(pls, pls->cur_seq_no));
++ char *tmpfilename= av_mallocz(c->max_url_size);
++ if (!tmpfilename) {
++ return NULL;
++ }
++ ff_dash_fill_tmpl_params(tmpfilename, c->max_url_size, pls->url_template, 0, pls->cur_seq_no + pls->start_number, 0, get_segment_start_time_based_on_timeline(pls, pls->cur_seq_no));
+ seg->url = av_strireplace(pls->url_template, pls->url_template, tmpfilename);
+ if (!seg->url) {
+ av_log(pls->parent, AV_LOG_WARNING, "Unable to resolve template url '%s', try to use origin template\n", pls->url_template);
+ seg->url = av_strdup(pls->url_template);
+ if (!seg->url) {
+ av_log(pls->parent, AV_LOG_ERROR, "Cannot resolve template url '%s'\n", pls->url_template);
++ av_free(tmpfilename);
+ return NULL;
+ }
+ }
+-
++ av_free(tmpfilename);
+ seg->size = -1;
+ }
+
+@@ -1299,10 +1619,14 @@
+ static int open_input(DASHContext *c, struct representation *pls, struct fragment *seg)
+ {
+ AVDictionary *opts = NULL;
+- char url[MAX_URL_SIZE];
+- int ret;
++ char *url = NULL;
++ int ret = 0;
+
+- set_httpheader_options(c, opts);
++ url = av_mallocz(c->max_url_size);
++ if (!url) {
++ goto cleanup;
++ }
++ set_httpheader_options(c, &opts);
+ if (seg->size >= 0) {
+ /* try to restrict the HTTP request to the part we want
+ * (if this is in fact a HTTP request) */
+@@ -1310,7 +1634,7 @@
+ av_dict_set_int(&opts, "end_offset", seg->url_offset + seg->size, 0);
+ }
+
+- ff_make_absolute_url(url, MAX_URL_SIZE, c->base_url, seg->url);
++ ff_make_absolute_url(url, c->max_url_size, c->base_url, seg->url);
+ av_log(pls->parent, AV_LOG_VERBOSE, "DASH request for url '%s', offset %"PRId64", playlist %d\n",
+ url, seg->url_offset, pls->rep_idx);
+ ret = open_url(pls->parent, &pls->input, url, c->avio_opts, opts, NULL);
+@@ -1318,19 +1642,8 @@
+ goto cleanup;
+ }
+
+- /* Seek to the requested position. If this was a HTTP request, the offset
+- * should already be where want it to, but this allows e.g. local testing
+- * without a HTTP server. */
+- if (!ret && seg->url_offset) {
+- int64_t seekret = avio_seek(pls->input, seg->url_offset, SEEK_SET);
+- if (seekret < 0) {
+- av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of DASH fragment '%s'\n", seg->url_offset, seg->url);
+- ret = (int) seekret;
+- ff_format_io_close(pls->parent, &pls->input);
+- }
+- }
+-
+ cleanup:
++ av_free(url);
+ av_dict_free(&opts);
+ pls->cur_seg_offset = 0;
+ pls->cur_seg_size = seg->size;
+@@ -1416,13 +1729,28 @@
+
+ ret = open_input(c, v, v->cur_seg);
+ if (ret < 0) {
+- if (ff_check_interrupt(c->interrupt_callback)) {
+- goto end;
+- ret = AVERROR_EXIT;
++ av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist %d error [%s]\n", v->rep_idx, av_err2str(ret));
++ if (ret == AVERROR_HTTP_NOT_FOUND || \
++ ret == AVERROR_HTTP_BAD_REQUEST || \
++ ret == AVERROR_HTTP_OTHER_4XX || \
++ ret == AVERROR_HTTP_SERVER_ERROR) {
++ if (ret == AVERROR_HTTP_OTHER_4XX) {
++ /* 410 - Gone ? our download is to slow? */
++ v->cur_seq_no++;
++ } else if (c->is_live && v->timelines || v->fragments) {
++ refresh_manifest(v->parent);
++ } else if (!c->is_live) {
++ /* skip missing segment in VOD */
++ v->cur_seq_no++;
++ }
++ if (ff_check_interrupt(c->interrupt_callback)) {
++ goto end;
++ ret = AVERROR_EXIT;
++ }
++ goto restart;
+ }
+- av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of playlist %d\n", v->rep_idx);
+- v->cur_seq_no++;
+- goto restart;
++ ret = AVERROR_INVALIDDATA;
++ goto end;
+ }
+ }
+
+@@ -1447,9 +1775,11 @@
+ if (ret > 0)
+ goto end;
+
+- if (!v->is_restart_needed)
+- v->cur_seq_no++;
+- v->is_restart_needed = 1;
++ if (c->is_live || v->cur_seq_no < v->last_seq_no) {
++ if (!v->is_restart_needed)
++ v->cur_seq_no++;
++ v->is_restart_needed = 1;
++ }
+
+ end:
+ return ret;
+@@ -1466,8 +1796,12 @@
+ if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
+ if (buf[0] != '\0') {
+ ret = av_dict_set(&c->avio_opts, *opt, buf, AV_DICT_DONT_STRDUP_VAL);
+- if (ret < 0)
++ if (ret < 0) {
++ av_freep(&buf);
+ return ret;
++ }
++ } else {
++ av_freep(&buf);
+ }
+ }
+ opt++;
+@@ -1486,21 +1820,26 @@
+ return AVERROR(EPERM);
+ }
+
++static void close_demux_for_component(struct representation *pls)
++{
++ /* note: the internal buffer could have changed */
++ av_freep(&pls->pb.buffer);
++ memset(&pls->pb, 0x00, sizeof(AVIOContext));
++ pls->ctx->pb = NULL;
++ avformat_close_input(&pls->ctx);
++ pls->ctx = NULL;
++}
++
+ static int reopen_demux_for_component(AVFormatContext *s, struct representation *pls)
+ {
+ DASHContext *c = s->priv_data;
+ AVInputFormat *in_fmt = NULL;
+ AVDictionary *in_fmt_opts = NULL;
+ uint8_t *avio_ctx_buffer = NULL;
+- int ret = 0;
++ int ret = 0, i;
+
+ if (pls->ctx) {
+- /* note: the internal buffer could have changed, and be != avio_ctx_buffer */
+- av_freep(&pls->pb.buffer);
+- memset(&pls->pb, 0x00, sizeof(AVIOContext));
+- pls->ctx->pb = NULL;
+- avformat_close_input(&pls->ctx);
+- pls->ctx = NULL;
++ close_demux_for_component(pls);
+ }
+ if (!(pls->ctx = avformat_alloc_context())) {
+ ret = AVERROR(ENOMEM);
+@@ -1538,12 +1877,22 @@
+ pls->ctx->pb = &pls->pb;
+ pls->ctx->io_open = nested_io_open;
+
++ pls->is_first_pkt = 1;
++ pls->pkt_start_time_offset = 0;
++
+ // provide additional information from mpd if available
+ ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
+ av_dict_free(&in_fmt_opts);
+ if (ret < 0)
+ goto fail;
+ if (pls->n_fragments) {
++#if FF_API_R_FRAME_RATE
++ if (pls->framerate.den) {
++ for (i = 0; i < pls->ctx->nb_streams; i++)
++ pls->ctx->streams[i]->r_frame_rate = pls->framerate;
++ }
++#endif
++
+ ret = avformat_find_stream_info(pls->ctx, NULL);
+ if (ret < 0)
+ goto fail;
+@@ -1560,7 +1909,7 @@
+
+ pls->parent = s;
+ pls->cur_seq_no = calc_cur_seg_no(s, pls);
+- pls->last_seq_no = calc_max_seg_no(pls);
++ pls->last_seq_no = calc_max_seg_no(pls, s->priv_data);
+
+ ret = reopen_demux_for_component(s, pls);
+ if (ret < 0) {
+@@ -1589,6 +1938,7 @@
+ DASHContext *c = s->priv_data;
+ int ret = 0;
+ int stream_index = 0;
++ int i;
+
+ c->interrupt_callback = &s->interrupt_callback;
+ // if the URL context is good, read important options we must broker later
+@@ -1610,27 +1960,23 @@
+ s->duration = (int64_t) c->media_presentation_duration * AV_TIME_BASE;
+ }
+
+- /* Open the demuxer for curent video and current audio components if available */
+- if (!ret && c->cur_video) {
+- ret = open_demux_for_component(s, c->cur_video);
+- if (!ret) {
+- c->cur_video->stream_index = stream_index;
+- ++stream_index;
+- } else {
+- free_representation(c->cur_video);
+- c->cur_video = NULL;
+- }
++ /* Open the demuxer for video and audio components if available */
++ for (i = 0; i < c->n_videos; i++) {
++ struct representation *cur_video = c->videos[i];
++ ret = open_demux_for_component(s, cur_video);
++ if (ret)
++ goto fail;
++ cur_video->stream_index = stream_index;
++ ++stream_index;
+ }
+
+- if (!ret && c->cur_audio) {
+- ret = open_demux_for_component(s, c->cur_audio);
+- if (!ret) {
+- c->cur_audio->stream_index = stream_index;
+- ++stream_index;
+- } else {
+- free_representation(c->cur_audio);
+- c->cur_audio = NULL;
+- }
++ for (i = 0; i < c->n_audios; i++) {
++ struct representation *cur_audio = c->audios[i];
++ ret = open_demux_for_component(s, cur_audio);
++ if (ret)
++ goto fail;
++ cur_audio->stream_index = stream_index;
++ ++stream_index;
+ }
+
+ if (!stream_index) {
+@@ -1646,11 +1992,25 @@
+ goto fail;
+ }
+
+- if (c->cur_video) {
+- av_program_add_stream_index(s, 0, c->cur_video->stream_index);
+- }
+- if (c->cur_audio) {
+- av_program_add_stream_index(s, 0, c->cur_audio->stream_index);
++ for (i = 0; i < c->n_videos; i++) {
++ struct representation *pls = c->videos[i];
++
++ av_program_add_stream_index(s, 0, pls->stream_index);
++ pls->assoc_stream = s->streams[pls->stream_index];
++ if (pls->bandwidth > 0)
++ av_dict_set_int(&pls->assoc_stream->metadata, "variant_bitrate", pls->bandwidth, 0);
++ if (pls->id[0])
++ av_dict_set(&pls->assoc_stream->metadata, "id", pls->id, 0);
++ }
++ for (i = 0; i < c->n_audios; i++) {
++ struct representation *pls = c->audios[i];
++
++ av_program_add_stream_index(s, 0, pls->stream_index);
++ pls->assoc_stream = s->streams[pls->stream_index];
++ if (pls->bandwidth > 0)
++ av_dict_set_int(&pls->assoc_stream->metadata, "variant_bitrate", pls->bandwidth, 0);
++ if (pls->id[0])
++ av_dict_set(&pls->assoc_stream->metadata, "id", pls->id, 0);
+ }
+ }
+
+@@ -1659,43 +2019,89 @@
+ return ret;
+ }
+
++static void recheck_discard_flags(AVFormatContext *s, struct representation **p, int n)
++{
++ int i, j;
++
++ for (i = 0; i < n; i++) {
++ struct representation *pls = p[i];
++
++ int needed = !pls->assoc_stream || pls->assoc_stream->discard < AVDISCARD_ALL;
++ if (needed && !pls->ctx) {
++ pls->cur_seg_offset = 0;
++ pls->init_sec_buf_read_offset = 0;
++ /* Catch up */
++ for (j = 0; j < n; j++) {
++ pls->cur_seq_no = FFMAX(pls->cur_seq_no, p[j]->cur_seq_no);
++ }
++ reopen_demux_for_component(s, pls);
++ av_log(s, AV_LOG_INFO, "Now receiving stream_index %d\n", pls->stream_index);
++ } else if (!needed && pls->ctx) {
++ close_demux_for_component(pls);
++ if (pls->input)
++ ff_format_io_close(pls->parent, &pls->input);
++ av_log(s, AV_LOG_INFO, "No longer receiving stream_index %d\n", pls->stream_index);
++ }
++ }
++}
++
+ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
+ {
+ DASHContext *c = s->priv_data;
+- int ret = 0;
++ int ret = 0, i;
++ int64_t mints = 0;
+ struct representation *cur = NULL;
+
+- if (!c->cur_audio && !c->cur_video ) {
+- return AVERROR_INVALIDDATA;
++ recheck_discard_flags(s, c->videos, c->n_videos);
++ recheck_discard_flags(s, c->audios, c->n_audios);
++
++ for (i = 0; i < c->n_videos; i++) {
++ struct representation *pls = c->videos[i];
++ if (!pls->ctx)
++ continue;
++ if (!cur || pls->cur_timestamp < mints) {
++ cur = pls;
++ mints = pls->cur_timestamp;
++ }
+ }
+- if (c->cur_audio && !c->cur_video) {
+- cur = c->cur_audio;
+- } else if (!c->cur_audio && c->cur_video) {
+- cur = c->cur_video;
+- } else if (c->cur_video->cur_timestamp < c->cur_audio->cur_timestamp) {
+- cur = c->cur_video;
+- } else {
+- cur = c->cur_audio;
++ for (i = 0; i < c->n_audios; i++) {
++ struct representation *pls = c->audios[i];
++ if (!pls->ctx)
++ continue;
++ if (!cur || pls->cur_timestamp < mints) {
++ cur = pls;
++ mints = pls->cur_timestamp;
++ }
+ }
+
+- if (cur->ctx) {
+- while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
+- ret = av_read_frame(cur->ctx, pkt);
+- if (ret >= 0) {
+- /* If we got a packet, return it */
+- cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den);
+- pkt->stream_index = cur->stream_index;
+- return 0;
+- }
+- if (cur->is_restart_needed) {
+- cur->cur_seg_offset = 0;
+- cur->init_sec_buf_read_offset = 0;
+- if (cur->input)
+- ff_format_io_close(cur->parent, &cur->input);
+- ret = reopen_demux_for_component(s, cur);
+- cur->is_restart_needed = 0;
+- }
+-
++ if (!cur) {
++ return AVERROR_INVALIDDATA;
++ }
++ while (!ff_check_interrupt(c->interrupt_callback) && !ret) {
++ ret = av_read_frame(cur->ctx, pkt);
++ if (ret >= 0) {
++ if (c->is_live && cur->is_first_pkt && 0 == pkt->pts) {
++ cur->pkt_start_time_offset = get_segment_start_time_based_on_timeline(cur, cur->cur_seq_no);
++ }
++ if (cur->pkt_start_time_offset) {
++ AVRational bq;
++ bq.num = 1;
++ bq.den = (int)cur->fragment_timescale;
++ pkt->pts += av_rescale_q(cur->pkt_start_time_offset, bq,cur->ctx->streams[0]->time_base);
++ }
++ /* If we got a packet, return it */
++ cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den);
++ pkt->stream_index = cur->stream_index;
++ cur->is_first_pkt = 0;
++ return 0;
++ }
++ if (cur->is_restart_needed) {
++ cur->cur_seg_offset = 0;
++ cur->init_sec_buf_read_offset = 0;
++ if (cur->input)
++ ff_format_io_close(cur->parent, &cur->input);
++ ret = reopen_demux_for_component(s, cur);
++ cur->is_restart_needed = 0;
+ }
+ }
+ return AVERROR_EOF;
+@@ -1704,12 +2110,8 @@
+ static int dash_close(AVFormatContext *s)
+ {
+ DASHContext *c = s->priv_data;
+- if (c->cur_audio) {
+- free_representation(c->cur_audio);
+- }
+- if (c->cur_video) {
+- free_representation(c->cur_video);
+- }
++ free_audio_list(c);
++ free_video_list(c);
+
+ av_freep(&c->cookies);
+ av_freep(&c->user_agent);
+@@ -1718,19 +2120,22 @@
+ return 0;
+ }
+
+-static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t seek_pos_msec, int flags)
++static int dash_seek(AVFormatContext *s, struct representation *pls, int64_t seek_pos_msec, int flags, int dry_run)
+ {
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+ int64_t duration = 0;
+
+- av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms], playlist %d\n", seek_pos_msec, pls->rep_idx);
++ av_log(pls->parent, AV_LOG_VERBOSE, "DASH seek pos[%"PRId64"ms], playlist %d%s\n",
++ seek_pos_msec, pls->rep_idx, dry_run ? " (dry)" : "");
+
+ // single fragment mode
+ if (pls->n_fragments == 1) {
+ pls->cur_timestamp = 0;
+ pls->cur_seg_offset = 0;
++ if (dry_run)
++ return 0;
+ ff_read_frame_flush(pls->ctx);
+ return av_seek_frame(pls->ctx, -1, seek_pos_msec * 1000, flags);
+ }
+@@ -1769,20 +2174,20 @@
+ } else if (pls->fragment_duration > 0) {
+ pls->cur_seq_no = pls->first_seq_no + ((seek_pos_msec * pls->fragment_timescale) / pls->fragment_duration) / 1000;
+ } else {
+- av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing fragment_duration\n");
++ av_log(pls->parent, AV_LOG_ERROR, "dash_seek missing timeline or fragment_duration\n");
+ pls->cur_seq_no = pls->first_seq_no;
+ }
+ pls->cur_timestamp = 0;
+ pls->cur_seg_offset = 0;
+ pls->init_sec_buf_read_offset = 0;
+- ret = reopen_demux_for_component(s, pls);
++ ret = dry_run ? 0 : reopen_demux_for_component(s, pls);
+
+ return ret;
+ }
+
+ static int dash_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+ {
+- int ret = 0;
++ int ret = 0, i;
+ DASHContext *c = s->priv_data;
+ int64_t seek_pos_msec = av_rescale_rnd(timestamp, 1000,
+ s->streams[stream_index]->time_base.den,
+@@ -1790,12 +2195,17 @@
+ AV_ROUND_DOWN : AV_ROUND_UP);
+ if ((flags & AVSEEK_FLAG_BYTE) || c->is_live)
+ return AVERROR(ENOSYS);
+- if (c->cur_audio) {
+- ret = dash_seek(s, c->cur_audio, seek_pos_msec, flags);
+- }
+- if (!ret && c->cur_video) {
+- ret = dash_seek(s, c->cur_video, seek_pos_msec, flags);
++
++ /* Seek in discarded streams with dry_run=1 to avoid reopening them */
++ for (i = 0; i < c->n_videos; i++) {
++ if (!ret)
++ ret = dash_seek(s, c->videos[i], seek_pos_msec, flags, !c->videos[i]->ctx);
++ }
++ for (i = 0; i < c->n_audios; i++) {
++ if (!ret)
++ ret = dash_seek(s, c->audios[i], seek_pos_msec, flags, !c->audios[i]->ctx);
+ }
++
+ return ret;
+ }
+
+@@ -1820,6 +2230,10 @@
+ #define OFFSET(x) offsetof(DASHContext, x)
+ #define FLAGS AV_OPT_FLAG_DECODING_PARAM
+ static const AVOption dash_options[] = {
++ {"audio_rep_index", "audio representation index to be used",
++ OFFSET(audio_rep_index), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, FLAGS},
++ {"video_rep_index", "video representation index to be used",
++ OFFSET(video_rep_index), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, FLAGS},
+ {"allowed_extensions", "List of file extensions that dash is allowed to access",
+ OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
+ {.str = "aac,m4a,m4s,m4v,mov,mp4"},
+@@ -1845,4 +2259,4 @@
+ .read_close = dash_close,
+ .read_seek = dash_read_seek,
+ .flags = AVFMT_NO_BYTE_SEEK,
+-};
++};
+\ No newline at end of file
--- /dev/null
+--- a/libavformat/Makefile
++++ b/libavformat/Makefile
+@@ -135,7 +135,7 @@
+ OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o
+ OBJS-$(CONFIG_DATA_MUXER) += rawenc.o
+ OBJS-$(CONFIG_DASH_MUXER) += dash.o dashenc.o
+-OBJS-$(CONFIG_DASH_DEMUXER) += dashdec.o
++OBJS-$(CONFIG_DASH_DEMUXER) += dash.o dashdec.o
+ OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o
+ OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o
+ OBJS-$(CONFIG_DCSTR_DEMUXER) += dcstr.o
--- /dev/null
+Taapat: disable log to fix freezing on edit list parsing intruduced in:
+http://git.videolan.org/gitweb.cgi/ffmpeg.git/?p=ffmpeg.git;a=commitdiff;h=ca6cae73db207f17a0d5507609de12842d8f0ca3
+
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -3191,8 +3191,10 @@
+
+ if (ctts_data_old && ctts_index_old < ctts_count_old) {
+ curr_ctts = ctts_data_old[ctts_index_old].duration;
++ /*
+ av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
+ curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
++ */
+ curr_cts += curr_ctts;
+ ctts_sample_old++;
+ if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
--- /dev/null
+--- a/libavformat/hls.c
++++ b/libavformat/hls.c
+@@ -1924,8 +1924,10 @@
+ HLSContext *c = s->priv_data;
+ int ret, i, minplaylist = -1;
+
+- recheck_discard_flags(s, c->first_packet);
+- c->first_packet = 0;
++ if (c->first_packet) {
++ recheck_discard_flags(s, 1);
++ c->first_packet = 0;
++ }
+
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
--- /dev/null
+diff -uNr ffmpeg-3.4.2/libavformat/mpegts.c ffmpeg-3.4.2_fix_mpegts/libavformat/mpegts.c
+--- ffmpeg-3.4.2/libavformat/mpegts.c 2018-02-12 01:29:06.000000000 +0100
++++ ffmpeg-3.4.2_fix_mpegts/libavformat/mpegts.c 2018-02-14 19:36:28.175054407 +0100
+@@ -917,10 +917,12 @@
+ pes->buffer = NULL;
+ reset_pes_packet_state(pes);
+
++ /*
+ sd = av_packet_new_side_data(pkt, AV_PKT_DATA_MPEGTS_STREAM_ID, 1);
+ if (!sd)
+ return AVERROR(ENOMEM);
+ *sd = pes->stream_id;
++ */
+
+ return 0;
+ }
--- /dev/null
+--- ffmpeg-3.4.2/libavformat/hls.c
++++ ffmpeg-3.4.2/libavformat/hls.c
+@@ -206,6 +206,8 @@
+ int strict_std_compliance;
+ char *allowed_extensions;
+ int max_reload;
++ char *key_uri_replace_old;
++ char *key_uri_replace_new;
+ } HLSContext;
+
+ static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
+@@ -1127,8 +1129,17 @@
+ AVDictionary *opts2 = NULL;
+ char iv[33], key[33], url[MAX_URL_SIZE];
+ if (strcmp(seg->key, pls->key_url)) {
++ char *key_url = NULL;
+ AVIOContext *pb;
+- if (open_url(pls->parent, &pb, seg->key, c->avio_opts, opts, NULL) == 0) {
++
++ if (NULL != c->key_uri_replace_old && \
++ NULL != c-> key_uri_replace_new && \
++ '\0' != c->key_uri_replace_old[0]) {
++ key_url = av_strireplace(seg->key, c->key_uri_replace_old, c->key_uri_replace_new);
++ } else {
++ key_url = seg->key;
++ }
++ if (open_url(pls->parent, &pb, key_url, c->avio_opts, opts, NULL) == 0) {
+ ret = avio_read(pb, pls->key, sizeof(pls->key));
+ if (ret != sizeof(pls->key)) {
+ av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
+@@ -1140,6 +1151,8 @@
+ seg->key);
+ }
+ av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
++ if (key_url != seg->key)
++ av_free(key_url);
+ }
+ ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
+ ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
+@@ -1846,7 +1859,7 @@
+ for (i = 0; i < c->n_playlists; i++)
+ c->playlists[i]->cur_needed = 0;
+
+- for (i = 0; i < s->nb_streams; i++) {
++ for (i = 0; i < s->nb_streams && s->streams[i]->id < c->n_playlists; i++) {
+ AVStream *st = s->streams[i];
+ struct playlist *pls = c->playlists[s->streams[i]->id];
+ if (st->discard < AVDISCARD_ALL)
+@@ -2159,6 +2172,8 @@
+ INT_MIN, INT_MAX, FLAGS},
+ {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
+ OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
++ { "key_uri_old", "allow to replace part of AES key uri - old", OFFSET(key_uri_replace_old), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
++ { "key_uri_new", "allow to replace part of AES key uri - new", OFFSET(key_uri_replace_new), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, FLAGS },
+ {NULL}
+ };
+
--- /dev/null
+--- a/libass/ass.c
++++ b/libass/ass.c
+@@ -627,6 +627,26 @@
+ "No event format found, using fallback");
+ }
+
++// we may get duplicate events from a rewinded stream ...
++static int check_duplicate_event_adv(ASS_Track *track)
++{
++ int i, last = track->n_events - 1;
++ for (i = 0; i < last; ++i)
++ if (track->events[i].Start == track->events[last].Start
++ && track->events[i].Duration == track->events[last].Duration
++ && track->events[i].Layer == track->events[last].Layer
++ && track->events[i].Style == track->events[last].Style
++ && track->events[i].MarginL == track->events[last].MarginL
++ && track->events[i].MarginR == track->events[last].MarginR
++ && track->events[i].MarginV == track->events[last].MarginV
++ && !strcmp(track->events[i].Name, track->events[last].Name)
++ && !strcmp(track->events[i].Effect, track->events[last].Effect)
++ && !strcmp(track->events[i].Text, track->events[last].Text)
++ )
++ return 1;
++ return 0;
++}
++
+ static int process_events_line(ASS_Track *track, char *str)
+ {
+ if (!strncmp(str, "Format:", 7)) {
+@@ -653,6 +673,11 @@
+ event_format_fallback(track);
+
+ process_event_tail(track, event, str, 0);
++
++ if (check_duplicate_event_adv(track)) {
++ ass_free_event(track, eid);
++ track->n_events--;
++ }
+ } else {
+ ass_msg(track->library, MSGL_V, "Not understood: '%.30s'", str);
+ }
+@@ -939,6 +964,9 @@
+
+ event->Start = timecode;
+ event->Duration = duration;
++
++ if (check_duplicate_event_adv(track))
++ break;
+
+ free(str);
+ return;
# possible values are tank, trinity, link, zee2, zee and neo
# please select also link for trinity duo
# and neo for neo-twin, neo2, hd1 and bse as well
+# For Armboxes you can set hd51.
# if you don't specify a value or something is misspelled
# the default value neo will be used
#
# makefile for tarball download
+$(ARCHIVE)/alsa-lib-$(ALSA_LIB_VER).tar.bz2:
+ $(WGET) ftp://ftp.alsa-project.org/pub/lib/alsa-lib-$(ALSA_LIB_VER).tar.bz2
+
$(ARCHIVE)/autofs-$(AUTOFS4_VER).tar.gz:
$(WGET) https://www.kernel.org/pub/linux/daemons/autofs/v4/autofs-$(AUTOFS4_VER).tar.gz
$(ARCHIVE)/zlib-$(ZLIB_VER).tar.xz:
$(WGET) http://downloads.sourceforge.net/project/libpng/zlib/$(ZLIB_VER)/zlib-$(ZLIB_VER).tar.xz
+$(ARCHIVE)/libass-$(LIBASS_VER).tar.xz:
+ $(WGET) https://github.com/libass/libass/releases/download/$(LIBASS_VER)/libass-$(LIBASS_VER).tar.xz
+
$(ARCHIVE)/libmad-0.15.1b.tar.gz:
$(WGET) http://www.fhloston-paradise.de/libmad-0.15.1b.tar.gz
$(ARCHIVE)/fbshot-$(FBSHOT_VER).tar.gz:
$(WGET) http://distro.ibiblio.org/amigolinux/download/Utils/fbshot/fbshot-$(FBSHOT_VER).tar.gz
+$(ARCHIVE)/ffmpeg-$(FFMPEG_VER).tar.xz:
+ $(WGET) http://www.ffmpeg.org/releases/ffmpeg-$(FFMPEG_VER).tar.xz
+
$(ARCHIVE)/ffmpeg-git-$(FFMPEG_GIT).tar.gz:
set -e; cd $(BUILD_TMP); \
rm -rf ffmpeg-git-$(FFMPEG_GIT); \
else \
cp --remove-destination -a skel-root-kronos/* $(TARGETPREFIX)/; \
fi \
- else \
+ elif [ $(PLATFORM) = "nevis" ]; then \
if [ -n $(SKEL_ROOT_DIR) ]; then \
[ ! -e $(BASE_DIR)/my-skel-root-nevis ] && ln -s $(SKEL_ROOT_DIR) $(BASE_DIR)/my-skel-root-nevis; \
cp --remove-destination -a my-skel-root-nevis/* $(TARGETPREFIX)/; \
else \
cp --remove-destination -a skel-root-nevis/* $(TARGETPREFIX)/; \
fi \
+ else \
+ if [ $(PLATFORM) = "bcm7251s" ]; then \
+ [ ! -e $(BASE_DIR)/my-skel-root-hd51 ] && ln -s $(SKEL_ROOT_DIR) $(BASE_DIR)/my-skel-root-hd51; \
+ cp --remove-destination -a my-skel-root-hd51/* $(TARGETPREFIX)/; \
+ else \
+ cp --remove-destination -a skel-root-hd51/* $(TARGETPREFIX)/; \
+ fi \
fi
touch $(TARGETPREFIX)/.$(PLATFORM)
$(TARGETPREFIX)/lib: | $(TARGETPREFIX)
mkdir -p $@
- cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/libs/* $@/
- if [ "$(CST_FFMPEG_VERSION)" = "ffmpeg-3.3" ]; then \
- cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/libs-$(CST_FFMPEG_VERSION)/* $@/; \
+ if test -e $(SOURCE_DIR)/git/DRIVERS; then \
+ cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/libs/* $@/; \
+ if [ "$(CST_FFMPEG_VERSION)" = "ffmpeg-3.3" ]; then \
+ cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/libs-$(CST_FFMPEG_VERSION)/* $@/; \
+ fi \
fi
$(TARGETPREFIX)/lib/firmware: | $(TARGETPREFIX)
mkdir -p $@
- cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/firmware/* $@/
+ if test -e $(SOURCE_DIR)/git/DRIVERS; then \
+ cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/firmware/* $@/; \
+ fi
$(TARGETPREFIX)/lib/modules/$(KVERSION_FULL): | $(TARGETPREFIX)
mkdir -p $@
- cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/drivers/$(KVERSION_FULL)/* $@/
+ if test -e $(SOURCE_DIR)/git/DRIVERS; then \
+ cp -a $(SOURCE_DIR)/git/DRIVERS/$(DRIVER_DIR)/drivers/$(KVERSION_FULL)/* $@/; \
+ fi
$(TARGETPREFIX)/lib/libc.so.6: | $(TARGETPREFIX)
if test -e $(CROSS_DIR)/$(TARGET)/sys-root/lib; then \
CST_KERNEL_VERSION ?= 2.6.34.13
KVERSION_FULL = $(CST_KERNEL_VERSION)-nevis
KBRANCH ?= $(CST_KERNEL_VERSION)-cnxt
+else ifeq ($(BOXMODEL), hd51)
+ BOXTYPE = armbox
+ BOXSERIES = hd51
+ TARGET ?= arm-cortex-linux-gnueabihf
+ PLATFORM = bcm7251s
+ DRIVER_DIR ?= $(PLATFORM)
+ CST_KERNEL_VERSION ?= 4.10.12
+ KVERSION_FULL = $(CST_KERNEL_VERSION)-nevis
+ KBRANCH ?= $(CST_KERNEL_VERSION)-cnxt
else
$(error $(BOXTYPE) BOXMODEL $(BOXMODEL) not supported)
endif
-ifeq ($(BOXTYPE), coolstream)
+ifeq ($(BOXTYPE), $(filter $(BOXTYPE), coolstream armbox))
BOXARCH = arm
endif
TARGET_EXTRA_CFLAGS = -fdata-sections -ffunction-sections
TARGET_EXTRA_LDFLAGS = -Wl,--gc-sections
CXX11_ABI = -D_GLIBCXX_USE_CXX11_ABI=0
+else ifeq ($(BOXSERIES), hd51)
+ CORTEX-STRINGS = -lcortex-strings
+ TARGET_MARCH_CFLAGS = -march=armv7ve -mtune=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard
+ TARGET_EXTRA_CFLAGS = -fdata-sections -ffunction-sections
+ TARGET_EXTRA_LDFLAGS = -Wl,--gc-sections
+ CXX11_ABI =
else
$(error $(BOXTYPE) BOXSERIES $(BOXSERIES) not supported)
endif
REPO_DRIVERS_THIRD_PARTY_CST = drivers-third-party-cst.git
REPO_GUI_NEUTRINO = gui-neutrino.git
REPO_GUI_YWEB = gui-yweb.git
-REPO_LIBRARY_DVBSI = library-dvbsi.git
-REPO_LIBRARY_FFMPEG_CST = library-ffmpeg-cst.git
+#REPO_LIBRARY_DVBSI = library-dvbsi.git
+#REPO_LIBRARY_FFMPEG_CST = library-ffmpeg-cst.git
+REPO_LIBSTB_HAL = library-stb-hal.git
REPO_KERNEL_CST = linux-kernel-cst.git
REPO_PLUGIN_BLOCKADS = plugin-blockads.git
REPO_PLUGIN_COOLITSCLIMAX = plugin-cooliTSclimax.git
REPO_PLUGINS = plugins.git # (Enthält Submodules)
# some usefull folders
+GIT_LIBSTB_HAL = $(SOURCE_DIR)/git/LIBSTB_HAL
GIT_BOOTLOADER = $(SOURCE_DIR)/git/BOOTLOADER
GIT_DRIVERS_THIRDPARTY = $(SOURCE_DIR)/git/DRIVERS_THIRDPARTY
GIT_DRIVERS = $(SOURCE_DIR)/git/DRIVERS
--- /dev/null
+ifeq ($(BOXTYPE), coolstream)
+FFMPEG_CONFIGURE = \
+ --disable-doc \
+ --disable-htmlpages \
+ --disable-manpages \
+ --disable-podpages \
+ --disable-txtpages \
+ \
+ --disable-parsers \
+ --enable-parser=aac \
+ --enable-parser=aac_latm \
+ --enable-parser=ac3 \
+ --enable-parser=dca \
+ --enable-parser=mpeg4video \
+ --enable-parser=mpegvideo \
+ --enable-parser=mpegaudio \
+ --enable-parser=h264 \
+ --enable-parser=vc1 \
+ --enable-parser=dvdsub \
+ --enable-parser=dvbsub \
+ --enable-parser=flac \
+ --enable-parser=vorbis \
+ \
+ --disable-decoders \
+ --enable-decoder=dca \
+ --enable-decoder=dvdsub \
+ --enable-decoder=dvbsub \
+ --enable-decoder=text \
+ --enable-decoder=srt \
+ --enable-decoder=subrip \
+ --enable-decoder=subviewer \
+ --enable-decoder=subviewer1 \
+ --enable-decoder=xsub \
+ --enable-decoder=pgssub \
+ --enable-decoder=movtext \
+ --enable-decoder=mp3 \
+ --enable-decoder=flac \
+ --enable-decoder=vorbis \
+ --enable-decoder=aac \
+ --enable-decoder=mjpeg \
+ --enable-decoder=pcm_s16le \
+ --enable-decoder=pcm_s16le_planar \
+ \
+ --disable-demuxers \
+ --enable-demuxer=aac \
+ --enable-demuxer=ac3 \
+ --enable-demuxer=avi \
+ --enable-demuxer=mov \
+ --enable-demuxer=vc1 \
+ --enable-demuxer=mpegts \
+ --enable-demuxer=mpegtsraw \
+ --enable-demuxer=mpegps \
+ --enable-demuxer=mpegvideo \
+ --enable-demuxer=wav \
+ --enable-demuxer=pcm_s16be \
+ --enable-demuxer=mp3 \
+ --enable-demuxer=pcm_s16le \
+ --enable-demuxer=matroska \
+ --enable-demuxer=flv \
+ --enable-demuxer=rm \
+ --enable-demuxer=rtsp \
+ --enable-demuxer=hls \
+ --enable-demuxer=dts \
+ --enable-demuxer=wav \
+ --enable-demuxer=ogg \
+ --enable-demuxer=flac \
+ --enable-demuxer=srt \
+ --enable-demuxer=hds \
+ --enable-demuxer=dash \
+ \
+ --disable-encoders \
+ --disable-muxers \
+ --enable-muxer=mpegts \
+ \
+ --disable-programs \
+ --disable-static \
+ --disable-filters \
+ \
+ --enable-librtmp \
+ --disable-protocol=data \
+ --disable-protocol=cache \
+ --disable-protocol=concat \
+ --disable-protocol=crypto \
+ --disable-protocol=ftp \
+ --disable-protocol=gopher \
+ --disable-protocol=httpproxy \
+ --disable-protocol=pipe \
+ --disable-protocol=sctp \
+ --disable-protocol=srtp \
+ --disable-protocol=subfile \
+ --disable-protocol=unix \
+ --disable-protocol=md5 \
+ --disable-protocol=hls \
+ --enable-openssl \
+ --enable-protocol=file \
+ --enable-protocol=http \
+ --enable-protocol=https \
+ --enable-protocol=rtmp \
+ --enable-protocol=rtmpe \
+ --enable-protocol=rtmps \
+ --enable-protocol=rtmpte \
+ --enable-protocol=mmsh \
+ --enable-protocol=mmst \
+ --enable-protocol=rtp \
+ --enable-protocol=tcp \
+ --enable-protocol=udp \
+ --enable-bsfs \
+ --disable-devices \
+ --enable-swresample \
+ --disable-postproc \
+ --disable-swscale \
+ --disable-mmx \
+ --disable-altivec \
+ --enable-network \
+ --enable-cross-compile \
+ --enable-shared \
+ --enable-small \
+ --disable-bzlib \
+ --enable-zlib \
+ --disable-xlib \
+ --enable-libxml2 \
+ --disable-debug \
+ --enable-stripping \
+ --enable-decoder=h264 \
+ --enable-decoder=vc1 \
+ --target-os=linux \
+ --disable-neon \
+ --disable-runtime-cpudetect \
+ --arch=arm \
+ --pkg-config=pkg-config
+
+else ifeq ($(BOXTYPE), armbox)
+FFMPEG_CONFIGURE = \
+ --disable-ffserver \
+ --disable-ffplay \
+ --enable-ffprobe \
+ \
+ --disable-doc \
+ --disable-htmlpages \
+ --disable-manpages \
+ --disable-podpages \
+ --disable-txtpages \
+ \
+ --disable-altivec \
+ --disable-amd3dnow \
+ --disable-amd3dnowext \
+ --disable-mmx \
+ --disable-mmxext \
+ --disable-sse \
+ --disable-sse2 \
+ --disable-sse3 \
+ --disable-ssse3 \
+ --disable-sse4 \
+ --disable-sse42 \
+ --disable-avx \
+ --disable-xop \
+ --disable-fma3 \
+ --disable-fma4 \
+ --disable-avx2 \
+ --disable-armv5te \
+ --disable-armv6 \
+ --disable-armv6t2 \
+ --disable-inline-asm \
+ --disable-yasm \
+ --disable-mips32r2 \
+ --disable-mipsdsp \
+ --disable-mipsdspr2 \
+ --disable-fast-unaligned \
+ \
+ --disable-dxva2 \
+ --disable-vaapi \
+ --disable-vdpau \
+ \
+ --disable-muxers \
+ --enable-muxer=apng \
+ --enable-muxer=flac \
+ --enable-muxer=mp3 \
+ --enable-muxer=h261 \
+ --enable-muxer=h263 \
+ --enable-muxer=h264 \
+ --enable-muxer=hevc \
+ --enable-muxer=image2 \
+ --enable-muxer=image2pipe \
+ --enable-muxer=m4v \
+ --enable-muxer=matroska \
+ --enable-muxer=mjpeg \
+ --enable-muxer=mp4 \
+ --enable-muxer=mpeg1video \
+ --enable-muxer=mpeg2video \
+ --enable-muxer=mpegts \
+ --enable-muxer=ogg \
+ \
+ --disable-parsers \
+ --enable-parser=aac \
+ --enable-parser=aac_latm \
+ --enable-parser=ac3 \
+ --enable-parser=dca \
+ --enable-parser=dvbsub \
+ --enable-parser=dvd_nav \
+ --enable-parser=dvdsub \
+ --enable-parser=flac \
+ --enable-parser=h264 \
+ --enable-parser=hevc \
+ --enable-parser=mjpeg \
+ --enable-parser=mpeg4video \
+ --enable-parser=mpegvideo \
+ --enable-parser=mpegaudio \
+ --enable-parser=png \
+ --enable-parser=vc1 \
+ --enable-parser=vorbis \
+ --enable-parser=vp8 \
+ --enable-parser=vp9 \
+ \
+ --disable-encoders \
+ --enable-encoder=aac \
+ --enable-encoder=h261 \
+ --enable-encoder=h263 \
+ --enable-encoder=h263p \
+ --enable-encoder=jpeg2000 \
+ --enable-encoder=jpegls \
+ --enable-encoder=ljpeg \
+ --enable-encoder=mjpeg \
+ --enable-encoder=mpeg1video \
+ --enable-encoder=mpeg2video \
+ --enable-encoder=mpeg4 \
+ --enable-encoder=png \
+ --enable-encoder=rawvideo \
+ \
+ --disable-decoders \
+ --enable-decoder=aac \
+ --enable-decoder=aac_latm \
+ --enable-decoder=adpcm_ct \
+ --enable-decoder=adpcm_g722 \
+ --enable-decoder=adpcm_g726 \
+ --enable-decoder=adpcm_g726le \
+ --enable-decoder=adpcm_ima_amv \
+ --enable-decoder=adpcm_ima_oki \
+ --enable-decoder=adpcm_ima_qt \
+ --enable-decoder=adpcm_ima_rad \
+ --enable-decoder=adpcm_ima_wav \
+ --enable-decoder=adpcm_ms \
+ --enable-decoder=adpcm_sbpro_2 \
+ --enable-decoder=adpcm_sbpro_3 \
+ --enable-decoder=adpcm_sbpro_4 \
+ --enable-decoder=adpcm_swf \
+ --enable-decoder=adpcm_yamaha \
+ --enable-decoder=alac \
+ --enable-decoder=ape \
+ --enable-decoder=atrac1 \
+ --enable-decoder=atrac3 \
+ --enable-decoder=atrac3p \
+ --enable-decoder=ass \
+ --enable-decoder=cook \
+ --enable-decoder=dca \
+ --enable-decoder=dsd_lsbf \
+ --enable-decoder=dsd_lsbf_planar \
+ --enable-decoder=dsd_msbf \
+ --enable-decoder=dsd_msbf_planar \
+ --enable-decoder=dvbsub \
+ --enable-decoder=dvdsub \
+ --enable-decoder=eac3 \
+ --enable-decoder=evrc \
+ --enable-decoder=flac \
+ --enable-decoder=g723_1 \
+ --enable-decoder=g729 \
+ --enable-decoder=h261 \
+ --enable-decoder=h263 \
+ --enable-decoder=h263i \
+ --enable-decoder=h264 \
+ --enable-decoder=hevc \
+ --enable-decoder=iac \
+ --enable-decoder=imc \
+ --enable-decoder=jpeg2000 \
+ --enable-decoder=jpegls \
+ --enable-decoder=mace3 \
+ --enable-decoder=mace6 \
+ --enable-decoder=metasound \
+ --enable-decoder=mjpeg \
+ --enable-decoder=mlp \
+ --enable-decoder=movtext \
+ --enable-decoder=mp1 \
+ --enable-decoder=mp3 \
+ --enable-decoder=mp3adu \
+ --enable-decoder=mp3on4 \
+ --enable-decoder=mpeg1video \
+ --enable-decoder=mpeg4 \
+ --enable-decoder=nellymoser \
+ --enable-decoder=opus \
+ --enable-decoder=pcm_alaw \
+ --enable-decoder=pcm_bluray \
+ --enable-decoder=pcm_dvd \
+ --enable-decoder=pcm_f32be \
+ --enable-decoder=pcm_f32le \
+ --enable-decoder=pcm_f64be \
+ --enable-decoder=pcm_f64le \
+ --enable-decoder=pcm_lxf \
+ --enable-decoder=pcm_mulaw \
+ --enable-decoder=pcm_s16be \
+ --enable-decoder=pcm_s16be_planar \
+ --enable-decoder=pcm_s16le \
+ --enable-decoder=pcm_s16le_planar \
+ --enable-decoder=pcm_s24be \
+ --enable-decoder=pcm_s24daud \
+ --enable-decoder=pcm_s24le \
+ --enable-decoder=pcm_s24le_planar \
+ --enable-decoder=pcm_s32be \
+ --enable-decoder=pcm_s32le \
+ --enable-decoder=pcm_s32le_planar \
+ --enable-decoder=pcm_s8 \
+ --enable-decoder=pcm_s8_planar \
+ --enable-decoder=pcm_u16be \
+ --enable-decoder=pcm_u16le \
+ --enable-decoder=pcm_u24be \
+ --enable-decoder=pcm_u24le \
+ --enable-decoder=pcm_u32be \
+ --enable-decoder=pcm_u32le \
+ --enable-decoder=pcm_u8 \
+ --enable-decoder=pcm_zork \
+ --enable-decoder=pgssub \
+ --enable-decoder=png \
+ --enable-decoder=qcelp \
+ --enable-decoder=qdm2 \
+ --enable-decoder=ra_144 \
+ --enable-decoder=ra_288 \
+ --enable-decoder=ralf \
+ --enable-decoder=s302m \
+ --enable-decoder=sipr \
+ --enable-decoder=shorten \
+ --enable-decoder=sonic \
+ --enable-decoder=srt \
+ --enable-decoder=ssa \
+ --enable-decoder=subrip \
+ --enable-decoder=subviewer \
+ --enable-decoder=subviewer1 \
+ --enable-decoder=tak \
+ --enable-decoder=text \
+ --enable-decoder=truehd \
+ --enable-decoder=truespeech \
+ --enable-decoder=tta \
+ --enable-decoder=vorbis \
+ --enable-decoder=wmalossless \
+ --enable-decoder=wmapro \
+ --enable-decoder=wmav1 \
+ --enable-decoder=wmav2 \
+ --enable-decoder=wmavoice \
+ --enable-decoder=wavpack \
+ --enable-decoder=xsub \
+ \
+ --disable-demuxers \
+ --enable-demuxer=aac \
+ --enable-demuxer=ac3 \
+ --enable-demuxer=apng \
+ --enable-demuxer=ass \
+ --enable-demuxer=avi \
+ --enable-demuxer=dts \
+ --enable-demuxer=dash \
+ --enable-demuxer=ffmetadata \
+ --enable-demuxer=flac \
+ --enable-demuxer=flv \
+ --enable-demuxer=h264 \
+ --enable-demuxer=hls \
+ --enable-demuxer=image2 \
+ --enable-demuxer=image2pipe \
+ --enable-demuxer=image_bmp_pipe \
+ --enable-demuxer=image_jpeg_pipe \
+ --enable-demuxer=image_jpegls_pipe \
+ --enable-demuxer=image_png_pipe \
+ --enable-demuxer=m4v \
+ --enable-demuxer=matroska \
+ --enable-demuxer=mjpeg \
+ --enable-demuxer=mov \
+ --enable-demuxer=mp3 \
+ --enable-demuxer=mpegts \
+ --enable-demuxer=mpegtsraw \
+ --enable-demuxer=mpegps \
+ --enable-demuxer=mpegvideo \
+ --enable-demuxer=mpjpeg \
+ --enable-demuxer=ogg \
+ --enable-demuxer=pcm_s16be \
+ --enable-demuxer=pcm_s16le \
+ --enable-demuxer=realtext \
+ --enable-demuxer=rawvideo \
+ --enable-demuxer=rm \
+ --enable-demuxer=rtp \
+ --enable-demuxer=rtsp \
+ --enable-demuxer=srt \
+ --enable-demuxer=vc1 \
+ --enable-demuxer=wav \
+ --enable-demuxer=webm_dash_manifest \
+ \
+ --disable-filters \
+ --enable-filter=scale \
+ --enable-filter=drawtext \
+ \
+ --enable-zlib \
+ --disable-bzlib \
+ --enable-openssl \
+ --enable-libass \
+ --enable-bsfs \
+ --disable-xlib \
+ --disable-libxcb \
+ --disable-libxcb-shm \
+ --disable-libxcb-xfixes \
+ --disable-libxcb-shape \
+ \
+ --enable-shared \
+ --enable-network \
+ --enable-nonfree \
+ --enable-small \
+ --enable-stripping \
+ --disable-static \
+ --disable-debug \
+ --disable-runtime-cpudetect \
+ --enable-pic \
+ --enable-pthreads \
+ --enable-hardcoded-tables \
+ \
+ --pkg-config=pkg-config \
+ --enable-cross-compile \
+ --arch=arm \
+ --target-os=linux \
+ --bindir=/sbin
+else
+ $(error Boxtype = $(BOXTYPE) not supported)
+endif
+
+FFMPEG_DEP =
+ifeq ($(PLATFORM), $(filter $(PLATFORM), apollo kronos))
+FFMPEG_CONFIGURE += --cpu=cortex-a9 --enable-vfp --extra-cflags="-mfpu=vfpv3-d16 -mfloat-abi=hard -I$(TARGETPREFIX)/include"
+else ifeq ($(PLATFORM), bcm7251s)
+FFMPEG_DEP = $(D)/libass $(D)/alsa-lib
+FFMPEG_CONFIGURE += --cpu=cortex-a15 --disable-vfp --extra-cflags="-Wno-deprecated-declarations -I$(TARGETPREFIX)/include"
+else
+FFMPEG_CONFIGURE += --disable-iconv
+FFMPEG_CONFIGURE += --cpu=armv6 --disable-vfp --extra-cflags="-I$(TARGETPREFIX)/include"
+endif
+
+$(D)/ffmpeg-armbox: $(ARCHIVE)/ffmpeg-$(FFMPEG_VER).tar.xz | $(TARGETPREFIX)
+ $(START_BUILD)
+ $(REMOVE)/ffmpeg-$(FFMPEG_VER)
+ $(UNTAR)/ffmpeg-$(FFMPEG_VER).tar.xz
+ set -e; pushd $(BUILD_TMP)/ffmpeg-$(FFMPEG_VER) && \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-fix-hls.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-buffer-size.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-aac.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-fix-edit-list-parsing.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-fix_mpegts.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-allow_to_choose_rtmp_impl_at_runtime.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-dashdec_improvements.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-fix-dash-build.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-hls_replace_key_uri.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-$(FFMPEG_VER)-chunked_transfer_fix_eof.patch; \
+ $(BUILDENV) \
+ ./configure \
+ $(FFMPEG_CONFIGURE) \
+ --extra-ldflags="-L$(TARGETPREFIX)/lib -lz" \
+ --logfile=$(BUILD_TMP)/Config-ffmpeg-$(FFMPEG_VER).log \
+ --cross-prefix=$(TARGET)- \
+ --prefix=/ \
+ --mandir=/.remove \
+ --datadir=/.remove \
+ --docdir=/.remove; \
+ $(MAKE) && \
+ $(MAKE) install DESTDIR=$(TARGETPREFIX)
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavfilter.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavdevice.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavformat.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavcodec.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavutil.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libswresample.pc
+ test -e $(PKG_CONFIG_PATH)/libswscale.pc && $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libswscale.pc || true
+ $(REMOVE)/ffmpeg-$(FFMPEG_VER) $(TARGETPREFIX)/.remove
+
+$(D)/ffmpeg-coolstream: $(ARCHIVE)/ffmpeg-git-$(FFMPEG_GIT).tar.gz | $(TARGETPREFIX)
+ $(START_BUILD)
+ $(REMOVE)/ffmpeg-git-$(FFMPEG_GIT)
+ $(UNTAR)/ffmpeg-git-$(FFMPEG_GIT).tar.gz
+ set -e; pushd $(BUILD_TMP)/ffmpeg-git-$(FFMPEG_GIT) && \
+ $(PATCH)/ffmpeg/0001-ffmpeg-hds-libroxml-3.x.patch; \
+ $(PATCH)/ffmpeg/0002-ffmpeg-aac-3.x.patch; \
+ $(PATCH)/ffmpeg/0003-ffmpeg-increase-IO-BUFFER-SIZE-to-128k.patch; \
+ $(PATCH)/ffmpeg/0003-Revert-libavformat-aviobuf-keep-track-of-the-original-buffer-size-and-restore-it-after.patch; \
+ $(PATCH)/ffmpeg/0004-FFmpeg-devel-v14*.patch; \
+ $(PATCH)/ffmpeg/0005-ffmpeg-fix-pts-for-cooli.patch; \
+ $(PATCH)/ffmpeg/0006-ffmpeg-fix-sps-pps-for-cooli.patch; \
+ $(PATCH)/ffmpeg/0007-ffmpeg-reset-compressed-header-flag.patch; \
+ $(PATCH)/ffmpeg/0008-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.-Origi.patch; \
+ $(PATCH)/ffmpeg/ffmpeg-3.3-allow-to-choose-rtmp-impl-at-runtime.patch; \
+ $(BUILDENV) \
+ ./configure \
+ $(FFMPEG_CONFIGURE) \
+ --extra-ldflags="-L$(TARGETPREFIX)/lib -lz" \
+ --logfile=$(BUILD_TMP)/Config-ffmpeg-$(FFMPEG_GIT).log \
+ --cross-prefix=$(TARGET)- \
+ --prefix=/ \
+ --mandir=/.remove \
+ --datadir=/.remove \
+ --docdir=/.remove; \
+ $(MAKE) && \
+ $(MAKE) install DESTDIR=$(TARGETPREFIX)
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavfilter.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavdevice.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavformat.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavcodec.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavutil.pc
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libswresample.pc
+ test -e $(PKG_CONFIG_PATH)/libswscale.pc && $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libswscale.pc || true
+ $(REMOVE)/ffmpeg-git-$(FFMPEG_GIT) $(TARGETPREFIX)/.remove
+
+$(D)/ffmpeg: $(D)/libxml2 $(D)/librtmp $(D)/libroxml $(FFMPEG_DEP) ffmpeg-$(BOXTYPE)
+ $(TOUCH)
+
false; \
fi
+$(D)/libass: $(D)/freetype $(D)/libfribidi $(ARCHIVE)/libass-$(LIBASS_VER).tar.xz | $(TARGET_DIR)
+ $(START_BUILD)
+ $(UNTAR)/libass-$(LIBASS_VER).tar.xz
+ pushd $(BUILD_TMP)/libass-$(LIBASS_VER) && \
+ $(PATCH)/libass-0.14.0.patch && \
+ $(CONFIGURE) \
+ --target=$(TARGET) \
+ --prefix= \
+ --disable-static \
+ --disable-test \
+ --disable-fontconfig \
+ --disable-harfbuzz \
+ --disable-require-system-font-provider && \
+ $(MAKE) && \
+ $(MAKE) install DESTDIR=$(TARGETPREFIX)
+ $(REMOVE)/libass-$(LIBASS_VER)
+ $(REWRITE_LIBTOOL)/libass.la
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libass.pc
+ $(TOUCH)
+
$(D)/libncurses: $(ARCHIVE)/ncurses-$(NCURSES_VER).tar.gz | ncurses-prereq $(TARGETPREFIX)
$(START_BUILD)
$(UNTAR)/ncurses-$(NCURSES_VER).tar.gz && \
$(START_BUILD)
$(UNTAR)/cortex-strings-git-$(CRTXSTR_GIT).tar.gz
set -e; cd $(BUILD_TMP)/cortex-strings-git-$(CRTXSTR_GIT); \
- $(CONFIGURE) --prefix= --enable-shared --disable-static --without-neon; \
+ $(CONFIGURE)
+ --prefix= \
+ --enable-shared \
+ --disable-static \
+ --without-neon; \
$(MAKE); \
make install DESTDIR=$(TARGETPREFIX)
$(REWRITE_LIBTOOL)/libcortex-strings.la
$(REMOVE)/libbluray-0.5.0
$(TOUCH)
-ifeq ($(BOXARCH), arm)
-FFMPEG_CONFIGURE = \
- --disable-doc \
- --disable-htmlpages \
- --disable-manpages \
- --disable-podpages \
- --disable-txtpages \
- \
- --disable-parsers \
- --enable-parser=aac \
- --enable-parser=aac_latm \
- --enable-parser=ac3 \
- --enable-parser=dca \
- --enable-parser=mpeg4video \
- --enable-parser=mpegvideo \
- --enable-parser=mpegaudio \
- --enable-parser=h264 \
- --enable-parser=vc1 \
- --enable-parser=dvdsub \
- --enable-parser=dvbsub \
- --enable-parser=flac \
- --enable-parser=vorbis \
- \
- --disable-decoders \
- --enable-decoder=dca \
- --enable-decoder=dvdsub \
- --enable-decoder=dvbsub \
- --enable-decoder=text \
- --enable-decoder=srt \
- --enable-decoder=subrip \
- --enable-decoder=subviewer \
- --enable-decoder=subviewer1 \
- --enable-decoder=xsub \
- --enable-decoder=pgssub \
- --enable-decoder=movtext \
- --enable-decoder=mp3 \
- --enable-decoder=flac \
- --enable-decoder=vorbis \
- --enable-decoder=aac \
- --enable-decoder=mjpeg \
- --enable-decoder=pcm_s16le \
- --enable-decoder=pcm_s16le_planar \
- \
- --disable-demuxers \
- --enable-demuxer=aac \
- --enable-demuxer=ac3 \
- --enable-demuxer=avi \
- --enable-demuxer=mov \
- --enable-demuxer=vc1 \
- --enable-demuxer=mpegts \
- --enable-demuxer=mpegtsraw \
- --enable-demuxer=mpegps \
- --enable-demuxer=mpegvideo \
- --enable-demuxer=wav \
- --enable-demuxer=pcm_s16be \
- --enable-demuxer=mp3 \
- --enable-demuxer=pcm_s16le \
- --enable-demuxer=matroska \
- --enable-demuxer=flv \
- --enable-demuxer=rm \
- --enable-demuxer=rtsp \
- --enable-demuxer=hls \
- --enable-demuxer=dts \
- --enable-demuxer=wav \
- --enable-demuxer=ogg \
- --enable-demuxer=flac \
- --enable-demuxer=srt \
- --enable-demuxer=hds \
- --enable-demuxer=dash \
- \
- --disable-encoders \
- --disable-muxers \
- --enable-muxer=mpegts \
- \
- --disable-programs \
- --disable-static \
- --disable-filters \
- \
- --enable-librtmp \
- --disable-protocol=data \
- --disable-protocol=cache \
- --disable-protocol=concat \
- --disable-protocol=crypto \
- --disable-protocol=ftp \
- --disable-protocol=gopher \
- --disable-protocol=httpproxy \
- --disable-protocol=pipe \
- --disable-protocol=sctp \
- --disable-protocol=srtp \
- --disable-protocol=subfile \
- --disable-protocol=unix \
- --disable-protocol=md5 \
- --disable-protocol=hls \
- --enable-openssl \
- --enable-protocol=file \
- --enable-protocol=http \
- --enable-protocol=https \
- --enable-protocol=rtmp \
- --enable-protocol=rtmpe \
- --enable-protocol=rtmps \
- --enable-protocol=rtmpte \
- --enable-protocol=mmsh \
- --enable-protocol=mmst \
- --enable-protocol=rtp \
- --enable-protocol=tcp \
- --enable-protocol=udp \
- --enable-bsfs \
- --disable-devices \
- --enable-swresample \
- --disable-postproc \
- --disable-swscale \
- --disable-mmx \
- --disable-altivec \
- --enable-network \
- --enable-cross-compile \
- --enable-shared \
- --enable-small \
- --disable-bzlib \
- --enable-zlib \
- --disable-xlib \
- --enable-libxml2 \
- --disable-debug \
- --enable-stripping \
- --enable-decoder=h264 \
- --enable-decoder=vc1 \
- --target-os=linux \
- --disable-neon \
- --disable-runtime-cpudetect \
- --arch=arm
-endif # ifeq ($(BOXARCH), arm)
-
-ifeq ($(PLATFORM), $(filter $(PLATFORM), apollo kronos))
-FFMPEG_CONFIGURE += --cpu=cortex-a9 --enable-vfp --extra-cflags="-mfpu=vfpv3-d16 -mfloat-abi=hard -I$(TARGETPREFIX)/include"
-else
-FFMPEG_CONFIGURE += --disable-iconv
-FFMPEG_CONFIGURE += --cpu=armv6 --disable-vfp --extra-cflags="-I$(TARGETPREFIX)/include"
-endif
-$(D)/ffmpeg: $(D)/libxml2 $(D)/librtmp $(D)/libroxml $(ARCHIVE)/ffmpeg-git-$(FFMPEG_GIT).tar.gz | $(TARGETPREFIX)
- $(START_BUILD)
- $(REMOVE)/ffmpeg-git-$(FFMPEG_GIT)
- $(UNTAR)/ffmpeg-git-$(FFMPEG_GIT).tar.gz
- set -e; pushd $(BUILD_TMP)/ffmpeg-git-$(FFMPEG_GIT) && \
- $(PATCH)/ffmpeg/0001-ffmpeg-hds-libroxml-3.x.patch; \
- $(PATCH)/ffmpeg/0002-ffmpeg-aac-3.x.patch; \
- $(PATCH)/ffmpeg/0003-ffmpeg-increase-IO-BUFFER-SIZE-to-128k.patch; \
- $(PATCH)/ffmpeg/0003-Revert-libavformat-aviobuf-keep-track-of-the-original-buffer-size-and-restore-it-after.patch; \
- $(PATCH)/ffmpeg/0004-FFmpeg-devel-v14*.patch; \
- $(PATCH)/ffmpeg/0005-ffmpeg-fix-pts-for-cooli.patch; \
- $(PATCH)/ffmpeg/0006-ffmpeg-fix-sps-pps-for-cooli.patch; \
- $(PATCH)/ffmpeg/0007-ffmpeg-reset-compressed-header-flag.patch; \
- $(PATCH)/ffmpeg/0008-add-ASF-VC1-Annex-G-and-RCV-bitstream-filters.-Origi.patch; \
- $(BUILDENV) \
- ./configure \
- $(FFMPEG_CONFIGURE) \
- --extra-ldflags="-L$(TARGETPREFIX)/lib -lz" \
- --logfile=$(BUILD_TMP)/Config-ffmpeg-$(FFMPEG_GIT).log \
- --cross-prefix=$(TARGET)- \
- --prefix=$(TARGETPREFIX) \
- --mandir=/.remove; \
- $(MAKE) && \
- $(MAKE) install
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavfilter.pc
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavdevice.pc
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavformat.pc
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavcodec.pc
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libavutil.pc
- $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/libswresample.pc
- $(REMOVE)/ffmpeg-git-$(FFMPEG_GIT) $(TARGETPREFIX)/.remove
- $(TOUCH)
-
$(D)/libroxml: $(ARCHIVE)/libroxml-$(LIBROXML_VER).tar.gz | $(TARGETPREFIX)
$(START_BUILD)
$(UNTAR)/libroxml-$(LIBROXML_VER).tar.gz
$(REMOVE)/libroxml-$(LIBROXML_VER)
$(TOUCH)
+DVBSI_CPPFLAG =
+ifeq ($(BOXSERIES), hd2)
+DVBSI_CPPFLAG = "-D_GLIBCXX_USE_CXX11_ABI=0"
+endif
$(D)/libdvbsi++: $(ARCHIVE)/libdvbsi++-$(LIBDVBSI_GIT).tar.bz2 | $(TARGETPREFIX)
$(START_BUILD)
$(UNTAR)/libdvbsi++-$(LIBDVBSI_GIT).tar.bz2
$(PATCH)/libdvbsi++-src-time_date_section.cpp-fix-sectionLength-check.patch; \
$(PATCH)/libdvbsi++-fix-unaligned-access-on-SuperH.patch; \
$(PATCH)/libdvbsi++-content_identifier_descriptor.patch; \
- $(CONFIGURE) CPPFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0" \
+ $(CONFIGURE) CPPFLAGS=$(DVBSI_CPPFLAG) \
--prefix=$(TARGETPREFIX) \
--build=$(BUILD) \
--host=$(TARGET); \
$(REMOVE)/SDL_mixer-1.2.11
$(TOUCH)
-$(D)/libalsa: $(ARCHIVE)/alsa-lib-1.0.12.tar.gz | $(TARGETPREFIX)
+$(D)/alsa-lib: $(ARCHIVE)/alsa-lib-$(ALSA_LIB_VER).tar.bz2
$(START_BUILD)
- $(UNTAR)/alsa-lib-1.0.12.tar.gz
- pushd $(BUILD_TMP)/alsa-lib-1.0.12 && \
- $(CONFIGURE) --prefix=$(TARGETPREFIX) \
- --build=$(BUILD) \
- --host=$(TARGET) \
- --enable-shared=yes && \
- $(MAKE) && \
- $(MAKE) install && \
- rm -rf $(TARGETPREFIX)/man
- $(REMOVE)/alsa-lib-1.0.12
+ $(UNTAR)/alsa-lib-$(ALSA_LIB_VER).tar.bz2
+ set -e; cd $(BUILD_TMP)/alsa-lib-$(ALSA_LIB_VER); \
+ $(PATCH)/alsa-lib-$(ALSA_LIB_VER).patch; \
+ $(PATCH)/alsa-lib-$(ALSA_LIB_VER)-link_fix.patch; \
+ $(CONFIGURE) \
+ --prefix= \
+ --datarootdir=/.remove \
+ --with-alsa-devdir=/dev/snd/ \
+ --with-plugindir=/lib/alsa \
+ --without-debug \
+ --with-debug=no \
+ --with-versioned=no \
+ --enable-symbolic-functions \
+ --disable-aload \
+ --disable-rawmidi \
+ --disable-resmgr \
+ --disable-old-symbols \
+ --disable-alisp \
+ --disable-hwdep \
+ --disable-python \
+ ; \
+ $(MAKE); \
+ $(MAKE) install DESTDIR=$(TARGETPREFIX)
+ $(REWRITE_PKGCONF) $(PKG_CONFIG_PATH)/alsa.pc
+ $(REWRITE_LIBTOOL)/libasound.la
+ $(REMOVE)/alsa-lib-$(ALSA_LIB_VER)
$(TOUCH)
-$(D)/libalsa-utils: $(D)/libalsa $(ARCHIVE)/alsa-utils-1.0.12.tar.gz | $(TARGETPREFIX)
+$(D)/libalsa-utils: $(D)/alsa-lib $(ARCHIVE)/alsa-utils-1.0.12.tar.gz | $(TARGETPREFIX)
$(START_BUILD)
$(UNTAR)/alsa-utils-1.0.12.tar.gz
pushd $(BUILD_TMP)/alsa-utils-1.0.12 && \
#Makefile to build NEUTRINO
-N_CFLAGS = -Wall -Werror -Wextra -Wshadow -Wsign-compare
+N_CFLAGS = -Wall -Wextra -Wshadow -Wsign-compare
+ifeq ($(BOXTYPE), coolstream)
+N_CFLAGS += -Werror
+endif
N_CFLAGS += -O2
N_CFLAGS += -fmax-errors=10
N_CFLAGS +=
endif
-ifeq ($(BOXMODEL), $(filter $(BOXMODEL), zee2 link))
-HW_TYPE = --with-boxmodel=apollo
-else
-HW_TYPE = --with-boxmodel=$(PLATFORM)
-endif
-
N_CFLAGS += -I$(TARGETPREFIX)/include
N_CFLAGS += -I$(NEUTRINO_OBJDIR)
N_CFLAGS += -I$(NEUTRINO_OBJDIR)/src/gui
# finally we can build outside of the source directory
NEUTRINO_OBJDIR = $(BUILD_TMP)/neutrino-hd
-# use this if you want to build inside the source dir - but you don't want that ;)
-# NEUTRINO_OBJDIR = $(SOURCE_DIR)/neutrino-hd
+LH_OBJDIR = $(BUILD_TMP)/LIBSTB_HAL
AUDIODEC = ffmpeg
ifeq ($(AUDIODEC), ffmpeg)
# enable ffmpeg audio decoder in neutrino
-N_CONFIG_OPTS = --enable-ffmpegdec
+ N_CONFIG_OPTS = --enable-ffmpegdec
else
-NEUTRINO_DEPS = libid3tag libmad
-N_CONFIG_OPTS = --with-tremor
-NEUTRINO_DEPS += libvorbis
+ NEUTRINO_DEPS = libid3tag libmad
+ N_CONFIG_OPTS = --with-tremor
+ NEUTRINO_DEPS += libvorbis
# enable FLAC decoder in neutrino
-N_CONFIG_OPTS += --enable-flac
-NEUTRINO_DEPS += libflac
+ N_CONFIG_OPTS += --enable-flac
+ NEUTRINO_DEPS += libflac
endif
+
ifeq ($(PLATFORM), $(filter $(PLATFORM), apollo kronos))
- NEUTRINO_DEPS += libiconv cortex-strings
+ NEUTRINO_DEPS += libiconv cortex-strings
+endif
+
+N_CONFIGURE_LIBSTB_HAL =
+ifeq ($(BOXTYPE), armbox)
+ NEUTRINO_DEPS += cortex-strings libstb-hal
+ N_CONFIGURE_LIBSTB_HAL += \
+ --with-stb-hal-includes=$(LH_OBJDIR)/include \
+ --with-stb-hal-build=$(LH_OBJDIR)
endif
neutrino-deps: $(NEUTRINO_DEPS)
cp -a $(BUILD_TMP)/neutrino-hd/config.h $(TARGETPREFIX)/include/config.h
# touch $@
-$(NEUTRINO_OBJDIR)/config.status: $(NEUTRINO_DEPS) $(D)/neutrino-hd-libs
+$(NEUTRINO_OBJDIR)/config.status: $(D)/neutrino-hd-libs $(NEUTRINO_DEPS)
test -d $(NEUTRINO_OBJDIR) || mkdir -p $(NEUTRINO_OBJDIR)
$(SOURCE_DIR)/neutrino-hd/autogen.sh
pushd $(NEUTRINO_OBJDIR) && \
export PKG_CONFIG=$(PKG_CONFIG) && \
export PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) && \
$(N_BUILDENV) \
- $(SOURCE_DIR)/neutrino-hd/configure --host=$(TARGET) --build=$(BUILD) --prefix= \
- --enable-maintainer-mode --with-target=cdk --with-targetprefix="" \
- --with-boxtype=$(BOXTYPE) \
- --with-boxmodel=$(BOXSERIES) \
+ $(SOURCE_DIR)/neutrino-hd/configure \
+ --host=$(TARGET) \
+ --build=$(BUILD) \
+ --prefix= \
+ --enable-maintainer-mode \
+ --enable-silent-rules \
+ \
+ $(N_CONFIG_OPTS) \
--enable-freesatepg \
--enable-mdev \
--enable-pip \
--enable-giflib \
--enable-pugixml \
--enable-fribidi \
- $(N_CONFIG_OPTS)
+ \
+ $(N_CONFIGURE_LIBSTB_HAL) \
+ --with-target=cdk \
+ --with-targetprefix="" \
+ --with-boxtype=$(BOXTYPE) \
+ --with-boxmodel=$(BOXSERIES)
+
+$(LH_OBJDIR)/config.status: $(LH_DEPS)
+ rm -rf $(LH_OBJDIR)
+ tar -C $(SOURCE_DIR)/git -cp LIBSTB_HAL --exclude-vcs | tar -C $(BUILD_TMP) -x;
+ pushd $(LH_OBJDIR) && \
+ ./autogen.sh && \
+ \
+ export PKG_CONFIG=$(PKG_CONFIG) && \
+ export PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) && \
+ $(N_BUILDENV) \
+ ./configure \
+ --host=$(TARGET) \
+ --build=$(BUILD) \
+ --prefix= \
+ --enable-maintainer-mode \
+ --enable-silent-rules \
+ --enable-shared=no \
+ \
+ $(LH_CONFIGURE_GSTREAMER) \
+ \
+ --with-target=cdk \
+ --with-boxtype=$(BOXMODEL)
+
+$(D)/libstb-hal: $(LH_OBJDIR)/config.status
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) \
+ $(MAKE) -C $(LH_OBJDIR) all DESTDIR=$(TARGETPREFIX)
+ $(MAKE) -C $(LH_OBJDIR) install DESTDIR=$(TARGETPREFIX)
+ $(REWRITE_LIBTOOL)/libstb-hal.la
+ touch $@
+
+libstb-hal-clean:
+ -make -C $(LH_OBJDIR) clean
+ -rm $(LH_OBJDIR)/config.status
+ -rm $(D)/libstb-hal
+
+libstb-hal-clean-all: libstb-hal-clean
+ -rm -r $(LH_OBJDIR)
neutrino-version: $(TARGETPREFIX)/bin/neutrino
if [ -e $(BASE_DIR)/customize/version.sh ]; then \
$(START_BUILD)
$(MAKE) $(D)/libsigc $(D)/giflib $(D)/openssl \
$(D)/libcurl $(D)/freetype $(D)/libjpeg \
- $(D)/libdvbsi++ $(D)/pugixml $(D)/ffmpeg \
+ $(D)/libdvbsi++ $(D)/pugixml $(D)/alsa-lib $(D)/ffmpeg \
$(D)/libbluray $(D)/libopenthreads $(D)/libusb $(D)/libfribidi \
$(D)/luaposix $(D)/luacurl $(D)/luasocket $(D)/lua-expat $(D)/lua-feedparser
$(TOUCH)
+
fi; \
fi
+$(GIT_LIBSTB_HAL):
+ mkdir -p $(SOURCE_DIR)/git
+ cd $(SOURCE_DIR)/git && \
+ if [ -d $(GIT_LIBSTB_HAL)/ ]; then \
+ cd $(GIT_LIBSTB_HAL) && \
+ git checkout mpx; \
+ git pull origin mpx; \
+ else \
+ cd $(SOURCE_DIR)/git; \
+ git clone $(CSGIT)/$(REPO_LIBSTB_HAL) LIBSTB_HAL; \
+ cd $(GIT_LIBSTB_HAL) && \
+ git checkout mpx; \
+ fi
+
$(GIT_BOOTLOADER):
mkdir -p $(SOURCE_DIR)/git
cd $(SOURCE_DIR)/git && \
# hack to make sure they are always copied
PHONY += $(SOURCE_DIR)/neutrino-hd
+PHONY += $(GIT_LIBSTB_HAL)
PHONY += $(GIT_BOOTLOADER)
PHONY += $(GIT_DRIVERS_THIRDPARTY)
PHONY += $(GIT_DRIVERS)
+# The Advanced Linux Sound Architecture (ALSA) provides audio and MIDI functionality to the Linux operating system.
+ALSA_LIB_VER = 1.1.5
AUTOFS4_VER = 4.1.4
FBSHOT_VER = 0.3
# FFMPEG-3.3 | A complete, cross-platform solution to record, convert and stream audio and video
+ifeq ($(BOXTYPE), armbox)
+FFMPEG_VER = 3.4.2
+else
FFMPEG_GIT = 2ba896f
+endif
# FLEX (the fast lexical analyser)
FLEX_VER=2.5.35
# libjpeg-turbo; a derivative of libjpeg for x86 and x86-64 processors which uses SIMD instructions (MMX, SSE2, etc.) to accelerate baseline JPEG compression and decompression
JPEG_TURBO_VER = 1.5.2
+# libass is a portable subtitle renderer for the ASS/SSA (Advanced Substation Alpha/Substation Alpha) subtitle format.
+LIBASS_VER=0.14.0
+
# libdvbsi++; libdvbsi++ is a open source C++ library for parsing DVB Service Information and MPEG-2 Program Specific Information.
LIBDVBSI_GIT=ff57e5