diff options
| author | Carlos Rafael Giani <dv@pseudoterminal.org> | 2017-08-11 23:36:55 +0200 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-08-16 00:03:14 +0100 |
| commit | ae841c4371fc7f4ee08a9a2002738f52057aa6bb (patch) | |
| tree | f517e15d5d5f7c36511d0f97f6819f535799224f /meta/recipes-multimedia | |
| parent | 71c2f1d0470aaf0402cf19a35b60ddae8e6b49fb (diff) | |
| download | poky-ae841c4371fc7f4ee08a9a2002738f52057aa6bb.tar.gz | |
gstreamer1.0-plugins-bad: upgrade to version 1.12.2
* Remove backported patches:
1. 0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch
2. 0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch
3. 0001-mssdemux-improved-live-playback-support.patch
* Refreshed the following patches:
1. 0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch
Extended patch to include fix for libgstallocators
2. 0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch
Updated to apply to 1.12.2
3. gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch
Updated to apply to 1.12.2
* Removed license checks in tta directory as it doesn't exist anymore.
* In 1.12.0, old unsupported plugins were removed. As a result, the
list of unsupported plugins was removed.
(From OE-Core rev: 1fa8492e54dd71ce7d4d853e0cb7295c28fa5e76)
Signed-off-by: Carlos Rafael Giani <dv@pseudoterminal.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-multimedia')
8 files changed, 89 insertions, 1249 deletions
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad.inc b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad.inc index dc47f581af..7bcd6db292 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad.inc +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad.inc | |||
| @@ -70,16 +70,11 @@ PACKAGECONFIG[vulkan] = "--enable-vulkan,--disable-vulkan,vulkan" | |||
| 70 | PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland-native wayland wayland-protocols" | 70 | PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland-native wayland wayland-protocols" |
| 71 | PACKAGECONFIG[webp] = "--enable-webp,--disable-webp,libwebp" | 71 | PACKAGECONFIG[webp] = "--enable-webp,--disable-webp,libwebp" |
| 72 | 72 | ||
| 73 | # these plugins have not been ported to 1.0 (yet): | ||
| 74 | # apexsink linsys nas timidity sdl xvid wininet | ||
| 75 | # sndio cdxaparse dccp faceoverlay hdvparse tta mve nuvdemux | ||
| 76 | # patchdetect sdi videomeasure | ||
| 77 | |||
| 78 | # these plugins have no corresponding library in OE-core or meta-openembedded: | 73 | # these plugins have no corresponding library in OE-core or meta-openembedded: |
| 79 | # openni2 winks direct3d directsound winscreencap acm apple_media | 74 | # openni2 winks direct3d directsound winscreencap acm apple_media iqa |
| 80 | # android_media avc bs2b chromaprint daala dts fdkaac gme gsm kate ladspa libde265 | 75 | # android_media avc bs2b chromaprint daala dts fdkaac gme gsm kate ladspa libde265 |
| 81 | # lv2 mimic mpeg2enc mplex musepack nvenc ofa openh264 opensles pvr soundtouch spandsp | 76 | # lv2 mpeg2enc mplex msdk musepack nvenc ofa openh264 opensles soundtouch spandsp |
| 82 | # spc teletextdec tinyalsa vdpau wasapi x265 zbar | 77 | # spc teletextdec tinyalsa vdpau wasapi x265 zbar webrtcdsp |
| 83 | 78 | ||
| 84 | # qt5 support is disabled, because it is not present in OE core, and requires more work than | 79 | # qt5 support is disabled, because it is not present in OE core, and requires more work than |
| 85 | # just adding a packageconfig (it requires access to moc, uic, rcc, and qmake paths). | 80 | # just adding a packageconfig (it requires access to moc, uic, rcc, and qmake paths). |
| @@ -95,7 +90,6 @@ EXTRA_OECONF += " \ | |||
| 95 | --enable-vcd \ | 90 | --enable-vcd \ |
| 96 | --disable-acm \ | 91 | --disable-acm \ |
| 97 | --disable-android_media \ | 92 | --disable-android_media \ |
| 98 | --disable-apexsink \ | ||
| 99 | --disable-apple_media \ | 93 | --disable-apple_media \ |
| 100 | --disable-avc \ | 94 | --disable-avc \ |
| 101 | --disable-bs2b \ | 95 | --disable-bs2b \ |
| @@ -108,42 +102,34 @@ EXTRA_OECONF += " \ | |||
| 108 | --disable-fdk_aac \ | 102 | --disable-fdk_aac \ |
| 109 | --disable-gme \ | 103 | --disable-gme \ |
| 110 | --disable-gsm \ | 104 | --disable-gsm \ |
| 105 | --disable-iqa \ | ||
| 111 | --disable-kate \ | 106 | --disable-kate \ |
| 112 | --disable-ladspa \ | 107 | --disable-ladspa \ |
| 113 | --disable-libde265 \ | 108 | --disable-libde265 \ |
| 114 | --disable-libvisual \ | ||
| 115 | --disable-linsys \ | ||
| 116 | --disable-lv2 \ | 109 | --disable-lv2 \ |
| 117 | --disable-mimic \ | ||
| 118 | --disable-mpeg2enc \ | 110 | --disable-mpeg2enc \ |
| 119 | --disable-mplex \ | 111 | --disable-mplex \ |
| 112 | --disable-msdk \ | ||
| 120 | --disable-musepack \ | 113 | --disable-musepack \ |
| 121 | --disable-nas \ | ||
| 122 | --disable-nvenc \ | 114 | --disable-nvenc \ |
| 123 | --disable-ofa \ | 115 | --disable-ofa \ |
| 124 | --disable-openexr \ | 116 | --disable-openexr \ |
| 125 | --disable-openh264 \ | 117 | --disable-openh264 \ |
| 126 | --disable-openni2 \ | 118 | --disable-openni2 \ |
| 127 | --disable-opensles \ | 119 | --disable-opensles \ |
| 128 | --disable-pvr \ | ||
| 129 | --disable-qt \ | 120 | --disable-qt \ |
| 130 | --disable-sdl \ | ||
| 131 | --disable-sdltest \ | ||
| 132 | --disable-sndio \ | ||
| 133 | --disable-soundtouch \ | 121 | --disable-soundtouch \ |
| 134 | --disable-spandsp \ | 122 | --disable-spandsp \ |
| 135 | --disable-spc \ | 123 | --disable-spc \ |
| 136 | --disable-teletextdec \ | 124 | --disable-teletextdec \ |
| 137 | --disable-timidity \ | ||
| 138 | --disable-tinyalsa \ | 125 | --disable-tinyalsa \ |
| 139 | --disable-vdpau \ | 126 | --disable-vdpau \ |
| 140 | --disable-wasapi \ | 127 | --disable-wasapi \ |
| 128 | --disable-webrtcdsp \ | ||
| 141 | --disable-wildmidi \ | 129 | --disable-wildmidi \ |
| 142 | --disable-wininet \ | ||
| 143 | --disable-winks \ | 130 | --disable-winks \ |
| 144 | --disable-winscreencap \ | 131 | --disable-winscreencap \ |
| 145 | --disable-x265 \ | 132 | --disable-x265 \ |
| 146 | --disable-xvid \ | ||
| 147 | --disable-zbar \ | 133 | --disable-zbar \ |
| 148 | ${@bb.utils.contains("TUNE_FEATURES", "mx32", "--disable-yadif", "", d)} \ | 134 | ${@bb.utils.contains("TUNE_FEATURES", "mx32", "--disable-yadif", "", d)} \ |
| 149 | " | 135 | " |
| @@ -157,3 +143,7 @@ FILES_${PN}-dev += "${libdir}/gstreamer-${LIBV}/include/gst/gl/gstglconfig.h" | |||
| 157 | FILES_${PN}-freeverb += "${datadir}/gstreamer-${LIBV}/presets/GstFreeverb.prs" | 143 | FILES_${PN}-freeverb += "${datadir}/gstreamer-${LIBV}/presets/GstFreeverb.prs" |
| 158 | FILES_${PN}-opencv += "${datadir}/gst-plugins-bad/${LIBV}/opencv*" | 144 | FILES_${PN}-opencv += "${datadir}/gst-plugins-bad/${LIBV}/opencv*" |
| 159 | FILES_${PN}-voamrwbenc += "${datadir}/gstreamer-${LIBV}/presets/GstVoAmrwbEnc.prs" | 145 | FILES_${PN}-voamrwbenc += "${datadir}/gstreamer-${LIBV}/presets/GstVoAmrwbEnc.prs" |
| 146 | |||
| 147 | do_compile_prepend() { | ||
| 148 | export GIR_EXTRA_LIBS_PATH="${B}/gst-libs/gst/allocators/.libs" | ||
| 149 | } | ||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch index 43f1ee0d23..8d99dc6ccc 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | From cff6fbf555a072408c21da1e818209c9d3814dd3 Mon Sep 17 00:00:00 2001 | 1 | From 7592e793b3906355d76ca9a59f8fea2749ea2a4e Mon Sep 17 00:00:00 2001 |
| 2 | From: Alexander Kanavin <alex.kanavin@gmail.com> | 2 | From: Alexander Kanavin <alex.kanavin@gmail.com> |
| 3 | Date: Tue, 27 Oct 2015 14:36:58 +0200 | 3 | Date: Tue, 27 Oct 2015 14:36:58 +0200 |
| 4 | Subject: [PATCH] Makefile.am: don't hardcode libtool name when running | 4 | Subject: [PATCH] Makefile.am: don't hardcode libtool name when running |
| @@ -7,17 +7,34 @@ Subject: [PATCH] Makefile.am: don't hardcode libtool name when running | |||
| 7 | Upstream-Status: Pending [review on oe-core list] | 7 | Upstream-Status: Pending [review on oe-core list] |
| 8 | Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> | 8 | Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> |
| 9 | 9 | ||
| 10 | %% original patch: 0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch | ||
| 11 | |||
| 12 | Signed-off-by: Maxin B. John <maxin.john@intel.com> | ||
| 10 | --- | 13 | --- |
| 11 | gst-libs/gst/gl/Makefile.am | 2 +- | 14 | gst-libs/gst/allocators/Makefile.am | 2 +- |
| 12 | gst-libs/gst/insertbin/Makefile.am | 2 +- | 15 | gst-libs/gst/gl/Makefile.am | 2 +- |
| 13 | gst-libs/gst/mpegts/Makefile.am | 2 +- | 16 | gst-libs/gst/insertbin/Makefile.am | 2 +- |
| 14 | 3 files changed, 3 insertions(+), 3 deletions(-) | 17 | gst-libs/gst/mpegts/Makefile.am | 2 +- |
| 18 | 4 files changed, 4 insertions(+), 4 deletions(-) | ||
| 15 | 19 | ||
| 16 | Index: gst-plugins-bad-1.10.1/gst-libs/gst/gl/Makefile.am | 20 | diff --git a/gst-libs/gst/allocators/Makefile.am b/gst-libs/gst/allocators/Makefile.am |
| 17 | =================================================================== | 21 | index e50d077..623f092 100644 |
| 18 | --- gst-plugins-bad-1.10.1.orig/gst-libs/gst/gl/Makefile.am | 22 | --- a/gst-libs/gst/allocators/Makefile.am |
| 19 | +++ gst-plugins-bad-1.10.1/gst-libs/gst/gl/Makefile.am | 23 | +++ b/gst-libs/gst/allocators/Makefile.am |
| 20 | @@ -171,7 +171,7 @@ GstGL-@GST_API_VERSION@.gir: $(INTROSPEC | 24 | @@ -37,7 +37,7 @@ GstBadAllocators-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstbadalloca |
| 25 | --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-@GST_API_VERSION@` \ | ||
| 26 | --library=libgstbadallocators-@GST_API_VERSION@.la \ | ||
| 27 | --include=Gst-@GST_API_VERSION@ \ | ||
| 28 | - --libtool="$(top_builddir)/libtool" \ | ||
| 29 | + --libtool="$(LIBTOOL)" \ | ||
| 30 | --pkg gstreamer-@GST_API_VERSION@ \ | ||
| 31 | --pkg-export gstreamer-badallocators-@GST_API_VERSION@ \ | ||
| 32 | --output $@ \ | ||
| 33 | diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am | ||
| 34 | index 2ae4773..dfa7a7d 100644 | ||
| 35 | --- a/gst-libs/gst/gl/Makefile.am | ||
| 36 | +++ b/gst-libs/gst/gl/Makefile.am | ||
| 37 | @@ -178,7 +178,7 @@ GstGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstgl-@GST_API_VERSION@ | ||
| 21 | --include=Gst-@GST_API_VERSION@ \ | 38 | --include=Gst-@GST_API_VERSION@ \ |
| 22 | --include=GstBase-@GST_API_VERSION@ \ | 39 | --include=GstBase-@GST_API_VERSION@ \ |
| 23 | --include=GstVideo-@GST_API_VERSION@ \ | 40 | --include=GstVideo-@GST_API_VERSION@ \ |
| @@ -26,11 +43,11 @@ Index: gst-plugins-bad-1.10.1/gst-libs/gst/gl/Makefile.am | |||
| 26 | --pkg gstreamer-@GST_API_VERSION@ \ | 43 | --pkg gstreamer-@GST_API_VERSION@ \ |
| 27 | --pkg gstreamer-base-@GST_API_VERSION@ \ | 44 | --pkg gstreamer-base-@GST_API_VERSION@ \ |
| 28 | --pkg gstreamer-video-@GST_API_VERSION@ \ | 45 | --pkg gstreamer-video-@GST_API_VERSION@ \ |
| 29 | Index: gst-plugins-bad-1.10.1/gst-libs/gst/insertbin/Makefile.am | 46 | diff --git a/gst-libs/gst/insertbin/Makefile.am b/gst-libs/gst/insertbin/Makefile.am |
| 30 | =================================================================== | 47 | index 1f8ea30..4b98ef6 100644 |
| 31 | --- gst-plugins-bad-1.10.1.orig/gst-libs/gst/insertbin/Makefile.am | 48 | --- a/gst-libs/gst/insertbin/Makefile.am |
| 32 | +++ gst-plugins-bad-1.10.1/gst-libs/gst/insertbin/Makefile.am | 49 | +++ b/gst-libs/gst/insertbin/Makefile.am |
| 33 | @@ -45,7 +45,7 @@ GstInsertBin-@GST_API_VERSION@.gir: $(IN | 50 | @@ -45,7 +45,7 @@ GstInsertBin-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstinsertbin-@GS |
| 34 | --library=libgstinsertbin-@GST_API_VERSION@.la \ | 51 | --library=libgstinsertbin-@GST_API_VERSION@.la \ |
| 35 | --include=Gst-@GST_API_VERSION@ \ | 52 | --include=Gst-@GST_API_VERSION@ \ |
| 36 | --include=GstBase-@GST_API_VERSION@ \ | 53 | --include=GstBase-@GST_API_VERSION@ \ |
| @@ -39,11 +56,11 @@ Index: gst-plugins-bad-1.10.1/gst-libs/gst/insertbin/Makefile.am | |||
| 39 | --pkg gstreamer-@GST_API_VERSION@ \ | 56 | --pkg gstreamer-@GST_API_VERSION@ \ |
| 40 | --pkg gstreamer-base-@GST_API_VERSION@ \ | 57 | --pkg gstreamer-base-@GST_API_VERSION@ \ |
| 41 | --pkg-export gstreamer-insertbin-@GST_API_VERSION@ \ | 58 | --pkg-export gstreamer-insertbin-@GST_API_VERSION@ \ |
| 42 | Index: gst-plugins-bad-1.10.1/gst-libs/gst/mpegts/Makefile.am | 59 | diff --git a/gst-libs/gst/mpegts/Makefile.am b/gst-libs/gst/mpegts/Makefile.am |
| 43 | =================================================================== | 60 | index aeea32e..929d9cc 100644 |
| 44 | --- gst-plugins-bad-1.10.1.orig/gst-libs/gst/mpegts/Makefile.am | 61 | --- a/gst-libs/gst/mpegts/Makefile.am |
| 45 | +++ gst-plugins-bad-1.10.1/gst-libs/gst/mpegts/Makefile.am | 62 | +++ b/gst-libs/gst/mpegts/Makefile.am |
| 46 | @@ -79,7 +79,7 @@ GstMpegts-@GST_API_VERSION@.gir: $(INTRO | 63 | @@ -79,7 +79,7 @@ GstMpegts-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstmpegts-@GST_API_ |
| 47 | --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-video-@GST_API_VERSION@` \ | 64 | --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-video-@GST_API_VERSION@` \ |
| 48 | --library=libgstmpegts-@GST_API_VERSION@.la \ | 65 | --library=libgstmpegts-@GST_API_VERSION@.la \ |
| 49 | --include=Gst-@GST_API_VERSION@ \ | 66 | --include=Gst-@GST_API_VERSION@ \ |
| @@ -52,3 +69,6 @@ Index: gst-plugins-bad-1.10.1/gst-libs/gst/mpegts/Makefile.am | |||
| 52 | --pkg gstreamer-@GST_API_VERSION@ \ | 69 | --pkg gstreamer-@GST_API_VERSION@ \ |
| 53 | --pkg gstreamer-video-@GST_API_VERSION@ \ | 70 | --pkg gstreamer-video-@GST_API_VERSION@ \ |
| 54 | --pkg-export gstreamer-mpegts-@GST_API_VERSION@ \ | 71 | --pkg-export gstreamer-mpegts-@GST_API_VERSION@ \ |
| 72 | -- | ||
| 73 | 2.4.0 | ||
| 74 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch index 86a4495a85..48d93ab284 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch | |||
| @@ -1,34 +1,38 @@ | |||
| 1 | From c271503d7e233428ac0323c51d6517113e26bef7 Mon Sep 17 00:00:00 2001 | 1 | From 7c8f68c5428380b930579dc9ef27c853264448fd Mon Sep 17 00:00:00 2001 |
| 2 | From: Khem Raj <raj.khem@gmail.com> | 2 | From: Khem Raj <raj.khem@gmail.com> |
| 3 | Date: Thu, 1 Dec 2016 00:27:13 -0800 | 3 | Date: Mon, 15 May 2017 15:06:11 +0300 |
| 4 | Subject: [PATCH] Prepend PKG_CONFIG_SYSROOT_DIR to pkg-config output | 4 | Subject: [PATCH] Prepend PKG_CONFIG_SYSROOT_DIR to pkg-config output |
| 5 | 5 | ||
| 6 | In cross environment we have to prepend the sysroot to the path found by | 6 | In cross environment we have to prepend the sysroot to the path found by |
| 7 | pkgconfig since the path returned from pkgconfig does not have sysroot prefixed | 7 | pkgconfig since the path returned from pkgconfig does not have sysroot prefixed |
| 8 | it ends up using the files from host system. If build host has wayland installed | 8 | it ends up using the files from host system. If build host has wayland installed |
| 9 | the build will succeed but if you dont have wayland-protocols installed on build host then | 9 | the build will succeed but if you dont have wayland-protocols installed on build |
| 10 | it wont find the files on build host | 10 | host then it wont find the files on build host |
| 11 | 11 | ||
| 12 | This should work ok with non sysrooted builds too since in those cases PKG_CONFIG_SYSROOT_DIR | 12 | This should work ok with non sysrooted builds too since |
| 13 | will be empty | 13 | in those cases PKG_CONFIG_SYSROOT_DIR will be empty |
| 14 | 14 | ||
| 15 | Upstream-Status: Pending | 15 | Upstream-Status: Pending |
| 16 | 16 | ||
| 17 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | 17 | Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| 18 | Signed-off-by: Maxin B. John <maxin.john@intel.com> | ||
| 18 | --- | 19 | --- |
| 19 | configure.ac | 2 +- | 20 | configure.ac | 2 +- |
| 20 | 1 file changed, 1 insertion(+), 1 deletion(-) | 21 | 1 file changed, 1 insertion(+), 1 deletion(-) |
| 21 | 22 | ||
| 22 | Index: gst-plugins-bad-1.10.1/configure.ac | 23 | diff --git a/configure.ac b/configure.ac |
| 23 | =================================================================== | 24 | index e307be6..83cdeb0 100644 |
| 24 | --- gst-plugins-bad-1.10.1.orig/configure.ac | 25 | --- a/configure.ac |
| 25 | +++ gst-plugins-bad-1.10.1/configure.ac | 26 | +++ b/configure.ac |
| 26 | @@ -2233,7 +2233,7 @@ AG_GST_CHECK_FEATURE(WAYLAND, [wayland s | 27 | @@ -2272,7 +2272,7 @@ AG_GST_CHECK_FEATURE(WAYLAND, [wayland sink], wayland , [ |
| 27 | PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, wayland-protocols >= 1.4, [ | 28 | PKG_CHECK_MODULES(WAYLAND, wayland-client >= 1.4.0 libdrm >= 2.4.55 wayland-protocols >= 1.4, [ |
| 28 | if test "x$wayland_scanner" != "x"; then | 29 | if test "x$wayland_scanner" != "x"; then |
| 29 | HAVE_WAYLAND="yes" | 30 | HAVE_WAYLAND="yes" |
| 30 | - AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-protocols`) | 31 | - AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, `$PKG_CONFIG --variable=pkgdatadir wayland-protocols`) |
| 31 | + AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, ${WAYLAND_PROTOCOLS_SYSROOT_DIR}`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`) | 32 | + AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, ${WAYLAND_PROTOCOLS_SYSROOT_DIR}`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`) |
| 32 | else | 33 | else |
| 33 | AC_MSG_RESULT([wayland-scanner is required to build the wayland plugin]) | 34 | AC_MSG_RESULT([wayland-scanner is required to build the wayland plugin]) |
| 34 | HAVE_WAYLAND="no" | 35 | HAVE_WAYLAND="no" |
| 36 | -- | ||
| 37 | 2.4.0 | ||
| 38 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch index 9fc91d8fc4..2235a57afa 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-gstreamer-gl.pc.in-don-t-append-GL_CFLAGS-to-CFLAGS.patch | |||
| @@ -1,24 +1,29 @@ | |||
| 1 | From a93ca63d01e7cd1e40b5be576992f77fac364bd5 Mon Sep 17 00:00:00 2001 | 1 | From 5622ca3b61603dc316a0f1fbede3f9aa353a5e48 Mon Sep 17 00:00:00 2001 |
| 2 | From: Alexander Kanavin <alex.kanavin@gmail.com> | 2 | From: Alexander Kanavin <alex.kanavin@gmail.com> |
| 3 | Date: Mon, 21 Mar 2016 18:21:17 +0200 | 3 | Date: Fri, 12 May 2017 16:47:12 +0300 |
| 4 | Subject: [PATCH] gstreamer-gl.pc.in: don't append GL_CFLAGS to CFLAGS | 4 | Subject: [PATCH] gstreamer-gl.pc.in: don't append GL_CFLAGS to CFLAGS |
| 5 | 5 | ||
| 6 | Dependencies' include directories should not be added in this way; | 6 | Dependencies' include directories should not be added in this way; |
| 7 | it causes problems when cross-compiling in sysroot environments. | 7 | it causes problems when cross-compiling in sysroot environments. |
| 8 | 8 | ||
| 9 | Upstream-Status: Pending | 9 | Upstream-Status: Pending |
| 10 | |||
| 10 | Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> | 11 | Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> |
| 12 | Signed-off-by: Maxin B. John <maxin.john@intel.com> | ||
| 11 | --- | 13 | --- |
| 12 | pkgconfig/gstreamer-gl.pc.in | 2 +- | 14 | pkgconfig/gstreamer-gl.pc.in | 2 +- |
| 13 | 1 file changed, 1 insertion(+), 1 deletion(-) | 15 | 1 file changed, 1 insertion(+), 1 deletion(-) |
| 14 | 16 | ||
| 15 | Index: gst-plugins-bad-1.10.1/pkgconfig/gstreamer-gl.pc.in | 17 | diff --git a/pkgconfig/gstreamer-gl.pc.in b/pkgconfig/gstreamer-gl.pc.in |
| 16 | =================================================================== | 18 | index 8e7a303..d167be1 100644 |
| 17 | --- gst-plugins-bad-1.10.1.orig/pkgconfig/gstreamer-gl.pc.in | 19 | --- a/pkgconfig/gstreamer-gl.pc.in |
| 18 | +++ gst-plugins-bad-1.10.1/pkgconfig/gstreamer-gl.pc.in | 20 | +++ b/pkgconfig/gstreamer-gl.pc.in |
| 19 | @@ -10,4 +10,4 @@ Version: @VERSION@ | 21 | @@ -13,4 +13,4 @@ Version: @VERSION@ |
| 20 | Requires: gstreamer-base-@GST_API_VERSION@ gstreamer-@GST_API_VERSION@ | 22 | Requires: gstreamer-base-@GST_API_VERSION@ gstreamer-@GST_API_VERSION@ |
| 21 | 23 | ||
| 22 | Libs: -L${libdir} -lgstgl-@GST_API_VERSION@ @GL_LIBS@ | 24 | Libs: -L${libdir} -lgstgl-@GST_API_VERSION@ |
| 23 | -Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include @GL_CFLAGS@ | 25 | -Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include @GL_CFLAGS@ |
| 24 | +Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include | 26 | +Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include |
| 27 | -- | ||
| 28 | 2.4.0 | ||
| 29 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch deleted file mode 100644 index 4832c18e78..0000000000 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-mssdemux-improved-live-playback-support.patch +++ /dev/null | |||
| @@ -1,929 +0,0 @@ | |||
| 1 | From 73721ad4e9e2d32e1c8b6a3b4aaa98401530e58a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Philippe Normand <philn@igalia.com> | ||
| 3 | Date: Tue, 29 Nov 2016 14:43:41 +0100 | ||
| 4 | Subject: [PATCH] mssdemux: improved live playback support | ||
| 5 | |||
| 6 | When a MSS server hosts a live stream the fragments listed in the | ||
| 7 | manifest usually don't have accurate timestamps and duration, except | ||
| 8 | for the first fragment, which additionally stores timing information | ||
| 9 | for the few upcoming fragments. In this scenario it is useless to | ||
| 10 | periodically fetch and update the manifest and the fragments list can | ||
| 11 | be incrementally built by parsing the first/current fragment. | ||
| 12 | |||
| 13 | https://bugzilla.gnome.org/show_bug.cgi?id=755036 | ||
| 14 | --- | ||
| 15 | Upstream-Status: Backport | ||
| 16 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 17 | |||
| 18 | ext/smoothstreaming/Makefile.am | 2 + | ||
| 19 | ext/smoothstreaming/gstmssdemux.c | 60 ++++++ | ||
| 20 | ext/smoothstreaming/gstmssfragmentparser.c | 266 ++++++++++++++++++++++++++ | ||
| 21 | ext/smoothstreaming/gstmssfragmentparser.h | 84 ++++++++ | ||
| 22 | ext/smoothstreaming/gstmssmanifest.c | 158 ++++++++++++++- | ||
| 23 | ext/smoothstreaming/gstmssmanifest.h | 7 + | ||
| 24 | gst-libs/gst/adaptivedemux/gstadaptivedemux.c | 27 ++- | ||
| 25 | gst-libs/gst/adaptivedemux/gstadaptivedemux.h | 14 ++ | ||
| 26 | 8 files changed, 606 insertions(+), 12 deletions(-) | ||
| 27 | create mode 100644 ext/smoothstreaming/gstmssfragmentparser.c | ||
| 28 | create mode 100644 ext/smoothstreaming/gstmssfragmentparser.h | ||
| 29 | |||
| 30 | diff --git a/ext/smoothstreaming/Makefile.am b/ext/smoothstreaming/Makefile.am | ||
| 31 | index 4faf9df9f..a5e1ad6ae 100644 | ||
| 32 | --- a/ext/smoothstreaming/Makefile.am | ||
| 33 | +++ b/ext/smoothstreaming/Makefile.am | ||
| 34 | @@ -13,8 +13,10 @@ libgstsmoothstreaming_la_LIBADD = \ | ||
| 35 | libgstsmoothstreaming_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} | ||
| 36 | libgstsmoothstreaming_la_SOURCES = gstsmoothstreaming-plugin.c \ | ||
| 37 | gstmssdemux.c \ | ||
| 38 | + gstmssfragmentparser.c \ | ||
| 39 | gstmssmanifest.c | ||
| 40 | libgstsmoothstreaming_la_LIBTOOLFLAGS = --tag=disable-static | ||
| 41 | |||
| 42 | noinst_HEADERS = gstmssdemux.h \ | ||
| 43 | + gstmssfragmentparser.h \ | ||
| 44 | gstmssmanifest.h | ||
| 45 | diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c | ||
| 46 | index 12fb40497..120d9c22b 100644 | ||
| 47 | --- a/ext/smoothstreaming/gstmssdemux.c | ||
| 48 | +++ b/ext/smoothstreaming/gstmssdemux.c | ||
| 49 | @@ -135,11 +135,18 @@ gst_mss_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream); | ||
| 50 | static gboolean gst_mss_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek); | ||
| 51 | static gint64 | ||
| 52 | gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux); | ||
| 53 | +static gint64 | ||
| 54 | +gst_mss_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream * | ||
| 55 | + stream); | ||
| 56 | static GstFlowReturn | ||
| 57 | gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux, | ||
| 58 | GstBuffer * buffer); | ||
| 59 | static gboolean gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, | ||
| 60 | gint64 * start, gint64 * stop); | ||
| 61 | +static GstFlowReturn gst_mss_demux_data_received (GstAdaptiveDemux * demux, | ||
| 62 | + GstAdaptiveDemuxStream * stream, GstBuffer * buffer); | ||
| 63 | +static gboolean | ||
| 64 | +gst_mss_demux_requires_periodical_playlist_update (GstAdaptiveDemux * demux); | ||
| 65 | |||
| 66 | static void | ||
| 67 | gst_mss_demux_class_init (GstMssDemuxClass * klass) | ||
| 68 | @@ -192,10 +199,15 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass) | ||
| 69 | gst_mss_demux_stream_select_bitrate; | ||
| 70 | gstadaptivedemux_class->stream_update_fragment_info = | ||
| 71 | gst_mss_demux_stream_update_fragment_info; | ||
| 72 | + gstadaptivedemux_class->stream_get_fragment_waiting_time = | ||
| 73 | + gst_mss_demux_stream_get_fragment_waiting_time; | ||
| 74 | gstadaptivedemux_class->update_manifest_data = | ||
| 75 | gst_mss_demux_update_manifest_data; | ||
| 76 | gstadaptivedemux_class->get_live_seek_range = | ||
| 77 | gst_mss_demux_get_live_seek_range; | ||
| 78 | + gstadaptivedemux_class->data_received = gst_mss_demux_data_received; | ||
| 79 | + gstadaptivedemux_class->requires_periodical_playlist_update = | ||
| 80 | + gst_mss_demux_requires_periodical_playlist_update; | ||
| 81 | |||
| 82 | GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin"); | ||
| 83 | } | ||
| 84 | @@ -650,6 +662,13 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux) | ||
| 85 | return interval; | ||
| 86 | } | ||
| 87 | |||
| 88 | +static gint64 | ||
| 89 | +gst_mss_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream * stream) | ||
| 90 | +{ | ||
| 91 | + /* Wait a second for live streams so we don't try premature fragments downloading */ | ||
| 92 | + return GST_SECOND; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | static GstFlowReturn | ||
| 96 | gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux, | ||
| 97 | GstBuffer * buffer) | ||
| 98 | @@ -670,3 +689,44 @@ gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start, | ||
| 99 | |||
| 100 | return gst_mss_manifest_get_live_seek_range (mssdemux->manifest, start, stop); | ||
| 101 | } | ||
| 102 | + | ||
| 103 | +static GstFlowReturn | ||
| 104 | +gst_mss_demux_data_received (GstAdaptiveDemux * demux, | ||
| 105 | + GstAdaptiveDemuxStream * stream, GstBuffer * buffer) | ||
| 106 | +{ | ||
| 107 | + GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux); | ||
| 108 | + GstMssDemuxStream *mssstream = (GstMssDemuxStream *) stream; | ||
| 109 | + gsize available; | ||
| 110 | + | ||
| 111 | + if (!gst_mss_manifest_is_live (mssdemux->manifest)) { | ||
| 112 | + return GST_ADAPTIVE_DEMUX_CLASS (parent_class)->data_received (demux, | ||
| 113 | + stream, buffer); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + if (gst_mss_stream_fragment_parsing_needed (mssstream->manifest_stream)) { | ||
| 117 | + gst_mss_manifest_live_adapter_push (mssstream->manifest_stream, buffer); | ||
| 118 | + available = | ||
| 119 | + gst_mss_manifest_live_adapter_available (mssstream->manifest_stream); | ||
| 120 | + // FIXME: try to reduce this minimal size. | ||
| 121 | + if (available < 4096) { | ||
| 122 | + return GST_FLOW_OK; | ||
| 123 | + } else { | ||
| 124 | + GST_LOG_OBJECT (stream->pad, "enough data, parsing fragment."); | ||
| 125 | + buffer = | ||
| 126 | + gst_mss_manifest_live_adapter_take_buffer (mssstream->manifest_stream, | ||
| 127 | + available); | ||
| 128 | + gst_mss_stream_parse_fragment (mssstream->manifest_stream, buffer); | ||
| 129 | + } | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + return GST_ADAPTIVE_DEMUX_CLASS (parent_class)->data_received (demux, stream, | ||
| 133 | + buffer); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +static gboolean | ||
| 137 | +gst_mss_demux_requires_periodical_playlist_update (GstAdaptiveDemux * demux) | ||
| 138 | +{ | ||
| 139 | + GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux); | ||
| 140 | + | ||
| 141 | + return (!gst_mss_manifest_is_live (mssdemux->manifest)); | ||
| 142 | +} | ||
| 143 | diff --git a/ext/smoothstreaming/gstmssfragmentparser.c b/ext/smoothstreaming/gstmssfragmentparser.c | ||
| 144 | new file mode 100644 | ||
| 145 | index 000000000..b554d4f31 | ||
| 146 | --- /dev/null | ||
| 147 | +++ b/ext/smoothstreaming/gstmssfragmentparser.c | ||
| 148 | @@ -0,0 +1,266 @@ | ||
| 149 | +/* | ||
| 150 | + * Microsoft Smooth-Streaming fragment parsing library | ||
| 151 | + * | ||
| 152 | + * gstmssfragmentparser.h | ||
| 153 | + * | ||
| 154 | + * Copyright (C) 2016 Igalia S.L | ||
| 155 | + * Copyright (C) 2016 Metrological | ||
| 156 | + * Author: Philippe Normand <philn@igalia.com> | ||
| 157 | + * | ||
| 158 | + * This library is free software; you can redistribute it and/or | ||
| 159 | + * modify it under the terms of the GNU Library General Public | ||
| 160 | + * License as published by the Free Software Foundation; either | ||
| 161 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 162 | + * | ||
| 163 | + * This library is distributed in the hope that it will be useful, | ||
| 164 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 165 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 166 | + * Library General Public License for more details. | ||
| 167 | + * | ||
| 168 | + * You should have received a copy of the GNU Library General Public | ||
| 169 | + * License along with this library (COPYING); if not, write to the | ||
| 170 | + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 171 | + * Boston, MA 02111-1307, USA. | ||
| 172 | + */ | ||
| 173 | + | ||
| 174 | +#include "gstmssfragmentparser.h" | ||
| 175 | +#include <gst/base/gstbytereader.h> | ||
| 176 | +#include <string.h> | ||
| 177 | + | ||
| 178 | +GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug); | ||
| 179 | +#define GST_CAT_DEFAULT mssdemux_debug | ||
| 180 | + | ||
| 181 | +void | ||
| 182 | +gst_mss_fragment_parser_init (GstMssFragmentParser * parser) | ||
| 183 | +{ | ||
| 184 | + parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_INIT; | ||
| 185 | + parser->tfrf.entries_count = 0; | ||
| 186 | +} | ||
| 187 | + | ||
| 188 | +void | ||
| 189 | +gst_mss_fragment_parser_clear (GstMssFragmentParser * parser) | ||
| 190 | +{ | ||
| 191 | + parser->tfrf.entries_count = 0; | ||
| 192 | + if (parser->tfrf.entries) { | ||
| 193 | + g_free (parser->tfrf.entries); | ||
| 194 | + parser->tfrf.entries = 0; | ||
| 195 | + } | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +static gboolean | ||
| 199 | +_parse_tfrf_box (GstMssFragmentParser * parser, GstByteReader * reader) | ||
| 200 | +{ | ||
| 201 | + guint8 version; | ||
| 202 | + guint32 flags = 0; | ||
| 203 | + guint8 fragment_count = 0; | ||
| 204 | + guint8 index = 0; | ||
| 205 | + | ||
| 206 | + if (!gst_byte_reader_get_uint8 (reader, &version)) { | ||
| 207 | + GST_ERROR ("Error getting box's version field"); | ||
| 208 | + return FALSE; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + if (!gst_byte_reader_get_uint24_be (reader, &flags)) { | ||
| 212 | + GST_ERROR ("Error getting box's flags field"); | ||
| 213 | + return FALSE; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + gst_byte_reader_get_uint8 (reader, &fragment_count); | ||
| 217 | + parser->tfrf.entries_count = fragment_count; | ||
| 218 | + parser->tfrf.entries = | ||
| 219 | + g_malloc (sizeof (GstTfrfBoxEntry) * parser->tfrf.entries_count); | ||
| 220 | + for (index = 0; index < fragment_count; index++) { | ||
| 221 | + guint64 absolute_time = 0; | ||
| 222 | + guint64 absolute_duration = 0; | ||
| 223 | + if (version & 0x01) { | ||
| 224 | + gst_byte_reader_get_uint64_be (reader, &absolute_time); | ||
| 225 | + gst_byte_reader_get_uint64_be (reader, &absolute_duration); | ||
| 226 | + } else { | ||
| 227 | + guint32 time = 0; | ||
| 228 | + guint32 duration = 0; | ||
| 229 | + gst_byte_reader_get_uint32_be (reader, &time); | ||
| 230 | + gst_byte_reader_get_uint32_be (reader, &duration); | ||
| 231 | + time = ~time; | ||
| 232 | + duration = ~duration; | ||
| 233 | + absolute_time = ~time; | ||
| 234 | + absolute_duration = ~duration; | ||
| 235 | + } | ||
| 236 | + parser->tfrf.entries[index].time = absolute_time; | ||
| 237 | + parser->tfrf.entries[index].duration = absolute_duration; | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + GST_LOG ("tfrf box parsed"); | ||
| 241 | + return TRUE; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +static gboolean | ||
| 245 | +_parse_tfxd_box (GstMssFragmentParser * parser, GstByteReader * reader) | ||
| 246 | +{ | ||
| 247 | + guint8 version; | ||
| 248 | + guint32 flags = 0; | ||
| 249 | + guint64 absolute_time = 0; | ||
| 250 | + guint64 absolute_duration = 0; | ||
| 251 | + | ||
| 252 | + if (!gst_byte_reader_get_uint8 (reader, &version)) { | ||
| 253 | + GST_ERROR ("Error getting box's version field"); | ||
| 254 | + return FALSE; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + if (!gst_byte_reader_get_uint24_be (reader, &flags)) { | ||
| 258 | + GST_ERROR ("Error getting box's flags field"); | ||
| 259 | + return FALSE; | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + if (version & 0x01) { | ||
| 263 | + gst_byte_reader_get_uint64_be (reader, &absolute_time); | ||
| 264 | + gst_byte_reader_get_uint64_be (reader, &absolute_duration); | ||
| 265 | + } else { | ||
| 266 | + guint32 time = 0; | ||
| 267 | + guint32 duration = 0; | ||
| 268 | + gst_byte_reader_get_uint32_be (reader, &time); | ||
| 269 | + gst_byte_reader_get_uint32_be (reader, &duration); | ||
| 270 | + time = ~time; | ||
| 271 | + duration = ~duration; | ||
| 272 | + absolute_time = ~time; | ||
| 273 | + absolute_duration = ~duration; | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + parser->tfxd.time = absolute_time; | ||
| 277 | + parser->tfxd.duration = absolute_duration; | ||
| 278 | + GST_LOG ("tfxd box parsed"); | ||
| 279 | + return TRUE; | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +gboolean | ||
| 283 | +gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser, | ||
| 284 | + GstBuffer * buffer) | ||
| 285 | +{ | ||
| 286 | + GstByteReader reader; | ||
| 287 | + GstMapInfo info; | ||
| 288 | + guint32 size; | ||
| 289 | + guint32 fourcc; | ||
| 290 | + const guint8 *uuid; | ||
| 291 | + gboolean error = FALSE; | ||
| 292 | + gboolean mdat_box_found = FALSE; | ||
| 293 | + | ||
| 294 | + static const guint8 tfrf_uuid[] = { | ||
| 295 | + 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95, | ||
| 296 | + 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f | ||
| 297 | + }; | ||
| 298 | + | ||
| 299 | + static const guint8 tfxd_uuid[] = { | ||
| 300 | + 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6, | ||
| 301 | + 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2 | ||
| 302 | + }; | ||
| 303 | + | ||
| 304 | + static const guint8 piff_uuid[] = { | ||
| 305 | + 0xa2, 0x39, 0x4f, 0x52, 0x5a, 0x9b, 0x4f, 0x14, | ||
| 306 | + 0xa2, 0x44, 0x6c, 0x42, 0x7c, 0x64, 0x8d, 0xf4 | ||
| 307 | + }; | ||
| 308 | + | ||
| 309 | + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { | ||
| 310 | + return FALSE; | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + gst_byte_reader_init (&reader, info.data, info.size); | ||
| 314 | + GST_TRACE ("Total buffer size: %u", gst_byte_reader_get_size (&reader)); | ||
| 315 | + | ||
| 316 | + size = gst_byte_reader_get_uint32_be_unchecked (&reader); | ||
| 317 | + fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); | ||
| 318 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_MOOF) { | ||
| 319 | + GST_TRACE ("moof box found"); | ||
| 320 | + size = gst_byte_reader_get_uint32_be_unchecked (&reader); | ||
| 321 | + fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); | ||
| 322 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_MFHD) { | ||
| 323 | + gst_byte_reader_skip_unchecked (&reader, size - 8); | ||
| 324 | + | ||
| 325 | + size = gst_byte_reader_get_uint32_be_unchecked (&reader); | ||
| 326 | + fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); | ||
| 327 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_TRAF) { | ||
| 328 | + size = gst_byte_reader_get_uint32_be_unchecked (&reader); | ||
| 329 | + fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); | ||
| 330 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_TFHD) { | ||
| 331 | + gst_byte_reader_skip_unchecked (&reader, size - 8); | ||
| 332 | + | ||
| 333 | + size = gst_byte_reader_get_uint32_be_unchecked (&reader); | ||
| 334 | + fourcc = gst_byte_reader_get_uint32_le_unchecked (&reader); | ||
| 335 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_TRUN) { | ||
| 336 | + GST_TRACE ("trun box found, size: %" G_GUINT32_FORMAT, size); | ||
| 337 | + if (!gst_byte_reader_skip (&reader, size - 8)) { | ||
| 338 | + GST_WARNING ("Failed to skip trun box, enough data?"); | ||
| 339 | + error = TRUE; | ||
| 340 | + goto beach; | ||
| 341 | + } | ||
| 342 | + } | ||
| 343 | + } | ||
| 344 | + } | ||
| 345 | + } | ||
| 346 | + } | ||
| 347 | + | ||
| 348 | + while (!mdat_box_found) { | ||
| 349 | + GST_TRACE ("remaining data: %u", gst_byte_reader_get_remaining (&reader)); | ||
| 350 | + if (!gst_byte_reader_get_uint32_be (&reader, &size)) { | ||
| 351 | + GST_WARNING ("Failed to get box size, enough data?"); | ||
| 352 | + error = TRUE; | ||
| 353 | + break; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + GST_TRACE ("box size: %" G_GUINT32_FORMAT, size); | ||
| 357 | + if (!gst_byte_reader_get_uint32_le (&reader, &fourcc)) { | ||
| 358 | + GST_WARNING ("Failed to get fourcc, enough data?"); | ||
| 359 | + error = TRUE; | ||
| 360 | + break; | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + if (fourcc == GST_MSS_FRAGMENT_FOURCC_MDAT) { | ||
| 364 | + GST_LOG ("mdat box found"); | ||
| 365 | + mdat_box_found = TRUE; | ||
| 366 | + break; | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + if (fourcc != GST_MSS_FRAGMENT_FOURCC_UUID) { | ||
| 370 | + GST_ERROR ("invalid UUID fourcc: %" GST_FOURCC_FORMAT, | ||
| 371 | + GST_FOURCC_ARGS (fourcc)); | ||
| 372 | + error = TRUE; | ||
| 373 | + break; | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + if (!gst_byte_reader_peek_data (&reader, 16, &uuid)) { | ||
| 377 | + GST_ERROR ("not enough data in UUID box"); | ||
| 378 | + error = TRUE; | ||
| 379 | + break; | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + if (memcmp (uuid, piff_uuid, 16) == 0) { | ||
| 383 | + gst_byte_reader_skip_unchecked (&reader, size - 8); | ||
| 384 | + GST_LOG ("piff box detected"); | ||
| 385 | + } | ||
| 386 | + | ||
| 387 | + if (memcmp (uuid, tfrf_uuid, 16) == 0) { | ||
| 388 | + gst_byte_reader_get_data (&reader, 16, &uuid); | ||
| 389 | + if (!_parse_tfrf_box (parser, &reader)) { | ||
| 390 | + GST_ERROR ("txrf box parsing error"); | ||
| 391 | + error = TRUE; | ||
| 392 | + break; | ||
| 393 | + } | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + if (memcmp (uuid, tfxd_uuid, 16) == 0) { | ||
| 397 | + gst_byte_reader_get_data (&reader, 16, &uuid); | ||
| 398 | + if (!_parse_tfxd_box (parser, &reader)) { | ||
| 399 | + GST_ERROR ("tfrf box parsing error"); | ||
| 400 | + error = TRUE; | ||
| 401 | + break; | ||
| 402 | + } | ||
| 403 | + } | ||
| 404 | + } | ||
| 405 | + | ||
| 406 | +beach: | ||
| 407 | + | ||
| 408 | + if (!error) | ||
| 409 | + parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED; | ||
| 410 | + | ||
| 411 | + GST_LOG ("Fragment parsing successful: %s", error ? "no" : "yes"); | ||
| 412 | + gst_buffer_unmap (buffer, &info); | ||
| 413 | + return !error; | ||
| 414 | +} | ||
| 415 | diff --git a/ext/smoothstreaming/gstmssfragmentparser.h b/ext/smoothstreaming/gstmssfragmentparser.h | ||
| 416 | new file mode 100644 | ||
| 417 | index 000000000..cf4711865 | ||
| 418 | --- /dev/null | ||
| 419 | +++ b/ext/smoothstreaming/gstmssfragmentparser.h | ||
| 420 | @@ -0,0 +1,84 @@ | ||
| 421 | +/* | ||
| 422 | + * Microsoft Smooth-Streaming fragment parsing library | ||
| 423 | + * | ||
| 424 | + * gstmssfragmentparser.h | ||
| 425 | + * | ||
| 426 | + * Copyright (C) 2016 Igalia S.L | ||
| 427 | + * Copyright (C) 2016 Metrological | ||
| 428 | + * Author: Philippe Normand <philn@igalia.com> | ||
| 429 | + * | ||
| 430 | + * This library is free software; you can redistribute it and/or | ||
| 431 | + * modify it under the terms of the GNU Library General Public | ||
| 432 | + * License as published by the Free Software Foundation; either | ||
| 433 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 434 | + * | ||
| 435 | + * This library is distributed in the hope that it will be useful, | ||
| 436 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 437 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 438 | + * Library General Public License for more details. | ||
| 439 | + * | ||
| 440 | + * You should have received a copy of the GNU Library General Public | ||
| 441 | + * License along with this library (COPYING); if not, write to the | ||
| 442 | + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 443 | + * Boston, MA 02111-1307, USA. | ||
| 444 | + */ | ||
| 445 | + | ||
| 446 | +#ifndef __GST_MSS_FRAGMENT_PARSER_H__ | ||
| 447 | +#define __GST_MSS_FRAGMENT_PARSER_H__ | ||
| 448 | + | ||
| 449 | +#include <gst/gst.h> | ||
| 450 | + | ||
| 451 | +G_BEGIN_DECLS | ||
| 452 | + | ||
| 453 | +#define GST_MSS_FRAGMENT_FOURCC_MOOF GST_MAKE_FOURCC('m','o','o','f') | ||
| 454 | +#define GST_MSS_FRAGMENT_FOURCC_MFHD GST_MAKE_FOURCC('m','f','h','d') | ||
| 455 | +#define GST_MSS_FRAGMENT_FOURCC_TRAF GST_MAKE_FOURCC('t','r','a','f') | ||
| 456 | +#define GST_MSS_FRAGMENT_FOURCC_TFHD GST_MAKE_FOURCC('t','f','h','d') | ||
| 457 | +#define GST_MSS_FRAGMENT_FOURCC_TRUN GST_MAKE_FOURCC('t','r','u','n') | ||
| 458 | +#define GST_MSS_FRAGMENT_FOURCC_UUID GST_MAKE_FOURCC('u','u','i','d') | ||
| 459 | +#define GST_MSS_FRAGMENT_FOURCC_MDAT GST_MAKE_FOURCC('m','d','a','t') | ||
| 460 | + | ||
| 461 | +typedef struct _GstTfxdBox | ||
| 462 | +{ | ||
| 463 | + guint8 version; | ||
| 464 | + guint32 flags; | ||
| 465 | + | ||
| 466 | + guint64 time; | ||
| 467 | + guint64 duration; | ||
| 468 | +} GstTfxdBox; | ||
| 469 | + | ||
| 470 | +typedef struct _GstTfrfBoxEntry | ||
| 471 | +{ | ||
| 472 | + guint64 time; | ||
| 473 | + guint64 duration; | ||
| 474 | +} GstTfrfBoxEntry; | ||
| 475 | + | ||
| 476 | +typedef struct _GstTfrfBox | ||
| 477 | +{ | ||
| 478 | + guint8 version; | ||
| 479 | + guint32 flags; | ||
| 480 | + | ||
| 481 | + gint entries_count; | ||
| 482 | + GstTfrfBoxEntry *entries; | ||
| 483 | +} GstTfrfBox; | ||
| 484 | + | ||
| 485 | +typedef enum _GstFragmentHeaderParserStatus | ||
| 486 | +{ | ||
| 487 | + GST_MSS_FRAGMENT_HEADER_PARSER_INIT, | ||
| 488 | + GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED | ||
| 489 | +} GstFragmentHeaderParserStatus; | ||
| 490 | + | ||
| 491 | +typedef struct _GstMssFragmentParser | ||
| 492 | +{ | ||
| 493 | + GstFragmentHeaderParserStatus status; | ||
| 494 | + GstTfxdBox tfxd; | ||
| 495 | + GstTfrfBox tfrf; | ||
| 496 | +} GstMssFragmentParser; | ||
| 497 | + | ||
| 498 | +void gst_mss_fragment_parser_init (GstMssFragmentParser * parser); | ||
| 499 | +void gst_mss_fragment_parser_clear (GstMssFragmentParser * parser); | ||
| 500 | +gboolean gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser, GstBuffer * buf); | ||
| 501 | + | ||
| 502 | +G_END_DECLS | ||
| 503 | + | ||
| 504 | +#endif /* __GST_MSS_FRAGMENT_PARSER_H__ */ | ||
| 505 | diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c | ||
| 506 | index 144bbb42d..e1031ba55 100644 | ||
| 507 | --- a/ext/smoothstreaming/gstmssmanifest.c | ||
| 508 | +++ b/ext/smoothstreaming/gstmssmanifest.c | ||
| 509 | @@ -1,5 +1,7 @@ | ||
| 510 | /* GStreamer | ||
| 511 | * Copyright (C) 2012 Smart TV Alliance | ||
| 512 | + * Copyright (C) 2016 Igalia S.L | ||
| 513 | + * Copyright (C) 2016 Metrological | ||
| 514 | * Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>, Collabora Ltd. | ||
| 515 | * | ||
| 516 | * gstmssmanifest.c: | ||
| 517 | @@ -31,6 +33,7 @@ | ||
| 518 | #include <gst/codecparsers/gsth264parser.h> | ||
| 519 | |||
| 520 | #include "gstmssmanifest.h" | ||
| 521 | +#include "gstmssfragmentparser.h" | ||
| 522 | |||
| 523 | GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug); | ||
| 524 | #define GST_CAT_DEFAULT mssdemux_debug | ||
| 525 | @@ -74,12 +77,17 @@ struct _GstMssStream | ||
| 526 | gboolean active; /* if the stream is currently being used */ | ||
| 527 | gint selectedQualityIndex; | ||
| 528 | |||
| 529 | + gboolean has_live_fragments; | ||
| 530 | + GstAdapter *live_adapter; | ||
| 531 | + | ||
| 532 | GList *fragments; | ||
| 533 | GList *qualities; | ||
| 534 | |||
| 535 | gchar *url; | ||
| 536 | gchar *lang; | ||
| 537 | |||
| 538 | + GstMssFragmentParser fragment_parser; | ||
| 539 | + | ||
| 540 | guint fragment_repetition_index; | ||
| 541 | GList *current_fragment; | ||
| 542 | GList *current_quality; | ||
| 543 | @@ -96,6 +104,7 @@ struct _GstMssManifest | ||
| 544 | |||
| 545 | gboolean is_live; | ||
| 546 | gint64 dvr_window; | ||
| 547 | + guint64 look_ahead_fragment_count; | ||
| 548 | |||
| 549 | GString *protection_system_id; | ||
| 550 | gchar *protection_data; | ||
| 551 | @@ -235,7 +244,8 @@ compare_bitrate (GstMssStreamQuality * a, GstMssStreamQuality * b) | ||
| 552 | } | ||
| 553 | |||
| 554 | static void | ||
| 555 | -_gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node) | ||
| 556 | +_gst_mss_stream_init (GstMssManifest * manifest, GstMssStream * stream, | ||
| 557 | + xmlNodePtr node) | ||
| 558 | { | ||
| 559 | xmlNodePtr iter; | ||
| 560 | GstMssFragmentListBuilder builder; | ||
| 561 | @@ -248,9 +258,21 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node) | ||
| 562 | stream->url = (gchar *) xmlGetProp (node, (xmlChar *) MSS_PROP_URL); | ||
| 563 | stream->lang = (gchar *) xmlGetProp (node, (xmlChar *) MSS_PROP_LANGUAGE); | ||
| 564 | |||
| 565 | + /* for live playback each fragment usually has timing | ||
| 566 | + * information for the few next look-ahead fragments so the | ||
| 567 | + * playlist can be built incrementally from the first fragment | ||
| 568 | + * of the manifest. | ||
| 569 | + */ | ||
| 570 | + | ||
| 571 | + GST_DEBUG ("Live stream: %s, look-ahead fragments: %" G_GUINT64_FORMAT, | ||
| 572 | + manifest->is_live ? "yes" : "no", manifest->look_ahead_fragment_count); | ||
| 573 | + stream->has_live_fragments = manifest->is_live | ||
| 574 | + && manifest->look_ahead_fragment_count; | ||
| 575 | + | ||
| 576 | for (iter = node->children; iter; iter = iter->next) { | ||
| 577 | if (node_has_type (iter, MSS_NODE_STREAM_FRAGMENT)) { | ||
| 578 | - gst_mss_fragment_list_builder_add (&builder, iter); | ||
| 579 | + if (!stream->has_live_fragments || !builder.fragments) | ||
| 580 | + gst_mss_fragment_list_builder_add (&builder, iter); | ||
| 581 | } else if (node_has_type (iter, MSS_NODE_STREAM_QUALITY)) { | ||
| 582 | GstMssStreamQuality *quality = gst_mss_stream_quality_new (iter); | ||
| 583 | stream->qualities = g_list_prepend (stream->qualities, quality); | ||
| 584 | @@ -259,17 +281,24 @@ _gst_mss_stream_init (GstMssStream * stream, xmlNodePtr node) | ||
| 585 | } | ||
| 586 | } | ||
| 587 | |||
| 588 | - stream->fragments = g_list_reverse (builder.fragments); | ||
| 589 | + if (stream->has_live_fragments) { | ||
| 590 | + stream->live_adapter = gst_adapter_new (); | ||
| 591 | + } | ||
| 592 | + | ||
| 593 | + if (builder.fragments) { | ||
| 594 | + stream->fragments = g_list_reverse (builder.fragments); | ||
| 595 | + stream->current_fragment = stream->fragments; | ||
| 596 | + } | ||
| 597 | |||
| 598 | /* order them from smaller to bigger based on bitrates */ | ||
| 599 | stream->qualities = | ||
| 600 | g_list_sort (stream->qualities, (GCompareFunc) compare_bitrate); | ||
| 601 | - | ||
| 602 | - stream->current_fragment = stream->fragments; | ||
| 603 | stream->current_quality = stream->qualities; | ||
| 604 | |||
| 605 | stream->regex_bitrate = g_regex_new ("\\{[Bb]itrate\\}", 0, 0, NULL); | ||
| 606 | stream->regex_position = g_regex_new ("\\{start[ _]time\\}", 0, 0, NULL); | ||
| 607 | + | ||
| 608 | + gst_mss_fragment_parser_init (&stream->fragment_parser); | ||
| 609 | } | ||
| 610 | |||
| 611 | |||
| 612 | @@ -315,6 +344,7 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 613 | xmlNodePtr nodeiter; | ||
| 614 | gchar *live_str; | ||
| 615 | GstMapInfo mapinfo; | ||
| 616 | + gchar *look_ahead_fragment_count_str; | ||
| 617 | |||
| 618 | if (!gst_buffer_map (data, &mapinfo, GST_MAP_READ)) { | ||
| 619 | return NULL; | ||
| 620 | @@ -335,6 +365,7 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 621 | /* the entire file is always available for non-live streams */ | ||
| 622 | if (!manifest->is_live) { | ||
| 623 | manifest->dvr_window = 0; | ||
| 624 | + manifest->look_ahead_fragment_count = 0; | ||
| 625 | } else { | ||
| 626 | /* if 0, or non-existent, the length is infinite */ | ||
| 627 | gchar *dvr_window_str = (gchar *) xmlGetProp (root, | ||
| 628 | @@ -346,6 +377,17 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 629 | manifest->dvr_window = 0; | ||
| 630 | } | ||
| 631 | } | ||
| 632 | + | ||
| 633 | + look_ahead_fragment_count_str = | ||
| 634 | + (gchar *) xmlGetProp (root, (xmlChar *) "LookAheadFragmentCount"); | ||
| 635 | + if (look_ahead_fragment_count_str) { | ||
| 636 | + manifest->look_ahead_fragment_count = | ||
| 637 | + g_ascii_strtoull (look_ahead_fragment_count_str, NULL, 10); | ||
| 638 | + xmlFree (look_ahead_fragment_count_str); | ||
| 639 | + if (manifest->look_ahead_fragment_count <= 0) { | ||
| 640 | + manifest->look_ahead_fragment_count = 0; | ||
| 641 | + } | ||
| 642 | + } | ||
| 643 | } | ||
| 644 | |||
| 645 | for (nodeiter = root->children; nodeiter; nodeiter = nodeiter->next) { | ||
| 646 | @@ -354,7 +396,7 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 647 | GstMssStream *stream = g_new0 (GstMssStream, 1); | ||
| 648 | |||
| 649 | manifest->streams = g_slist_append (manifest->streams, stream); | ||
| 650 | - _gst_mss_stream_init (stream, nodeiter); | ||
| 651 | + _gst_mss_stream_init (manifest, stream, nodeiter); | ||
| 652 | } | ||
| 653 | |||
| 654 | if (nodeiter->type == XML_ELEMENT_NODE | ||
| 655 | @@ -371,6 +413,11 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 656 | static void | ||
| 657 | gst_mss_stream_free (GstMssStream * stream) | ||
| 658 | { | ||
| 659 | + if (stream->live_adapter) { | ||
| 660 | + gst_adapter_clear (stream->live_adapter); | ||
| 661 | + g_object_unref (stream->live_adapter); | ||
| 662 | + } | ||
| 663 | + | ||
| 664 | g_list_free_full (stream->fragments, g_free); | ||
| 665 | g_list_free_full (stream->qualities, | ||
| 666 | (GDestroyNotify) gst_mss_stream_quality_free); | ||
| 667 | @@ -379,6 +426,7 @@ gst_mss_stream_free (GstMssStream * stream) | ||
| 668 | g_regex_unref (stream->regex_position); | ||
| 669 | g_regex_unref (stream->regex_bitrate); | ||
| 670 | g_free (stream); | ||
| 671 | + gst_mss_fragment_parser_clear (&stream->fragment_parser); | ||
| 672 | } | ||
| 673 | |||
| 674 | void | ||
| 675 | @@ -1079,6 +1127,9 @@ GstFlowReturn | ||
| 676 | gst_mss_stream_advance_fragment (GstMssStream * stream) | ||
| 677 | { | ||
| 678 | GstMssStreamFragment *fragment; | ||
| 679 | + const gchar *stream_type_name = | ||
| 680 | + gst_mss_stream_type_name (gst_mss_stream_get_type (stream)); | ||
| 681 | + | ||
| 682 | g_return_val_if_fail (stream->active, GST_FLOW_ERROR); | ||
| 683 | |||
| 684 | if (stream->current_fragment == NULL) | ||
| 685 | @@ -1086,14 +1137,20 @@ gst_mss_stream_advance_fragment (GstMssStream * stream) | ||
| 686 | |||
| 687 | fragment = stream->current_fragment->data; | ||
| 688 | stream->fragment_repetition_index++; | ||
| 689 | - if (stream->fragment_repetition_index < fragment->repetitions) { | ||
| 690 | - return GST_FLOW_OK; | ||
| 691 | - } | ||
| 692 | + if (stream->fragment_repetition_index < fragment->repetitions) | ||
| 693 | + goto beach; | ||
| 694 | |||
| 695 | stream->fragment_repetition_index = 0; | ||
| 696 | stream->current_fragment = g_list_next (stream->current_fragment); | ||
| 697 | + | ||
| 698 | + GST_DEBUG ("Advanced to fragment #%d on %s stream", fragment->number, | ||
| 699 | + stream_type_name); | ||
| 700 | if (stream->current_fragment == NULL) | ||
| 701 | return GST_FLOW_EOS; | ||
| 702 | + | ||
| 703 | +beach: | ||
| 704 | + gst_mss_fragment_parser_clear (&stream->fragment_parser); | ||
| 705 | + gst_mss_fragment_parser_init (&stream->fragment_parser); | ||
| 706 | return GST_FLOW_OK; | ||
| 707 | } | ||
| 708 | |||
| 709 | @@ -1173,6 +1230,11 @@ gst_mss_stream_seek (GstMssStream * stream, gboolean forward, | ||
| 710 | GST_DEBUG ("Stream %s seeking to %" G_GUINT64_FORMAT, stream->url, time); | ||
| 711 | for (iter = stream->fragments; iter; iter = g_list_next (iter)) { | ||
| 712 | fragment = iter->data; | ||
| 713 | + if (stream->has_live_fragments) { | ||
| 714 | + if (fragment->time + fragment->repetitions * fragment->duration > time) | ||
| 715 | + stream->current_fragment = iter; | ||
| 716 | + break; | ||
| 717 | + } | ||
| 718 | if (fragment->time + fragment->repetitions * fragment->duration > time) { | ||
| 719 | stream->current_fragment = iter; | ||
| 720 | stream->fragment_repetition_index = | ||
| 721 | @@ -1256,9 +1318,14 @@ static void | ||
| 722 | gst_mss_stream_reload_fragments (GstMssStream * stream, xmlNodePtr streamIndex) | ||
| 723 | { | ||
| 724 | xmlNodePtr iter; | ||
| 725 | - guint64 current_gst_time = gst_mss_stream_get_fragment_gst_timestamp (stream); | ||
| 726 | + guint64 current_gst_time; | ||
| 727 | GstMssFragmentListBuilder builder; | ||
| 728 | |||
| 729 | + if (stream->has_live_fragments) | ||
| 730 | + return; | ||
| 731 | + | ||
| 732 | + current_gst_time = gst_mss_stream_get_fragment_gst_timestamp (stream); | ||
| 733 | + | ||
| 734 | gst_mss_fragment_list_builder_init (&builder); | ||
| 735 | |||
| 736 | GST_DEBUG ("Current position: %" GST_TIME_FORMAT, | ||
| 737 | @@ -1514,3 +1581,74 @@ gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start, | ||
| 738 | |||
| 739 | return ret; | ||
| 740 | } | ||
| 741 | + | ||
| 742 | +void | ||
| 743 | +gst_mss_manifest_live_adapter_push (GstMssStream * stream, GstBuffer * buffer) | ||
| 744 | +{ | ||
| 745 | + gst_adapter_push (stream->live_adapter, buffer); | ||
| 746 | +} | ||
| 747 | + | ||
| 748 | +gsize | ||
| 749 | +gst_mss_manifest_live_adapter_available (GstMssStream * stream) | ||
| 750 | +{ | ||
| 751 | + return gst_adapter_available (stream->live_adapter); | ||
| 752 | +} | ||
| 753 | + | ||
| 754 | +GstBuffer * | ||
| 755 | +gst_mss_manifest_live_adapter_take_buffer (GstMssStream * stream, gsize nbytes) | ||
| 756 | +{ | ||
| 757 | + return gst_adapter_take_buffer (stream->live_adapter, nbytes); | ||
| 758 | +} | ||
| 759 | + | ||
| 760 | +gboolean | ||
| 761 | +gst_mss_stream_fragment_parsing_needed (GstMssStream * stream) | ||
| 762 | +{ | ||
| 763 | + return stream->fragment_parser.status == GST_MSS_FRAGMENT_HEADER_PARSER_INIT; | ||
| 764 | +} | ||
| 765 | + | ||
| 766 | +void | ||
| 767 | +gst_mss_stream_parse_fragment (GstMssStream * stream, GstBuffer * buffer) | ||
| 768 | +{ | ||
| 769 | + GstMssStreamFragment *current_fragment = NULL; | ||
| 770 | + const gchar *stream_type_name; | ||
| 771 | + guint8 index; | ||
| 772 | + | ||
| 773 | + if (!stream->has_live_fragments) | ||
| 774 | + return; | ||
| 775 | + | ||
| 776 | + if (!gst_mss_fragment_parser_add_buffer (&stream->fragment_parser, buffer)) | ||
| 777 | + return; | ||
| 778 | + | ||
| 779 | + current_fragment = stream->current_fragment->data; | ||
| 780 | + current_fragment->time = stream->fragment_parser.tfxd.time; | ||
| 781 | + current_fragment->duration = stream->fragment_parser.tfxd.duration; | ||
| 782 | + | ||
| 783 | + stream_type_name = | ||
| 784 | + gst_mss_stream_type_name (gst_mss_stream_get_type (stream)); | ||
| 785 | + | ||
| 786 | + for (index = 0; index < stream->fragment_parser.tfrf.entries_count; index++) { | ||
| 787 | + GList *l = g_list_last (stream->fragments); | ||
| 788 | + GstMssStreamFragment *last; | ||
| 789 | + GstMssStreamFragment *fragment; | ||
| 790 | + | ||
| 791 | + if (l == NULL) | ||
| 792 | + break; | ||
| 793 | + | ||
| 794 | + last = (GstMssStreamFragment *) l->data; | ||
| 795 | + | ||
| 796 | + if (last->time == stream->fragment_parser.tfrf.entries[index].time) | ||
| 797 | + continue; | ||
| 798 | + | ||
| 799 | + fragment = g_new (GstMssStreamFragment, 1); | ||
| 800 | + fragment->number = last->number + 1; | ||
| 801 | + fragment->repetitions = 1; | ||
| 802 | + fragment->time = stream->fragment_parser.tfrf.entries[index].time; | ||
| 803 | + fragment->duration = stream->fragment_parser.tfrf.entries[index].duration; | ||
| 804 | + | ||
| 805 | + stream->fragments = g_list_append (stream->fragments, fragment); | ||
| 806 | + GST_LOG ("Adding fragment number: %u to %s stream, time: %" G_GUINT64_FORMAT | ||
| 807 | + ", duration: %" G_GUINT64_FORMAT ", repetitions: %u", | ||
| 808 | + fragment->number, stream_type_name, | ||
| 809 | + fragment->time, fragment->duration, fragment->repetitions); | ||
| 810 | + } | ||
| 811 | +} | ||
| 812 | diff --git a/ext/smoothstreaming/gstmssmanifest.h b/ext/smoothstreaming/gstmssmanifest.h | ||
| 813 | index 6b7b1f971..03b066ae5 100644 | ||
| 814 | --- a/ext/smoothstreaming/gstmssmanifest.h | ||
| 815 | +++ b/ext/smoothstreaming/gstmssmanifest.h | ||
| 816 | @@ -26,6 +26,7 @@ | ||
| 817 | #include <glib.h> | ||
| 818 | #include <gio/gio.h> | ||
| 819 | #include <gst/gst.h> | ||
| 820 | +#include <gst/base/gstadapter.h> | ||
| 821 | |||
| 822 | G_BEGIN_DECLS | ||
| 823 | |||
| 824 | @@ -73,5 +74,11 @@ const gchar * gst_mss_stream_get_lang (GstMssStream * stream); | ||
| 825 | |||
| 826 | const gchar * gst_mss_stream_type_name (GstMssStreamType streamtype); | ||
| 827 | |||
| 828 | +void gst_mss_manifest_live_adapter_push(GstMssStream * stream, GstBuffer * buffer); | ||
| 829 | +gsize gst_mss_manifest_live_adapter_available(GstMssStream * stream); | ||
| 830 | +GstBuffer * gst_mss_manifest_live_adapter_take_buffer(GstMssStream * stream, gsize nbytes); | ||
| 831 | +gboolean gst_mss_stream_fragment_parsing_needed(GstMssStream * stream); | ||
| 832 | +void gst_mss_stream_parse_fragment(GstMssStream * stream, GstBuffer * buffer); | ||
| 833 | + | ||
| 834 | G_END_DECLS | ||
| 835 | #endif /* __GST_MSS_MANIFEST_H__ */ | ||
| 836 | diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c | ||
| 837 | index 634e4f388..ddca726b6 100644 | ||
| 838 | --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c | ||
| 839 | +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c | ||
| 840 | @@ -291,6 +291,9 @@ gst_adaptive_demux_wait_until (GstClock * clock, GCond * cond, GMutex * mutex, | ||
| 841 | GstClockTime end_time); | ||
| 842 | static gboolean gst_adaptive_demux_clock_callback (GstClock * clock, | ||
| 843 | GstClockTime time, GstClockID id, gpointer user_data); | ||
| 844 | +static gboolean | ||
| 845 | +gst_adaptive_demux_requires_periodical_playlist_update_default (GstAdaptiveDemux | ||
| 846 | + * demux); | ||
| 847 | |||
| 848 | /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init | ||
| 849 | * method to get to the padtemplates */ | ||
| 850 | @@ -412,6 +415,9 @@ gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass) | ||
| 851 | klass->data_received = gst_adaptive_demux_stream_data_received_default; | ||
| 852 | klass->finish_fragment = gst_adaptive_demux_stream_finish_fragment_default; | ||
| 853 | klass->update_manifest = gst_adaptive_demux_update_manifest_default; | ||
| 854 | + klass->requires_periodical_playlist_update = | ||
| 855 | + gst_adaptive_demux_requires_periodical_playlist_update_default; | ||
| 856 | + | ||
| 857 | } | ||
| 858 | |||
| 859 | static void | ||
| 860 | @@ -686,7 +692,9 @@ gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent, | ||
| 861 | demux->priv->stop_updates_task = FALSE; | ||
| 862 | g_mutex_unlock (&demux->priv->updates_timed_lock); | ||
| 863 | /* Task to periodically update the manifest */ | ||
| 864 | - gst_task_start (demux->priv->updates_task); | ||
| 865 | + if (demux_class->requires_periodical_playlist_update (demux)) { | ||
| 866 | + gst_task_start (demux->priv->updates_task); | ||
| 867 | + } | ||
| 868 | } | ||
| 869 | } else { | ||
| 870 | /* no streams */ | ||
| 871 | @@ -2125,6 +2133,13 @@ gst_adaptive_demux_stream_data_received_default (GstAdaptiveDemux * demux, | ||
| 872 | return gst_adaptive_demux_stream_push_buffer (stream, buffer); | ||
| 873 | } | ||
| 874 | |||
| 875 | +static gboolean | ||
| 876 | +gst_adaptive_demux_requires_periodical_playlist_update_default (GstAdaptiveDemux | ||
| 877 | + * demux) | ||
| 878 | +{ | ||
| 879 | + return TRUE; | ||
| 880 | +} | ||
| 881 | + | ||
| 882 | static GstFlowReturn | ||
| 883 | _src_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) | ||
| 884 | { | ||
| 885 | @@ -3338,7 +3353,15 @@ gst_adaptive_demux_stream_download_loop (GstAdaptiveDemuxStream * stream) | ||
| 886 | GST_DEBUG_OBJECT (stream->pad, "EOS, checking to stop download loop"); | ||
| 887 | /* we push the EOS after releasing the object lock */ | ||
| 888 | if (gst_adaptive_demux_is_live (demux)) { | ||
| 889 | - if (gst_adaptive_demux_stream_wait_manifest_update (demux, stream)) { | ||
| 890 | + GstAdaptiveDemuxClass *demux_class = | ||
| 891 | + GST_ADAPTIVE_DEMUX_GET_CLASS (demux); | ||
| 892 | + | ||
| 893 | + /* this might be a fragment download error, refresh the manifest, just in case */ | ||
| 894 | + if (!demux_class->requires_periodical_playlist_update (demux)) { | ||
| 895 | + ret = gst_adaptive_demux_update_manifest (demux); | ||
| 896 | + break; | ||
| 897 | + } else if (gst_adaptive_demux_stream_wait_manifest_update (demux, | ||
| 898 | + stream)) { | ||
| 899 | goto end; | ||
| 900 | } | ||
| 901 | gst_task_stop (stream->download_task); | ||
| 902 | diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h | ||
| 903 | index 780f4d93f..9a1a1b7d1 100644 | ||
| 904 | --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h | ||
| 905 | +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h | ||
| 906 | @@ -459,6 +459,20 @@ struct _GstAdaptiveDemuxClass | ||
| 907 | * selected period. | ||
| 908 | */ | ||
| 909 | GstClockTime (*get_period_start_time) (GstAdaptiveDemux *demux); | ||
| 910 | + | ||
| 911 | + /** | ||
| 912 | + * requires_periodical_playlist_update: | ||
| 913 | + * @demux: #GstAdaptiveDemux | ||
| 914 | + * | ||
| 915 | + * Some adaptive streaming protocols allow the client to download | ||
| 916 | + * the playlist once and build up the fragment list based on the | ||
| 917 | + * current fragment metadata. For those protocols the demuxer | ||
| 918 | + * doesn't need to periodically refresh the playlist. This vfunc | ||
| 919 | + * is relevant only for live playback scenarios. | ||
| 920 | + * | ||
| 921 | + * Return: %TRUE if the playlist needs to be refreshed periodically by the demuxer. | ||
| 922 | + */ | ||
| 923 | + gboolean (*requires_periodical_playlist_update) (GstAdaptiveDemux * demux); | ||
| 924 | }; | ||
| 925 | |||
| 926 | GType gst_adaptive_demux_get_type (void); | ||
| 927 | -- | ||
| 928 | 2.11.0 | ||
| 929 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch deleted file mode 100644 index 76d29e151b..0000000000 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch +++ /dev/null | |||
| @@ -1,183 +0,0 @@ | |||
| 1 | From e9178fa082116d4bf733b184a8b6951112c17900 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Matthew Waters <matthew@centricular.com> | ||
| 3 | Date: Thu, 10 Nov 2016 17:18:36 +1100 | ||
| 4 | Subject: [PATCH] smoothstreaming: implement adaptivedemux's | ||
| 5 | get_live_seek_range() | ||
| 6 | |||
| 7 | Allows seeking through the available fragments that are still available | ||
| 8 | on the server as specified by the DVRWindowLength attribute in the | ||
| 9 | manifest. | ||
| 10 | |||
| 11 | https://bugzilla.gnome.org/show_bug.cgi?id=774178 | ||
| 12 | --- | ||
| 13 | Upstream-Status: Backport | ||
| 14 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 15 | |||
| 16 | ext/smoothstreaming/gstmssdemux.c | 13 ++++++ | ||
| 17 | ext/smoothstreaming/gstmssmanifest.c | 84 ++++++++++++++++++++++++++++++++++++ | ||
| 18 | ext/smoothstreaming/gstmssmanifest.h | 1 + | ||
| 19 | 3 files changed, 98 insertions(+) | ||
| 20 | |||
| 21 | diff --git a/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c | ||
| 22 | index 9d0aece2b..b66e19514 100644 | ||
| 23 | --- a/ext/smoothstreaming/gstmssdemux.c | ||
| 24 | +++ b/ext/smoothstreaming/gstmssdemux.c | ||
| 25 | @@ -138,6 +138,8 @@ gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux); | ||
| 26 | static GstFlowReturn | ||
| 27 | gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux, | ||
| 28 | GstBuffer * buffer); | ||
| 29 | +static gboolean gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, | ||
| 30 | + gint64 * start, gint64 * stop); | ||
| 31 | |||
| 32 | static void | ||
| 33 | gst_mss_demux_class_init (GstMssDemuxClass * klass) | ||
| 34 | @@ -192,6 +194,8 @@ gst_mss_demux_class_init (GstMssDemuxClass * klass) | ||
| 35 | gst_mss_demux_stream_update_fragment_info; | ||
| 36 | gstadaptivedemux_class->update_manifest_data = | ||
| 37 | gst_mss_demux_update_manifest_data; | ||
| 38 | + gstadaptivedemux_class->get_live_seek_range = | ||
| 39 | + gst_mss_demux_get_live_seek_range; | ||
| 40 | |||
| 41 | GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin"); | ||
| 42 | } | ||
| 43 | @@ -659,3 +663,12 @@ gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux, | ||
| 44 | gst_mss_manifest_reload_fragments (mssdemux->manifest, buffer); | ||
| 45 | return GST_FLOW_OK; | ||
| 46 | } | ||
| 47 | + | ||
| 48 | +static gboolean | ||
| 49 | +gst_mss_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start, | ||
| 50 | + gint64 * stop) | ||
| 51 | +{ | ||
| 52 | + GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux); | ||
| 53 | + | ||
| 54 | + return gst_mss_manifest_get_live_seek_range (mssdemux->manifest, start, stop); | ||
| 55 | +} | ||
| 56 | diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c | ||
| 57 | index 1b72e8de1..317b3cef9 100644 | ||
| 58 | --- a/ext/smoothstreaming/gstmssmanifest.c | ||
| 59 | +++ b/ext/smoothstreaming/gstmssmanifest.c | ||
| 60 | @@ -42,6 +42,7 @@ GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug); | ||
| 61 | |||
| 62 | #define MSS_PROP_BITRATE "Bitrate" | ||
| 63 | #define MSS_PROP_DURATION "d" | ||
| 64 | +#define MSS_PROP_DVR_WINDOW_LENGTH "DVRWindowLength" | ||
| 65 | #define MSS_PROP_LANGUAGE "Language" | ||
| 66 | #define MSS_PROP_NUMBER "n" | ||
| 67 | #define MSS_PROP_REPETITIONS "r" | ||
| 68 | @@ -94,6 +95,7 @@ struct _GstMssManifest | ||
| 69 | xmlNodePtr xmlrootnode; | ||
| 70 | |||
| 71 | gboolean is_live; | ||
| 72 | + gint64 dvr_window; | ||
| 73 | |||
| 74 | GString *protection_system_id; | ||
| 75 | gchar *protection_data; | ||
| 76 | @@ -330,6 +332,22 @@ gst_mss_manifest_new (GstBuffer * data) | ||
| 77 | xmlFree (live_str); | ||
| 78 | } | ||
| 79 | |||
| 80 | + /* the entire file is always available for non-live streams */ | ||
| 81 | + if (!manifest->is_live) { | ||
| 82 | + manifest->dvr_window = 0; | ||
| 83 | + } else { | ||
| 84 | + /* if 0, or non-existent, the length is infinite */ | ||
| 85 | + gchar *dvr_window_str = (gchar *) xmlGetProp (root, | ||
| 86 | + (xmlChar *) MSS_PROP_DVR_WINDOW_LENGTH); | ||
| 87 | + if (dvr_window_str) { | ||
| 88 | + manifest->dvr_window = g_ascii_strtoull (dvr_window_str, NULL, 10); | ||
| 89 | + xmlFree (dvr_window_str); | ||
| 90 | + if (manifest->dvr_window <= 0) { | ||
| 91 | + manifest->dvr_window = 0; | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | for (nodeiter = root->children; nodeiter; nodeiter = nodeiter->next) { | ||
| 97 | if (nodeiter->type == XML_ELEMENT_NODE | ||
| 98 | && (strcmp ((const char *) nodeiter->name, "StreamIndex") == 0)) { | ||
| 99 | @@ -1406,3 +1424,69 @@ gst_mss_stream_get_lang (GstMssStream * stream) | ||
| 100 | { | ||
| 101 | return stream->lang; | ||
| 102 | } | ||
| 103 | + | ||
| 104 | +static GstClockTime | ||
| 105 | +gst_mss_manifest_get_dvr_window_length_clock_time (GstMssManifest * manifest) | ||
| 106 | +{ | ||
| 107 | + gint64 timescale; | ||
| 108 | + | ||
| 109 | + /* the entire file is always available for non-live streams */ | ||
| 110 | + if (manifest->dvr_window == 0) | ||
| 111 | + return GST_CLOCK_TIME_NONE; | ||
| 112 | + | ||
| 113 | + timescale = gst_mss_manifest_get_timescale (manifest); | ||
| 114 | + return (GstClockTime) gst_util_uint64_scale_round (manifest->dvr_window, | ||
| 115 | + GST_SECOND, timescale); | ||
| 116 | +} | ||
| 117 | + | ||
| 118 | +static gboolean | ||
| 119 | +gst_mss_stream_get_live_seek_range (GstMssStream * stream, gint64 * start, | ||
| 120 | + gint64 * stop) | ||
| 121 | +{ | ||
| 122 | + GList *l; | ||
| 123 | + GstMssStreamFragment *fragment; | ||
| 124 | + guint64 timescale = gst_mss_stream_get_timescale (stream); | ||
| 125 | + | ||
| 126 | + g_return_val_if_fail (stream->active, FALSE); | ||
| 127 | + | ||
| 128 | + /* XXX: assumes all the data in the stream is still available */ | ||
| 129 | + l = g_list_first (stream->fragments); | ||
| 130 | + fragment = (GstMssStreamFragment *) l->data; | ||
| 131 | + *start = gst_util_uint64_scale_round (fragment->time, GST_SECOND, timescale); | ||
| 132 | + | ||
| 133 | + l = g_list_last (stream->fragments); | ||
| 134 | + fragment = (GstMssStreamFragment *) l->data; | ||
| 135 | + *stop = gst_util_uint64_scale_round (fragment->time + fragment->duration * | ||
| 136 | + fragment->repetitions, GST_SECOND, timescale); | ||
| 137 | + | ||
| 138 | + return TRUE; | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +gboolean | ||
| 142 | +gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start, | ||
| 143 | + gint64 * stop) | ||
| 144 | +{ | ||
| 145 | + GSList *iter; | ||
| 146 | + gboolean ret = FALSE; | ||
| 147 | + | ||
| 148 | + for (iter = manifest->streams; iter; iter = g_slist_next (iter)) { | ||
| 149 | + GstMssStream *stream = iter->data; | ||
| 150 | + | ||
| 151 | + if (stream->active) { | ||
| 152 | + /* FIXME: bound this correctly for multiple streams */ | ||
| 153 | + if (!(ret = gst_mss_stream_get_live_seek_range (stream, start, stop))) | ||
| 154 | + break; | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + if (ret && gst_mss_manifest_is_live (manifest)) { | ||
| 159 | + GstClockTime dvr_window = | ||
| 160 | + gst_mss_manifest_get_dvr_window_length_clock_time (manifest); | ||
| 161 | + | ||
| 162 | + if (GST_CLOCK_TIME_IS_VALID (dvr_window) && *stop - *start > dvr_window) { | ||
| 163 | + *start = *stop - dvr_window; | ||
| 164 | + } | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + return ret; | ||
| 168 | +} | ||
| 169 | diff --git a/ext/smoothstreaming/gstmssmanifest.h b/ext/smoothstreaming/gstmssmanifest.h | ||
| 170 | index af7419c23..6b7b1f971 100644 | ||
| 171 | --- a/ext/smoothstreaming/gstmssmanifest.h | ||
| 172 | +++ b/ext/smoothstreaming/gstmssmanifest.h | ||
| 173 | @@ -54,6 +54,7 @@ void gst_mss_manifest_reload_fragments (GstMssManifest * manifest, GstBuffer * d | ||
| 174 | GstClockTime gst_mss_manifest_get_min_fragment_duration (GstMssManifest * manifest); | ||
| 175 | const gchar * gst_mss_manifest_get_protection_system_id (GstMssManifest * manifest); | ||
| 176 | const gchar * gst_mss_manifest_get_protection_data (GstMssManifest * manifest); | ||
| 177 | +gboolean gst_mss_manifest_get_live_seek_range (GstMssManifest * manifest, gint64 * start, gint64 * stop); | ||
| 178 | |||
| 179 | GstMssStreamType gst_mss_stream_get_type (GstMssStream *stream); | ||
| 180 | GstCaps * gst_mss_stream_get_caps (GstMssStream * stream); | ||
| 181 | -- | ||
| 182 | 2.11.0 | ||
| 183 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch deleted file mode 100644 index 4e51040863..0000000000 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | From 0fbee8f37427b88339194b22ba9aa210772a8613 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Matthew Waters <matthew@centricular.com> | ||
| 3 | Date: Thu, 10 Nov 2016 17:20:27 +1100 | ||
| 4 | Subject: [PATCH] smoothstreaming: use the duration from the list of fragments | ||
| 5 | if not present in the manifest | ||
| 6 | |||
| 7 | Provides a more accurate duration for live streams that may be minutes | ||
| 8 | or hours in front of the earliest fragment. | ||
| 9 | |||
| 10 | https://bugzilla.gnome.org/show_bug.cgi?id=774178 | ||
| 11 | --- | ||
| 12 | Upstream-Status: Backport | ||
| 13 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 14 | |||
| 15 | ext/smoothstreaming/gstmssmanifest.c | 24 ++++++++++++++++++++++++ | ||
| 16 | 1 file changed, 24 insertions(+) | ||
| 17 | |||
| 18 | diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c | ||
| 19 | index 317b3cef9..144bbb42d 100644 | ||
| 20 | --- a/ext/smoothstreaming/gstmssmanifest.c | ||
| 21 | +++ b/ext/smoothstreaming/gstmssmanifest.c | ||
| 22 | @@ -888,6 +888,7 @@ gst_mss_manifest_get_duration (GstMssManifest * manifest) | ||
| 23 | gchar *duration; | ||
| 24 | guint64 dur = -1; | ||
| 25 | |||
| 26 | + /* try the property */ | ||
| 27 | duration = | ||
| 28 | (gchar *) xmlGetProp (manifest->xmlrootnode, | ||
| 29 | (xmlChar *) MSS_PROP_STREAM_DURATION); | ||
| 30 | @@ -895,6 +896,29 @@ gst_mss_manifest_get_duration (GstMssManifest * manifest) | ||
| 31 | dur = g_ascii_strtoull (duration, NULL, 10); | ||
| 32 | xmlFree (duration); | ||
| 33 | } | ||
| 34 | + /* else use the fragment list */ | ||
| 35 | + if (dur <= 0) { | ||
| 36 | + guint64 max_dur = 0; | ||
| 37 | + GSList *iter; | ||
| 38 | + | ||
| 39 | + for (iter = manifest->streams; iter; iter = g_slist_next (iter)) { | ||
| 40 | + GstMssStream *stream = iter->data; | ||
| 41 | + | ||
| 42 | + if (stream->active) { | ||
| 43 | + if (stream->fragments) { | ||
| 44 | + GList *l = g_list_last (stream->fragments); | ||
| 45 | + GstMssStreamFragment *fragment = (GstMssStreamFragment *) l->data; | ||
| 46 | + guint64 frag_dur = | ||
| 47 | + fragment->time + fragment->duration * fragment->repetitions; | ||
| 48 | + max_dur = MAX (frag_dur, max_dur); | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + if (max_dur != 0) | ||
| 54 | + dur = max_dur; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | return dur; | ||
| 58 | } | ||
| 59 | |||
| 60 | -- | ||
| 61 | 2.11.0 | ||
| 62 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.12.2.bb index a7692304d8..8321da0c27 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.10.4.bb +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.12.2.bb | |||
| @@ -1,9 +1,7 @@ | |||
| 1 | require gstreamer1.0-plugins-bad.inc | 1 | require gstreamer1.0-plugins-bad.inc |
| 2 | 2 | ||
| 3 | LIC_FILES_CHKSUM = "file://COPYING;md5=73a5855a8119deb017f5f13cf327095d \ | 3 | LIC_FILES_CHKSUM = "file://COPYING;md5=73a5855a8119deb017f5f13cf327095d \ |
| 4 | file://COPYING.LIB;md5=21682e4e8fea52413fd26c60acb907e5 \ | 4 | file://COPYING.LIB;md5=21682e4e8fea52413fd26c60acb907e5 " |
| 5 | file://gst/tta/crc32.h;beginline=12;endline=29;md5=27db269c575d1e5317fffca2d33b3b50 \ | ||
| 6 | file://gst/tta/filters.h;beginline=12;endline=29;md5=8a08270656f2f8ad7bb3655b83138e5a" | ||
| 7 | 5 | ||
| 8 | SRC_URI = " \ | 6 | SRC_URI = " \ |
| 9 | http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-${PV}.tar.xz \ | 7 | http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-${PV}.tar.xz \ |
| @@ -15,15 +13,12 @@ SRC_URI = " \ | |||
| 15 | file://0009-glimagesink-Downrank-to-marginal.patch \ | 13 | file://0009-glimagesink-Downrank-to-marginal.patch \ |
| 16 | file://0001-introspection.m4-prefix-pkgconfig-paths-with-PKG_CON.patch \ | 14 | file://0001-introspection.m4-prefix-pkgconfig-paths-with-PKG_CON.patch \ |
| 17 | file://0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch \ | 15 | file://0001-Prepend-PKG_CONFIG_SYSROOT_DIR-to-pkg-config-output.patch \ |
| 18 | file://0001-smoothstreaming-implement-adaptivedemux-s-get_live_s.patch \ | ||
| 19 | file://0001-smoothstreaming-use-the-duration-from-the-list-of-fr.patch \ | ||
| 20 | file://0001-mssdemux-improved-live-playback-support.patch \ | ||
| 21 | file://link-with-libvchostif.patch \ | 16 | file://link-with-libvchostif.patch \ |
| 22 | file://0001-vkdisplay-Use-ifdef-for-platform-specific-defines.patch \ | 17 | file://0001-vkdisplay-Use-ifdef-for-platform-specific-defines.patch \ |
| 23 | file://0002-vulkan-Use-the-generated-version-of-vkconfig.h.patch \ | 18 | file://0002-vulkan-Use-the-generated-version-of-vkconfig.h.patch \ |
| 24 | " | 19 | " |
| 25 | SRC_URI[md5sum] = "2757103e57a096a1a05b3ab85b8381af" | 20 | SRC_URI[md5sum] = "5683f0ea91f9e1e0613b0f6f729980a7" |
| 26 | SRC_URI[sha256sum] = "23ddae506b3a223b94869a0d3eea3e9a12e847f94d2d0e0b97102ce13ecd6966" | 21 | SRC_URI[sha256sum] = "9c2c7edde4f59d74eb414e0701c55131f562e5c605a3ce9b091754f106c09e37" |
| 27 | 22 | ||
| 28 | S = "${WORKDIR}/gst-plugins-bad-${PV}" | 23 | S = "${WORKDIR}/gst-plugins-bad-${PV}" |
| 29 | 24 | ||
