['gst-plugins-ugly', { 'option': get_option('ugly'), 'build-hotdoc': true}],
['gst-libav', { 'option': get_option('libav'), 'build-hotdoc': true}],
['gst-rtsp-server', { 'option': get_option('rtsp_server'), 'build-hotdoc': true}],
- ['gst-devtools', { 'option': get_option('devtools'), 'build-hotdoc': true, 'subproject_options': tools_option}],
+ ['gst-devtools', { 'option': get_option('devtools'), 'build-hotdoc': true}],
['gst-integration-testsuites', { 'option': get_option('devtools') }],
- ['gst-editing-services', { 'option': get_option('ges'), 'build-hotdoc': true, 'subproject_options': tools_option}],
+ ['gst-editing-services', { 'option': get_option('ges'), 'build-hotdoc': true}],
['gstreamer-vaapi', { 'option': get_option('vaapi'), 'build-hotdoc': true}],
+ ['gst-omx', { 'option': get_option('omx'), 'build-hotdoc': true}],
['gstreamer-sharp', { 'option': get_option('sharp') }],
['pygobject', { 'option': get_option('python'), 'match_gst_version': false, 'sysdep': 'pygobject-3.0', 'sysdep_version': '>= 3.8' }],
- ['gst-python', { 'option': get_option('python')}],
+ ['gst-python', { 'option': gst_python_option}],
['gst-examples', { 'option': get_option('gst-examples'), 'match_gst_versions': false}],
['gst-plugins-rs', { 'option': get_option('rs'), 'build-hotdoc': true, 'match_gst_version': false}],
]
option('good', type : 'feature', value : 'enabled')
option('ugly', type : 'feature', value : 'enabled')
option('bad', type : 'feature', value : 'enabled')
-option('libav', type : 'feature', value : 'auto')
++option('libav', type : 'feature', value : 'enabled')
option('devtools', type : 'feature', value : 'auto')
-option('ges', type : 'feature', value : 'auto')
-option('rtsp_server', type : 'feature', value : 'auto')
+option('ges', type : 'feature', value : 'enabled')
+option('rtsp_server', type : 'feature', value : 'enabled')
+option('omx', type : 'feature', value : 'enabled')
+ option('rs', type : 'feature', value : 'disabled')
option('vaapi', type : 'feature', value : 'disabled')
+ option('gst-examples', type : 'feature', value : 'auto', description : 'Build gst-examples subproject')
+ # Bindings
+ option('python', type : 'feature', value : 'auto')
option('sharp', type : 'feature', value : 'disabled')
- option('rs', type : 'feature', value : 'disabled')
- option('gst-examples', type : 'feature', value : 'auto', description : 'Build gst-examples')
- option('tls', type : 'feature', value : 'auto', description : 'TLS support using glib-networking')
- option('qt5', type : 'feature', value : 'auto', description : 'Qt5 Support')
- option('tools', type : 'feature', value : 'enabled', description : 'Build command line tools')
+ # External subprojects
+ option('tls', type : 'feature', value : 'auto', description : 'TLS support using glib-networking as a subproject')
+ option('libnice', type : 'feature', value : 'auto', description: 'ICE support using libnice as a subproject')
# Build for fuzzing
option('oss_fuzz', type : 'feature', value : 'disabled',
# Common options, automatically inherited by subprojects
option('tests', type : 'feature', value : 'auto', description : 'Build tests')
-option('tools', type : 'feature', value : 'auto', yield : true, description : 'Build command line tools')
++option('tools', type : 'feature', value : 'enabled', yield : true, description : 'Build command line tools')
option('examples', type : 'feature', value : 'auto', description : 'Build examples')
option('introspection', type : 'feature', value : 'auto', description : 'Generate introspection data')
- option('nls', type : 'feature', value : 'auto', description : 'Enable native language support (translations)')
- option('orc', type : 'feature', value : 'auto', description : 'Enable Optimized Inner Loop Runtime Compiler')
- option('doc', type : 'feature', value : 'auto', description : 'Generate API documentation with hotdoc')
+ option('nls', type : 'feature', value : 'auto', description : 'Native language support (translations)')
+ option('orc', type : 'feature', value : 'auto', description : 'Optimized Inner Loop Runtime Compiler (SIMD)')
+ option('doc', type : 'feature', value : 'disabled', description : 'Generate API documentation with hotdoc')
option('gtk_doc', type : 'feature', value : 'disabled', description : 'Generate API documentation with gtk-doc')
+ option('qt5', type : 'feature', value : 'auto', description : 'Qt5 toolkit support')
+ option('qt6', type : 'feature', value : 'auto', description : 'Qt6 toolkit support')
+ option('webrtc', type : 'feature', value : 'auto', description : 'WebRTC support')
option('package-origin', type : 'string', value : 'Unknown package origin', yield : true,
description : 'package origin URL to use in plugins')
--- /dev/null
- Version: 1.22.8
- Release: 17
+%bcond_with x
+%bcond_with wayland
+
+%define gst_branch 1.0
+%define _lib_gstreamer_dir %{_libdir}/gstreamer-%{gst_branch}
+%define _lib_girepository %{_libdir}/girepository-%{gst_branch}
+%define _enable_v4l2h264enc 0
+%define _enable_introspection 0
+
+#######################################################################
+## how to build each plugin :
+## add define option at gbs build cmd like [ --define "plugin bad" ]
+## if not, all the source code in subprojects will be built
+#######################################################################
+
+%if 0%{?plugin:1}
+ %if "%{plugin}" == "core"
+ %define _name gstreamer
+ %define _core_opt ""
+ %endif
+ %if "%{plugin}" == "base" || "%{plugin}" == "good" || "%{plugin}" == "bad" || "%{plugin}" == "ugly"
+ %define _name gst-plugins-%{plugin}
+ %define _base_opt ""
+ %define _good_opt ""
+ %define _bad_opt ""
+ %define _ugly_opt ""
+ %endif
+ %if "%{plugin}" == "omx" || "%{plugin}" == "libav"
+ %define _name gst-%{plugin}
+ %define _omx_opt ""
+ %define _libav_opt ""
+ %endif
+ %if "%{plugin}" == "rs"
+ %define _name gst-rtsp-server
+ %define _rs_opt ""
+ %endif
+ %if "%{plugin}" == "es"
+ %define _name gst-editing-services
+ %define _es_opt ""
+ %endif
+
+ %define _source_path subprojects/%{_name}
+
+%else
+
+ %define plugin all
+ %define _name gstreamer
+ %define _source_path .
+
+ # plugin option prefix
+ %define _core_opt gstreamer:
+ %define _base_opt gst-plugins-base:
+ %define _good_opt gst-plugins-good:
+ %define _bad_opt gst-plugins-bad:
+ %define _ugly_opt gst-plugins-ugly:
+ %define _omx_opt gst-omx:
+ %define _libav_opt gst-libav:
+ %define _rs_opt gst-rtsp-server:
+ %define _es_opt gst-editing-services:
+
+%endif
+
+Name: %{_name}
- BuildRequires: pkgconfig(opencore-amrwb)
- %if "%{tizen_profile_name}" != "tv"
- BuildRequires: pkgconfig(opencore-amrnb)
- %endif
++Version: 1.24.9
++Release: 0
+Summary: Streaming-Media Framework Runtime
+License: LGPL-2.0+
+Group: Multimedia/Framework
+Url: http://gstreamer.freedesktop.org/
+Source0: gstreamer-%{version}.tar.gz
+Source1001: gstreamer.manifest
+BuildRequires: meson >= 0.62.0
+BuildRequires: gettext-tools
+BuildRequires: pkgconfig(glib-2.0) >= 2.32.0
+
+
+%if "%{plugin}" == "all" || "%{plugin}" == "core"
+
+BuildRequires: bison
+BuildRequires: fdupes
+BuildRequires: flex
+BuildRequires: libtool
+BuildRequires: pkgconfig(dlog)
+%if "%{_enable_introspection}" == "1"
+BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.31.1
+%endif
+BuildRequires: pkgconfig(libxml-2.0)
+
+%description -n gstreamer
+GStreamer is a streaming-media framework, based on graphs of filters
+which operate on media data. Applications using this library can do
+anything from real-time sound processing to playing videos, and just
+about anything else media-related. Its plug-in-based architecture
+means that new data types or processing capabilities can be added by
+installing new plug-ins.
+
+%package -n gstreamer-utils
+Summary: Streaming-Media Framework Runtime
+Group: Multimedia/Framework
+Provides: gstreamer:%{_bindir}/gst-launch-%{gst_branch} = %{version}
+# Symbol for unversioned wrappers:
+Provides: gstreamer-utils_versioned = %{version}
+
+%description -n gstreamer-utils
+GStreamer is a streaming-media framework, based on graphs of filters
+which operate on media data. Applications using this library can do
+anything from real-time sound processing to playing videos, and just
+about anything else media-related. Its plug-in-based architecture
+means that new data types or processing capabilities can be added by
+installing new plug-ins.
+
+%package -n gstreamer-devel
+Summary: Include Files and Libraries mandatory for Development
+Group: Development/Libraries
+# gstreamer-utils is required for the gstreamer-provides rpm magic.
+Requires: gstreamer-utils = %{version}
+Requires: gstreamer = %{version}
+
+%description -n gstreamer-devel
+This package contains all necessary include files and libraries needed
+to develop applications that require these.
+
+%else
+
+BuildRequires: pkgconfig(gstreamer-1.0)
+
+%if "%{plugin}" != "base"
+BuildRequires: pkgconfig(gstreamer-plugins-base-1.0)
+%endif
+
+%endif
+
+#######################################################
+## Package info of Base Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-plugins-base
+Summary: GStreamer Streaming-Media Framework Plug-Ins
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "base"
+
+BuildRequires: orc >= 0.4.16
+BuildRequires: python
+BuildRequires: pkgconfig(alsa) >= 0.9.1
+BuildRequires: pkgconfig(freetype2) >= 2.0.9
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(ogg) >= 1.0
+BuildRequires: pkgconfig(opus)
+BuildRequires: pkgconfig(theoradec) >= 1.1
+BuildRequires: pkgconfig(theoraenc) >= 1.1
+BuildRequires: pkgconfig(vorbis) >= 1.0
+BuildRequires: pkgconfig(vorbisenc) >= 1.0
+BuildRequires: pkgconfig(zlib)
+%if "%{_enable_introspection}" == "1"
+BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.31.1
+%endif
+%if "%{tizen_profile_name}" != "tv"
+BuildRequires: update-desktop-files
+%endif
+%if %{with wayland}
+%if 0%{?enable_gl:1}
+BuildRequires: pkgconfig(gles20)
+BuildRequires: pkgconfig(wayland-egl) >= 9.0
+%endif # wayland
+%endif # gl
+%if %{with x}
+BuildRequires: pkgconfig(dri2proto)
+BuildRequires: pkgconfig(libdri2)
+BuildRequires: pkgconfig(ice)
+BuildRequires: pkgconfig(sm)
+BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(xv)
+BuildRequires: pkgconfig(xfixes)
+%endif
+# gstreamer-utils is required for the gstreamer-provides rpm magic.
+Requires: gstreamer >= 1.0.0
+Requires: opus
+Supplements: gstreamer
+
+%description -n gst-plugins-base
+GStreamer is a streaming media framework based on graphs of filters
+that operate on media data. Applications using this library can do
+anything media-related, from real-time sound processing to playing
+videos. Its plug-in-based architecture means that new data types or
+processing capabilities can be added simply by installing new plug-ins.
+
+%if "%{tizen_profile_name}" != "tv"
+%package -n gst-plugins-base-extension-adder
+Summary: libgstadder.so for gst-plugins-base
+Requires: gst-plugins-base = %{version}-%{release}
+Provides: gst-plugins-base-profile_mobile = %{version}-%{release}
+
+%description -n gst-plugins-base-extension-adder
+Libgstadder.so for gst-plugin-base. Supplicant for gst-plugin-base.
+This is for Tizen mobile profile.
+%endif
+
+%package -n gst-plugins-base-devel
+Summary: Include files and Libraries
+Requires: gst-plugins-base = %{version}
+
+%description -n gst-plugins-base-devel
+This package contains all necessary include files and libraries needed
+to compile and link applications that use gstreamer-plugins-base.
+
+%endif
+
+#######################################################
+## Package info of Good Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-plugins-good
+Summary: GStreamer Streaming-Media Framework Plug-Ins
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "good"
+
+BuildRequires: libjpeg-devel
+BuildRequires: orc >= 0.4.16
+BuildRequires: python
+BuildRequires: xsltproc
+BuildRequires: pkgconfig(bzip2)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(libpulse) >= 1.0
+BuildRequires: pkgconfig(libsoup-2.4)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(libxml-2.0) >= 2.4.9
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(vpx)
+BuildRequires: pkgconfig(zlib)
++BuildRequires: pkgconfig(opencore-amrwb)
+%if "%{tizen_profile_name}" != "tv"
++BuildRequires: pkgconfig(opencore-amrnb)
+BuildRequires: pkgconfig(libpng) >= 1.2
+%endif
+%if %{with x}
+BuildRequires: pkgconfig(ice)
+BuildRequires: pkgconfig(sm)
+BuildRequires: pkgconfig(xdamage)
+BuildRequires: pkgconfig(xfixes)
+# used by libgstvideo4linux2.so
+BuildRequires: pkgconfig(xv)
+%endif
+Requires: gstreamer >= %{version}
+Requires: gst-plugins-base >= %{version}
+Requires: libsoup
+
+%description -n gst-plugins-good
+GStreamer is a streaming media framework based on graphs of filters
+that operate on media data. Applications using this library can do
+anything media-related, from real-time sound processing to playing
+videos. Its plug-in-based architecture means that new data types or
+processing capabilities can be added simply by installing new plug-ins.
+
+%package -n gst-plugins-good-extra
+Summary: Complementary plugins for gst-plugins-good
+Group: Productivity/Multimedia/Other
+Requires: gst-plugins-good = %{version}
+Enhances: gst-plugins-good
+
+%description -n gst-plugins-good-extra
+This package provides complementary plugins for gst-plugins-good and
+plugins not included in official Tizen images, which may be used for development / experimental purposes.
+
+%if "%{tizen_profile_name}" != "tv"
+%package -n gst-plugins-good-cairo
+Summary: Cairo plugin for gst-plugins-good
+Group: Multimedia/Framework
+BuildRequires: pkgconfig(cairo)
+BuildRequires: pkgconfig(cairo-gobject)
+Requires: gst-plugins-good = %{version}
+Enhances: gst-plugins-good
+
+%description -n gst-plugins-good-cairo
+This package provides cairo plugin for gst-plugins-good and
+this is not included in Tizen headless image.
+
+%package -n gst-plugins-good-v4l2
+Summary: Video4Linux2 plugin for gst-plugins-good
+Group: Multimedia/Framework
+BuildRequires: pkgconfig(libv4l2)
+Requires: gst-plugins-good = %{version}
+Enhances: gst-plugins-good
+
+%description -n gst-plugins-good-v4l2
+This package provides Video4Linux2 plugin for gst-plugins-good.
+%endif
+
+%endif
+
+#######################################################
+## Package info of Bad Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-plugins-bad
+Summary: GStreamer Streaming-Media Framework Plug-Ins
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "bad"
+
+BuildRequires: python
+BuildRequires: xsltproc
+BuildRequires: pkgconfig(gio-2.0) >= 2.25.0
+BuildRequires: pkgconfig(libcurl) >= 7.21.0
+BuildRequires: pkgconfig(libexif) >= 0.6.16
+BuildRequires: pkgconfig(libsrtp2) >= 2.1.0
+BuildRequires: pkgconfig(libusb-1.0)
+BuildRequires: pkgconfig(nice)
+BuildRequires: pkgconfig(openal)
+BuildRequires: pkgconfig(openssl1.1)
+BuildRequires: pkgconfig(opus)
+BuildRequires: pkgconfig(orc-0.4) >= 0.4.11
+BuildRequires: pkgconfig(sndfile) >= 1.0.16
+BuildRequires: pkgconfig(soundtouch) > 1.4
+%if "%{tizen_profile_name}" != "tv"
+BuildRequires: pkgconfig(srt)
+%endif
+%if %{with wayland}
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(wayland-client) >= 1.0.0
+BuildRequires: pkgconfig(wayland-cursor) >= 1.0.0
+BuildRequires: pkgconfig(wayland-protocols)
+%endif
+%if %{with x}
+BuildRequires: pkgconfig(x11)
+%endif
+Requires: gstreamer >= %{version}
+
+%description -n gst-plugins-bad
+GStreamer is a streaming media framework based on graphs of filters
+that operate on media data. Applications using this library can do
+anything media-related,from real-time sound processing to playing
+videos. Its plug-in-based architecture means that new data types or
+processing capabilities can be added simply by installing new plug-ins.
+
+%package -n gst-plugins-bad-devel
+Summary: GStreamer Streaming-Media Framework Plug-Ins
+Requires: gst-plugins-bad = %{version}-%{release}
+Requires: gst-plugins-base-devel
+
+%description -n gst-plugins-bad-devel
+GStreamer is a streaming media framework based on graphs of filters
+that operate on media data. Applications using this library can do
+anything media-related,from real-time sound processing to playing
+videos. Its plug-in-based architecture means that new data types or
+processing capabilities can be added simply by installing new plug-ins.
+
+%endif
+
+#######################################################
+## Package info of Ugly Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-plugins-ugly
+Summary: GStreamer plugins from the "ugly" set
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "ugly"
+
+BuildRequires: which
- -D %{_core_opt}ptp-helper-permissions=none \
+
+%description -n gst-plugins-ugly
+ GStreamer is a streaming media framework, based on graphs of filters
+ which operate on media data. Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related. Its plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This packages contains plugins from the "ugly" set, a set of
+ good-quality plug-ins that might pose distribution problems.
+
+%endif
+
+#######################################################
+## Package info of Omx Plugin
+#######################################################
+
+%if "%{tizen_profile_name}" != "tv"
+%ifarch %{arm} aarch64 riscv64
+
+%if "%{plugin}" == "all"
+%package -n gst-omx
+Summary: GStreamer plug-in that allows communication with OpenMAX IL components
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "omx"
+
+BuildRequires: which
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(mm-common)
+%if "%{target}" == "rpi"
+BuildRequires: pkgconfig(bcm_host)
+BuildRequires: pkgconfig(brcmegl)
+%endif
+
+%description -n gst-omx
+gst-openmax is a GStreamer plug-in that allows communication with OpenMAX IL components.
+Multiple OpenMAX IL implementations can be used.
+
+%endif # plugin
+%endif # arch
+%endif # profile
+
+#######################################################
+## Package info of libav Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-libav
+Summary: Libav plugin for GStreamer
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "libav"
+
+BuildRequires: bzip2-devel
+BuildRequires: gettext
+BuildRequires: which
+BuildRequires: yasm
+BuildRequires: pkgconfig(libavcodec)
+BuildRequires: pkgconfig(libavfilter)
+BuildRequires: pkgconfig(libavformat)
+BuildRequires: pkgconfig(libavutil)
+BuildRequires: pkgconfig(orc-0.4)
+BuildRequires: pkgconfig(theora)
+BuildRequires: pkgconfig(vorbis)
+BuildRequires: pkgconfig(zlib)
+
+%description -n gst-libav
+This GStreamer plugin supports a large number of audio and video compression
+formats through the use of the libav library. The plugin contains GStreamer
+elements for decoding 90+ formats (AVI, MPEG, OGG, Matroska, ASF, ...),
+demuxing 30+ formats and colorspace conversion.
+
+%endif
+
+#######################################################
+## Package info of rtsp-server Plugin
+#######################################################
+
+%if "%{plugin}" == "all"
+%package -n gst-rtsp-server
+Summary: Multimedia Framework Library
+Group: System/Libraries
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "rs"
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description -n gst-rtsp-server
+This GStreamer plugin supports a large number of audio and video compression
+formats through the use of the libav library. The plugin contains GStreamer
+elements for decoding 90+ formats (AVI, MPEG, OGG, Matroska, ASF, ...),
+demuxing 30+ formats and colorspace conversion.
+
+%package -n gst-rtsp-server-devel
+Summary: Multimedia Framework RTSP server library (DEV)
+Group: Development/Libraries
+Requires: gst-rtsp-server = %{version}-%{release}
+
+%description -n gst-rtsp-server-devel
+
+%endif
+
+#######################################################
+## Package info of editing-services Plugin
+#######################################################
+
+%if "%{tizen_profile_name}" != "tv"
+
+%if "%{plugin}" == "all"
+%package -n gst-editing-services
+Summary: GStreamer Editing Service Plug-Ins
+Group: Multimedia/Framework
+%endif
+
+%if "%{plugin}" == "all" || "%{plugin}" == "es"
+
+BuildRequires: flex
+BuildRequires: gtk-doc
+BuildRequires: pkgconfig(libxml-2.0)
+Requires: gstreamer >= 1.0.0
+Supplements: gstreamer
+
+%description -n gst-editing-services
+This is a high-level library for facilitating the creation of audio/video
+non-linear editors.
+
+%package -n gst-editing-services-devel
+Summary: Development files for gst-editing-services
+Requires: gst-editing-services = %{version}-%{release}
+
+%description -n gst-editing-services-devel
+This package contains libraries and header files for
+developing applications that use %{name}
+
+%endif # plugin
+
+%endif # profile
+
+#######################################################
+## Prep
+#######################################################
+
+%prep
+%setup -q -n gstreamer-%{version}
+cp %{SOURCE1001} ./gstreamer.manifest
+cp %{SOURCE1001} ./gst-plugins-base.manifest
+cp %{SOURCE1001} ./gst-plugins-good.manifest
+cp %{SOURCE1001} ./gst-plugins-bad.manifest
+cp %{SOURCE1001} ./gst-plugins-ugly.manifest
+cp %{SOURCE1001} ./gst-libav.manifest
+cp %{SOURCE1001} ./gst-rtsp-server.manifest
+%if "%{tizen_profile_name}" != "tv"
+cp %{SOURCE1001} ./gst-omx.manifest
+cp %{SOURCE1001} ./gst-editing-services.manifest
+%endif
+
+#######################################################
+## Build
+#######################################################
+
+%build
+
+%if "%{plugin}" != "all"
+pushd %{_source_path}
+%endif
+
+mkdir -p build
+export CFLAGS="%{optflags} \
+ -fno-strict-aliasing\
+ -fstack-protector-strong\
+ -Wl,-z,relro\
+%if "%{tizen_profile_name}" == "tv"
+ -Wno-declaration-after-statement\
+%endif
+ -D_FORTIFY_SOURCE=2"
+export CXXFLAGS+=" -Wno-error"
+export LDFLAGS+=" -pthread"
+
+meson --auto-features=disabled --prefix=/usr --libdir=%{_libdir} --datadir=%{_datadir} --sysconfdir=%{_hal_sysconfdir} \
+%if "%{plugin}" == "all"
+ %if "%{tizen_profile_name}" == "tv"
+ -D ges=disabled \
+ -D omx=disabled \
+ %endif # profile
+ %ifarch x86_64 %{ix86}
+ -D omx=disabled \
+ %endif # arch
++ -D webrtc=enabled \
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "core"
+ -D %{_core_opt}check=enabled \
+ -D %{_core_opt}coretracers=enabled \
+ -D %{_core_opt}extra-checks=enabled \
- -D %{_bad_opt}wayland=enabled \
+ -D %{_core_opt}tools=enabled \
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_core_opt}tv-profile=true \
+ %endif # profile
+ %if "%{_enable_introspection}" == "1"
+ -D %{_core_opt}introspection=enabled \
+ %endif # introspection
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "base"
+ -D %{_base_opt}alsa=enabled \
+ -D %{_base_opt}app=enabled \
+ -D %{_base_opt}audioconvert=enabled \
+ -D %{_base_opt}audiomixer=enabled \
+ -D %{_base_opt}audiorate=enabled \
+ -D %{_base_opt}audioresample=enabled \
+ -D %{_base_opt}audiotestsrc=enabled \
+ -D %{_base_opt}compositor=enabled \
+ -D %{_base_opt}gio=enabled \
+ -D %{_base_opt}gio-typefinder=enabled \
+ -D %{_base_opt}ogg=enabled \
+ -D %{_base_opt}opus=enabled \
+ -D %{_base_opt}overlaycomposition=enabled \
+ -D %{_base_opt}pbtypes=enabled \
+ -D %{_base_opt}playback=enabled \
+ -D %{_base_opt}rawparse=enabled \
+ -D %{_base_opt}subparse=enabled \
+ -D %{_base_opt}tbm=true \
+ -D %{_base_opt}tcp=enabled \
+ -D %{_base_opt}tools=disabled \
+ -D %{_base_opt}theora=enabled \
+ -D %{_base_opt}typefind=enabled \
+ -D %{_base_opt}videoconvertscale=enabled \
+ -D %{_base_opt}videorate=enabled \
+ -D %{_base_opt}videotestsrc=enabled \
+ -D %{_base_opt}volume=enabled \
+ -D %{_base_opt}vorbis=enabled \
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_base_opt}tv-profile=true \
+ %else
+ -D %{_base_opt}adder=enabled \
+ -D %{_base_opt}encoding=enabled \
+ %if 0%{?enable_gl:1}
+ -D %{_base_opt}gl=enabled \
+ %endif # gl
+ %endif # profile
+ %if "%{_enable_introspection}" == "1"
+ -D %{_base_opt}introspection=enabled \
+ %endif # introspection
+%endif # base plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "good"
+ %if 0%{?ENABLE_AALIB}
+ -D %{_good_opt}aalib=enabled \
+ %endif
+ -D %{_good_opt}adaptivedemux2=enabled \
++ -D %{_good_opt}amrwbdec=enabled \
+ -D %{_good_opt}apetag=enabled \
+ -D %{_good_opt}audiofx=enabled \
+ -D %{_good_opt}audioparsers=enabled \
+ -D %{_good_opt}autodetect=enabled \
+ -D %{_good_opt}avi=enabled \
+ -D %{_good_opt}debugutils=enabled \
+ -D %{_good_opt}deinterlace=enabled \
+ -D %{_good_opt}icydemux=enabled \
+ -D %{_good_opt}id3demux=enabled \
+ -D %{_good_opt}interleave=enabled \
+ -D %{_good_opt}isomp4=enabled \
+ -D %{_good_opt}jpeg=enabled \
+ -D %{_good_opt}law=enabled \
+ -D %{_good_opt}pulse=enabled \
+ -D %{_good_opt}replaygain=enabled \
+ -D %{_good_opt}rtp=enabled \
+ -D %{_good_opt}rtpmanager=enabled \
+ -D %{_good_opt}rtsp=enabled \
+ -D %{_good_opt}soup=enabled \
+ -D %{_good_opt}tbm=true \
+ -D %{_good_opt}udp=enabled \
+ -D %{_good_opt}videocrop=enabled \
+ -D %{_good_opt}videofilter=enabled \
+ -D %{_good_opt}vpx=enabled \
+ -D %{_good_opt}wavenc=enabled \
+ -D %{_good_opt}wavparse=enabled \
+ %if "%{_enable_v4l2h264enc}" == "1"
+ -D %{_good_opt}v4l2h264enc=enabled \
+ %endif
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_good_opt}tv-profile=true \
+ %ifnarch %{arm} aarch64
+ -D %{_good_opt}v4l2=enabled \
+ %endif
+ %else
++ -D %{_good_opt}amrnb=enabled \
+ -D %{_good_opt}cairo=enabled \
+ -D %{_good_opt}effectv=enabled \
+ -D %{_good_opt}flv=enabled \
+ -D %{_good_opt}imagefreeze=enabled \
+ -D %{_good_opt}matroska=enabled \
+ -D %{_good_opt}multifile=enabled \
+ -D %{_good_opt}png=enabled \
+ -D %{_good_opt}smpte=enabled \
+ -D %{_good_opt}v4l2=enabled \
+ -D %{_good_opt}v4l2-libv4l2=enabled \
+ -D %{_good_opt}v4l2-probe=true \
+ -D %{_good_opt}videobox=enabled \
+ -D %{_good_opt}videomixer=enabled \
+ %endif # profile
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "bad"
+ -D %{_bad_opt}aes=enabled \
+ -D %{_bad_opt}audiobuffersplit=enabled \
+ -D %{_bad_opt}audiolatency=enabled \
+ -D %{_bad_opt}audiomixmatrix=enabled \
+ -D %{_bad_opt}debugutils=enabled \
+ -D %{_bad_opt}dtls=enabled \
+ -D %{_bad_opt}gst_play_tests=false\
+ -D %{_bad_opt}introspection=disabled \
+ -D %{_bad_opt}ipcpipeline=enabled \
+ -D %{_bad_opt}midi=enabled \
+ -D %{_bad_opt}mpegtsdemux=enabled \
+ -D %{_bad_opt}mpegtsmux=enabled \
+ -D %{_bad_opt}netsim=enabled \
+ -D %{_bad_opt}openal=enabled \
+ -D %{_bad_opt}opus=enabled \
+ -D %{_bad_opt}proxy=enabled \
+ -D %{_bad_opt}sctp=enabled \
+ -D %{_bad_opt}sdp=enabled \
+ -D %{_bad_opt}shm=enabled \
+ -D %{_bad_opt}soundtouch=enabled \
+ -D %{_bad_opt}srtp=enabled \
+ -D %{_bad_opt}timecode=enabled \
+ -D %{_bad_opt}videoframe_audiolevel=enabled \
+ -D %{_bad_opt}videoparsers=enabled \
- -D %{_ugly_opt}amrwbdec=enabled \
+ -D %{_bad_opt}webrtc=enabled \
+ %if %{with wayland}
+ -D %{_bad_opt}wayland=enabled \
+ %endif
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_bad_opt}tv-profile=true \
+ %else
+ -D %{_bad_opt}autoconvert=enabled \
+ -D %{_bad_opt}camerabin2=enabled \
+ -D %{_bad_opt}coloreffects=enabled \
+ -D %{_bad_opt}dash=enabled \
+ -D %{_bad_opt}gaudieffects=enabled \
+ -D %{_bad_opt}gdp=enabled \
+ -D %{_bad_opt}hls=enabled \
+ -D %{_bad_opt}id3tag=enabled \
+ -D %{_bad_opt}jpegformat=enabled \
+ -D %{_bad_opt}mpegdemux=enabled \
+ -D %{_bad_opt}rist=enabled \
+ -D %{_bad_opt}rtp=enabled \
+ -D %{_bad_opt}srt=enabled \
+ -D %{_bad_opt}smoothstreaming=enabled \
+ %if 0%{?enable_gl:1}
+ -D %{_bad_opt}gl=enabled \
+ %endif # gl
+ %endif # profile
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "ugly"
- -D %{_ugly_opt}amrnb=enabled \
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_ugly_opt}tv-profile=true \
+ %else
- %{_libexecdir}/gstreamer-%{gst_branch}/gst-ptp-helper
+ -D %{_ugly_opt}asfdemux=enabled \
+ %endif # profile
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "libav"
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_libav_opt}tv-profile=true \
+ %endif # profile
+%endif # plugin
+%if "%{plugin}" == "all" || "%{plugin}" == "rs"
+ %if "%{tizen_profile_name}" == "tv"
+ -D %{_rs_opt}tv-profile=true \
+ %endif # profile
+ -D %{_rs_opt}introspection=disabled \
+ -D %{_rs_opt}rtspclientsink=enabled \
+%endif
+%if "%{tizen_profile_name}" != "tv"
+ %ifarch %{arm} aarch64 riscv64
+ %if "%{plugin}" == "all" || "%{plugin}" == "omx"
+ -D %{_omx_opt}tools=disabled \
+ %if "%{target}" == "rpi"
+ -D %{_omx_opt}header_path=/opt/vc/include/interface/vmcs_host/khronos/IL \
+ -D %{_omx_opt}target=rpi \
+ %else
+ %ifarch riscv64
+ -D %{_omx_opt}target=generic \
+ %else
+ %ifarch aarch64
+ -D %{_omx_opt}target=exynos64 \
+ %else
+ -D %{_omx_opt}target=exynos \
+ -D %{_omx_opt}vp9=true \
+ %endif # arch aarch64
+ %endif # arch riscv64
+ %endif # target
+ %endif # plugin
+ %endif # arch
+ %if "%{plugin}" == "all" || "%{plugin}" == "es"
+ -D %{_es_opt}introspection=disabled \
+ -D %{_es_opt}tools=enabled \
+ -D %{_es_opt}xptv=enabled \
+ -D %{_es_opt}python=enabled \
+ %endif # plugin
+%endif # profile
+ build
+
+ninja -C build all %{?_smp_mflags}
+
+%if "%{plugin}" != "all"
+popd
+%endif
+
+#######################################################
+## Install
+#######################################################
+
+%install
+rm -rf %{buildroot}
+export DESTDIR=%{buildroot}
+ninja -C %{_source_path}/build install
+mkdir -p %{buildroot}%{_datadir}/gstreamer-%{gst_branch}/presets
+rm -rf %{buildroot}%{_datadir}/gstreamer-%{gst_branch}/encoding-profiles
+rm -rf %{buildroot}%{_datadir}/locale
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+#######################################################
+## Packaging rpms
+#######################################################
+
+###################### gstreamer ######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "core"
+
+%files -n gstreamer
+%manifest gstreamer.manifest
+%defattr(-, root, root)
+%license subprojects/gstreamer/COPYING
+%dir %{_datadir}/gstreamer-%{gst_branch}
+%dir %{_datadir}/gstreamer-%{gst_branch}/presets
+%dir %{_lib_gstreamer_dir}
+%{_lib_gstreamer_dir}/libgstcoreelements.so
+%{_lib_gstreamer_dir}/libgstcoretracers.so
+%dir %{_libexecdir}/gstreamer-%{gst_branch}
+%{_libexecdir}/gstreamer-%{gst_branch}/gst-hotdoc-plugins-scanner
+%{_libexecdir}/gstreamer-%{gst_branch}/gst-plugin-scanner
- %{_lib_gstreamer_dir}/libgstamrnb.so
++%{_libexecdir}/gstreamer-%{gst_branch}/gst-completion-helper
+%exclude %{_libexecdir}/gstreamer-%{gst_branch}/gst-plugins-doc-cache-generator
+%{_libdir}/libgstbase-%{gst_branch}.so.*
+%{_libdir}/libgstcontroller-%{gst_branch}.so.*
+%{_libdir}/libgstnet-%{gst_branch}.so.*
+%{_libdir}/libgstcheck-%{gst_branch}.so.*
+%{_libdir}/libgstreamer-%{gst_branch}.so.*
+%if "%{_enable_introspection}" == "1"
+%{_lib_girepository}/Gst-%{gst_branch}.typelib
+%{_lib_girepository}/GstBase-%{gst_branch}.typelib
+%{_lib_girepository}/GstController-%{gst_branch}.typelib
+%{_lib_girepository}/GstNet-%{gst_branch}.typelib
+%{_lib_girepository}/GstCheck-%{gst_branch}.typelib
+%endif #introspection
+%{_datadir}/gdb/auto-load/usr/%{_lib}/libgstreamer-%{gst_branch}*-gdb.py
+%{_datadir}/gstreamer-%{gst_branch}/gdb/glib_gobject_helper.py
+%{_datadir}/gstreamer-%{gst_branch}/gdb/gst_gdb.py
+
+%files -n gstreamer-utils
+%manifest gstreamer.manifest
+%defattr(-, root, root)
+%license subprojects/gstreamer/COPYING
+%{_bindir}/gst-inspect-%{gst_branch}
+%{_bindir}/gst-launch-%{gst_branch}
+%{_bindir}/gst-stats-%{gst_branch}
+%{_bindir}/gst-typefind-%{gst_branch}
+%exclude %doc %{_mandir}/man?/*-%{gst_branch}.*
+
+%files -n gstreamer-devel
+%manifest gstreamer.manifest
+%defattr(-, root, root)
+%{_datadir}/aclocal/gst-element-check-%{gst_branch}.m4
+%{_includedir}/gstreamer-%{gst_branch}/gst/*.h
+%{_includedir}/gstreamer-%{gst_branch}/gst/base/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/controller/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/net/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/check/*
+%{_libdir}/libgstbase-%{gst_branch}.so
+%{_libdir}/libgstcontroller-%{gst_branch}.so
+%{_libdir}/libgstnet-%{gst_branch}.so
+%{_libdir}/libgstcheck-%{gst_branch}.so
+%{_libdir}/libgstreamer-%{gst_branch}.so
+%{_libdir}/pkgconfig/gstreamer-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-base-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-controller-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-net-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-check-%{gst_branch}.pc
+%if "%{_enable_introspection}" == "1"
+%{_datadir}/gir-%{gst_branch}/Gst-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstBase-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstController-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstNet-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstCheck-%{gst_branch}.gir
+%endif #introspection
+
+%changelog
+
+%endif
+
+###################### gst-plugins-base ######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "base"
+
+%files -n gst-plugins-base
+%manifest gst-plugins-base.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-base/COPYING
+%{_lib_gstreamer_dir}/libgstalsa.so
+%{_lib_gstreamer_dir}/libgstapp.so
+%{_lib_gstreamer_dir}/libgstaudioconvert.so
+%{_lib_gstreamer_dir}/libgstaudiomixer.so
+%{_lib_gstreamer_dir}/libgstaudiorate.so
+%{_lib_gstreamer_dir}/libgstaudioresample.so
+%{_lib_gstreamer_dir}/libgstaudiotestsrc.so
+%{_lib_gstreamer_dir}/libgstcompositor.so
+%{_lib_gstreamer_dir}/libgstgio.so
+%{_lib_gstreamer_dir}/libgstogg.so
+%{_lib_gstreamer_dir}/libgstopus.so
+%{_lib_gstreamer_dir}/libgstoverlaycomposition.so
+%{_lib_gstreamer_dir}/libgstpbtypes.so
+%{_lib_gstreamer_dir}/libgstplayback.so
+%{_lib_gstreamer_dir}/libgstrawparse.so
+%{_lib_gstreamer_dir}/libgstsubparse.so
+%{_lib_gstreamer_dir}/libgsttcp.so
+%{_lib_gstreamer_dir}/libgsttheora.so
+%{_lib_gstreamer_dir}/libgsttypefindfunctions.so
+%{_lib_gstreamer_dir}/libgstvideoconvertscale.so
+%{_lib_gstreamer_dir}/libgstvideorate.so
+%{_lib_gstreamer_dir}/libgstvideotestsrc.so
+%{_lib_gstreamer_dir}/libgstvolume.so
+%{_lib_gstreamer_dir}/libgstvorbis.so
+%if %{with x}
+%{_lib_gstreamer_dir}/libgstximagesink.so
+%{_lib_gstreamer_dir}/libgstxvimagesink.so
+%endif
+%{_libdir}/libgstallocators-%{gst_branch}.so.*
+%{_libdir}/libgstapp-%{gst_branch}.so.*
+%{_libdir}/libgstaudio-%{gst_branch}.so.*
+%{_libdir}/libgstfft-%{gst_branch}.so.*
+%{_libdir}/libgstpbutils-%{gst_branch}.so.*
+%{_libdir}/libgstriff-%{gst_branch}.so.*
+%{_libdir}/libgstrtp-%{gst_branch}.so.*
+%{_libdir}/libgstrtsp-%{gst_branch}.so.*
+%{_libdir}/libgstsdp-%{gst_branch}.so.*
+%{_libdir}/libgsttag-%{gst_branch}.so.*
+%{_libdir}/libgstvideo-%{gst_branch}.so.*
+%if "%{tizen_profile_name}" != "tv"
+%{_lib_gstreamer_dir}/libgstencoding.so
+%endif #profile
+%if "%{_enable_introspection}" == "1"
+%{_lib_girepository}/GstAllocators-%{gst_branch}.typelib
+%{_lib_girepository}/GstApp-%{gst_branch}.typelib
+%{_lib_girepository}/GstAudio-%{gst_branch}.typelib
+%{_lib_girepository}/GstPbutils-%{gst_branch}.typelib
+%{_lib_girepository}/GstRtp-%{gst_branch}.typelib
+%{_lib_girepository}/GstRtsp-%{gst_branch}.typelib
+%{_lib_girepository}/GstSdp-%{gst_branch}.typelib
+%{_lib_girepository}/GstTag-%{gst_branch}.typelib
+%{_lib_girepository}/GstVideo-%{gst_branch}.typelib
+%endif #introspection
+%dir %{_datadir}/gst-plugins-base/
+%dir %{_datadir}/gst-plugins-base/%{gst_branch}/
+%{_datadir}/gst-plugins-base/%{gst_branch}/license-translations.dict
+
+%if "%{tizen_profile_name}" != "tv"
+%files -n gst-plugins-base-extension-adder
+%{_lib_gstreamer_dir}/libgstadder.so
+%license subprojects/gst-plugins-base/COPYING
+%endif # profile
+
+%files -n gst-plugins-base-devel
+%manifest gst-plugins-base.manifest
+%defattr(-, root, root)
+%{_includedir}/gstreamer-%{gst_branch}/gst/allocators/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/app/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/audio/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/fft/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/pbutils/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/riff/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/rtp/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/rtsp/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/sdp/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/tag/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/video/*
+%if "%{plugin}" == "all" && "%{tizen_profile_name}" != "tv"
+%exclude %{_includedir}/gstreamer-%{gst_branch}/gst/audio/audio-bad-prelude.h
+%exclude %{_includedir}/gstreamer-%{gst_branch}/gst/audio/gstnonstreamaudiodecoder.h
+%exclude %{_includedir}/gstreamer-%{gst_branch}/gst/audio/gstplanaraudioadapter.h
+%endif
+%{_libdir}/libgstallocators-%{gst_branch}.so
+%{_libdir}/libgstapp-%{gst_branch}.so
+%{_libdir}/libgstaudio-%{gst_branch}.so
+%{_libdir}/libgstfft-%{gst_branch}.so
+%{_libdir}/libgstpbutils-%{gst_branch}.so
+%{_libdir}/libgstriff-%{gst_branch}.so
+%{_libdir}/libgstrtp-%{gst_branch}.so
+%{_libdir}/libgstrtsp-%{gst_branch}*.so
+%{_libdir}/libgstsdp-%{gst_branch}.so
+%{_libdir}/libgsttag-%{gst_branch}.so
+%{_libdir}/libgstvideo-%{gst_branch}.so
+%{_libdir}/pkgconfig/gstreamer-allocators-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-app-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-audio-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-fft-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-pbutils-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-plugins-base-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-riff-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-rtp-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-rtsp-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-sdp-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-tag-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-video-%{gst_branch}.pc
+%if "%{_enable_introspection}" == "1"
+%{_datadir}/gir-%{gst_branch}/GstAllocators-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstApp-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstAudio-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstPbutils-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstRtp-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstRtsp-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstSdp-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstTag-%{gst_branch}.gir
+%{_datadir}/gir-%{gst_branch}/GstVideo-%{gst_branch}.gir
+%endif # introspection
+
+%endif # plugin
+
+###################### gst-plugins-good ######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "good"
+
+%files -n gst-plugins-good
+%manifest gst-plugins-good.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-good/COPYING
+%{_lib_gstreamer_dir}/libgstadaptivedemux2.so
+%{_lib_gstreamer_dir}/libgstalaw.so
++%{_lib_gstreamer_dir}/libgstamrwbdec.so
+%{_lib_gstreamer_dir}/libgstapetag.so
+%{_lib_gstreamer_dir}/libgstaudiofx.so
+%{_lib_gstreamer_dir}/libgstaudioparsers.so
+%{_lib_gstreamer_dir}/libgstautodetect.so
+%{_lib_gstreamer_dir}/libgstavi.so
+%{_lib_gstreamer_dir}/libgstdebug.so
+%{_lib_gstreamer_dir}/libgstdeinterlace.so
+%{_lib_gstreamer_dir}/libgsticydemux.so
+%{_lib_gstreamer_dir}/libgstid3demux.so
+%{_lib_gstreamer_dir}/libgstinterleave.so
+%{_lib_gstreamer_dir}/libgstisomp4.so
+%{_lib_gstreamer_dir}/libgstjpeg.so
+%{_lib_gstreamer_dir}/libgstmulaw.so
+%{_lib_gstreamer_dir}/libgstnavigationtest.so
+%{_lib_gstreamer_dir}/libgstpulseaudio.so
+%{_lib_gstreamer_dir}/libgstreplaygain.so
+%{_lib_gstreamer_dir}/libgstrtp.so
+%{_lib_gstreamer_dir}/libgstrtpmanager.so
+%{_lib_gstreamer_dir}/libgstrtsp.so
+%{_lib_gstreamer_dir}/libgstsoup.so
+%{_lib_gstreamer_dir}/libgstudp.so
+%{_lib_gstreamer_dir}/libgstvideocrop.so
+%{_lib_gstreamer_dir}/libgstvideofilter.so
+%{_lib_gstreamer_dir}/libgstvpx.so
+%{_lib_gstreamer_dir}/libgstwavenc.so
+%{_lib_gstreamer_dir}/libgstwavparse.so
+%if %{with x}
+%{_lib_gstreamer_dir}/libgstximagesrc.so
+%endif # x
+%if "%{tizen_profile_name}" != "tv"
++%{_lib_gstreamer_dir}/libgstamrnb.so
+%{_lib_gstreamer_dir}/libgsteffectv.so
+%{_lib_gstreamer_dir}/libgstflv.so
+%{_lib_gstreamer_dir}/libgstimagefreeze.so
+%{_lib_gstreamer_dir}/libgstmatroska.so
+%{_lib_gstreamer_dir}/libgstmultifile.so
+%{_lib_gstreamer_dir}/libgstsmpte.so
+%{_lib_gstreamer_dir}/libgstvideobox.so
+%{_lib_gstreamer_dir}/libgstvideomixer.so
++%exclude %{_datadir}/gstreamer-%{gst_branch}/presets/GstAmrnbEnc.prs
+%else # profile
+%ifnarch %{arm} aarch64
+%{_lib_gstreamer_dir}/libgstvideo4linux2.so
+%endif # arch
+%endif # profile
+%{_datadir}/gstreamer-%{gst_branch}/presets/GstQTMux.prs
+%{_datadir}/gstreamer-%{gst_branch}/presets/GstVP8Enc.prs
+
+%files -n gst-plugins-good-extra
+%manifest gst-plugins-good.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-good/COPYING
+%if 0%{?ENABLE_AALIB}
+%{_lib_gstreamer_dir}/libgstaasink.so
+%endif
+%if "%{tizen_profile_name}" != "tv"
+%{_lib_gstreamer_dir}/libgstimagefreeze.so
+%{_lib_gstreamer_dir}/libgstpng.so
+%endif
+
+%if "%{tizen_profile_name}" != "tv"
+%files -n gst-plugins-good-cairo
+%manifest gst-plugins-good.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-good/COPYING
+%{_lib_gstreamer_dir}/libgstcairo.so
+
+%files -n gst-plugins-good-v4l2
+%manifest gst-plugins-good.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-good/COPYING
+%{_lib_gstreamer_dir}/libgstvideo4linux2.so
+%endif
+
+%endif
+
+###################### gst-plugins-bad ######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "bad"
+
+%files -n gst-plugins-bad
+%manifest gst-plugins-bad.manifest
+%defattr(-, root, root)
+%license subprojects/gst-plugins-bad/COPYING
+%if "%{tizen_profile_name}" != "tv"
+%{_lib_gstreamer_dir}/libgstautoconvert.so
+%{_lib_gstreamer_dir}/libgstcamerabin.so
+%{_lib_gstreamer_dir}/libgstcoloreffects.so
+%{_lib_gstreamer_dir}/libgstdash.so
+%{_lib_gstreamer_dir}/libgstgaudieffects.so
+%{_lib_gstreamer_dir}/libgstgdp.so
+%{_lib_gstreamer_dir}/libgsthls.so
+%{_lib_gstreamer_dir}/libgstid3tag.so
+%{_lib_gstreamer_dir}/libgstjpegformat.so
+%{_lib_gstreamer_dir}/libgstmpegpsdemux.so
+%{_lib_gstreamer_dir}/libgstrist.so
+%{_lib_gstreamer_dir}/libgstsmoothstreaming.so
+%{_lib_gstreamer_dir}/libgstsrt.so
+%{_libdir}/libgstadaptivedemux-%{gst_branch}.so.0*
+%{_libdir}/libgstbadaudio-%{gst_branch}.so.0*
+%{_libdir}/libgstbasecamerabinsrc-%{gst_branch}.so.0*
+%{_libdir}/libgstcuda-%{gst_branch}.so.0*
+%{_libdir}/libgstinsertbin-%{gst_branch}.so.0*
+%{_libdir}/libgstisoff-%{gst_branch}.so.0*
+%{_libdir}/libgstphotography-%{gst_branch}.so.0*
+%{_libdir}/libgstplay-%{gst_branch}.so.0*
+%{_libdir}/libgstplayer-%{gst_branch}.so.0*
+%{_libdir}/libgsturidownloader-%{gst_branch}.so.0*
+%if 0%{?enable_gl:1}
+%{_lib_gstreamer_dir}/libgstopengl.so
+%{_libdir}/libgstgl-%{gst_branch}.so.0*
+%endif
+%endif # profile
+%{_lib_gstreamer_dir}/libgstaes.so
+%{_lib_gstreamer_dir}/libgstaudiobuffersplit.so
+%{_lib_gstreamer_dir}/libgstaudiolatency.so
+%{_lib_gstreamer_dir}/libgstaudiomixmatrix.so
+%{_lib_gstreamer_dir}/libgstdebugutilsbad.so
+%{_lib_gstreamer_dir}/libgstdtls.so
+%{_lib_gstreamer_dir}/libgstipcpipeline.so
+%{_lib_gstreamer_dir}/libgstmidi.so
+%{_lib_gstreamer_dir}/libgstmpegtsdemux.so
+%{_lib_gstreamer_dir}/libgstmpegtsmux.so
+%{_lib_gstreamer_dir}/libgstnetsim.so
+%{_lib_gstreamer_dir}/libgstnice.so
+%{_lib_gstreamer_dir}/libgstopenal.so
+%{_lib_gstreamer_dir}/libgstopusparse.so
+%{_lib_gstreamer_dir}/libgstproxy.so
+%if "%{tizen_profile_name}" != "tv"
+%{_lib_gstreamer_dir}/libgstrtpmanagerbad.so
+%endif
+%{_lib_gstreamer_dir}/libgstsctp.so
+%{_lib_gstreamer_dir}/libgstsdpelem.so
+%{_lib_gstreamer_dir}/libgstshm.so
+%{_lib_gstreamer_dir}/libgstsoundtouch.so
+%{_lib_gstreamer_dir}/libgstsrtp.so
+%{_lib_gstreamer_dir}/libgsttimecode.so
+%{_lib_gstreamer_dir}/libgstvideoframe_audiolevel.so
+%{_lib_gstreamer_dir}/libgstvideoparsersbad.so
+%if %{with wayland}
+%{_lib_gstreamer_dir}/libgstwaylandsink.so
+%endif
+%{_lib_gstreamer_dir}/libgstwebrtc.so
+%{_libdir}/libgstcodecparsers-%{gst_branch}.so.0*
+%{_libdir}/libgstcodecs-%{gst_branch}.so.0*
+%{_libdir}/libgstmpegts-%{gst_branch}.so.0*
+%{_libdir}/libgstsctp-%{gst_branch}.so.0*
+%{_libdir}/libgsttranscoder-%{gst_branch}.so.0*
+%if %{with wayland}
+%{_libdir}/libgstwayland-%{gst_branch}.so.0*
+%endif
+%{_libdir}/libgstwebrtc-%{gst_branch}.so.0*
+%{_libdir}/libgstwebrtcnice-%{gst_branch}.so.0*
+%exclude %{_bindir}/gst-transcoder-%{gst_branch}
+
+%files -n gst-plugins-bad-devel
+%manifest gst-plugins-bad.manifest
+%defattr(-, root, root)
+%if "%{tizen_profile_name}" != "tv"
+%{_includedir}/gstreamer-%{gst_branch}/gst/audio/audio-bad-prelude.h
+%{_includedir}/gstreamer-%{gst_branch}/gst/audio/gstnonstreamaudiodecoder.h
+%{_includedir}/gstreamer-%{gst_branch}/gst/audio/gstplanaraudioadapter.h
+%{_includedir}/gstreamer-%{gst_branch}/gst/basecamerabinsrc/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/cuda/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/insertbin/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/interfaces/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/isoff/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/play/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/player/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/uridownloader/*
+%endif
+%{_includedir}/gstreamer-%{gst_branch}/gst/codecparsers/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/mpegts/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/sctp/*
+%{_includedir}/gstreamer-%{gst_branch}/gst/transcoder/*
+%if %{with wayland}
+%{_includedir}/gstreamer-%{gst_branch}/gst/wayland/*
+%endif
+%{_includedir}/gstreamer-%{gst_branch}/gst/webrtc/*
+%if "%{tizen_profile_name}" != "tv"
+%{_libdir}/libgstadaptivedemux*.so
+%{_libdir}/libgstbadaudio*.so
+%{_libdir}/libgstbasecamerabinsrc*.so
+%{_libdir}/libgstcuda*.so
+%{_libdir}/libgstinsertbin*.so
+%{_libdir}/libgstisoff*.so
+%{_libdir}/libgstphotography*.so
+%{_libdir}/libgstplay*.so
+%{_libdir}/libgsturidownloader*.so
+%if 0%{?enable_gl:1}
+%{_lib_gstreamer_dir}/include/gst/gl/*
+%endif # gl
+%endif # profile
+
+%{_libdir}/libgstcodecparsers*.so
+%{_libdir}/libgstcodecs*.so
+%{_libdir}/libgstmpegts*.so
+%{_libdir}/libgstsctp*.so
+%{_libdir}/libgsttranscoder*.so
+%if %{with wayland}
+%{_libdir}/libgstwayland*.so
+%endif
+%{_libdir}/libgstwebrtc*.so
+%{_libdir}/pkgconfig/gstreamer-codecparsers-%{gst_branch}.pc
+%if "%{tizen_profile_name}" != "tv"
+%{_libdir}/pkgconfig/gstreamer-bad-audio-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-cuda-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-insertbin-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-photography-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-play-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-player-%{gst_branch}.pc
+%if 0%{?enable_gl:1}
+%{_libdir}/pkgconfig/gstreamer-gl-*.pc
+%endif # gl
+%endif # profile
+%{_libdir}/pkgconfig/gstreamer-mpegts-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-plugins-bad-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-sctp-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-transcoder-%{gst_branch}.pc
+%if %{with wayland}
+%{_libdir}/pkgconfig/gstreamer-wayland-%{gst_branch}.pc
+%endif
+%{_libdir}/pkgconfig/gstreamer-webrtc-%{gst_branch}.pc
+%{_libdir}/pkgconfig/gstreamer-webrtc-nice-%{gst_branch}.pc
+
+%endif # plugin
+
+###################### gst-plugins-ugly ######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "ugly"
+
+%files -n gst-plugins-ugly
+%manifest gst-plugins-ugly.manifest
+%defattr(-,root,root,-)
+%license subprojects/gst-plugins-ugly/COPYING
+%if "%{tizen_profile_name}" != "tv"
- %exclude %{_datadir}/gstreamer-%{gst_branch}/presets/GstAmrnbEnc.prs
+%{_lib_gstreamer_dir}/libgstasf.so
- %{_lib_gstreamer_dir}/libgstamrwbdec.so
+%endif # profile
+
+%endif # plugin
+
+######################## gst-libav ###########################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "libav"
+
+%files -n gst-libav
+%manifest gst-libav.manifest
+%defattr(-,root,root,-)
+%license subprojects/gst-libav/COPYING
+%{_lib_gstreamer_dir}/libgstlibav.so
+
+%endif
+
+###################### gst-rtsp-server #######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "rs"
+
+%files -n gst-rtsp-server
+%manifest gst-rtsp-server.manifest
+%defattr(-,root,root,-)
+%license subprojects/gst-rtsp-server/COPYING
+%{_libdir}/libgstrtspserver*.so.*
+%{_lib_gstreamer_dir}/libgstrtspclientsink.so
+
+%files -n gst-rtsp-server-devel
+%defattr(-,root,root,-)
+%{_libdir}/libgstrtspserver*.so
+%{_includedir}/gstreamer-%{gst_branch}/gst/rtsp-server/rtsp-*.h
+%{_includedir}/gstreamer-%{gst_branch}/gst/rtsp-server/gstwfd*.h
+%{_libdir}/pkgconfig/gstreamer-rtsp-server-%{gst_branch}.pc
+
+%endif
+
+%if "%{tizen_profile_name}" != "tv"
+
+########################## gst-omx ###########################
+%ifarch %{arm} aarch64 riscv64
+
+%if "%{plugin}" == "all" || "%{plugin}" == "omx"
+
+%files -n gst-omx
+%manifest gst-omx.manifest
+%defattr(-,root,root,-)
+%license subprojects/gst-omx/COPYING
+%{_lib_gstreamer_dir}/libgstomx.so
+
+%endif
+
+%endif # arch
+
+###################### gst-editing-services #######################
+
+%if "%{plugin}" == "all" || "%{plugin}" == "es"
+
+%files -n gst-editing-services
+%manifest gst-editing-services.manifest
+%defattr(-,root,root,-)
+%license subprojects/gst-editing-services/COPYING
+%{_libdir}/libges-%{gst_branch}.so.*
+%{_lib_gstreamer_dir}/libgstges.so
+%{_lib_gstreamer_dir}/libgstnle.so
+%exclude %{_libdir}/gst-validate-launcher/python/launcher/apps/geslaunch.py
+%exclude %{_datadir}/gstreamer-%{gst_branch}/validate/scenarios/ges-edit-clip-while-paused.scenario
+%{_bindir}/ges-launch-%{gst_branch}
+
+%files -n gst-editing-services-devel
+%{_libdir}/libges-%{gst_branch}.so
+%{_includedir}/gstreamer-%{gst_branch}/ges/*
+%{_libdir}/pkgconfig/gst-editing-services-%{gst_branch}.pc
+
+%endif # plugin
+
+%endif # profile
Run
-- for m in @1@; do cp scripts/gen-changelog.py subprojects/$m/scripts/gen-changelog.py; done
++ for m in @1@; do cp scripts/gen-changelog.py subprojects/$m/scripts/gen-changelog.py; done
from the top-level git source directory to sync them up.
subdir('docs')
pygi_override_dir = get_option('pygi-overrides-dir')
- #if pygi_override_dir == ''
- # pygi_override_dir = python3.get_install_dir(
-if pygi_override_dir == '' and python.found()
- pygi_override_dir = python.get_install_dir(
- subdir : join_paths('gi', 'overrides')
- )
-endif
-
-if python.found()
- message('pygobject overrides directory = @0@'.format(pygi_override_dir))
- subdir('bindings/python')
-endif
++#if pygi_override_dir == '' and python.found()
++# pygi_override_dir = python.get_install_dir(
+# subdir : join_paths('gi', 'overrides')
+# )
+#endif
+
- #message('pygobject overrides directory = @0@'.format(pygi_override_dir))
- #subdir('bindings/python')
++#if python.found()
++# message('pygobject overrides directory = @0@'.format(pygi_override_dir))
++# subdir('bindings/python')
++#endif
# Set release date
if gst_version_nano == 0
gst_ffmpegdemux_register (plugin);
gst_ffmpegmux_register (plugin);
gst_ffmpegdeinterlace_register (plugin);
+ gst_ffmpegvidcmp_register (plugin);
+#endif
/* Now we can return the pointer to the newly created Plugin object. */
return TRUE;
/* copy over the aspect ratios, ffmpeg expects the stream aspect to match the
* codec aspect. */
st->sample_aspect_ratio = st->codecpar->sample_aspect_ratio;
+ /* copy over the frame rate to be used in the container format. */
+ st->time_base.num = tmp.time_base.num;
+ st->time_base.den = tmp.time_base.den;
+#ifdef TIZEN_FEATURE_LIBAV
+ /* ref counting bug fix */
+ gst_object_unref(ffmpegmux);
+#endif /* TIZEN_FEATURE_LIBAV */
+
GST_LOG_OBJECT (pad, "accepted caps %" GST_PTR_FORMAT, caps);
return TRUE;
if (ffmpegmux->opened) {
ffmpegmux->opened = FALSE;
gst_ffmpegdata_close (ffmpegmux->context->pb);
+ ffmpegmux->context->pb = NULL;
}
+#ifdef TIZEN_FEATURE_LIBAV
+ for (i = 0 ; i < ffmpegmux->context->nb_streams ; i++) {
+ sti = ffstream(ffmpegmux->context->streams[i]);
+ ffmpegmux->context->streams[i]->start_time = AV_NOPTS_VALUE;
+ ffmpegmux->context->streams[i]->duration = AV_NOPTS_VALUE;
+ sti->cur_dts = AV_NOPTS_VALUE;
+ }
+ }
+#endif
break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
add_project_arguments('-fno-strict-aliasing', language: 'c')
endif
+ # Disable compiler warnings for unused variables and args if gst debug system is disabled
if gst_dep.type_name() == 'internal'
- gst_proj = subproject('gstreamer')
-
- if not gst_proj.get_variable('gst_debug')
- message('GStreamer debug system is disabled')
- add_project_arguments('-Wno-unused', language: 'c')
- else
- message('GStreamer debug system is enabled')
- endif
+ gst_proj = subproject('gstreamer')
+ gst_debug_disabled = not gst_proj.get_variable('gst_debug')
else
- # We can't check that in the case of subprojects as we won't
- # be able to build against an internal dependency (which is not built yet)
- if not cc.compiles('''
- #include <gst/gstconfig.h>
- #ifdef GST_DISABLE_GST_DEBUG
- #error "debugging disabled, make compiler fail"
- #endif''' , dependencies: gst_dep)
- message('GStreamer debug system is disabled')
- add_project_arguments('-Wno-unused', language: 'c')
- else
- message('GStreamer debug system is enabled')
- endif
+ # We can't check that in the case of subprojects as we won't
+ # be able to build against an internal dependency (which is not built yet)
+ gst_debug_disabled = cc.has_header_symbol('gst/gstconfig.h', 'GST_DISABLE_GST_DEBUG', dependencies: gst_dep)
+ endif
+
+ if gst_debug_disabled
+ message('GStreamer debug system is disabled')
+ if cc.get_argument_syntax() == 'msvc'
+ msvc_args = cc.get_supported_arguments([
+ '/wd4101', # 'identifier' : unreferenced local variable
+ '/wd4189', # 'identifier' : local variable is initialized but not referenced
+ ])
+ add_project_arguments(msvc_args, language: 'c')
+ elif cc.has_argument('-Wno-unused')
+ add_project_arguments(['-Wno-unused'], language: 'c')
+ endif
+ else
+ if cc.get_argument_syntax() == 'msvc' and gst_version_is_dev
+ msvc_args = cc.get_supported_arguments([
+ '/we4101', # 'identifier' : unreferenced local variable
+ '/we4189', # 'identifier' : local variable is initialized but not referenced
+ ])
+ add_project_arguments(msvc_args, language: 'c')
+ endif
+ message('GStreamer debug system is enabled')
endif
+# Tizen options
+if get_option('tv-profile')
+cdata.set ('TIZEN_PRODUCT_TV', true)
+endif
+cdata.set ('TIZEN_FEATURE_LIBAV', true)
+cdata.set ('TIZEN_FEATURE_LIBAV_VIDEODECODER_ADD_VIDEOMETA', true)
+
warning_flags = [
'-Wmissing-declarations',
'-Wmissing-prototypes',
--- /dev/null
- version : '1.22.8',
+project('gst-omx', 'c',
- if gst_version_nano == 0
- extract_release_date = find_program('scripts/extract-release-date-from-doap-file.py')
- run_result = run_command(extract_release_date, gst_version, files('gst-omx.doap'), check: true)
- release_date = run_result.stdout().strip()
- cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', release_date)
- message('Package release date: ' + release_date)
- endif
++ version : '1.24.9',
+ meson_version : '>= 0.62',
+ default_options : [ 'warning_level=1',
+ 'buildtype=debugoptimized' ])
+
+gst_version = meson.project_version()
+version_arr = gst_version.split('.')
+gst_version_major = version_arr[0].to_int()
+gst_version_minor = version_arr[1].to_int()
+gst_version_micro = version_arr[2].to_int()
+ if version_arr.length() == 4
+ gst_version_nano = version_arr[3].to_int()
+else
+ gst_version_nano = 0
+endif
+
+glib_req = '>= 2.62.0'
+gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor)
+tizil_req = '>= 0.19.0'
+api_version = '1.0'
+
+plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir'))
+
+cc = meson.get_compiler('c')
+
+if cc.get_id() == 'msvc'
+ msvc_args = [
+ # Ignore several spurious warnings for things gstreamer does very commonly
+ # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
+ # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
+ # NOTE: Only add warnings here if you are sure they're spurious
+ '/wd4018', # implicit signed/unsigned conversion
+ '/wd4146', # unary minus on unsigned (beware INT_MIN)
+ '/wd4244', # lossy type conversion (e.g. double -> int)
+ '/wd4305', # truncating type conversion (e.g. double -> float)
+ cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
+
+ # Enable some warnings on MSVC to match GCC/Clang behaviour
+ '/w14062', # enumerator 'identifier' in switch of enum 'enumeration' is not handled
+ '/w14101', # 'identifier' : unreferenced local variable
+ '/w14189', # 'identifier' : local variable is initialized but not referenced
+ ]
+ add_project_arguments(msvc_args, language: 'c')
+ # Disable SAFESEH with MSVC for plugins and libs that use external deps that
+ # are built with MinGW
+ noseh_link_args = ['/SAFESEH:NO']
+else
+ noseh_link_args = []
+endif
+
+# glib doesn't support unloading, which means that unloading and reloading
+# any library that registers static types will fail
+if cc.has_link_argument('-Wl,-z,nodelete')
+ add_project_link_arguments('-Wl,-z,nodelete', language: 'c')
+endif
+
+cdata = configuration_data()
+check_headers = [
+# ['HAVE_DLFCN_H', 'dlfcn.h'],
+# ['HAVE_FCNTL_H', 'fcntl.h'],
+# ['HAVE_INTTYPES_H', 'inttypes.h'],
+# ['HAVE_MEMORY_H', 'memory.h'],
+# ['HAVE_MSACM_H', 'msacm.h'],
+# ['HAVE_PTHREAD_H', 'pthread.h'],
+# ['HAVE_STDINT_H', 'stdint.h'],
+# ['HAVE_STDLIB_H', 'stdlib.h'],
+# ['HAVE_STRINGS_H', 'strings.h'],
+# ['HAVE_STRING_H', 'string.h'],
+# ['HAVE_SYS_PARAM_H', 'sys/param.h'],
+# ['HAVE_SYS_SOCKET_H', 'sys/socket.h'],
+# ['HAVE_SYS_STAT_H', 'sys/stat.h'],
+# ['HAVE_SYS_TIME_H', 'sys/time.h'],
+# ['HAVE_SYS_TYPES_H', 'sys/types.h'],
+# ['HAVE_SYS_UTSNAME_H', 'sys/utsname.h'],
+# ['HAVE_UNISTD_H', 'unistd.h'],
+]
+
+foreach h : check_headers
+ if cc.has_header(h.get(1))
+ cdata.set(h.get(0), 1)
+ endif
+endforeach
+
+check_functions = [
+# check token HAVE_CPU_ALPHA
+# check token HAVE_CPU_ARM
+# check token HAVE_CPU_CRIS
+# check token HAVE_CPU_CRISV32
+# check token HAVE_CPU_HPPA
+# check token HAVE_CPU_I386
+# check token HAVE_CPU_IA64
+# check token HAVE_CPU_M68K
+# check token HAVE_CPU_MIPS
+# check token HAVE_CPU_PPC
+# check token HAVE_CPU_PPC64
+# check token HAVE_CPU_S390
+# check token HAVE_CPU_SPARC
+# check token HAVE_CPU_X86_64
+# ['HAVE_DCGETTEXT', 'dcgettext'],
+# check token HAVE_EXPERIMENTAL
+# check token HAVE_EXTERNAL
+# ['HAVE_GETPAGESIZE', 'getpagesize'],
+# check token HAVE_GETTEXT
+]
+
+foreach f : check_functions
+ if cc.has_function(f.get(1))
+ cdata.set(f.get(0), 1)
+ endif
+endforeach
+
+#cdata.set('SIZEOF_CHAR', cc.sizeof('char'))
+#cdata.set('SIZEOF_INT', cc.sizeof('int'))
+#cdata.set('SIZEOF_LONG', cc.sizeof('long'))
+#cdata.set('SIZEOF_SHORT', cc.sizeof('short'))
+#cdata.set('SIZEOF_VOIDP', cc.sizeof('void*'))
+
+cdata.set('VERSION', '"@0@"'.format(gst_version))
+cdata.set('PACKAGE', '"gst-omx"')
+cdata.set('PACKAGE_VERSION', '"@0@"'.format(gst_version))
+cdata.set('PACKAGE_BUGREPORT', '"https://gitlab.freedesktop.org/gstreamer/gst-omx/issues/new"')
+cdata.set('PACKAGE_NAME', '"GStreamer OMX Plugins"')
+cdata.set('GETTEXT_PACKAGE', '"gst-omx-1.0"')
+cdata.set('GST_API_VERSION', '"@0@"'.format(api_version))
+cdata.set('GST_PACKAGE_NAME', '"GStreamer OpenMAX Plug-ins"')
+cdata.set('GST_PACKAGE_ORIGIN', '"Unknown package origin"')
+cdata.set('GST_LICENSE', '"LGPL"')
+cdata.set('LIBDIR', '"@0@"'.format(get_option('libdir')))
+
+# FIXME: This should be exposed as a configuration option
+host_system = host_machine.system()
+if host_system == 'linux'
+ cdata.set('DEFAULT_VIDEOSRC', '"v4l2src"')
+elif host_system == 'osx'
+ cdata.set('DEFAULT_VIDEOSRC', '"avfvideosrc"')
+else
+ cdata.set('DEFAULT_VIDEOSRC', '"videotestsrc"')
+endif
+
+# Mandatory GST deps
+gst_dep = dependency('gstreamer-1.0', version : gst_req,
+ fallback : ['gstreamer', 'gst_dep'])
+gstbase_dep = dependency('gstreamer-base-1.0', version : gst_req,
+ fallback : ['gstreamer', 'gst_base_dep'])
+gstcontroller_dep = dependency('gstreamer-controller-1.0', version : gst_req,
+ fallback : ['gstreamer', 'gst_controller_dep'])
+gstallocators_dep = dependency('gstreamer-allocators-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'allocators_dep'])
+
+gstpbutils_dep = dependency('gstreamer-pbutils-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'pbutils_dep'])
+gstaudio_dep = dependency('gstreamer-audio-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'audio_dep'])
+gstfft_dep = dependency('gstreamer-fft-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'fft_dep'])
+gsttag_dep = dependency('gstreamer-tag-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'tag_dep'])
+gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'video_dep'])
+
+gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req,
+ fallback : ['gst-plugins-base', 'gstgl_dep'], required : false)
+
+x11_dep = dependency('x11', required : false)
+
+gstcheck_dep = dependency('gstreamer-check-1.0', version : gst_req,
+ required : get_option('tests'),
+ fallback : ['gstreamer', 'gst_check_dep'])
+
+libm = cc.find_library('m', required : false)
+gmodule_dep = dependency('gmodule-no-export-2.0', version: glib_req)
+
+gst_omx_args = ['-DHAVE_CONFIG_H']
+configinc = include_directories('.')
+omx_header_path = get_option('header_path')
+if omx_header_path != ''
+ omx_inc = []
+ gst_omx_args += ['-I' + omx_header_path]
+else
+ omx_inc = include_directories (join_paths ('omx', 'openmax'))
+endif
+
+default_omx_struct_packing = 0
+omx_target = get_option ('target')
+if omx_target == 'generic'
+ cdata.set('USE_OMX_TARGET_GENERIC', 1)
+elif omx_target == 'rpi'
+ cdata.set('USE_OMX_TARGET_RPI', 1)
+ cdata.set('OMX_SKIP64BIT', 1)
+ default_omx_struct_packing = 4
+
+ if gstgl_dep.found()
+ if gstgl_dep.type_name() == 'pkgconfig'
+ gl_winsys = gstgl_dep.get_variable('gl_winsys').split(' ')
+ gl_platforms = gstgl_dep.get_variable('gl_platforms').split(' ')
+ elif gstgl_dep.type_name() == 'internal'
+ # XXX assume gst-plugins-base was built with dispmanx and egl support
+ gl_winsys = ['dispmanx']
+ gl_platforms = ['egl']
+ else
+ error ('unreachable dependency type')
+ endif
+
+ if not gl_winsys.contains('dispmanx') or not gl_platforms.contains ('egl')
+ gstgl_dep = dependency('', required : false)
+ endif
+ endif
+elif omx_target == 'bellagio'
+ cdata.set('USE_OMX_TARGET_BELLAGIO', 1)
+elif omx_target == 'zynqultrascaleplus'
+ cdata.set('USE_OMX_TARGET_ZYNQ_USCALE_PLUS', 1)
+ have_allegro_header = cc.has_header (
+ 'OMX_Allegro.h',
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+ if not have_allegro_header
+ error ('Need Allegro OMX headers to build for Zynq UltraScale+. Use -Dheader_path option to specify the path of those headers.')
+ endif
+elif omx_target == 'tizonia'
+ if omx_header_path != ''
+ warning('Ignoring -Dheader_path because path is in tizilheaders.pc')
+ endif
+ cdata.set('USE_OMX_TARGET_TIZONIA', 1)
+ tizil_dep = dependency('tizilheaders', version : tizil_req)
+ cdata.set('TIZONIA_LIBDIR', tizil_dep.get_variable('libdir'))
+ tizil_includedir = tizil_dep.get_variable('includedir')
+ gst_omx_args += ['-I' + tizil_includedir + '/tizonia']
+ omx_inc = []
+elif omx_target == 'exynos64'
+ cdata.set('USE_OMX_TARGET_EXYNOS64', 1)
+elif omx_target == 'exynos'
+ cdata.set('USE_OMX_TARGET_EXYNOS', 1)
+else
+ error ('Unsupported omx target specified. Use the -Dtarget option')
+endif
+
+message ('OMX target: ' + omx_target)
+
+# Tizen options
+tbm_dep = dependency('libtbm', required : true)
+have_omx_vp9 = get_option('vp9')
+cdata.set ('HAVE_VP9', have_omx_vp9)
+cdata.set ('TIZEN_FEATURE_OMX', true)
+
+extra_video_headers = ''
+# Check for optional OpenMAX extension headers
+
+if cc.has_header (
+ 'OMX_VideoExt.h',
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+ extra_video_headers += '''
+#include <OMX_VideoExt.h>'''
+ cdata.set ('HAVE_VIDEO_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_IndexExt.h',
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+ cdata.set ('HAVE_INDEX_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_ComponentExt.h',
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+ cdata.set ('HAVE_COMPONENT_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_CoreExt.h',
+ args : gst_omx_args)
+ cdata.set ('HAVE_CORE_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_AudioExt.h',
+ args : gst_omx_args)
+ cdata.set ('HAVE_AUDIO_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_IVCommonExt.h',
+ args : gst_omx_args)
+ cdata.set ('HAVE_IV_COMMON_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_ImageExt.h',
+ args : gst_omx_args)
+ cdata.set ('HAVE_IMAGE_EXT', 1)
+endif
+
+if cc.has_header (
+ 'OMX_OtherExt.h',
+ args : gst_omx_args)
+ cdata.set ('HAVE_OTHER_EXT', 1)
+endif
+
+have_omx_vp8 = cc.has_header_symbol(
+ 'OMX_Video.h',
+ 'OMX_VIDEO_CodingVP8',
+ prefix : extra_video_headers,
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+if have_omx_vp8
+ cdata.set('HAVE_VP8', 1)
+endif
+
+have_omx_theora = cc.has_header_symbol(
+ 'OMX_Video.h',
+ 'OMX_VIDEO_CodingTheora',
+ prefix : extra_video_headers,
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+if have_omx_theora
+ cdata.set('HAVE_THEORA', 1)
+endif
+
+have_omx_hevc = cc.has_header_symbol(
+ 'OMX_Video.h',
+ 'OMX_VIDEO_CodingHEVC',
+ prefix : extra_video_headers,
+ args : gst_omx_args,
+ include_directories : [omx_inc])
+if have_omx_hevc
+ cdata.set('HAVE_HEVC', 1)
+endif
+
+if gstgl_dep.found()
+ cdata.set ('HAVE_GST_GL', 1)
+endif
+
+if x11_dep.found()
+ cdata.set ('HAVE_X11', 1)
+endif
+
+omx_struct_packing = get_option ('struct_packing').to_int()
+if omx_struct_packing == 0
+ omx_struct_packing = default_omx_struct_packing
+endif
+if omx_struct_packing != 0
+ cdata.set('GST_OMX_STRUCT_PACKING', omx_struct_packing)
+endif
+
+omx_conf_dir = join_paths (get_option ('prefix'), get_option ('sysconfdir'), 'xdg')
+cdata.set_quoted('GST_OMX_CONFIG_DIR', omx_conf_dir)
+
+warning_flags = [
+ '-Wmissing-declarations',
+ '-Wredundant-decls',
+ '-Wwrite-strings',
+ '-Winit-self',
+ '-Wmissing-include-dirs',
+ '-Wno-multichar',
+ '-Wvla',
+ '-Wpointer-arith',
+ '-Wundef',
+]
+
+warning_c_flags = [
+ '-Wmissing-prototypes',
+ '-Wold-style-definition',
+ '-Waggregate-return',
+]
+
+have_cxx = add_languages('cpp', required : false)
+
+if have_cxx
+ cxx = meson.get_compiler('cpp')
+endif
+
+foreach extra_arg : warning_flags
+ if cc.has_argument (extra_arg)
+ add_project_arguments([extra_arg], language: 'c')
+ endif
+ if have_cxx and cxx.has_argument (extra_arg)
+ add_project_arguments([extra_arg], language: 'cpp')
+ endif
+endforeach
+
+foreach extra_arg : warning_c_flags
+ if cc.has_argument (extra_arg)
+ add_project_arguments([extra_arg], language: 'c')
+ endif
+endforeach
+
+# Disable compiler warnings for unused variables and args if gst debug system is disabled
+if gst_dep.type_name() == 'internal'
+ gst_debug_disabled = not subproject('gstreamer').get_variable('gst_debug')
+else
+ # We can't check that in the case of subprojects as we won't
+ # be able to build against an internal dependency (which is not built yet)
+ gst_debug_disabled = cc.has_header_symbol('gst/gstconfig.h', 'GST_DISABLE_GST_DEBUG', dependencies: gst_dep)
+endif
+
+if gst_debug_disabled
+ message('GStreamer debug system is disabled')
+ if cc.has_argument('-Wno-unused')
+ add_project_arguments('-Wno-unused', language: 'c')
+ endif
+ if have_cxx and cxx.has_argument ('-Wno-unused')
+ add_project_arguments('-Wno-unused', language: 'cpp')
+ endif
+else
+ message('GStreamer debug system is enabled')
+endif
+
+subdir('config')
+
+if not get_option('examples').disabled()
+ subdir('examples')
+endif
+
+subdir('omx')
+
+if not get_option('tools').disabled()
+ subdir('tools')
+endif
+
+if not get_option('tests').disabled() and gstcheck_dep.found()
+ subdir('tests')
+endif
+subdir('docs')
+
+# Set release date
++#if gst_version_nano == 0
++# extract_release_date = find_program('scripts/extract-release-date-from-doap-file.py')
++# run_result = run_command(extract_release_date, gst_version, files('gst-omx.doap'), check: true)
++# release_date = run_result.stdout().strip()
++# cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', release_date)
++# message('Package release date: ' + release_date)
++#endif
+
+configure_file(output: 'config.h', configuration: cdata)
+
+meson.add_dist_script('scripts/gen-changelog.py', meson.project_name(), '1.20.0', meson.project_version())
--- /dev/null
- /*\r
- * Copyright (c) 2010 The Khronos Group Inc.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files (the\r
- * "Software"), to deal in the Software without restriction, including\r
- * without limitation the rights to use, copy, modify, merge, publish,\r
- * distribute, sublicense, and/or sell copies of the Software, and to\r
- * permit persons to whom the Software is furnished to do so, subject\r
- * to the following conditions:\r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
- \r
- /** OMX_ComponentExt.h - OpenMax IL version 1.1.2\r
- * The OMX_ComponentExt header file contains extensions to the definitions used\r
- * by both the application and the component to access common items.\r
- */\r
- \r
- #ifndef OMX_ComponentExt_h\r
- #define OMX_ComponentExt_h\r
- \r
- #ifdef __cplusplus\r
- extern "C" {\r
- #endif /* __cplusplus */\r
- \r
- /* Each OMX header must include all required header files to allow the\r
- * header to compile without errors. The includes below are required\r
- * for this header file to compile successfully \r
- */\r
- #include <OMX_Types.h>\r
- \r
- \r
- /** Set/query the commit mode */\r
- typedef struct OMX_CONFIG_COMMITMODETYPE {\r
- OMX_U32 nSize;\r
- OMX_VERSIONTYPE nVersion;\r
- OMX_BOOL bDeferred;\r
- } OMX_CONFIG_COMMITMODETYPE;\r
- \r
- /** Explicit commit */\r
- typedef struct OMX_CONFIG_COMMITTYPE {\r
- OMX_U32 nSize;\r
- OMX_VERSIONTYPE nVersion;\r
- } OMX_CONFIG_COMMITTYPE;\r
- \r
- \r
- #ifdef __cplusplus\r
- }\r
- #endif /* __cplusplus */\r
- \r
- #endif /* OMX_ComponentExt_h */\r
++/*
++ * Copyright (c) 2010 The Khronos Group Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject
++ * to the following conditions:
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ *
++ */
++
++/** OMX_ComponentExt.h - OpenMax IL version 1.1.2
++ * The OMX_ComponentExt header file contains extensions to the definitions used
++ * by both the application and the component to access common items.
++ */
++
++#ifndef OMX_ComponentExt_h
++#define OMX_ComponentExt_h
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++/* Each OMX header must include all required header files to allow the
++ * header to compile without errors. The includes below are required
++ * for this header file to compile successfully
++ */
++#include <OMX_Types.h>
++
++
++/** Set/query the commit mode */
++typedef struct OMX_CONFIG_COMMITMODETYPE {
++ OMX_U32 nSize;
++ OMX_VERSIONTYPE nVersion;
++ OMX_BOOL bDeferred;
++} OMX_CONFIG_COMMITMODETYPE;
++
++/** Explicit commit */
++typedef struct OMX_CONFIG_COMMITTYPE {
++ OMX_U32 nSize;
++ OMX_VERSIONTYPE nVersion;
++} OMX_CONFIG_COMMITTYPE;
++
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* OMX_ComponentExt_h */
--- /dev/null
- /*\r
- * Copyright (c) 2010 The Khronos Group Inc.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files (the\r
- * "Software"), to deal in the Software without restriction, including\r
- * without limitation the rights to use, copy, modify, merge, publish,\r
- * distribute, sublicense, and/or sell copies of the Software, and to\r
- * permit persons to whom the Software is furnished to do so, subject\r
- * to the following conditions:\r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
- \r
- /** OMX_CoreExt.h - OpenMax IL version 1.1.2\r
- * The OMX_CoreExt header file contains extensions to the definitions used\r
- * by both the application and the component to access common items.\r
- */\r
- \r
- #ifndef OMX_CoreExt_h\r
- #define OMX_CoreExt_h\r
- \r
- #ifdef __cplusplus\r
- extern "C" {\r
- #endif /* __cplusplus */\r
- \r
- /* Each OMX header shall include all required header files to allow the\r
- * header to compile without errors. The includes below are required\r
- * for this header file to compile successfully\r
- */\r
- #include <OMX_Core.h>\r
- \r
- /** Extensions to the standard IL errors. */ \r
- typedef enum OMX_ERROREXTTYPE \r
- {\r
- OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),\r
- OMX_ErrorExtMax = 0x7FFFFFFF\r
- } OMX_ERROREXTTYPE;\r
- \r
- \r
- /** Event type extensions. */\r
- typedef enum OMX_EVENTEXTTYPE\r
- {\r
- OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change\r
- in a param, config, or extension */\r
- OMX_EventExtMax = 0x7FFFFFFF\r
- } OMX_EVENTEXTTYPE;\r
- \r
- \r
- /** Enable or disable a callback event. */\r
- typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {\r
- OMX_U32 nSize; /**< size of the structure in bytes */\r
- OMX_VERSIONTYPE nVersion; /**< OMX specification version information */\r
- OMX_U32 nPortIndex; /**< port that this structure applies to */\r
- OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */\r
- OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */\r
- } OMX_CONFIG_CALLBACKREQUESTTYPE;\r
- \r
- #ifdef __cplusplus\r
- }\r
- #endif /* __cplusplus */\r
- \r
- #endif /* OMX_CoreExt_h */\r
- /* File EOF */\r
++/*
++ * Copyright (c) 2010 The Khronos Group Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject
++ * to the following conditions:
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ *
++ */
++
++/** OMX_CoreExt.h - OpenMax IL version 1.1.2
++ * The OMX_CoreExt header file contains extensions to the definitions used
++ * by both the application and the component to access common items.
++ */
++
++#ifndef OMX_CoreExt_h
++#define OMX_CoreExt_h
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++/* Each OMX header shall include all required header files to allow the
++ * header to compile without errors. The includes below are required
++ * for this header file to compile successfully
++ */
++#include <OMX_Core.h>
++
++/** Extensions to the standard IL errors. */
++typedef enum OMX_ERROREXTTYPE
++{
++ OMX_ErrorInvalidMode = (OMX_S32) (OMX_ErrorKhronosExtensions + 0x00000001),
++ OMX_ErrorExtMax = 0x7FFFFFFF
++} OMX_ERROREXTTYPE;
++
++
++/** Event type extensions. */
++typedef enum OMX_EVENTEXTTYPE
++{
++ OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
++ in a param, config, or extension */
++ OMX_EventExtMax = 0x7FFFFFFF
++} OMX_EVENTEXTTYPE;
++
++
++/** Enable or disable a callback event. */
++typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
++ OMX_U32 nSize; /**< size of the structure in bytes */
++ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
++ OMX_U32 nPortIndex; /**< port that this structure applies to */
++ OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */
++ OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
++} OMX_CONFIG_CALLBACKREQUESTTYPE;
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* OMX_CoreExt_h */
++/* File EOF */
--- /dev/null
- /*\r
- * Copyright (c) 2010 The Khronos Group Inc. \r
- * \r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files (the\r
- * "Software"), to deal in the Software without restriction, including\r
- * without limitation the rights to use, copy, modify, merge, publish,\r
- * distribute, sublicense, and/or sell copies of the Software, and to\r
- * permit persons to whom the Software is furnished to do so, subject\r
- * to the following conditions: \r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software. \r
- * \r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
- *\r
- */\r
- \r
- /** @file OMX_IndexExt.h - OpenMax IL version 1.1.2\r
- * The OMX_IndexExt header file contains extensions to the definitions \r
- * for both applications and components .\r
- */\r
- \r
- #ifndef OMX_IndexExt_h\r
- #define OMX_IndexExt_h\r
- \r
- #ifdef __cplusplus\r
- extern "C" {\r
- #endif /* __cplusplus */\r
- \r
- /* Each OMX header shall include all required header files to allow the\r
- * header to compile without errors. The includes below are required\r
- * for this header file to compile successfully\r
- */\r
- #include <OMX_Index.h>\r
- \r
- \r
- /** Khronos standard extension indices.\r
- \r
- This enum lists the current Khronos extension indices to OpenMAX IL.\r
- */\r
- typedef enum OMX_INDEXEXTTYPE {\r
- \r
- /* Component parameters and configurations */\r
- OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,\r
- OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */\r
- OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */\r
- OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */\r
- \r
- /* Port parameters and configurations */\r
- OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,\r
- \r
- /* Audio parameters and configurations */\r
- OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,\r
- \r
- /* Image parameters and configurations */\r
- OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,\r
- \r
- /* Video parameters and configurations */\r
- OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,\r
- OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */\r
- OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */\r
- OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */\r
- \r
- /* Image & Video common configurations */\r
- OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,\r
- \r
- /* Other configurations */\r
- OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,\r
- \r
- /* Time configurations */\r
- OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,\r
- \r
- OMX_IndexExtMax = 0x7FFFFFFF\r
- } OMX_INDEXEXTTYPE;\r
- \r
- #ifdef __cplusplus\r
- }\r
- #endif /* __cplusplus */\r
- \r
- #endif /* OMX_IndexExt_h */\r
- /* File EOF */\r
++/*
++ * Copyright (c) 2010 The Khronos Group Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject
++ * to the following conditions:
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ *
++ */
++
++/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2
++ * The OMX_IndexExt header file contains extensions to the definitions
++ * for both applications and components .
++ */
++
++#ifndef OMX_IndexExt_h
++#define OMX_IndexExt_h
++
++#ifdef __cplusplus
++extern "C" {
++#endif /* __cplusplus */
++
++/* Each OMX header shall include all required header files to allow the
++ * header to compile without errors. The includes below are required
++ * for this header file to compile successfully
++ */
++#include <OMX_Index.h>
++
++
++/** Khronos standard extension indices.
++
++This enum lists the current Khronos extension indices to OpenMAX IL.
++*/
++typedef enum OMX_INDEXEXTTYPE {
++
++ /* Component parameters and configurations */
++ OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,
++ OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */
++ OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */
++ OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */
++
++ /* Port parameters and configurations */
++ OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,
++
++ /* Audio parameters and configurations */
++ OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
++
++ /* Image parameters and configurations */
++ OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
++
++ /* Video parameters and configurations */
++ OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,
++ OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */
++ OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */
++ OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */
++
++ /* Image & Video common configurations */
++ OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
++
++ /* Other configurations */
++ OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
++
++ /* Time configurations */
++ OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
++
++ OMX_IndexExtMax = 0x7FFFFFFF
++} OMX_INDEXEXTTYPE;
++
++#ifdef __cplusplus
++}
++#endif /* __cplusplus */
++
++#endif /* OMX_IndexExt_h */
++/* File EOF */
*
*/
++#ifdef HAVE_CONFIG_H
++# include "config.h"
++#endif
++
#include "gstmpdclient.h"
#include "gstmpdparser.h"
'gstdtlselement.c',
]
- openssl_dep = dependency('openssl1.1', version : '>= 1.0.1', required : get_option('dtls'))
- libcrypto_dep = dependency('libcrypto1.1', required : get_option('dtls'))
+ dtls_option = get_option('dtls').enable_if(get_option('webrtc').enabled(), error_message: 'webrtc option is enabled')
-openssl_dep = dependency('openssl', version: '>= 1.0.1', required: dtls_option)
++openssl_dep = dependency('openssl1.1', version: '>= 1.0.1', required: dtls_option)
+ libcrypto_dep = dependency('libcrypto', required: dtls_option)
if openssl_dep.found() and libcrypto_dep.found()
gstdtls = library('gstdtls',
if (media->group_id == NULL || media->name == NULL)
goto required_attributes_missing;
- if (media->mtype == GST_HLS_MEDIA_TYPE_CLOSED_CAPTIONS)
+#ifndef TIZEN_FEATURE_HLSDEMUX_LANG_TAG
+ if (media->mtype == GST_HLS_MEDIA_TYPE_CLOSED_CAPTIONS && media->uri != NULL)
goto uri_with_cc;
+#endif
GST_DEBUG ("media: %s, group '%s', name '%s', uri '%s', %s %s %s, lang=%s",
GST_HLS_MEDIA_TYPE_NAME (media->mtype), media->group_id, media->name,
gboolean found;
DC_LOCK (webrtc);
- found = g_ptr_array_remove (webrtc->priv->pending_data_channels, channel)
+#ifdef TIZEN_FEATURE_WEBRTC_MODIFICATION
+ GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
+ if (channel->parent.prev_ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN ||
+ channel->parent.prev_ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING)
+ webrtc->priv->data_channels_closed++;
+ GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
+#endif
+ found_pending =
+ g_ptr_array_remove (webrtc->priv->pending_data_channels, channel);
+ found = found_pending
|| g_ptr_array_remove (webrtc->priv->data_channels, channel);
if (found == FALSE) {
static GstStructure *
_get_peer_connection_stats (GstWebRTCBin * webrtc)
{
- GstStructure *s = gst_structure_new_empty ("unused");
+ guint opened;
+ guint closed;
+ GstStructure *s = gst_structure_new_empty ("peer-connection-stats");
- /* FIXME: datachannel */
- gst_structure_set (s, "data-channels-opened", G_TYPE_UINT, 0,
- "data-channels-closed", G_TYPE_UINT, 0, "data-channels-requested",
+#ifdef TIZEN_FEATURE_WEBRTC_MODIFICATION
+ /* FIXME: 'data-channels-requested/accepted' should be updated */
+ gst_structure_set (s, "data-channels-opened", G_TYPE_UINT,
+ webrtc->priv->data_channels_opened, "data-channels-closed", G_TYPE_UINT,
+ webrtc->priv->data_channels_closed, NULL);
+#else
-
+ gst_webrtc_bin_get_peer_connection_stats (webrtc, &opened, &closed);
+ gst_structure_set (s, "data-channels-opened", G_TYPE_UINT, opened,
+ "data-channels-closed", G_TYPE_UINT, closed, "data-channels-requested",
G_TYPE_UINT, 0, "data-channels-accepted", G_TYPE_UINT, 0, NULL);
+#endif
return s;
}
-subdir('uridownloader')
+subdir('codecparsers')
- subdir('mpegts')
+subdir('codecs')
++subdir('mpegts')
+subdir('sctp')
+subdir('transcoder')
+subdir('wayland')
+subdir('webrtc')
+if not (get_option('tv-profile'))
+subdir('uridownloader')
subdir('adaptivedemux')
subdir('audio')
subdir('basecamerabinsrc')
wl_req = '>= 1.15'
wl_client_dep = dependency('wayland-client', version: wl_req, required: get_option('wayland'))
- libdrm_dep = dependency('libdrm', version: '>= 2.4.55', required: get_option('wayland'))
- wl_protocol_dep = dependency('wayland-protocols', version: wl_req, required: get_option('wayland'))
+ libdrm_dep = dependency('libdrm', version: '>= 2.4.98', required: get_option('wayland'))
-wl_proto_req = '>= 1.26'
++# Forking Wayland protocol and not adhering to the used version
++wl_proto_req = '>= 1.18'
+ wl_protocol_dep = dependency('wayland-protocols', version: wl_proto_req, required: get_option('wayland'))
wl_scanner = find_program('wayland-scanner', required: get_option('wayland'))
# Also used in ext/wayland
use_wayland = wl_protocol_dep.found() and wl_client_dep.found() and wl_scanner.found() and libdrm_dep.found()
cand =
nice_agent_parse_remote_candidate_sdp (nice->priv->nice_agent,
rc->nice_stream_id, new_candidate);
++#ifndef TIZEN_FEATURE_BUG_FIX
g_free (new_candidate);
++#endif
if (!cand) {
- GST_WARNING_OBJECT (ice, "Could not parse candidate");
- #else
- GST_WARNING_OBJECT (ice, "Could not parse candidate \'%s\'", new_candidate);
+ if (rc->promise) {
+ GError *error =
+ g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
+ "Could not parse candidate \'%s\'", new_candidate);
+ GstStructure *s = gst_structure_new ("application/x-gst-promise", "error",
+ G_TYPE_ERROR, error, NULL);
+ gst_promise_reply (rc->promise, s);
+ g_clear_error (&error);
+ } else {
+ GST_WARNING_OBJECT (ice, "Could not parse candidate \'%s\'",
+ new_candidate);
+ }
+#ifdef TIZEN_FEATURE_BUG_FIX
++ g_free (new_candidate);
+#endif
return;
}
--
++#ifdef TIZEN_FEATURE_BUG_FIX
++ g_free (new_candidate);
++#endif
g_free (new_addr);
add_ice_candidate_to_libnice (ice, rc->nice_stream_id, cand);
}
if (!g_str_has_suffix (address, ".local")) {
- GST_WARNING_OBJECT (nice, "candidate address \'%s\' does not end "
- "with \'.local\'", address);
+#ifndef TIZEN_FEATURE_WEBRTC_MODIFICATION
+ if (promise) {
+ GError *error =
+ g_error_new (GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_INTERNAL_FAILURE,
+ "candidate address \'%s\' does not end " "with \'.local\'",
+ address);
+ GstStructure *s = gst_structure_new ("application/x-gst-promise",
+ "error", G_TYPE_ERROR, error, NULL);
+ gst_promise_reply (promise, s);
+ g_clear_error (&error);
+ } else {
+ GST_WARNING_OBJECT (nice,
+ "candidate address \'%s\' does not end "
+ "with \'.local\'", address);
+ }
goto done;
+#else
+ GST_INFO_OBJECT (nice, "keep going to resolve the domain name \'%s\'",
+ address);
+#endif
}
rc = g_new0 (struct resolve_candidate_data, 1);
options |= NICE_AGENT_OPTION_ICE_TRICKLE;
options |= NICE_AGENT_OPTION_REGULAR_NOMINATION;
++#ifdef TIZEN_FEATURE_WEBRTC_MODIFICATION
+ options |= NICE_AGENT_OPTION_CONSENT_FRESHNESS;
++#endif
+
+ /* https://gitlab.freedesktop.org/libnice/libnice/-/merge_requests/257 */
+ #if HAVE_LIBNICE_CONSENT_FIX
+ options |= NICE_AGENT_OPTION_CONSENT_FRESHNESS;
+ #endif
ice->priv->nice_agent = nice_agent_new_full (ice->priv->main_context,
NICE_COMPATIBILITY_RFC5245, options);
* Boston, MA 02110-1301, USA.
*/
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
#include "id3tag.h"
#include <string.h>
gst_scene_change_class_init (GstSceneChangeClass * klass)
{
GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass);
+ GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
+ GstCaps *tmp = NULL;
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
case GST_H264_PARSER_OK:
GST_DEBUG_OBJECT (h264parse, "complete nal (offset, size): (%u, %u) ",
nalu.offset, nalu.size);
+#ifdef TIZEN_FEATURE_H264PARSE_MODIFICATION
+ last_nal_type = nalu.type;
+#endif
break;
+ case GST_H264_PARSER_NO_NAL:
++#ifdef TIZEN_FEATURE_H264PARSE_MODIFICATION
++ if (last_nal_type == GST_H264_NAL_SEQ_END) {
++ GST_WARNING_OBJECT (h264parse, "No H.264 NAL unit found, but last "
++ "nal type is SEQ_END, So push remain buffer");
++ gst_buffer_unmap (buffer, &map);
++ gst_h264_parse_parse_frame (parse, frame);
++ return gst_base_parse_finish_frame (parse, frame, size);
++ }
++#endif
+ /* In NAL alignment, assume the NAL is broken */
+ if (h264parse->in_align == GST_H264_PARSE_ALIGN_NAL ||
+ h264parse->in_align == GST_H264_PARSE_ALIGN_AU) {
+ goto broken;
+ }
+ goto more;
case GST_H264_PARSER_NO_NAL_END:
/* In NAL alignment, assume the NAL is complete */
if (h264parse->in_align == GST_H264_PARSE_ALIGN_NAL ||
endif
cdata.set('GST_ENABLE_EXTRA_CHECKS', not get_option('extra-checks').disabled())
- gnustl_dep = declare_dependency()
- if host_system == 'android'
- gnustl_dep = dependency('gnustl', required : false)
- endif
-
+# TIZEN BUILD OPTION
+
+# TIZEN_FEATURE_XXX can be generally used for all of modules in this subproject
+cdata.set('TIZEN_FEATURE_FIX_MEMORY_LEAK', true)
+cdata.set('TIZEN_FEATURE_FIX_SEG_FAULT', true)
+
+# TIZEN_FEATURE_[MODULE]_XXX should be used for a particular module
+cdata.set('TIZEN_FEATURE_ADAPTIVE_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_PROPERTY', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_EMPTY_VTT', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_UPDATE_SEGMENT', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_DISCONT_SEQUENCE', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_UPDATE_MANIFEST', true)
+cdata.set('TIZEN_FEATURE_TSDEMUX_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_TSDEMUX_INVALID_PCR_PID', true)
+cdata.set('TIZEN_FEATURE_TSDEMUX_LANG_TAG', true)
+cdata.set('TIZEN_FEATURE_TSDEMUX_UPDATE_PMT', true)
+cdata.set('TIZEN_FEATURE_TSDEMUX_UPDATE_STREAM', true)
+cdata.set('TIZEN_FEATURE_HLS_WEBVTT', true)
+cdata.set('TIZEN_FEATURE_OALSINK_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_MPEGDEMUX_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_H264PARSE_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_AD', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_LANG_TAG', true)
+cdata.set('TIZEN_FEATURE_HLSDEMUX_DISCONT', true)
+cdata.set('TIZEN_FEATURE_WEBRTC_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_WEBRTC_IMPORT_NETSIM', true)
+cdata.set('TIZEN_FEATURE_WEBRTC_SSRC_TIMEOUT_NOTIFICATION', true)
+cdata.set('TIZEN_FEATURE_DTLS_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_PITCH_AUDIO_META', true)
+cdata.set('TIZEN_FEATURE_SRT_LATENCY', true)
+cdata.set('TIZEN_FEATURE_BUG_FIX', true)
+if get_option('tv-profile')
+ cdata.set('TIZEN_PROFILE_TV', true)
+ cdata.set('TIZEN_FEATURE_TRUSTZONE', true)
+endif
+
+# TIZEN_GLOBAL_BUILD_OPTION
+cdata.set('TIZEN_FEATURE_BASEPARSE_MODIFICATION', true)
+cdata.set('TIZEN_FEATURE_WAYLAND_ENHANCEMENT', true)
+cdata.set('USE_TBM', true)
+
+# For plugins from libnice
+libnice_dep = dependency('nice', version : '>=0.1.17', required : get_option('nice'))
+
+# TIZEN BUILD OPTION end
+
# Disable compiler warnings for unused variables and args if gst debug system is disabled
if gst_dep.type_name() == 'internal'
gst_debug_disabled = not subproject('gstreamer').get_variable('gst_debug')
# Common feature options
option('examples', type : 'feature', value : 'auto', yield : true)
+ option('tools', type : 'feature', value : 'auto', yield : true)
option('tests', type : 'feature', value : 'auto', yield : true)
-option('introspection', type : 'feature', value : 'auto', yield : true, description : 'Generate gobject-introspection bindings')
+option('introspection', type : 'feature', value : 'auto', yield : false, description : 'Generate gobject-introspection bindings')
option('nls', type : 'feature', value : 'auto', yield: true, description : 'Enable native language support (translations)')
option('orc', type : 'feature', value : 'auto', yield : true)
option('gobject-cast-checks', type : 'feature', value : 'auto', yield : true,
subdir('tinyalsa')
subdir('uvch264')
subdir('v4l2codecs')
+ subdir('uvcgadget')
+if not (get_option('tv-profile'))
subdir('va')
+endif
subdir('wasapi')
subdir('wasapi2')
subdir('wic')
#include <gst/allocators/gstdmabuf.h>
#include <gst/allocators/gstfdmemory.h>
#include <gst/allocators/gstphysmemory.h>
+ #include <gst/allocators/gstdrmdumb.h>
+ #include <gst/allocators/gstshmallocator.h>
+#ifdef USE_TBM
+#include <gst/allocators/gsttizenmemory.h>
+#include <gst/allocators/gsttizenbufferpool.h>
+#endif
+
#endif /* __GST_ALLOCATORS_H__ */
'gstfdmemory.h',
'gstphysmemory.h',
'gstdmabuf.h',
+ 'gstdrmdumb.h',
+ 'gstshmallocator.h',
])
+
+if tbm_dep.found()
+ gst_allocators_headers += files([
+ 'gsttizenmemory.h',
+ 'gsttizenbufferpool.h',
+ ])
+ gst_allocators_extra_defs += ['-DUSE_TBM']
+endif
install_headers(gst_allocators_headers, subdir : 'gstreamer-1.0/gst/allocators/')
- gst_allocators_sources = files([ 'gstdmabuf.c', 'gstfdmemory.c', 'gstphysmemory.c'])
+ gst_allocators_sources = files([
+ 'gstdrmdumb.c',
+ 'gstdmabuf.c',
+ 'gstfdmemory.c',
+ 'gstphysmemory.c',
+ 'gstshmallocator.c',
+ ])
+
+if tbm_dep.found()
- gst_allocators_sources += files(['gsttizenmemory.c', 'gsttizenbufferpool.c'])
++ gst_allocators_sources += files([
++ 'gsttizenmemory.c',
++ 'gsttizenbufferpool.c'
++ ])
++endif
++
+ gst_allocators_cargs = [
+ gst_plugins_base_args,
+ '-DBUILDING_GST_ALLOCATORS',
+ '-DG_LOG_DOMAIN="GStreamer-Allocators"',
+ ]
+
+ if cc.has_function('memfd_create')
+ gst_allocators_cargs += [
+ '-DHAVE_MEMFD_CREATE',
+ '-D_GNU_SOURCE',
+ ]
+ elif cc.has_function('shm_open')
+ gst_allocators_cargs += [
+ '-DHAVE_SHM_OPEN',
+ ]
endif
gstallocators = library('gstallocators-@0@'.format(api_version),
soversion : soversion,
darwin_versions : osxversion,
install : true,
- dependencies : [gst_dep, video_dep, tbm_dep],
- dependencies : [libdrm_dep, gst_dep],
++ dependencies : [libdrm_dep, gst_dep, video_dep, tbm_dep],
)
pkg_name = 'gstreamer-allocators-1.0'
pkgconfig.generate(gstallocators,
- libraries : [gst_dep],
+ libraries : [libdrm_dep, gst_dep],
variables : pkgconfig_variables,
subdirs : pkgconfig_subdirs,
+ extra_cflags : gst_allocators_extra_defs,
name : pkg_name,
description : 'Allocators implementation',
)
MAKE_YUV_T_FORMAT (NV12_10BE_8L128, "raw video",
GST_MAKE_FOURCC ('N', 'T', '1', '2'), DPTH10_10_10, PSTR0, PLANE011,
OFFS001, SUB420, PACK_NV12_10BE_8L128, TILE_10bit_8x128 (LINEAR)),
+#ifdef TIZEN_PROFILE_TV
+ MAKE_YUV_FORMAT (STV0, "raw video", GST_MAKE_FOURCC ('S', 'T', 'V', '0'),
+ DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
+ MAKE_YUV_FORMAT (STV1, "raw video", GST_MAKE_FOURCC ('S', 'T', 'V', '1'),
+ DPTH888, PSTR111, PLANE012, OFFS0, SUB420, PACK_420),
+#endif
+ MAKE_YUV_T_FORMAT (NV12_10LE40_4L4, "raw video",
+ GST_MAKE_FOURCC ('M', 'H', '2', '1'), DPTH10_10_10, PSTR0, PLANE011,
+ OFFS001, SUB420, PACK_NV12_10LE40_TILED, TILE_10bit_4x4 (LINEAR)),
+ {0x00000000, {GST_VIDEO_FORMAT_DMA_DRM, "DMA_DRM", "DMA DRM video",
+ GST_VIDEO_FORMAT_FLAG_COMPLEX, DPTH0, PSTR0, PLANE_NA, OFFS0}},
+ MAKE_YUV_ST_FORMAT (MT2110T, "raw video",
+ GST_MAKE_FOURCC ('M', 'T', '2', 'T'), DPTH10_10_10, PSTR0, PLANE011,
+ OFFS001, SUB420, PACK_MT2110T_TILED, TILE_10bit_16x32s (LINEAR)),
+ MAKE_YUV_ST_FORMAT (MT2110R, "raw video",
+ GST_MAKE_FOURCC ('M', 'T', '2', 'R'), DPTH10_10_10, PSTR0, PLANE011,
+ OFFS001, SUB420, PACK_MT2110R_TILED, TILE_10bit_16x32s (LINEAR)),
+ MAKE_YUVA_FORMAT (A422, "raw video", GST_MAKE_FOURCC ('A', '4', '2', '2'),
+ DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4224, PACK_A422),
+ MAKE_YUVA_FORMAT (A444, "raw video", GST_MAKE_FOURCC ('A', '4', '4', '4'),
+ DPTH8888, PSTR1111, PLANE0123, OFFS0, SUB4444, PACK_A444),
+ MAKE_YUVA_LE_FORMAT (A444_12LE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_12LE),
+ MAKE_YUVA_FORMAT (A444_12BE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_12BE),
+ MAKE_YUVA_LE_FORMAT (A422_12LE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_12LE),
+ MAKE_YUVA_FORMAT (A422_12BE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_12BE),
+ MAKE_YUVA_LE_FORMAT (A420_12LE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_12LE),
+ MAKE_YUVA_FORMAT (A420_12BE, "raw video", 0x00000000, DPTH12_12_12_12,
+ PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_12BE),
+ MAKE_YUVA_LE_FORMAT (A444_16LE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_16LE),
+ MAKE_YUVA_FORMAT (A444_16BE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_16BE),
+ MAKE_YUVA_LE_FORMAT (A422_16LE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_16LE),
+ MAKE_YUVA_FORMAT (A422_16BE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4224, PACK_A422_16BE),
+ MAKE_YUVA_LE_FORMAT (A420_16LE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_16LE),
+ MAKE_YUVA_FORMAT (A420_16BE, "raw video", 0x00000000, DPTH16_16_16_16,
+ PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_16BE),
+ MAKE_RGB_LE_FORMAT (GBR_16LE, "raw video", DPTH16_16_16, PSTR222, PLANE201,
+ OFFS0, SUB444, PACK_GBR_16LE),
+ MAKE_RGB_FORMAT (GBR_16BE, "raw video", DPTH16_16_16, PSTR222, PLANE201,
+ OFFS0, SUB444, PACK_GBR_16BE),
+ MAKE_RGBA_FORMAT (RBGA, "raw video", DPTH8888, PSTR4444, PLANE0, OFFS0213,
+ SUB4444, PACK_RBGA),
};
G_GNUC_END_IGNORE_DEPRECATIONS;
* Since: 1.22
*/
GST_VIDEO_FORMAT_NV12_10BE_8L128,
+ GST_VIDEO_FORMAT_STV0, /* TIZEN_PROFILE_TV */
+ GST_VIDEO_FORMAT_STV1, /* TIZEN_PROFILE_TV */
+
+ /**
+ * GST_VIDEO_FORMAT_NV12_10LE40_4L4:
+ *
+ * @GST_VIDEO_FORMAT_NV12_10LE40 with 4x4 pixels tiles (5 bytes
+ * per tile row). This format is produced by Verisilicon/Hantro decoders.
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_NV12_10LE40_4L4,
+
+ /**
+ * GST_VIDEO_FORMAT_DMA_DRM:
+ *
+ * @GST_VIDEO_FORMAT_DMA_DRM represent the DMA DRM special format. It's
+ * only used with memory:DMABuf #GstCapsFeatures, where an extra
+ * parameter (drm-format) is required to define the image format and
+ * its memory layout.
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_DMA_DRM,
+
+ /**
+ * GST_VIDEO_FORMAT_MT2110T:
+ *
+ * Mediatek 10bit NV12 little endian with 16x32 tiles in linear order, tile 2
+ * bits.
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_MT2110T,
+
+ /**
+ * GST_VIDEO_FORMAT_MT2110R:
+ *
+ * Mediatek 10bit NV12 little endian with 16x32 tiles in linear order, raster
+ * 2 bits.
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_MT2110R,
+
+ /**
+ * GST_VIDEO_FORMAT_A422:
+ *
+ * planar 4:4:2:2 YUV, 8 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A422,
+
+ /**
+ * GST_VIDEO_FORMAT_A444:
+ *
+ * planar 4:4:4:4 YUV, 8 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A444,
+
+ /**
+ * GST_VIDEO_FORMAT_A444_12LE:
+ *
+ * planar 4:4:4:4 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A444_12LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A444_12BE:
+ *
+ * planar 4:4:4:4 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A444_12BE,
+
+ /**
+ * GST_VIDEO_FORMAT_A422_12LE:
+ *
+ * planar 4:4:2:2 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A422_12LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A422_12BE:
+ *
+ * planar 4:4:2:2 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A422_12BE,
+
+ /**
+ * GST_VIDEO_FORMAT_A420_12LE:
+ *
+ * planar 4:4:2:0 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A420_12LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A420_12BE:
+ *
+ * planar 4:4:2:0 YUV, 12 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A420_12BE,
+
+ /**
+ * GST_VIDEO_FORMAT_A444_16LE:
+ *
+ * planar 4:4:4:4 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A444_16LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A444_16BE:
+ *
+ * planar 4:4:4:4 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A444_16BE,
+
+ /**
+ * GST_VIDEO_FORMAT_A422_16LE:
+ *
+ * planar 4:4:2:2 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A422_16LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A422_16BE:
+ *
+ * planar 4:4:2:2 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A422_16BE,
+
+ /**
+ * GST_VIDEO_FORMAT_A420_16LE:
+ *
+ * planar 4:4:2:0 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A420_16LE,
+
+ /**
+ * GST_VIDEO_FORMAT_A420_16BE:
+ *
+ * planar 4:4:2:0 YUV, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_A420_16BE,
+
+ /**
+ * GST_VIDEO_FORMAT_GBR_16LE:
+ *
+ * planar 4:4:4 RGB, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_GBR_16LE,
+
+ /**
+ * GST_VIDEO_FORMAT_GBR_16BE:
+ *
+ * planar 4:4:4 RGB, 16 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_GBR_16BE,
+
+ /**
+ * GST_VIDEO_FORMAT_RBGA:
+ *
+ * packed RGB with alpha, 8 bits per channel
+ *
+ * Since: 1.24
+ */
+ GST_VIDEO_FORMAT_RBGA,
} GstVideoFormat;
#define GST_VIDEO_MAX_PLANES 4
* - prefer YUV formats over RGB ones
* - prefer I420 over YV12
* - format name
+ *
+ * Since: 1.24
*/
#if G_BYTE_ORDER == G_BIG_ENDIAN
- #define GST_VIDEO_FORMATS_ALL "{ ABGR64_BE, BGRA64_BE, AYUV64, ARGB64_BE, ARGB64, " \
- "RGBA64_BE, ABGR64_LE, BGRA64_LE, ARGB64_LE, RGBA64_LE, GBRA_12BE, GBRA_12LE, Y412_BE, " \
- "Y412_LE, A444_10BE, GBRA_10BE, A444_10LE, GBRA_10LE, A422_10BE, A422_10LE, " \
- "A420_10BE, A420_10LE, Y410, RGB10A2_LE, BGR10A2_LE, GBRA, ABGR, VUYA, BGRA, " \
- "AYUV, ARGB, RGBA, A420, AV12, Y444_16BE, Y444_16LE, v216, P016_BE, P016_LE, Y444_12BE, " \
- "GBR_12BE, Y444_12LE, GBR_12LE, I422_12BE, I422_12LE, Y212_BE, Y212_LE, I420_12BE, " \
- "I420_12LE, P012_BE, P012_LE, Y444_10BE, GBR_10BE, Y444_10LE, GBR_10LE, r210, " \
- "I422_10BE, I422_10LE, NV16_10LE32, Y210, v210, UYVP, I420_10BE, I420_10LE, " \
- "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
- "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \
- "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \
- "S420, ITLV, SN12, ST12, SN21, INVZ, STV0, STV1, " \
- "BGR16, RGB15, BGR15, RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE32, GRAY8 }"
+ #define GST_VIDEO_FORMATS_ALL_STR "A444_16BE, A444_16LE, AYUV64, ARGB64, " \
+ "RGBA64_BE, ARGB64_BE, BGRA64_BE, ABGR64_BE, RGBA64_LE, ARGB64_LE, " \
+ "BGRA64_LE, ABGR64_LE, A422_16BE, A422_16LE, A420_16BE, A420_16LE, " \
+ "A444_12BE, GBRA_12BE, A444_12LE, GBRA_12LE, Y412_BE, Y412_LE, A422_12BE, " \
+ "A422_12LE, A420_12BE, A420_12LE, A444_10BE, GBRA_10BE, A444_10LE, " \
+ "GBRA_10LE, A422_10BE, A422_10LE, A420_10BE, A420_10LE, Y410, BGR10A2_LE, " \
+ "RGB10A2_LE, A444, GBRA, AYUV, VUYA, RGBA, RBGA, ARGB, BGRA, ABGR, A422, " \
+ "A420, AV12, Y444_16BE, GBR_16BE, Y444_16LE, GBR_16LE, v216, P016_BE, " \
+ "P016_LE, Y444_12BE, GBR_12BE, Y444_12LE, GBR_12LE, I422_12BE, I422_12LE, " \
+ "Y212_BE, Y212_LE, I420_12BE, I420_12LE, P012_BE, P012_LE, Y444_10BE, " \
+ "GBR_10BE, Y444_10LE, GBR_10LE, r210, I422_10BE, I422_10LE, NV16_10LE32, " \
+ "Y210, UYVP, v210, I420_10BE, I420_10LE, P010_10BE, MT2110R, MT2110T, " \
+ "NV12_10BE_8L128, NV12_10LE40_4L4, P010_10LE, NV12_10LE40, NV12_10LE32, " \
+ "Y444, BGRP, GBR, RGBP, NV24, v308, IYU2, RGBx, xRGB, BGRx, xBGR, RGB, " \
+ "BGR, Y42B, NV16, NV61, YUY2, YVYU, UYVY, VYUY, I420, YV12, NV12, NV21, " \
+ "NV12_16L32S, NV12_32L32, NV12_4L4, NV12_64Z32, NV12_8L128, Y41B, IYU1, " \
+ "YUV9, YVU9, BGR16, RGB16, BGR15, RGB15, RGB8P, GRAY16_BE, GRAY16_LE, " \
++ "S420, ITLV, SN12, ST12, SN21, INVZ, STV0, STV1, " \
+ "GRAY10_LE32, GRAY8"
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
- #define GST_VIDEO_FORMATS_ALL "{ ABGR64_LE, BGRA64_LE, AYUV64, ARGB64_LE, ARGB64, " \
- "RGBA64_LE, ABGR64_BE, BGRA64_BE, ARGB64_BE, RGBA64_BE, GBRA_12LE, GBRA_12BE, Y412_LE, " \
- "Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, " \
- "A420_10LE, A420_10BE, RGB10A2_LE, BGR10A2_LE, Y410, GBRA, ABGR, VUYA, BGRA, " \
- "AYUV, ARGB, RGBA, A420, AV12, Y444_16LE, Y444_16BE, v216, P016_LE, P016_BE, Y444_12LE, " \
- "GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, " \
- "I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, " \
- "I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, " \
- "P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \
- "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \
- "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \
- "S420, ITLV, SN12, ST12, SN21, INVZ, STV0, STV1, " \
- "BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }"
+ #define GST_VIDEO_FORMATS_ALL_STR "A444_16LE, A444_16BE, AYUV64, RGBA64_LE, " \
+ "ARGB64, ARGB64_LE, BGRA64_LE, ABGR64_LE, RGBA64_BE, ARGB64_BE, BGRA64_BE, " \
+ "ABGR64_BE, A422_16LE, A422_16BE, A420_16LE, A420_16BE, A444_12LE, " \
+ "GBRA_12LE, A444_12BE, GBRA_12BE, Y412_LE, Y412_BE, A422_12LE, A422_12BE, " \
+ "A420_12LE, A420_12BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, " \
+ "A422_10LE, A422_10BE, A420_10LE, A420_10BE, BGR10A2_LE, RGB10A2_LE, Y410, " \
+ "A444, GBRA, AYUV, VUYA, RGBA, RBGA, ARGB, BGRA, ABGR, A422, A420, AV12, " \
+ "Y444_16LE, GBR_16LE, Y444_16BE, GBR_16BE, v216, P016_LE, P016_BE, " \
+ "Y444_12LE, GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, " \
+ "Y212_BE, I420_12LE, I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, " \
+ "Y444_10BE, GBR_10BE, r210, I422_10LE, I422_10BE, NV16_10LE32, Y210, UYVP, " \
+ "v210, I420_10LE, I420_10BE, P010_10LE, NV12_10LE40, NV12_10LE32, " \
+ "P010_10BE, MT2110R, MT2110T, NV12_10BE_8L128, NV12_10LE40_4L4, Y444, " \
+ "BGRP, GBR, RGBP, NV24, v308, IYU2, RGBx, xRGB, BGRx, xBGR, RGB, BGR, " \
+ "Y42B, NV16, NV61, YUY2, YVYU, UYVY, VYUY, I420, YV12, NV12, NV21, " \
+ "NV12_16L32S, NV12_32L32, NV12_4L4, NV12_64Z32, NV12_8L128, Y41B, IYU1, " \
+ "YUV9, YVU9, BGR16, RGB16, BGR15, RGB15, RGB8P, GRAY16_LE, GRAY16_BE, " \
++ "S420, ITLV, SN12, ST12, SN21, INVZ, STV0, STV1, " \
+ "GRAY10_LE32, GRAY8"
#endif
+ /**
+ * GST_VIDEO_FORMATS_ANY_STR:
+ *
+ * This is similar to %GST_VIDEO_FORMATS_ALL_STR but includes formats like
+ * DMA_DRM for which no software converter exists. This should be used for
+ * passthrough template caps.
+ *
+ * Since: 1.24
+ */
+ #define GST_VIDEO_FORMATS_ANY_STR "DMA_DRM, " GST_VIDEO_FORMATS_ALL_STR
+
+ /**
+ * GST_VIDEO_FORMATS_ALL:
+ *
+ * List of all video formats, for use in template caps strings.
+ *
+ * Formats are sorted by decreasing "quality", using these criteria by priority:
+ * - number of components
+ * - depth
+ * - subsampling factor of the width
+ * - subsampling factor of the height
+ * - number of planes
+ * - native endianness preferred
+ * - pixel stride
+ * - poffset
+ * - prefer non-complex formats
+ * - prefer YUV formats over RGB ones
+ * - prefer I420 over YV12
+ * - format name
+ */
+ #define GST_VIDEO_FORMATS_ALL "{ " GST_VIDEO_FORMATS_ALL_STR " }"
+
+ /**
+ * GST_VIDEO_FORMATS_ANY:
+ *
+ * This is similar to %GST_VIDEO_FORMATS_ALL but includes formats like DMA_DRM
+ * that do not have a software converter. This should be used for passthrough
+ * template caps.
+ *
+ * Since: 1.24
+ */
+ #define GST_VIDEO_FORMATS_ANY "{ " GST_VIDEO_FORMATS_ANY_STR " }"
+
GST_VIDEO_API
const GstVideoFormat * gst_video_formats_raw (guint * len);
info->size = info->offset[1] + n_tile_x * uv_n_tile_y * tile_size;
break;
}
+ case GST_VIDEO_FORMAT_MT2110T:
+ case GST_VIDEO_FORMAT_MT2110R:
+ {
+ const gsize tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
+ gint n_tile_x = GST_ROUND_UP_16 (info->width) / 16;
+ gint n_tile_y = GST_ROUND_UP_32 (info->height) / 32;
+
+ info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y);
+ info->stride[1] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = tile_size * n_tile_x * n_tile_y;
+ info->size = info->offset[1] + info->offset[1] / 2;
+ break;
+ }
case GST_VIDEO_FORMAT_ENCODED:
+ case GST_VIDEO_FORMAT_DMA_DRM:
break;
case GST_VIDEO_FORMAT_UNKNOWN:
+#ifdef TIZEN_FEATURE_VIDEO_MODIFICATION
+ default:
+#endif
GST_ERROR ("invalid format");
g_warning ("invalid format");
return FALSE;
/* Properties */
GstCaps *caps;
+#ifdef TIZEN_FEATURE_FORCE_SW_DECODER
+ gboolean force_sw_decoders_for_video;
+ gboolean force_sw_decoders_for_audio;
+#endif
+
+ GList *candidate_decoders;
};
struct _GstDecodebin3Class
GstEvent * event);
static void gst_decode_bin_update_factories_list (GstDecodebin3 * dbin);
- #if 0
- static gboolean have_factory (GstDecodebin3 * dbin, GstCaps * caps,
- GstElementFactoryListType ftype);
- #endif
-
- static void reset_input (GstDecodebin3 * dbin, DecodebinInput * input);
- static void free_input (GstDecodebin3 * dbin, DecodebinInput * input);
- static DecodebinInput *create_new_input (GstDecodebin3 * dbin, gboolean main);
- static gboolean set_input_group_id (DecodebinInput * input, guint32 * group_id);
- static gboolean reconfigure_output_stream (DecodebinOutputStream * output,
- MultiQueueSlot * slot, GstMessage ** msg);
- static void free_output_stream (GstDecodebin3 * dbin,
- DecodebinOutputStream * output);
- static DecodebinOutputStream *create_output_stream (GstDecodebin3 * dbin,
+ static DecodebinCollection *db_collection_new (GstStreamCollection *
+ collection);
+ static void db_collection_free (DecodebinCollection * collection);
+
+ static void gst_decodebin_input_reset (DecodebinInput * input);
+ static void gst_decodebin_input_free (DecodebinInput * input);
+ static DecodebinInput *gst_decodebin_input_new (GstDecodebin3 * dbin,
+ gboolean main);
+ static gboolean gst_decodebin_input_set_group_id (DecodebinInput * input,
+ guint32 * group_id);
+ static void gst_decodebin_input_unblock_streams (DecodebinInput * input,
+ gboolean unblock_other_inputs);
+ static void gst_decodebin_input_link_to_slot (DecodebinInputStream * input);
+
+ static gboolean db_output_stream_reconfigure (DecodebinOutputStream * output,
+ GstMessage ** msg);
+ static void db_output_stream_reset (DecodebinOutputStream * output);
+ static void db_output_stream_free (DecodebinOutputStream * output);
+ static DecodebinOutputStream *db_output_stream_new (GstDecodebin3 * dbin,
GstStreamType type);
- static GstPadProbeReturn slot_unassign_probe (GstPad * pad,
+ static GstPadProbeReturn mq_slot_unassign_probe (GstPad * pad,
GstPadProbeInfo * info, MultiQueueSlot * slot);
- static gboolean reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot);
- static MultiQueueSlot *get_slot_for_input (GstDecodebin3 * dbin,
+ static void mq_slot_reassign (MultiQueueSlot * slot);
+ static MultiQueueSlot
+ * gst_decodebin_get_slot_for_input_stream_locked (GstDecodebin3 * dbin,
DecodebinInputStream * input);
- static void link_input_to_slot (DecodebinInputStream * input,
- MultiQueueSlot * slot);
- static void free_multiqueue_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot);
- static void free_multiqueue_slot_async (GstDecodebin3 * dbin,
- MultiQueueSlot * slot);
+ static void mq_slot_free (GstDecodebin3 * dbin, MultiQueueSlot * slot);
+
+ static void handle_stream_switch (GstDecodebin3 * dbin);
static GstStreamCollection *get_merged_collection (GstDecodebin3 * dbin);
- static void update_requested_selection (GstDecodebin3 * dbin);
+ static void update_requested_selection (GstDecodebin3 * dbin,
+ DecodebinCollection * new_collection);
-
+#ifdef TIZEN_FEATURE_FORCE_SW_DECODER
+static GList *create_decoder_factory_list (GstDecodebin3 * dbin, GstCaps * caps);
+#endif
-
- /* FIXME: Really make all the parser stuff a self-contained helper object */
- #include "gstdecodebin3-parse.c"
+ static void parsebin_pad_added_cb (GstElement * demux, GstPad * pad,
+ DecodebinInput * input);
+ static void parsebin_pad_removed_cb (GstElement * demux, GstPad * pad,
+ DecodebinInput * input);
+#ifdef TIZEN_FEATURE_RESOURCE_MANAGER
+static gboolean gst_decodebin3_request_resource (GstDecodebin3 * dbin,
+ GstStreamCollection * collection, GstStream * stream)
+{
+ /* do not consider the resource limit */
+ return TRUE;
+}
+
+static gboolean
+_gst_boolean_accumulator (GSignalInvocationHint * ihint,
+ GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+ gboolean myboolean;
+
+ myboolean = g_value_get_boolean (handler_return);
+ if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+ g_value_set_boolean (return_accu, myboolean);
+
+ return myboolean;
+}
+#endif
+
static gboolean
_gst_int_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer dummy)
g_mutex_init (&dbin->factories_lock);
g_mutex_init (&dbin->selection_lock);
g_mutex_init (&dbin->input_lock);
+ g_cond_init (&dbin->posting_cond);
+ dbin->posting_collection = FALSE;
dbin->caps = gst_static_caps_get (&default_raw_caps);
+#ifdef TIZEN_FEATURE_FORCE_SW_DECODER
+ dbin->force_sw_decoders_for_video = DEFAULT_FORCE_SW_DECODERS;
+ dbin->force_sw_decoders_for_audio = DEFAULT_FORCE_SW_DECODERS;
+#endif
GST_OBJECT_FLAG_SET (dbin, GST_BIN_FLAG_STREAMS_AWARE);
}
for (tmp = dbin->factories; tmp; tmp = tmp->next) {
GstElementFactory *fact = (GstElementFactory *) tmp->data;
if (gst_element_factory_list_is_type (fact,
- GST_ELEMENT_FACTORY_TYPE_DECODER))
+ GST_ELEMENT_FACTORY_TYPE_DECODER)) {
+#ifdef TIZEN_FEATURE_FORCE_SW_DECODER
+ if (!(dbin->force_sw_decoders_for_video &&
+ gst_element_factory_list_is_type (fact, GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) &&
+ gst_element_factory_list_is_type (fact, GST_ELEMENT_FACTORY_TYPE_HARDWARE)) &&
+ !(dbin->force_sw_decoders_for_audio &&
+ gst_element_factory_list_is_type (fact, GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) &&
+ gst_element_factory_list_is_type (fact, GST_ELEMENT_FACTORY_TYPE_HARDWARE))) {
+ dbin->decoder_factories =
+ g_list_append (dbin->decoder_factories, fact);
+ } else {
+ GST_DEBUG ("%s is added into skipped list", GST_OBJECT_NAME(fact));
+ dbin->skipped_decoder_factories =
+ g_list_append (dbin->skipped_decoder_factories, fact);
+ }
++#else
+ dbin->decoder_factories = g_list_append (dbin->decoder_factories, fact);
- else
+#endif
+ } else {
dbin->decodable_factories =
g_list_append (dbin->decodable_factories, fact);
+ }
}
}
}
GST_DEBUG_OBJECT (pad, "Got regular eos (all_inputs_are_eos)");
/* drop current event as eos will be sent in check_all_slot_for_eos
* when all output streams are also eos */
+#ifndef TIZEN_FEATURE_DISABLE_EOS_DROP
ret = GST_PAD_PROBE_DROP;
+#endif
SELECTION_LOCK (dbin);
- check_all_slot_for_eos (dbin, ev);
+ check_and_drain_multiqueue_locked (dbin, ev);
SELECTION_UNLOCK (dbin);
}
}
return GST_PAD_PROBE_DROP;
}
- /* Returns FALSE if the output couldn't be properly configured and the
- * associated GstStreams should be disabled */
static gboolean
- reconfigure_output_stream (DecodebinOutputStream * output,
- MultiQueueSlot * slot, GstMessage ** msg)
+ clear_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
+ {
+ GST_DEBUG_OBJECT (pad, "clearing sticky event %" GST_PTR_FORMAT, *event);
+ gst_event_unref (*event);
+ *event = NULL;
+ return TRUE;
+ }
+
+ static gboolean
+ copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
+ {
+ GstPad *gpad = GST_PAD_CAST (user_data);
+
+ GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
+ gst_pad_store_sticky_event (gpad, *event);
+
+ return TRUE;
+ }
+
+ static gboolean
+ decode_pad_set_target (GstGhostPad * pad, GstPad * target)
+ {
+ gboolean res = gst_ghost_pad_set_target (pad, target);
+ if (!res)
+ return res;
+
+ if (target == NULL)
+ gst_pad_sticky_events_foreach (GST_PAD_CAST (pad), clear_sticky_events,
+ NULL);
+ else
+ gst_pad_sticky_events_foreach (target, copy_sticky_events, pad);
+
+ return res;
+ }
+
+ static void
+ db_output_stream_expose_src_pad (DecodebinOutputStream * output)
+ {
+ MultiQueueSlot *slot = output->slot;
+ GstEvent *stream_start;
+
+ if (output->src_exposed)
+ return;
+
+ stream_start =
+ gst_pad_get_sticky_event (slot->src_pad, GST_EVENT_STREAM_START, 0);
+
+ /* Ensure GstStream is accesiable from pad-added callback */
+ if (stream_start) {
+ gst_pad_store_sticky_event (output->src_pad, stream_start);
+ gst_event_unref (stream_start);
+ } else {
+ GST_WARNING_OBJECT (slot->src_pad, "Pad has no stored stream-start event");
+ }
+
+ output->src_exposed = TRUE;
+ gst_element_add_pad (GST_ELEMENT_CAST (slot->dbin), output->src_pad);
+ }
+
+ static CandidateDecoder *
+ add_candidate_decoder (GstDecodebin3 * dbin, GstElement * element)
+ {
+ GST_OBJECT_LOCK (dbin);
+ CandidateDecoder *candidate;
+ candidate = g_new0 (CandidateDecoder, 1);
+ candidate->element = element;
+ dbin->candidate_decoders =
+ g_list_prepend (dbin->candidate_decoders, candidate);
+ GST_OBJECT_UNLOCK (dbin);
+ return candidate;
+ }
+
+ static void
+ remove_candidate_decoder (GstDecodebin3 * dbin, CandidateDecoder * candidate)
+ {
+ GST_OBJECT_LOCK (dbin);
+ dbin->candidate_decoders =
+ g_list_remove (dbin->candidate_decoders, candidate);
+ if (candidate->error)
+ gst_message_unref (candidate->error);
+ g_free (candidate);
+ GST_OBJECT_UNLOCK (dbin);
+ }
+
+ /** db_output_stream_setup_decoder:
+ * @output: A #DecodebinOutputStream
+ * @caps: (transfer none): The #GstCaps for which we want a decoder
+ * @msg: A pointer to a #GstMessage
+ *
+ * Finds the appropriate decoder for @caps and sets it up. If the @caps match
+ * the decodebin output caps, it will be configured to propagate the stream
+ * as-is without any decoder.
+ *
+ * Returns: #TRUE if a decoder was found and properly setup, else #FALSE. If the
+ * failure was due to missing plugins, then @msg will be properly filled up.
+ */
+ static gboolean
+ db_output_stream_setup_decoder (DecodebinOutputStream * output,
+ GstCaps * new_caps, GstMessage ** msg)
{
- GstDecodebin3 *dbin = output->dbin;
- GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
- gboolean needs_decoder;
gboolean ret = TRUE;
+ GstDecodebin3 *dbin = output->dbin;
+ MultiQueueSlot *slot = output->slot;
+ GList *factories, *next_factory;
- needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
-
- GST_DEBUG_OBJECT (dbin,
- "Reconfiguring output %p to slot %p, needs_decoder:%d", output, slot,
- needs_decoder);
+ GST_DEBUG_OBJECT (dbin, "output %s:%s caps %" GST_PTR_FORMAT,
+ GST_DEBUG_PAD_NAME (output->src_pad), new_caps);
- /* FIXME : Maybe make the output un-hook itself automatically ? */
- if (output->slot != NULL && output->slot != slot) {
- GST_WARNING_OBJECT (dbin,
- "Output still linked to another slot (%p)", output->slot);
- gst_caps_unref (new_caps);
- return ret;
+ /* If no decoder is required, use the slot source pad and we're done */
+ if (gst_caps_can_intersect (new_caps, dbin->caps)) {
+ output->decoder_src = gst_object_ref (slot->src_pad);
+ goto done;
}
- /* Check if existing config is reusable as-is by checking if
- * the existing decoder accepts the new caps, if not delete
- * it and create a new one */
- if (output->decoder) {
- gboolean can_reuse_decoder;
+ factories = next_factory = create_decoder_factory_list (dbin, new_caps);
+ if (!next_factory) {
+ GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT, new_caps);
+ g_assert (output->decoder == NULL);
+ ret = FALSE;
+ goto missing_decoder;
+ }
- if (needs_decoder) {
- can_reuse_decoder =
- gst_pad_query_accept_caps (output->decoder_sink, new_caps);
- } else
- can_reuse_decoder = FALSE;
-
- if (can_reuse_decoder) {
- if (output->type & GST_STREAM_TYPE_VIDEO && output->drop_probe_id == 0) {
- GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
- output->drop_probe_id =
- gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
- (GstPadProbeCallback) keyframe_waiter_probe, output, NULL);
- }
- GST_DEBUG_OBJECT (dbin, "Reusing existing decoder for slot %p", slot);
- if (output->linked == FALSE) {
- gst_pad_link_full (slot->src_pad, output->decoder_sink,
- GST_PAD_LINK_CHECK_NOTHING);
- output->linked = TRUE;
+ while (next_factory) {
+ CandidateDecoder *candidate = NULL;
-
++#ifdef TIZEN_FEATURE_RESOURCE_MANAGER
++ if (gst_element_factory_list_is_type (next_factory->data,
++ GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
++ gboolean result = FALSE;
++ if (dbin->output_collection && slot->active_stream) {
++ g_signal_emit (G_OBJECT (dbin),
++ gst_decodebin3_signals[SIGNAL_REQUEST_RESOURCE], 0, dbin->output_collection->collection, slot->active_stream,
++ &result);
++ if (!result) {
++ GstCaps *caps;
++ GST_WARNING_OBJECT (dbin, "Failed to get HW resource.");
++ SELECTION_UNLOCK (dbin);
++ caps = gst_stream_get_caps (slot->active_stream);
++ gst_element_post_message (GST_ELEMENT_CAST (dbin),
++ gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
++ gst_caps_unref (caps);
++ SELECTION_LOCK (dbin);
++ goto cleanup;
++ }
+ }
- gst_caps_unref (new_caps);
- return ret;
+ }
-
- GST_DEBUG_OBJECT (dbin, "Removing old decoder for slot %p", slot);
-
- if (output->linked)
- gst_pad_unlink (slot->src_pad, output->decoder_sink);
- output->linked = FALSE;
- if (output->drop_probe_id) {
- gst_pad_remove_probe (slot->src_pad, output->drop_probe_id);
- output->drop_probe_id = 0;
++#endif
+ /* If we don't have a decoder yet, instantiate one */
+ output->decoder = gst_element_factory_create (
+ (GstElementFactory *) next_factory->data, NULL);
+ GST_DEBUG ("Trying decoder %" GST_PTR_FORMAT, output->decoder);
+
+ if (output->decoder == NULL)
+ goto try_next;
+
+ if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
+ GST_WARNING_OBJECT (dbin, "could not add decoder '%s' to pipeline",
+ GST_ELEMENT_NAME (output->decoder));
+ goto try_next;
}
-
- if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad, NULL)) {
- GST_ERROR_OBJECT (dbin, "Could not release decoder pad");
- gst_caps_unref (new_caps);
- goto cleanup;
+ output->decoder_sink = gst_element_get_static_pad (output->decoder, "sink");
+ output->decoder_src = gst_element_get_static_pad (output->decoder, "src");
+
+ candidate = add_candidate_decoder (dbin, output->decoder);
+ if (gst_pad_link_full (slot->src_pad, output->decoder_sink,
+ GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
+ GST_WARNING_OBJECT (dbin, "could not link to %s:%s",
+ GST_DEBUG_PAD_NAME (output->decoder_sink));
+ goto try_next;
}
+ output->linked = TRUE;
- gst_element_set_locked_state (output->decoder, TRUE);
- gst_element_set_state (output->decoder, GST_STATE_NULL);
-
- gst_bin_remove ((GstBin *) dbin, output->decoder);
- output->decoder = NULL;
- output->decoder_latency = GST_CLOCK_TIME_NONE;
- } else if (output->linked) {
- /* Otherwise if we have no decoder yet but the output is linked make
- * sure that the ghost pad is really unlinked in case no decoder was
- * needed previously */
- if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad, NULL)) {
- GST_ERROR_OBJECT (dbin, "Could not release ghost pad");
- gst_caps_unref (new_caps);
- goto cleanup;
+ if (gst_element_set_state (output->decoder, GST_STATE_READY) ==
+ GST_STATE_CHANGE_FAILURE) {
+ GST_WARNING_OBJECT (dbin, "Decoder '%s' failed to reach READY state",
+ GST_ELEMENT_NAME (output->decoder));
+ goto try_next;
}
- }
- gst_object_replace ((GstObject **) & output->decoder_sink, NULL);
- gst_object_replace ((GstObject **) & output->decoder_src, NULL);
+ if (!gst_pad_query_accept_caps (output->decoder_sink, new_caps)) {
+ GST_DEBUG_OBJECT (dbin,
+ "Decoder '%s' did not accept the caps, trying the next type",
+ GST_ELEMENT_NAME (output->decoder));
+ goto try_next;
+ }
- /* If a decoder is required, create one */
- if (needs_decoder) {
- GList *factories, *next_factory;
+ if (gst_element_set_state (output->decoder, GST_STATE_PAUSED) ==
+ GST_STATE_CHANGE_FAILURE) {
+ GST_WARNING_OBJECT (dbin, "Decoder '%s' failed to reach PAUSED state",
+ GST_ELEMENT_NAME (output->decoder));
+ goto try_next;
+ }
- factories = next_factory = create_decoder_factory_list (dbin, new_caps);
- while (!output->decoder) {
- gboolean decoder_failed = FALSE;
+ /* Everything went well, we have a decoder */
+ GST_DEBUG ("created decoder %" GST_PTR_FORMAT, output->decoder);
- /* If we don't have a decoder yet, instantiate one */
- if (next_factory) {
- #ifdef TIZEN_FEATURE_RESOURCE_MANAGER
- if (gst_element_factory_list_is_type (next_factory->data,
- GST_ELEMENT_FACTORY_TYPE_HARDWARE)) {
- gboolean result = FALSE;
- g_signal_emit (G_OBJECT (dbin),
- gst_decodebin3_signals[SIGNAL_REQUEST_RESOURCE], 0, dbin->collection, slot->active_stream,
- &result);
- if (!result) {
- GstCaps *caps;
- GST_WARNING_OBJECT (dbin, "Failed to get HW resource.");
- SELECTION_UNLOCK (dbin);
- caps = gst_stream_get_caps (slot->active_stream);
- gst_element_post_message (GST_ELEMENT_CAST (dbin),
- gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
- gst_caps_unref (caps);
- SELECTION_LOCK (dbin);
- goto cleanup;
- }
- }
- #endif
- output->decoder = gst_element_factory_create ((GstElementFactory *)
- next_factory->data, NULL);
- GST_DEBUG ("Created decoder '%s'", GST_ELEMENT_NAME (output->decoder));
- } else {
- GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT,
- new_caps);
- g_assert (output->decoder == NULL);
- }
+ handle_stored_latency_message (dbin, output, candidate);
+ remove_candidate_decoder (dbin, candidate);
+ break;
- if (output->decoder == NULL) {
- GstCaps *caps;
+ try_next:{
+ db_output_stream_reset (output);
+ if (candidate)
+ remove_candidate_decoder (dbin, candidate);
- /* FIXME : Should we be smarter if there's a missing decoder ?
- * Should we deactivate that stream ? */
- caps = gst_stream_get_caps (slot->active_stream);
- *msg = gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps);
- gst_caps_unref (caps);
- ret = FALSE;
- goto cleanup;
- }
- if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
- GST_ERROR_OBJECT (dbin, "could not add decoder to pipeline");
- ret = FALSE;
- goto cleanup;
- }
- output->decoder_sink =
- gst_element_get_static_pad (output->decoder, "sink");
- output->decoder_src = gst_element_get_static_pad (output->decoder, "src");
- if (output->type & GST_STREAM_TYPE_VIDEO) {
- GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
- output->drop_probe_id =
- gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
- (GstPadProbeCallback) keyframe_waiter_probe, output, NULL);
- }
- if (gst_pad_link_full (slot->src_pad, output->decoder_sink,
- GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
- GST_ERROR_OBJECT (dbin, "could not link to %s:%s",
- GST_DEBUG_PAD_NAME (output->decoder_sink));
+ if (!next_factory->next) {
ret = FALSE;
+ if (output->decoder == NULL)
+ goto missing_decoder;
goto cleanup;
}
- if (gst_element_set_state (output->decoder,
- GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
- GST_DEBUG_OBJECT (dbin,
- "Decoder '%s' failed to reach READY state, trying the next type",
- GST_ELEMENT_NAME (output->decoder));
- decoder_failed = TRUE;
- }
- if (!gst_pad_query_accept_caps (output->decoder_sink, new_caps)) {
- GST_DEBUG_OBJECT (dbin,
- "Decoder '%s' did not accept the caps, trying the next type",
- GST_ELEMENT_NAME (output->decoder));
- decoder_failed = TRUE;
- }
- if (decoder_failed) {
- gst_pad_unlink (slot->src_pad, output->decoder_sink);
- if (output->drop_probe_id) {
- gst_pad_remove_probe (slot->src_pad, output->drop_probe_id);
- output->drop_probe_id = 0;
- }
-
- gst_element_set_locked_state (output->decoder, TRUE);
- gst_element_set_state (output->decoder, GST_STATE_NULL);
-
- gst_bin_remove ((GstBin *) dbin, output->decoder);
- output->decoder = NULL;
- }
next_factory = next_factory->next;
}
- gst_plugin_feature_list_free (factories);
- } else {
- output->decoder_src = gst_object_ref (slot->src_pad);
- output->decoder_sink = NULL;
}
- gst_caps_unref (new_caps);
-
- output->linked = TRUE;
- if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad,
- output->decoder_src)) {
- GST_ERROR_OBJECT (dbin, "Could not expose decoder pad");
- ret = FALSE;
- goto cleanup;
+ gst_plugin_feature_list_free (factories);
+
+ done:
+ if (output->type & GST_STREAM_TYPE_VIDEO && slot->drop_probe_id == 0) {
+ GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
+ slot->drop_probe_id =
+ gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
+ (GstPadProbeCallback) keyframe_waiter_probe, slot, NULL);
}
- output->linked = TRUE;
-
- if (output->src_exposed == FALSE) {
- GstEvent *stream_start;
-
- stream_start = gst_pad_get_sticky_event (slot->src_pad,
- GST_EVENT_STREAM_START, 0);
-
- /* Ensure GstStream is accesiable from pad-added callback */
- if (stream_start) {
- gst_pad_store_sticky_event (output->src_pad, stream_start);
- gst_event_unref (stream_start);
- } else {
- GST_WARNING_OBJECT (slot->src_pad,
- "Pad has no stored stream-start event");
- }
+ /* Set the decode pad target */
+ decode_pad_set_target ((GstGhostPad *) output->src_pad, output->decoder_src);
- output->src_exposed = TRUE;
- gst_element_add_pad (GST_ELEMENT_CAST (dbin), output->src_pad);
- }
+ /* Expose the source pad if needed */
+ db_output_stream_expose_src_pad (output);
if (output->decoder)
gst_element_sync_state_with_parent (output->decoder);
}
}
- *
+ /** db_output_stream_reconfigure:
+ * @output: A #DecodebinOutputStream
+ * @msg: A pointer to a #GstMessage
+ *
+ * (Re)Configure the @output for the associated slot active stream.
++ *
+ * Returns: #TRUE if the output was properly (re)configured. #FALSE if it
+ * failed, in which case the stream shouldn't be used and the @msg might contain
+ * a message to be posted on the bus.
+ */
+ static gboolean
+ db_output_stream_reconfigure (DecodebinOutputStream * output, GstMessage ** msg)
+ {
+ MultiQueueSlot *slot = output->slot;
+ GstDecodebin3 *dbin = output->dbin;
+ GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
+ gboolean needs_decoder;
+ gboolean ret = TRUE;
+
+ needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
+
+ GST_DEBUG_OBJECT (dbin,
+ "Reconfiguring output %s:%s to slot %s:%s, needs_decoder:%d",
+ GST_DEBUG_PAD_NAME (output->src_pad), GST_DEBUG_PAD_NAME (slot->src_pad),
+ needs_decoder);
+
+ /* First check if we can re-use the output as-is for the new caps:
+ * * Either we have a decoder and it can accept the new caps
+ * * Or we don't have one and don't need one
+ */
+
+ /* If we need a decoder and the existing one can accept the new caps, re-use it */
+ if (needs_decoder && output->decoder &&
+ gst_pad_query_accept_caps (output->decoder_sink, new_caps)) {
+ GST_DEBUG_OBJECT (dbin,
+ "Reusing existing decoder '%" GST_PTR_FORMAT "' for slot %p",
+ output->decoder, slot);
+ /* Re-add the keyframe-waiter probe */
+ if (output->type & GST_STREAM_TYPE_VIDEO && slot->drop_probe_id == 0) {
+ GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
+ slot->drop_probe_id =
+ gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
+ (GstPadProbeCallback) keyframe_waiter_probe, slot, NULL);
+ }
+ if (output->linked == FALSE) {
+ gst_pad_link_full (slot->src_pad, output->decoder_sink,
+ GST_PAD_LINK_CHECK_NOTHING);
+ output->linked = TRUE;
+ }
+ } else {
+ /* We need to reset the output and set it up again */
+ db_output_stream_reset (output);
+
+ /* Setup the decoder */
+ ret = db_output_stream_setup_decoder (output, new_caps, msg);
+ }
+
+ gst_caps_unref (new_caps);
+
+ return ret;
+ }
+
static GstPadProbeReturn
idle_reconfigure (GstPad * pad, GstPadProbeInfo * info, MultiQueueSlot * slot)
{
}
}
}
-
++#endif
+ /*** audio/x-brstm ***/
+
+ static GstStaticCaps brstm_caps = GST_STATIC_CAPS ("audio/x-brstm");
+
+ #define BRSTM_CAPS (gst_static_caps_get(&brstm_caps))
+ static void
+ brstm_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 8);
+
+ if (data) {
+ if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('R', 'S', 'T', 'M'))
+ return;
+ if (GST_READ_UINT32_LE (data + 4) != 0xfffe
+ && GST_READ_UINT32_LE (data + 4) != 0xfeff)
+ return;
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, BRSTM_CAPS);
+ }
+ }
+
+ /*** audio/x-bfstm ***/
+
+ static GstStaticCaps bfstm_caps = GST_STATIC_CAPS ("audio/x-bfstm");
+
+ #define BFSTM_CAPS (gst_static_caps_get(&bfstm_caps))
+ static void
+ bfstm_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 8);
+
+ if (data) {
+ if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('F', 'S', 'T', 'M') &&
+ GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('C', 'S', 'T', 'M'))
+ return;
+ if (GST_READ_UINT32_LE (data + 4) != 0xfffe
+ && GST_READ_UINT32_LE (data + 4) != 0xfeff)
+ return;
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, BFSTM_CAPS);
+ }
+ }
+
+ /*** audio/x-dsf ***/
+
+ static GstStaticCaps dsf_caps = GST_STATIC_CAPS ("audio/x-dsf");
+
+ #define DSF_CAPS (gst_static_caps_get(&dsf_caps))
+ static void
+ dsf_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 12);
+
+ if (data) {
+ if (memcmp (data, "DSD ", 4) != 0)
+ return;
+ if (GST_READ_UINT64_BE (data + 4) == 28)
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, DSF_CAPS);
+ }
+ }
+
+ /*** video/x-ea ***/
+
+ static GstStaticCaps ea_caps = GST_STATIC_CAPS ("video/x-ea");
+
+ #define EA_CAPS (gst_static_caps_get(&ea_caps))
+ static void
+ ea_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 8);
+
+ if (data) {
+ static const guint32 ea_fourccs[] = {
+ GST_MAKE_FOURCC ('I', 'S', 'N', 'h'),
+ GST_MAKE_FOURCC ('S', 'C', 'H', 'l'),
+ GST_MAKE_FOURCC ('S', 'E', 'A', 'D'),
+ GST_MAKE_FOURCC ('S', 'H', 'E', 'N'),
+ GST_MAKE_FOURCC ('k', 'V', 'G', 'T'),
+ GST_MAKE_FOURCC ('M', 'A', 'D', 'k'),
+ GST_MAKE_FOURCC ('M', 'P', 'C', 'h'),
+ GST_MAKE_FOURCC ('M', 'V', 'h', 'd'),
+ GST_MAKE_FOURCC ('M', 'V', 'I', 'h'),
+ GST_MAKE_FOURCC ('A', 'V', 'P', '6'),
+ };
+
+ guint32 fourcc = GST_READ_UINT32_LE (data);
+ gboolean found = FALSE;
+
+ for (gsize i = 0; i < G_N_ELEMENTS (ea_fourccs); i++) {
+ if (fourcc == ea_fourccs[i]) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ return;
+
+ guint32 size = GST_READ_UINT32_LE (data + 4);
+ gboolean big_endian = size > 0x000fffff;
+ if (big_endian)
+ size = GUINT32_SWAP_LE_BE (size);
+ if (size > 0xfffff || size < 8)
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, EA_CAPS);
+ }
+ }
+
+ /*** video/x-film-cpk ***/
+
+ static GstStaticCaps film_cpk_caps = GST_STATIC_CAPS ("video/x-film-cpk");
+
+ #define FILM_CPK_CAPS (gst_static_caps_get(&film_cpk_caps))
+ static void
+ film_cpk_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 20);
+
+ if (data) {
+ if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('F', 'I', 'L', 'M'))
+ return;
+ if (GST_READ_UINT32_LE (data + 16) != GST_MAKE_FOURCC ('F', 'D', 'S', 'C'))
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, FILM_CPK_CAPS);
+ }
+ }
+
+ /*** application/gxf ***/
+
+ static GstStaticCaps gxf_caps = GST_STATIC_CAPS ("application/gxf");
+
+ #define GXF_CAPS (gst_static_caps_get(&gxf_caps))
+ static void
+ gxf_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 16);
+
+ if (data) {
+ if (memcmp (data, "\x00\x00\x00\x00\x01\xbc", 6) != 0)
+ return;
+ if (memcmp (data + 10, "\x00\x00\x00\x00\xe1\xe2", 6) != 0)
+ return;
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, GXF_CAPS);
+ }
+ }
+
+ /*** application/x-iff ***/
+
+ static GstStaticCaps iff_caps = GST_STATIC_CAPS ("application/x-iff");
+
+ #define IFF_CAPS (gst_static_caps_get(&iff_caps))
+ static void
+ iff_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 16);
+
+ if (data) {
+ if (GST_READ_UINT32_LE (data) == GST_MAKE_FOURCC ('F', 'O', 'R', 'M') &&
+ (GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('8', 'S', 'V', 'X')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('1', '6', 'S',
+ 'V')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('M', 'A', 'U',
+ 'D')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('P', 'B', 'M',
+ ' ')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('A', 'C', 'B',
+ 'M')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('D', 'E', 'E',
+ 'P')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('I', 'L', 'B',
+ 'M')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('R', 'G', 'B',
+ '8')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('A', 'N', 'I',
+ 'M')
+ || GST_READ_UINT32_LE (data + 8) == GST_MAKE_FOURCC ('R', 'G', 'B',
+ 'N'))) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, IFF_CAPS);
+ return;
+ }
+
+ if (GST_READ_UINT32_LE (data) == GST_MAKE_FOURCC ('F', 'R', 'M', '8')
+ && GST_READ_UINT32_LE (data + 12) == GST_MAKE_FOURCC ('D', 'S', 'D',
+ ' ')) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, IFF_CAPS);
+ return;
+ }
+ }
+ }
+
+ /*** video/x-idcin ***/
+
+ static GstStaticCaps idcin_caps = GST_STATIC_CAPS ("video/x-idcin");
+
+ #define IDCIN_CAPS (gst_static_caps_get(&idcin_caps))
+ static void
+ idcin_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 20 + 64 * 1024 + 4);
+ if (!data)
+ return;
+
+ // See ffmpeg/libavformat/idcin.c:idcin_probe() for details
+
+ guint number, sample_rate;
+ guint w, h;
+ gint i;
+
+ w = GST_READ_UINT32_LE (data);
+ if (w == 0 || w > 1024)
+ return;
+
+ h = GST_READ_UINT32_LE (data + 4);
+ if (h == 0 || h > 1024)
+ return;
+
+ sample_rate = GST_READ_UINT32_LE (data + 8);
+ if (sample_rate && (sample_rate < 8000 || sample_rate > 48000))
+ return;
+
+ number = GST_READ_UINT32_LE (data + 12);
+ if (number > 2 || (sample_rate && !number))
+ return;
+
+ number = GST_READ_UINT32_LE (data + 16);
+ if (number > 2 || (sample_rate && !number))
+ return;
+
+ i = 20 + 64 * 1024;
+ if (GST_READ_UINT32_LE (data + i) == 1)
+ i += 768;
+
+ data = gst_type_find_peek (tf, 0, 20 + 64 * 1024 + 768 + 12);
+ if (!data)
+ return;
+
+ if (GST_READ_UINT32_LE (data + i + 8) != w * h)
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, IDCIN_CAPS);
+ }
+
+ /*** video/x-idcin ***/
+
+ static GstStaticCaps mm_caps = GST_STATIC_CAPS ("application/x-mm");
+
+ #define MM_CAPS (gst_static_caps_get(&mm_caps))
+ static void
+ mm_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 24 + 6);
+ if (!data)
+ return;
+
+ // See ffmpeg/libavformat/mm.c:probe() for details
+ gint len, type, fps, w, h;
+
+ if (GST_READ_UINT16_LE (&data[0]) != 0x00)
+ return;
+ len = GST_READ_UINT32_LE (&data[2]);
+ if (len != 22 && len != 24)
+ return;
+ fps = GST_READ_UINT16_LE (&data[8]);
+ w = GST_READ_UINT16_LE (&data[12]);
+ h = GST_READ_UINT16_LE (&data[14]);
+ if (!fps || fps > 60 || !w || w > 2048 || !h || h > 2048)
+ return;
+ type = GST_READ_UINT16_LE (&data[len]);
+ if (!type || type > 0x31)
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, MM_CAPS);
+ }
+
+ /*** video/x-ipmovie ***/
+
+ static GstStaticCaps ipmovie_caps = GST_STATIC_CAPS ("video/x-ipmovie");
+ #define IPMOVIE_CAPS (gst_static_caps_get(&ipmovie_caps))
+ static void
+ ipmovie_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 4096)
+ length = 4096;
+
+ static const char signature[] = "Interplay MVE File\x1A\0\x1A";
+ if (length < sizeof (signature))
+ return;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ for (gsize i = 0; i < length - sizeof (signature); i++) {
+ if (memcmp (data + i, signature, sizeof (signature)) != 0) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, IPMOVIE_CAPS);
+ return;
+ }
+ }
+ }
+
+ /*** application/vnd.smaf ***/
+
+ static GstStaticCaps mmf_caps = GST_STATIC_CAPS ("application/vnd.smaf");
+
+ #define MMF_CAPS (gst_static_caps_get(&mmf_caps))
+ static void
+ mmf_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data = gst_type_find_peek (tf, 0, 12);
+ if (!data)
+ return;
+
+ if (data[0] == 'M' && data[1] == 'M' &&
+ data[2] == 'M' && data[3] == 'D' &&
+ data[8] == 'C' && data[9] == 'N' && data[10] == 'T' && data[11] == 'I')
+ gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, MMF_CAPS);
+ }
+
+ /*** video/x-nsv ***/
+
+ static GstStaticCaps nsv_caps = GST_STATIC_CAPS ("video/x-nsv");
+
+ #define NSV_CAPS (gst_static_caps_get(&nsv_caps))
+ static void
+ nsv_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ static const guint8 marker[4] = { 'N', 'S', 'V', 's', };
+ const guint8 *data;
+ guint64 length;
+ gsize i;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 4096)
+ length = 4096;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 4)
+ return;
+
+ if (data[0] == 'N' && data[1] == 'S' &&
+ data[2] == 'V' && (data[3] == 'f' || data[3] == 's')) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, NSV_CAPS);
+ return;
+ }
+
+ if (length < 24)
+ return;
+
+ for (i = 1; i < length - 23; i++) {
+ if (memcmp (&data[i], marker, sizeof (marker)) == 0) {
+ gsize offset = i + 23;
+ if (offset < length) {
+ guint32 vsize = GST_READ_UINT24_LE (&data[i + 19]) >> 4;
+ guint32 asize = GST_READ_UINT16_LE (&data[i + 22]) >> 4;
+ offset += asize + vsize;
+ if (offset + 1 < length && GST_READ_UINT16_LE (&data[offset]) == 0xBEEF) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_NEARLY_CERTAIN, NSV_CAPS);
+ return;
+ }
+ }
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MINIMUM, NSV_CAPS);
+ return;
+ }
+ }
+ }
+
+ /*** application/x-nut ***/
+
+ static GstStaticCaps nut_caps = GST_STATIC_CAPS ("application/x-nut");
+
+ #define NUT_CAPS (gst_static_caps_get(&nut_caps))
+ static void
+ nut_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ guint64 marker = (0x7A561F5F04ADULL + (((guint64) ('N' << 8) + 'M') << 48));
+ const guint8 *data;
+ guint64 length;
+ gsize i;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 4096)
+ length = 4096;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 8)
+ return;
+
+ for (i = 0; i < length - 8; i++) {
+ if (GST_READ_UINT64_BE (&data[i]) == marker) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, NUT_CAPS);
+ return;
+ }
+ }
+ }
+
+ /*** application/x-pxstr ***/
+
+ static GstStaticCaps pxstr_caps = GST_STATIC_CAPS ("application/x-pxstr");
+
+ #define PXSTR_CAPS (gst_static_caps_get(&pxstr_caps))
+ static void
+ pxstr_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ static const guint8 sync_header[] =
+ { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00
+ };
+ static const gsize raw_cd_sector_size = 2352;
+ const guint8 *data;
+ guint64 length;
+ int n_vid = 0, n_aud = 0;
+ gsize i;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > raw_cd_sector_size * 5)
+ length = raw_cd_sector_size * 5;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 12)
+ return;
+
+ if (GST_READ_UINT32_LE (data) == GST_MAKE_FOURCC ('R', 'I', 'F', 'F')
+ && GST_READ_UINT32_LE (&data[8]) == GST_MAKE_FOURCC ('C', 'D', 'X', 'A')) {
+ length -= 0x2C;
+ data = &data[0x2C];
+ }
+
+ // minimum CD sector size
+ if (length < raw_cd_sector_size)
+ return;
+
+ for (i = 0; i < length;) {
+ if (length - i > 0x25)
+ break;
+
+ if (memcmp (&data[i], sync_header, sizeof (sync_header)) != 0)
+ return;
+
+ if (data[i + 0x11] >= 32)
+ return;
+
+ switch (data[i + 0x12] & 0x0E) {
+ /* data and video */
+ case 0x08:
+ case 0x02:{
+ gint16 current_sector = (gint16) GST_READ_UINT16_LE (&data[i + 0x1C]);
+ gint16 sector_count = (gint16) GST_READ_UINT16_LE (&data[i + 0x1E]);
+ gint16 frame_size = (gint16) GST_READ_UINT16_LE (&data[i + 0x24]);
+
+ if (!(frame_size > 0
+ && current_sector < sector_count
+ && sector_count * 0x780 >= frame_size))
+ return;
+
+ n_vid++;
+ break;
+ }
+ /* audio */
+ case 0x04:{
+ if (data[i + 0x13] & 0x2A)
+ return;
+ n_aud++;
+ break;
+ }
+ default:
+ if (data[i + 0x12] & 0x0E)
+ return;
+ break;
+ }
+ i += raw_cd_sector_size;
+ }
+
+ if (n_aud + n_vid > 3)
+ gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, PXSTR_CAPS);
+ else if (n_aud + n_vid)
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MINIMUM, PXSTR_CAPS);
+ }
+
+ /*** application/x-smk ***/
+
+ static GstStaticCaps smk_caps = GST_STATIC_CAPS ("application/x-smk");
+
+ #define SMK_CAPS (gst_static_caps_get(&smk_caps))
+ static void
+ smk_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 12)
+ length = 12;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 12)
+ return;
+
+ if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('S', 'M', 'K', '2')
+ && GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('S', 'M', 'K', '4')) {
+ return;
+ }
+
+ if (GST_READ_UINT32_LE (&data[4]) > 32768
+ || GST_READ_UINT32_LE (&data[8]) > 32768) {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MINIMUM, SMK_CAPS);
+ } else {
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SMK_CAPS);
+ }
+ }
+
+ /*** application/x-sol ***/
+
+ static GstStaticCaps sol_caps = GST_STATIC_CAPS ("application/x-sol");
+
+ #define SOL_CAPS (gst_static_caps_get(&sol_caps))
+ static void
+ sol_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+ guint16 magic;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 8)
+ length = 8;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 8)
+ return;
+
+ magic = (guint16) GST_READ_UINT32_LE (data);
+ if (magic != 0x0b8d && magic != 0x0c0d && magic != 0x0c8d)
+ return;
+
+ if (GST_READ_UINT32_BE (&data[4]) != GST_MAKE_FOURCC ('S', 'O', 'L', 0))
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SOL_CAPS);
+ }
+
+ /*** application/x-vmd ***/
+
+ static GstStaticCaps vmd_caps = GST_STATIC_CAPS ("application/x-vmd");
+
+ #define VMD_CAPS (gst_static_caps_get(&vmd_caps))
+ static void
+ vmd_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+ int w, h, rate;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 806)
+ length = 806;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 806)
+ return;
+
+ if (GST_READ_UINT16_LE (data) != 0x0330 - 2)
+ return;
+
+ w = GST_READ_UINT16_LE (&data[12]);
+ h = GST_READ_UINT16_LE (&data[14]);
+ rate = GST_READ_UINT16_LE (&data[804]);
+ if ((!w || w > 2048 || !h || h > 2048)
+ && rate != 22050)
+ return;
+ gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, VMD_CAPS);
+ }
+
+ /*** application/x-wc3movie ***/
+
+ static GstStaticCaps wc3movie_caps = GST_STATIC_CAPS ("application/x-wc3movie");
+
+ #define WC3MOVIE_CAPS (gst_static_caps_get(&wc3movie_caps))
+ static void
+ wc3movie_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 12)
+ length = 12;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 12)
+ return;
+
+ if (GST_READ_UINT32_LE (data) != GST_MAKE_FOURCC ('F', 'O', 'R', 'M')
+ || GST_READ_UINT32_LE (&data[8]) != GST_MAKE_FOURCC ('M', 'O', 'V', 'E'))
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, WC3MOVIE_CAPS);
+ }
+
+ /*** application/x-wsaud ***/
+
+ static GstStaticCaps wsaud_caps = GST_STATIC_CAPS ("application/x-wsaud");
+
+ #define WSAUD_CAPS (gst_static_caps_get(&wsaud_caps))
+ static void
+ wsaud_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+ int rate;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 20)
+ length = 20;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 20)
+ return;
+
+ rate = GST_READ_UINT16_LE (data);
+ if (rate < 8000 || rate > 48000)
+ return;
+
+ if (data[10] & 0xfc)
+ return;
+
+ if (data[11] != 99 && data[11] != 1)
+ return;
+
+ if (GST_READ_UINT32_LE (&data[16]) != 0x0000DEAF)
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_POSSIBLE, WSAUD_CAPS);
+ }
+
+ /*** application/x-wsvqa ***/
+
+ static GstStaticCaps wsvqa_caps = GST_STATIC_CAPS ("application/x-wsvqa");
+
+ #define WSVQA_CAPS (gst_static_caps_get(&wsvqa_caps))
+ static void
+ wsvqa_type_find (GstTypeFind * tf, gpointer unused)
+ {
+ const guint8 *data;
+ guint64 length;
+
+ length = gst_type_find_get_length (tf);
+ if (length == 0 || length > 12)
+ length = 12;
+
+ data = gst_type_find_peek (tf, 0, length);
+ if (!data)
+ return;
+
+ if (length < 12)
+ return;
+
+ if (GST_READ_UINT32_BE (data) != GST_MAKE_FOURCC ('F', 'O', 'R', 'M')
+ || GST_READ_UINT32_BE (&data[8]) != GST_MAKE_FOURCC ('W', 'V', 'Q', 'A'))
+ return;
+
+ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, WSVQA_CAPS);
+ }
+
++#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
/*** video/vivo ***/
static GstStaticCaps vivo_caps = GST_STATIC_CAPS ("video/vivo");
pva_type_find, "pva", PVA_CAPS, NULL, NULL);
GST_TYPE_FIND_REGISTER_DEFINE (aa, "audio/audible", GST_RANK_MARGINAL,
aa_type_find, "aa,aax", AA_CAPS, NULL, NULL);
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
GST_TYPE_FIND_REGISTER_DEFINE (tap, "audio/x-tap-tap", GST_RANK_PRIMARY,
tap_type_find, "tap", TAP_CAPS, NULL, NULL);
+#endif
+ GST_TYPE_FIND_REGISTER_DEFINE (brstm, "audio/x-brstm", GST_RANK_SECONDARY,
+ brstm_type_find, "brstm", BRSTM_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (bfstm, "audio/x-bfstm", GST_RANK_SECONDARY,
+ bfstm_type_find, "bfstm,bcstm", BFSTM_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (dsf, "audio/x-dsf", GST_RANK_PRIMARY,
+ dsf_type_find, NULL, DSF_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (ea, "video/x-ea", GST_RANK_SECONDARY,
+ ea_type_find, NULL, EA_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (film_cpk, "video/x-film-cpk", GST_RANK_SECONDARY,
+ film_cpk_type_find, "cpk", FILM_CPK_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (gxf, "application/gxf", GST_RANK_SECONDARY,
+ gxf_type_find, NULL, GXF_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (iff, "application/x-iff", GST_RANK_SECONDARY,
+ iff_type_find, NULL, IFF_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (ipmovie, "application/x-ipmovie",
+ GST_RANK_SECONDARY, ipmovie_type_find, NULL, IPMOVIE_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (idcin, "video/x-idcin", GST_RANK_MARGINAL,
+ idcin_type_find, NULL, IDCIN_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (mm, "application/x-mm", GST_RANK_MARGINAL,
+ mm_type_find, NULL, MM_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (mmf, "application/vnd.smaf", GST_RANK_SECONDARY,
+ mmf_type_find, "mmf", MMF_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (nsv, "video/x-nsv", GST_RANK_MARGINAL,
+ nsv_type_find, "nsv", NSV_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (nut, "application/x-nut", GST_RANK_MARGINAL,
+ nut_type_find, "nut", NUT_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (pxstr, "application/x-pxstr", GST_RANK_MARGINAL,
+ pxstr_type_find, "pxstr", PXSTR_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (smk, "application/x-smk", GST_RANK_MARGINAL,
+ smk_type_find, "smk", SMK_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (sol, "application/x-sol", GST_RANK_MARGINAL,
+ sol_type_find, "sol", SOL_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (vmd, "application/x-vmd", GST_RANK_MARGINAL,
+ vmd_type_find, "vmd", VMD_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (wc3movie, "application/x-wc3movie",
+ GST_RANK_MARGINAL, wc3movie_type_find, "wc3movie", WC3MOVIE_CAPS, NULL,
+ NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (wsaud, "application/x-wsaud", GST_RANK_MARGINAL,
+ wsaud_type_find, "wsaud", WSAUD_CAPS, NULL, NULL);
+ GST_TYPE_FIND_REGISTER_DEFINE (wsvqa, "application/x-wsvqa", GST_RANK_MARGINAL,
+ wsvqa_type_find, "wsvqa", WSVQA_CAPS, NULL, NULL);
++
/* must use strings, macros don't accept initializers */
/*Riff Type find register */
+ GST_TYPE_FIND_REGISTER (fourxm, plugin);
GST_TYPE_FIND_REGISTER (avi, plugin);
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
GST_TYPE_FIND_REGISTER (qcp, plugin);
GST_TYPE_FIND_REGISTER (cdxa, plugin);
+#endif
GST_TYPE_FIND_REGISTER (riff_mid, plugin);
GST_TYPE_FIND_REGISTER (wav, plugin);
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
GST_TYPE_FIND_REGISTER (webp, plugin);
+#endif
+ /*'Start with' Type find register */
+ GST_TYPE_FIND_REGISTER (asf, plugin);
++
+ GST_TYPE_FIND_REGISTER (xwma, plugin);
+
+ /*'Start with' Type find register */
+ GST_TYPE_FIND_REGISTER (asf, plugin);
+ GST_TYPE_FIND_REGISTER (avs, plugin);
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
GST_TYPE_FIND_REGISTER (vcd, plugin);
+#endif
GST_TYPE_FIND_REGISTER (imelody, plugin);
GST_TYPE_FIND_REGISTER (scc, plugin);
#if 0
GST_TYPE_FIND_REGISTER (ssa, plugin);
GST_TYPE_FIND_REGISTER (pva, plugin);
GST_TYPE_FIND_REGISTER (aa, plugin);
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
GST_TYPE_FIND_REGISTER (tap, plugin);
+#endif
+ GST_TYPE_FIND_REGISTER (brstm, plugin);
+ GST_TYPE_FIND_REGISTER (bfstm, plugin);
+ GST_TYPE_FIND_REGISTER (dsf, plugin);
+ GST_TYPE_FIND_REGISTER (ea, plugin);
+ GST_TYPE_FIND_REGISTER (film_cpk, plugin);
+ GST_TYPE_FIND_REGISTER (gxf, plugin);
+ GST_TYPE_FIND_REGISTER (iff, plugin);
return TRUE;
}
GST_RANK_PRIMARY, "mid,midi", "RMID");
TYPE_FIND_REGISTER_RIFF_DEFINE (wav, "audio/x-wav", GST_RANK_PRIMARY, "wav",
"WAVE");
+#ifndef TIZEN_FEATURE_DISABLE_MIME_TYPES
TYPE_FIND_REGISTER_RIFF_DEFINE (webp, "image/webp", GST_RANK_PRIMARY,
"webp", "WEBP");
+#endif
+ TYPE_FIND_REGISTER_RIFF_DEFINE (fourxm, "video/x-4xm", GST_RANK_PRIMARY,
+ NULL, "4XMV");
+ TYPE_FIND_REGISTER_RIFF_DEFINE (xwma, "audio/x-xwma", GST_RANK_PRIMARY,
+ NULL, "XWMA");
GstVideoConverter *convert;
+ GstStructure *converter_config;
+ gboolean converter_config_changed;
+
gint borders_h;
gint borders_w;
+#ifdef USE_TBM
+ GstBufferPool *pool;
+#endif
} GstVideoConvertScalePrivate;
#define gst_video_convert_scale_parent_class parent_class
if (priv->convert)
gst_video_converter_free (priv->convert);
+#ifdef USE_TBM
+ if (priv->pool) {
+ gst_buffer_pool_set_active (priv->pool, FALSE);
+ gst_object_unref (priv->pool);
+ priv->pool = NULL;
+ }
+#endif
+ if (priv->converter_config)
+ gst_structure_free (priv->converter_config);
+ priv->converter_config = NULL;
+
G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (self));
}
gst_adaptive_demux_get_manifest_ref_uri (demux), NULL);
}
+ if (start_bitrate == 0)
+ start_bitrate = demux->connection_speed;
+
/* select the initial variant stream */
- if (demux->connection_speed == 0) {
- variant = hlsdemux->master->default_variant;
- } else if (hlsdemux->start_bitrate > 0) {
- variant =
+ if (start_bitrate > 0) {
+#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT
- gst_hls_master_playlist_get_variant_for_bitrate_and_resolution (
- hlsdemux->master, NULL, hlsdemux->start_bitrate, demux->min_bitrate,
- demux->max_width, demux->max_height);
- #else
- gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
- NULL, hlsdemux->start_bitrate, demux->min_bitrate);
- #endif
- } else {
+ variant =
- #ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT
- gst_hls_master_playlist_get_variant_for_bitrate_and_resolution (
- hlsdemux->master, NULL, demux->connection_speed, demux->min_bitrate,
- demux->max_width, demux->max_height);
++ gst_hls_master_playlist_get_variant_for_bitrate_and_resolution (hlsdemux->master,
++ FALSE, start_bitrate, demux->min_bitrate,
++ demux->max_width, demux->max_height, hlsdemux->failed_variants);
+#else
+ variant =
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
- NULL, demux->connection_speed, demux->min_bitrate);
+ FALSE, start_bitrate, demux->min_bitrate, hlsdemux->failed_variants);
+#endif
+ } else {
+ variant = hlsdemux->master->default_variant;
}
- if (variant) {
- GST_INFO_OBJECT (hlsdemux,
- "Manifest processed, initial variant selected : `%s`", variant->name);
- gst_hls_demux_set_current_variant (hlsdemux, variant); // FIXME: inline?
+ if (variant == NULL) {
+ GST_ELEMENT_ERROR (demux, STREAM, FAILED,
+ (_("Internal data stream error.")),
+ ("Could not find an initial variant to play"));
}
+ GST_INFO_OBJECT (hlsdemux,
+ "Manifest processed, initial variant selected : `%s`", variant->name);
+ gst_hls_demux_set_current_variant (hlsdemux, variant);
+
GST_DEBUG_OBJECT (hlsdemux, "Manifest handled, now setting up streams");
ret = gst_hls_demux_setup_streams (demux);
}
}
- g_list_free_full (hlsdemux->mappings, (GDestroyNotify) gst_hls_time_map_free);
- hlsdemux->mappings = active;
- }
-
- /* Go over the DSN from the playlist and add any missing time mapping */
- static void
- gst_hls_update_time_mappings (GstHLSDemux * demux,
- GstHLSMediaPlaylist * playlist)
- {
- guint idx, len = playlist->segments->len;
- gint64 dsn = G_MAXINT64;
-
- for (idx = 0; idx < len; idx++) {
- GstM3U8MediaSegment *segment = g_ptr_array_index (playlist->segments, idx);
-
- if (dsn == G_MAXINT64 || segment->discont_sequence != dsn) {
- dsn = segment->discont_sequence;
- if (!gst_hls_find_time_map (demux, segment->discont_sequence))
- gst_hls_demux_add_time_mapping (demux, segment->discont_sequence,
- segment->stream_time, segment->datetime);
- }
- }
- }
-
- static void
- setup_initial_playlist (GstHLSDemux * demux, GstHLSMediaPlaylist * playlist)
- {
- guint idx, len = playlist->segments->len;
- GstM3U8MediaSegment *segment;
- GstClockTimeDiff pos = 0;
-
- GST_DEBUG_OBJECT (demux,
- "Setting up initial variant segment and time mapping");
-
- /* This is the initial variant playlist. We will use it to base all our timing
- * from. */
-
- for (idx = 0; idx < len; idx++) {
- segment = g_ptr_array_index (playlist->segments, idx);
-
- segment->stream_time = pos;
- pos += segment->duration;
- }
- }
-
- /* Reset hlsdemux in case of live synchronization loss (i.e. when a media
- * playlist update doesn't match at all with the previous one) */
- static void
- gst_hls_demux_reset_for_lost_sync (GstHLSDemux * hlsdemux)
- {
- GstAdaptiveDemux *demux = (GstAdaptiveDemux *) hlsdemux;
- GList *iter;
-
- GST_DEBUG_OBJECT (hlsdemux, "Resetting for lost sync");
-
- for (iter = demux->input_period->streams; iter; iter = iter->next) {
- GstHLSDemuxStream *hls_stream = iter->data;
- GstAdaptiveDemux2Stream *stream = (GstAdaptiveDemux2Stream *) hls_stream;
-
- if (hls_stream->current_segment)
- gst_m3u8_media_segment_unref (hls_stream->current_segment);
- hls_stream->current_segment = NULL;
-
- if (hls_stream->is_variant) {
- GstHLSTimeMap *map;
- /* Resynchronize the variant stream */
- g_assert (stream->current_position != GST_CLOCK_STIME_NONE);
- hls_stream->current_segment =
- gst_hls_media_playlist_get_starting_segment (hls_stream->playlist);
- hls_stream->current_segment->stream_time = stream->current_position;
- gst_hls_media_playlist_recalculate_stream_time (hls_stream->playlist,
- hls_stream->current_segment);
- GST_DEBUG_OBJECT (stream,
- "Resynced variant playlist to %" GST_STIME_FORMAT,
- GST_STIME_ARGS (stream->current_position));
- map =
- gst_hls_find_time_map (hlsdemux,
- hls_stream->current_segment->discont_sequence);
- if (map)
- map->internal_time = GST_CLOCK_TIME_NONE;
- gst_hls_update_time_mappings (hlsdemux, hls_stream->playlist);
- gst_hls_media_playlist_dump (hls_stream->playlist);
- } else {
- /* Force playlist update for the rendition streams, it will resync to the
- * variant stream on the next round */
- if (hls_stream->playlist)
- gst_hls_media_playlist_unref (hls_stream->playlist);
- hls_stream->playlist = NULL;
- hls_stream->playlist_fetched = FALSE;
- }
- }
- }
-
- static GstFlowReturn
- gst_hls_demux_stream_update_media_playlist (GstHLSDemux * demux,
- GstHLSDemuxStream * stream, gchar ** uri, GError ** err)
- {
- GstHLSMediaPlaylist *new_playlist;
-
- GST_DEBUG_OBJECT (stream, "Updating %s", *uri);
-
- new_playlist = download_media_playlist (demux, *uri, err, stream->playlist);
- if (new_playlist == NULL) {
- GST_WARNING_OBJECT (stream, "Could not get playlist '%s'", *uri);
- return GST_FLOW_ERROR;
- }
-
- /* Check if a redirect happened */
- if (g_strcmp0 (*uri, new_playlist->uri)) {
- GST_DEBUG_OBJECT (stream, "Playlist URI update : '%s' => '%s'", *uri,
- new_playlist->uri);
- g_free (*uri);
- *uri = g_strdup (new_playlist->uri);
- }
-
- /* Synchronize playlist with previous one. If we can't update the playlist
- * timing and inform the base class that we lost sync */
- if (stream->playlist
- && !gst_hls_media_playlist_sync_to_playlist (new_playlist,
- stream->playlist)) {
- /* Failure to synchronize with the previous media playlist is only fatal for
- * variant streams. */
- if (stream->is_variant) {
- GST_DEBUG_OBJECT (stream,
- "Could not synchronize new variant playlist with previous one !");
- goto lost_sync;
- }
-
- /* For rendition streams, we can attempt synchronization against the
- * variant playlist which is constantly updated */
- if (demux->main_stream->playlist
- && !gst_hls_media_playlist_sync_to_playlist (new_playlist,
- demux->main_stream->playlist)) {
- GST_DEBUG_OBJECT (stream,
- "Could not do fallback synchronization of rendition stream to variant stream");
- goto lost_sync;
- }
- } else if (!stream->is_variant && demux->main_stream->playlist) {
- /* For initial rendition media playlist, attempt to synchronize the playlist
- * against the variant stream. This is non-fatal if it fails. */
- GST_DEBUG_OBJECT (stream,
- "Attempting to synchronize initial rendition stream with variant stream");
- gst_hls_media_playlist_sync_to_playlist (new_playlist,
- demux->main_stream->playlist);
- }
-
- if (stream->current_segment) {
- GstM3U8MediaSegment *new_segment;
- GST_DEBUG_OBJECT (stream,
- "Current segment sn:%" G_GINT64_FORMAT " stream_time:%" GST_STIME_FORMAT
- " uri:%s", stream->current_segment->sequence,
- GST_STIME_ARGS (stream->current_segment->stream_time),
- stream->current_segment->uri);
-
- /* Use best-effort techniques to find the correponding current media segment
- * in the new playlist. This might be off in some cases, but it doesn't matter
- * since we will be checking the embedded timestamp later */
- new_segment =
- gst_hls_media_playlist_sync_to_segment (new_playlist,
- stream->current_segment);
- if (new_segment) {
- if (new_segment->discont_sequence !=
- stream->current_segment->discont_sequence)
- gst_hls_demux_add_time_mapping (demux, new_segment->discont_sequence,
- new_segment->stream_time, new_segment->datetime);
- /* This can happen in case of misaligned variants/renditions. Only warn about it */
- if (new_segment->stream_time != stream->current_segment->stream_time)
- GST_WARNING_OBJECT (stream,
- "Returned segment stream time %" GST_STIME_FORMAT
- " differs from current stream time %" GST_STIME_FORMAT,
- GST_STIME_ARGS (new_segment->stream_time),
- GST_STIME_ARGS (stream->current_segment->stream_time));
- } else {
- /* Not finding a matching segment only happens in live (otherwise we would
- * have found a match by stream time) when we are at the live edge. This is normal*/
- GST_DEBUG_OBJECT (stream, "Could not find a matching segment");
- }
- gst_m3u8_media_segment_unref (stream->current_segment);
- stream->current_segment = new_segment;
- } else {
- GST_DEBUG_OBJECT (stream, "No current segment");
- }
-
- if (stream->playlist) {
- gst_hls_media_playlist_unref (stream->playlist);
- stream->playlist = new_playlist;
- } else {
- if (stream->is_variant) {
- GST_DEBUG_OBJECT (stream, "Setting up initial playlist");
- setup_initial_playlist (demux, new_playlist);
- }
- stream->playlist = new_playlist;
- }
-
- if (stream->is_variant) {
- /* Update time mappings. We only use the variant stream for collecting
- * mappings since it is the reference on which rendition stream timing will
- * be based. */
- gst_hls_update_time_mappings (demux, stream->playlist);
- }
- gst_hls_media_playlist_dump (stream->playlist);
-
- if (stream->current_segment) {
- GST_DEBUG_OBJECT (stream,
- "After update, current segment now sn:%" G_GINT64_FORMAT
- " stream_time:%" GST_STIME_FORMAT " uri:%s",
- stream->current_segment->sequence,
- GST_STIME_ARGS (stream->current_segment->stream_time),
- stream->current_segment->uri);
- } else {
- GST_DEBUG_OBJECT (stream, "No current segment selected");
- }
-
- GST_DEBUG_OBJECT (stream, "done");
-
- return GST_FLOW_OK;
-
- /* ERRORS */
- lost_sync:
- {
- /* Set new playlist, lost sync handler will know what to do with it */
- if (stream->playlist)
- gst_hls_media_playlist_unref (stream->playlist);
- stream->playlist = new_playlist;
-
- gst_hls_demux_reset_for_lost_sync (demux);
-
- return GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC;
- }
- }
-
- static GstFlowReturn
- gst_hls_demux_stream_update_rendition_playlist (GstHLSDemux * demux,
- GstHLSDemuxStream * stream)
- {
- GstFlowReturn ret = GST_FLOW_OK;
- GstHLSRenditionStream *target_rendition =
- stream->pending_rendition ? stream->
- pending_rendition : stream->current_rendition;
-
- ret = gst_hls_demux_stream_update_media_playlist (demux, stream,
- &target_rendition->uri, NULL);
- if (ret != GST_FLOW_OK)
- return ret;
-
- if (stream->pending_rendition) {
- gst_hls_rendition_stream_unref (stream->current_rendition);
- /* Stealing ref */
- stream->current_rendition = stream->pending_rendition;
- stream->pending_rendition = NULL;
- }
-
- stream->playlist_fetched = TRUE;
-
- return ret;
- }
-
- static GstFlowReturn
- gst_hls_demux_stream_update_variant_playlist (GstHLSDemux * demux,
- GstHLSDemuxStream * stream, GError ** err)
- {
- GstFlowReturn ret = GST_FLOW_OK;
- GstHLSVariantStream *target_variant =
- demux->pending_variant ? demux->pending_variant : demux->current_variant;
-
- ret = gst_hls_demux_stream_update_media_playlist (demux, stream,
- &target_variant->uri, err);
- if (ret != GST_FLOW_OK)
- return ret;
-
- if (demux->pending_variant) {
- gst_hls_variant_stream_unref (demux->current_variant);
- /* Stealing ref */
- demux->current_variant = demux->pending_variant;
- demux->pending_variant = NULL;
- }
-
- stream->playlist_fetched = TRUE;
-
- return ret;
+ g_list_free_full (hlsdemux->mappings, (GDestroyNotify) gst_hls_time_map_free);
+ hlsdemux->mappings = active;
}
- static GstFlowReturn
- gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream)
+ /* Go over the DSN from the playlist and add any missing time mapping */
+ void
+ gst_hls_update_time_mappings (GstHLSDemux * demux,
+ GstHLSMediaPlaylist * playlist)
{
- GstFlowReturn ret = GST_FLOW_OK;
- GstHLSDemuxStream *hlsdemux_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
- GstAdaptiveDemux *demux = stream->demux;
- GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
- GstM3U8MediaSegment *file;
- gboolean discont;
-
- /* If the rendition playlist needs to be updated, do it now */
- if (!hlsdemux_stream->is_variant && !hlsdemux_stream->playlist_fetched) {
- ret = gst_hls_demux_stream_update_rendition_playlist (hlsdemux,
- hlsdemux_stream);
- if (ret != GST_FLOW_OK)
- return ret;
- }
+ guint idx, len = playlist->segments->len;
+ gint64 dsn = G_MAXINT64;
- GST_DEBUG_OBJECT (stream,
- "Updating fragment information, current_position:%" GST_TIME_FORMAT,
- GST_TIME_ARGS (stream->current_position));
-
- /* Find the current segment if we don't already have it */
- if (hlsdemux_stream->current_segment == NULL) {
- GST_LOG_OBJECT (stream, "No current segment");
- if (stream->current_position == GST_CLOCK_TIME_NONE) {
- GST_DEBUG_OBJECT (stream, "Setting up initial segment");
- hlsdemux_stream->current_segment =
- gst_hls_media_playlist_get_starting_segment
- (hlsdemux_stream->playlist);
- } else {
- if (gst_hls_media_playlist_has_lost_sync (hlsdemux_stream->playlist,
- stream->current_position)) {
- GST_WARNING_OBJECT (stream, "Lost SYNC !");
- return GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC;
- }
- GST_DEBUG_OBJECT (stream,
- "Looking up segment for position %" GST_TIME_FORMAT,
- GST_TIME_ARGS (stream->current_position));
- hlsdemux_stream->current_segment =
- gst_hls_media_playlist_seek (hlsdemux_stream->playlist, TRUE,
- GST_SEEK_FLAG_SNAP_NEAREST, stream->current_position);
-
- if (hlsdemux_stream->current_segment == NULL) {
- GST_INFO_OBJECT (stream, "At the end of the current media playlist");
- return GST_FLOW_EOS;
- }
+ for (idx = 0; idx < len; idx++) {
+ GstM3U8MediaSegment *segment = g_ptr_array_index (playlist->segments, idx);
- /* Update time mapping. If it already exists it will be ignored */
- gst_hls_demux_add_time_mapping (hlsdemux,
- hlsdemux_stream->current_segment->discont_sequence,
- hlsdemux_stream->current_segment->stream_time,
- hlsdemux_stream->current_segment->datetime);
+ if (dsn == G_MAXINT64 || segment->discont_sequence != dsn) {
+ dsn = segment->discont_sequence;
+ if (!gst_hls_demux_find_time_map (demux, segment->discont_sequence))
+ gst_hls_demux_add_time_mapping (demux, segment->discont_sequence,
+ segment->stream_time, segment->datetime);
}
}
+ }
- file = hlsdemux_stream->current_segment;
-
- GST_DEBUG_OBJECT (stream, "Current segment stream_time %" GST_STIME_FORMAT,
- GST_STIME_ARGS (file->stream_time));
+ /* Called by the base class with the manifest lock held */
+ static GstFlowReturn
+ gst_hls_demux_update_manifest (GstAdaptiveDemux * demux)
+ {
+ GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
- discont = file->discont || stream->discont;
+ /* Take a copy of the main variant playlist for base class
+ * calls that need access from outside the scheduler task,
+ * holding the MANIFEST_LOCK */
+ if (hlsdemux->main_stream && hlsdemux->main_stream->playlist) {
+ if (hlsdemux->main_playlist)
+ gst_hls_media_playlist_unref (hlsdemux->main_playlist);
+ hlsdemux->main_playlist =
+ gst_hls_media_playlist_ref (hlsdemux->main_stream->playlist);
+
- gboolean need_header = GST_ADAPTIVE_DEMUX2_STREAM_NEED_HEADER (stream);
++#ifdef TIZEN_FEATURE_POST_VARIANT_INFO
++ GST_DEBUG_OBJECT (hlsdemux, "post variant info message");
++ gst_element_post_message (GST_ELEMENT_CAST (hlsdemux),
++ gst_message_new_element (GST_OBJECT_CAST (hlsdemux),
++ gst_structure_new (GST_ADAPTIVE_DEMUX_VARIANT_MESSAGE_NAME,
++ "video-variant-info", G_TYPE_POINTER,
++ hlsdemux->master->variant_info, NULL)));
++#endif
+
- /* Check if the MAP header file changed and update it */
- if (file->init_file != NULL
- && !gst_m3u8_init_file_equal (hlsdemux_stream->init_file,
- file->init_file)) {
- GST_DEBUG_OBJECT (stream, "MAP header info changed. Updating");
- if (hlsdemux_stream->init_file != NULL)
- gst_m3u8_init_file_unref (hlsdemux_stream->init_file);
- hlsdemux_stream->init_file = gst_m3u8_init_file_ref (file->init_file);
- need_header = TRUE;
+ return GST_FLOW_OK;
}
- if (file->init_file && need_header) {
- GstM3U8InitFile *header_file = file->init_file;
- g_free (stream->fragment.header_uri);
- stream->fragment.header_uri = g_strdup (header_file->uri);
- stream->fragment.header_range_start = header_file->offset;
- if (header_file->size != -1) {
- stream->fragment.header_range_end =
- header_file->offset + header_file->size - 1;
- } else {
- stream->fragment.header_range_end = -1;
- }
+ return GST_ADAPTIVE_DEMUX_FLOW_BUSY;
+ }
- stream->need_header = TRUE;
- }
+ void
+ gst_hls_demux_handle_variant_playlist_update (GstHLSDemux * demux,
+ const gchar * playlist_uri, GstHLSMediaPlaylist * playlist)
+ {
+ if (demux->main_stream == NULL || !demux->main_stream->playlist_fetched) {
+ GstM3U8MediaSegment *segment;
- /* set up our source for download */
- if (hlsdemux_stream->reset_pts || discont || demux->segment.rate < 0.0) {
- stream->fragment.stream_time = file->stream_time;
- } else {
- stream->fragment.stream_time = GST_CLOCK_STIME_NONE;
+ GST_DEBUG_OBJECT (demux,
+ "Setting up initial variant segment and time mapping");
+
+ /* This is the initial variant playlist. We will use it to base all our timing
+ * from. */
+ segment = g_ptr_array_index (playlist->segments, 0);
+ if (segment) {
+ segment->stream_time = 0;
+ gst_hls_media_playlist_recalculate_stream_time (playlist, segment);
+ }
}
- g_free (hlsdemux_stream->current_key);
- hlsdemux_stream->current_key = g_strdup (file->key);
- g_free (hlsdemux_stream->current_iv);
- hlsdemux_stream->current_iv = g_memdup2 (file->iv, sizeof (file->iv));
-
- g_free (stream->fragment.uri);
- stream->fragment.uri = g_strdup (file->uri);
-
- GST_DEBUG_OBJECT (stream, "Stream URI now %s", file->uri);
+ if (demux->pending_variant) {
+ /* The pending variant must always match the one that just got updated:
+ * The loader should only do a callback for the most recently set URI */
+ g_assert (!g_strcmp0 (demux->pending_variant->uri, playlist_uri));
- stream->fragment.range_start = file->offset;
- if (file->size != -1)
- stream->fragment.range_end = file->offset + file->size - 1;
- else
- stream->fragment.range_end = -1;
+ gboolean changed = (demux->pending_variant != demux->current_variant);
- stream->fragment.duration = file->duration;
+ gst_hls_variant_stream_unref (demux->current_variant);
+ /* Stealing ref */
+ demux->current_variant = demux->pending_variant;
+ demux->pending_variant = NULL;
- stream->recommended_buffering_threshold =
- gst_hls_media_playlist_recommended_buffering_threshold
- (hlsdemux_stream->playlist);
+ if (changed) {
+ GstAdaptiveDemux *basedemux = GST_ADAPTIVE_DEMUX (demux);
+ const gchar *main_uri =
+ gst_adaptive_demux_get_manifest_ref_uri (basedemux);
+ gchar *uri = demux->current_variant->uri;
+ gint new_bandwidth = demux->current_variant->bandwidth;
+
+ gst_element_post_message (GST_ELEMENT_CAST (demux),
+ gst_message_new_element (GST_OBJECT_CAST (demux),
+ gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
+ "manifest-uri", G_TYPE_STRING,
+ main_uri, "uri", G_TYPE_STRING,
+ uri, "bitrate", G_TYPE_INT, new_bandwidth, NULL)));
+
+ GST_DEBUG_OBJECT (demux, "Changed variant");
+ }
+ }
- if (discont)
- stream->discont = TRUE;
+ /* Update time mappings. We only use the variant stream for collecting
+ * mappings since it is the reference on which rendition stream timing will
+ * be based. */
+ gst_hls_update_time_mappings (demux, playlist);
+ gst_hls_media_playlist_dump (playlist);
- return ret;
+ /* Get the base class to call the update_manifest() vfunc with the MANIFEST_LOCK()
+ * held */
+ gst_adaptive_demux2_manual_manifest_update (GST_ADAPTIVE_DEMUX (demux));
}
- static gboolean
- gst_hls_demux_stream_can_start (GstAdaptiveDemux2Stream * stream)
+ void
+ gst_hls_demux_handle_variant_playlist_update_error (GstHLSDemux * demux,
+ const gchar * playlist_uri)
{
- GstHLSDemux *hlsdemux = (GstHLSDemux *) stream->demux;
- GstHLSDemuxStream *hls_stream = (GstHLSDemuxStream *) stream;
- GList *tmp;
+ GST_DEBUG_OBJECT (demux, "Playlist update failure for variant URI %s",
+ playlist_uri);
- GST_DEBUG_OBJECT (stream, "is_variant:%d mappings:%p", hls_stream->is_variant,
- hlsdemux->mappings);
+ /* Check if this is a new load of the pending variant, or a reload
+ * of the current variant */
+ GstHLSVariantStream *variant = demux->pending_variant;
+ if (variant == NULL)
+ variant = demux->current_variant;
- /* Variant streams can always start straight away */
- if (hls_stream->is_variant)
- return TRUE;
+ /* If the variant has an fallback URIs available, we can try one of those */
+ if (variant->fallback != NULL) {
+ gchar *fallback_uri = (gchar *) (variant->fallback->data);
- /* Renditions of the exact same type as the variant are pure alternatives,
- * they must be started. This can happen for example with audio-only manifests
- * where the initial stream selected is a rendition and not a variant */
- if (hls_stream->rendition_type == hlsdemux->main_stream->rendition_type)
- return TRUE;
+ GST_DEBUG_OBJECT (demux,
+ "Variant playlist update failed. Switching to fallback URI %s",
+ fallback_uri);
- /* Rendition streams only require delaying if we don't have time mappings yet */
- if (!hlsdemux->mappings)
- return FALSE;
+ variant->fallback = g_list_remove (variant->fallback, fallback_uri);
+ g_free (variant->uri);
+ variant->uri = fallback_uri;
- /* We can start if we have at least one internal time observation */
- for (tmp = hlsdemux->mappings; tmp; tmp = tmp->next) {
- GstHLSTimeMap *map = tmp->data;
- if (map->internal_time != GST_CLOCK_TIME_NONE)
- return TRUE;
+ if (demux->main_stream) {
+ /* The variant stream exists, update the playlist we're loading */
+ gst_hls_demux_stream_set_playlist_uri (demux->main_stream, variant->uri);
+ }
+ return;
}
- /* Otherwise we have to wait */
- return FALSE;
- }
-
- /* Returns TRUE if the rendition stream switched group-id */
- static gboolean
- gst_hls_demux_update_rendition_stream (GstHLSDemux * hlsdemux,
- GstHLSDemuxStream * hls_stream, GError ** err)
- {
- gchar *current_group_id, *requested_group_id;
- GstHLSRenditionStream *replacement_media = NULL;
- GList *tmp;
-
- /* There always should be a current variant set */
- g_assert (hlsdemux->current_variant);
- /* There always is a GstHLSRenditionStream set for rendition streams */
- g_assert (hls_stream->current_rendition);
-
- requested_group_id =
- hlsdemux->current_variant->media_groups[hls_stream->
- current_rendition->mtype];
- current_group_id = hls_stream->current_rendition->group_id;
+ GST_DEBUG_OBJECT (demux, "Variant playlist update failed. "
+ "Marking variant URL %s as failed and switching over to another variant",
+ playlist_uri);
- GST_DEBUG_OBJECT (hlsdemux,
- "Checking playlist change for variant stream %s lang: %s current group-id: %s / requested group-id: %s",
- gst_stream_type_get_name (hls_stream->rendition_type), hls_stream->lang,
- current_group_id, requested_group_id);
+ /* The variant must always match the one that just got updated:
+ * The loader should only do a callback for the most recently set URI */
+ g_assert (!g_strcmp0 (variant->uri, playlist_uri));
-
- if (!g_strcmp0 (requested_group_id, current_group_id)) {
- GST_DEBUG_OBJECT (hlsdemux, "No change needed");
- return FALSE;
+ /* If we didn't already add this playlist to the failed variants list
+ * do so now. It's possible we get an update error again if we failed
+ * to choose a new variant and posted error but didn't get shut down
+ * yet */
+ if (g_list_find (demux->failed_variants, variant) == NULL) {
+ demux->failed_variants =
+ g_list_prepend (demux->failed_variants,
+ gst_hls_variant_stream_ref (variant));
}
- GST_DEBUG_OBJECT (hlsdemux,
- "group-id changed, looking for replacement playlist");
-
- /* Need to switch/update */
- for (tmp = hlsdemux->master->renditions; tmp; tmp = tmp->next) {
- GstHLSRenditionStream *cand = tmp->data;
+ /* Now try to find another variant to play */
+ gdouble play_rate = gst_adaptive_demux_play_rate (GST_ADAPTIVE_DEMUX (demux));
+ guint64 bitrate = gst_hls_demux_get_bitrate (demux);
- if (cand->mtype == hls_stream->current_rendition->mtype
- && !g_strcmp0 (cand->lang, hls_stream->lang)
- && !g_strcmp0 (cand->group_id, requested_group_id)) {
- replacement_media = cand;
- break;
- }
- }
- if (!replacement_media) {
- GST_ERROR_OBJECT (hlsdemux,
- "Could not find a replacement playlist. Staying with previous one");
- return FALSE;
- }
+ GST_DEBUG_OBJECT (demux, "Trying to find failover variant playlist");
- GST_DEBUG_OBJECT (hlsdemux, "Use replacement playlist %s",
- replacement_media->name);
- hls_stream->playlist_fetched = FALSE;
- if (hls_stream->pending_rendition) {
- GST_ERROR_OBJECT (hlsdemux,
- "Already had a pending rendition switch to '%s'",
- hls_stream->pending_rendition->name);
- gst_hls_rendition_stream_unref (hls_stream->pending_rendition);
+ if (!gst_hls_demux_change_variant_playlist (demux,
+ variant->iframe, bitrate / MAX (1.0, ABS (play_rate)), NULL)) {
+ GST_ERROR_OBJECT (demux, "Failed to choose a new variant to play");
+ GST_ELEMENT_ERROR (demux, STREAM, FAILED,
+ (_("Internal data stream error.")),
+ ("Could not update any variant playlist"));
}
- hls_stream->pending_rendition =
- gst_hls_rendition_stream_ref (replacement_media);
- return TRUE;
}
- static gboolean
- gst_hls_demux_stream_select_bitrate (GstAdaptiveDemux2Stream * stream,
- guint64 bitrate)
+ /* Reset hlsdemux in case of live synchronization loss (i.e. when a media
+ * playlist update doesn't match at all with the previous one) */
+ void
+ gst_hls_demux_reset_for_lost_sync (GstHLSDemux * hlsdemux)
{
- GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (stream->demux);
- GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (stream->demux);
- GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
+ GstAdaptiveDemux *demux = (GstAdaptiveDemux *) hlsdemux;
+ GList *iter;
- /* Fast-Path, no changes possible */
- if (hlsdemux->master == NULL || hlsdemux->master->is_simple)
- return FALSE;
+ GST_DEBUG_OBJECT (hlsdemux, "Resetting for lost sync");
- if (hls_stream->is_variant) {
- gdouble play_rate = gst_adaptive_demux_play_rate (demux);
- gboolean changed = FALSE;
+ for (iter = demux->input_period->streams; iter; iter = iter->next) {
+ GstHLSDemuxStream *hls_stream = iter->data;
+ GstAdaptiveDemux2Stream *stream = (GstAdaptiveDemux2Stream *) hls_stream;
- /* Handle variant streams */
- GST_DEBUG_OBJECT (hlsdemux,
- "Checking playlist change for main variant stream");
- gst_hls_demux_change_playlist (hlsdemux, bitrate / MAX (1.0,
- ABS (play_rate)), &changed);
+ if (hls_stream->current_segment)
+ gst_m3u8_media_segment_unref (hls_stream->current_segment);
+ hls_stream->current_segment = NULL;
- GST_DEBUG_OBJECT (hlsdemux, "Returning changed: %d", changed);
- return changed;
- }
+ if (hls_stream->is_variant) {
+ GstHLSTimeMap *map;
+ GstM3U8SeekResult seek_result;
- /* Handle rendition streams */
- return gst_hls_demux_update_rendition_stream (hlsdemux, hls_stream, NULL);
+ /* Resynchronize the variant stream */
+ g_assert (stream->current_position != GST_CLOCK_STIME_NONE);
+ if (gst_hls_media_playlist_get_starting_segment (hls_stream->playlist,
+ &seek_result)) {
+ hls_stream->current_segment = seek_result.segment;
+ hls_stream->in_partial_segments = seek_result.found_partial_segment;
+ hls_stream->part_idx = seek_result.part_idx;
+
+ hls_stream->current_segment->stream_time = stream->current_position;
+ gst_hls_media_playlist_recalculate_stream_time (hls_stream->playlist,
+ hls_stream->current_segment);
+ GST_DEBUG_OBJECT (stream,
+ "Resynced variant playlist to %" GST_STIME_FORMAT,
+ GST_STIME_ARGS (stream->current_position));
+ map =
+ gst_hls_demux_find_time_map (hlsdemux,
+ hls_stream->current_segment->discont_sequence);
+ if (map)
+ map->internal_time = GST_CLOCK_TIME_NONE;
+ gst_hls_update_time_mappings (hlsdemux, hls_stream->playlist);
+ gst_hls_media_playlist_dump (hls_stream->playlist);
+ } else {
+ GST_ERROR_OBJECT (stream, "Failed to locate a segment to restart at!");
+ }
+ } else {
+ /* Force playlist update for the rendition streams, it will resync to the
+ * variant stream on the next round */
+ if (hls_stream->playlist)
+ gst_hls_media_playlist_unref (hls_stream->playlist);
+ hls_stream->playlist = NULL;
+ hls_stream->playlist_fetched = FALSE;
+ }
+ }
}
static void
gst_hls_demux_clear_all_pending_data (demux);
}
- /*
- * update: TRUE only when requested from parent class (via
- * ::demux_update_manifest() or ::change_playlist() ).
- */
static GstFlowReturn
- gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
- GError ** err)
+ gst_hls_demux_check_variant_playlist_loaded (GstHLSDemux * demux)
{
- GstFlowReturn ret = GST_FLOW_OK;
- GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX (demux);
-
- GST_DEBUG_OBJECT (demux, "update:%d", update);
-
- /* Download and update the appropriate variant playlist (pending if any, else
- * current) */
- ret = gst_hls_demux_stream_update_variant_playlist (demux, demux->main_stream,
- err);
- if (ret != GST_FLOW_OK)
- return ret;
-
- if (update && gst_hls_demux_is_live (adaptive_demux)) {
- GList *tmp;
- GST_DEBUG_OBJECT (demux,
- "LIVE, Marking rendition streams to be updated next");
- /* We're live, instruct all rendition medias to be updated next */
- for (tmp = adaptive_demux->input_period->streams; tmp; tmp = tmp->next) {
- GstHLSDemuxStream *hls_stream = tmp->data;
- if (!hls_stream->is_variant)
- hls_stream->playlist_fetched = FALSE;
- }
- }
+ GstHLSVariantStream *target_variant =
+ demux->pending_variant ? demux->pending_variant : demux->current_variant;
+ GstHLSDemuxStream *stream = demux->main_stream;
- #ifdef TIZEN_FEATURE_POST_VARIANT_INFO
- GST_DEBUG_OBJECT (demux, "post variant info message");
- gst_element_post_message (GST_ELEMENT_CAST (demux),
- gst_message_new_element (GST_OBJECT_CAST (demux),
- gst_structure_new (GST_ADAPTIVE_DEMUX_VARIANT_MESSAGE_NAME,
- "video-variant-info", G_TYPE_POINTER,
- demux->master->variant_info, NULL)));
- #endif
+ /* The demuxer has been resetted in the meantime */
+ if (target_variant == NULL)
+ return GST_FLOW_FLUSHING;
- return GST_FLOW_OK;
+ return gst_hls_demux_stream_check_current_playlist_uri (stream,
+ target_variant->uri);
}
- static gboolean
- gst_hls_demux_change_playlist (GstHLSDemux * demux, guint max_bitrate,
- gboolean * changed)
+ gboolean
+ gst_hls_demux_change_variant_playlist (GstHLSDemux * demux,
+ gboolean iframe_variant, guint max_bitrate, gboolean * changed)
{
- GstHLSVariantStream *lowest_variant, *lowest_ivariant;
- GstHLSVariantStream *previous_variant, *new_variant;
- gint old_bandwidth, new_bandwidth;
GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX_CAST (demux);
- GstAdaptiveDemux2Stream *stream;
- g_return_val_if_fail (demux->main_stream != NULL, FALSE);
- stream = (GstAdaptiveDemux2Stream *) demux->main_stream;
+ if (changed)
+ *changed = FALSE;
- /* Make sure we keep a reference in case we need to switch back */
- previous_variant = gst_hls_variant_stream_ref (demux->current_variant);
- new_variant =
+ /* Make sure we keep a reference for the debug output below */
+ GstHLSVariantStream *new_variant =
+#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT
+ gst_hls_master_playlist_get_variant_for_bitrate_and_resolution (demux->master,
- demux->current_variant, max_bitrate, adaptive_demux->min_bitrate,
- adaptive_demux->max_width, adaptive_demux->max_height);
++ iframe_variant, max_bitrate, adaptive_demux->min_bitrate,
++ adaptive_demux->max_width, adaptive_demux->max_height, demux->failed_variants);
+#else
gst_hls_master_playlist_get_variant_for_bitrate (demux->master,
- demux->current_variant, max_bitrate, adaptive_demux->min_bitrate);
+ iframe_variant, max_bitrate, adaptive_demux->min_bitrate,
+ demux->failed_variants);
+#endif
- retry_failover_protection:
- old_bandwidth = previous_variant->bandwidth;
- new_bandwidth = new_variant->bandwidth;
+ /* We're out of available variants to use */
+ if (new_variant == NULL) {
+ return FALSE;
+ }
+
+ GstHLSVariantStream *previous_variant =
+ gst_hls_variant_stream_ref (demux->current_variant);
/* Don't do anything else if the playlist is the same */
- if (new_bandwidth == old_bandwidth) {
+ if (new_variant == previous_variant) {
+ GST_TRACE_OBJECT (demux, "Variant didn't change from bandwidth %dbps",
+ new_variant->bandwidth);
gst_hls_variant_stream_unref (previous_variant);
return TRUE;
}
* Boston, MA 02110-1301, USA.
*/
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
#include <stdlib.h>
#include <math.h>
#include <errno.h>
return GST_CLOCK_TIME_NONE;
/* The recommended buffering threshold is 1.5 average segment duration */
- return 3 * (playlist->duration / playlist->segments->len) / 2;
+ GstClockTime threshold =
+ 3 * (playlist->duration / playlist->segments->len) / 2;
+
+ if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (playlist)) {
- /* For live playlists, reduce the recommended buffering threshold
++ /* For live playlists, reduce the recommended buffering threshold
+ * to match the starting hold back distance if needed, otherwise
+ * we'll hit the live edge and have to wait before we hit 100% */
+ if (GST_CLOCK_TIME_IS_VALID (playlist->hold_back)
+ && threshold > playlist->hold_back)
+ threshold = playlist->hold_back;
+ else if (GST_CLOCK_TIME_IS_VALID (playlist->targetduration)
+ && threshold > 3 * playlist->targetduration)
+ threshold = 3 * playlist->targetduration;
+
+ if (GST_CLOCK_TIME_IS_VALID (playlist->part_hold_back)
+ && threshold > playlist->part_hold_back)
+ threshold = playlist->part_hold_back;
+ else if (GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)
+ && threshold > 3 * playlist->partial_targetduration)
+ threshold = 3 * playlist->partial_targetduration;
+ }
+
+ return threshold;
}
GstHLSRenditionStream *
return playlist;
}
- playlist, GstHLSVariantStream * current_variant, guint bitrate,
- guint min_bitrate, guint max_width, guint max_height)
+#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT
+static guint
+get_num_of_codec(GstHLSVariantStream * variant)
+{
+#define MAX_NUM_OF_CODEC 10
+ guint cnt = 0;
+ gchar** codec_list = NULL;
+
+ if (!variant || !variant->codecs)
+ return 0;
+
+ codec_list = g_strsplit (variant->codecs, ",", MAX_NUM_OF_CODEC);
+ if (!codec_list)
+ return 0;
+
+ cnt = g_strv_length (codec_list);
+ g_strfreev (codec_list);
+
+ return cnt;
+}
+
+static gboolean
+is_codec_change_available(GstHLSVariantStream * variant, guint req_num)
+{
+ if (!variant)
+ return FALSE;
+
+ if (req_num == 0)
+ return TRUE;
+
+ if (get_num_of_codec (variant) == req_num)
+ return TRUE;
+
+ GST_WARNING ("can not support to change codec");
+ return FALSE;
+}
+
+GstHLSVariantStream *
+hls_master_playlist_get_variant_for_bitrate_and_resolution (GstHLSMasterPlaylist *
- GstHLSVariantStream *variant = current_variant;
++ playlist, gboolean iframe_variant, guint bitrate,
++ guint min_bitrate, guint max_width, guint max_height, GList * failed_variants)
+{
- /* get variant list */
- if (current_variant == NULL || !current_variant->iframe)
- l = g_list_last (playlist->variants);
- else
++ GstHLSVariantStream *variant = NULL;
+ GstHLSVariantStream *variant_by_min = NULL; // lowest
+ GList *l = NULL;
+ guint num_of_codec = 0;
+
+ GST_DEBUG ("bitrate: %u, min_bitrate: %u, max resolution: %u X %u",
+ bitrate, min_bitrate, max_width, max_height);
+
- num_of_codec = get_num_of_codec (current_variant);
++ /* variant lists are sorted low to high, so iterate from highest to lowest */
++ if (iframe_variant && playlist->iframe_variants != NULL)
+ l = g_list_last (playlist->iframe_variants);
++ else
++ l = g_list_last (playlist->variants);
+
++ num_of_codec = get_num_of_codec (l->data);
+
+ for (; l; l = g_list_previous(l)) {
++ if (g_list_find (failed_variants, l->data) != NULL)
++ /* Ignore all variants from the failed list */
++ continue;
++
+ variant = l->data;
++
+ if (!is_codec_change_available ((GstHLSVariantStream *)variant, num_of_codec))
+ continue;
+
+ GST_DEBUG ("stream info: %d, %d x %d", variant->bandwidth, variant->width, variant->height);
+
+ if (variant->bandwidth >= min_bitrate)
+ variant_by_min = variant;
+
+ if (variant->bandwidth <= bitrate) {
+ if (max_width == 0 || max_height == 0 || variant->width == 0 || variant->height == 0)
+ break;
+
+ if (variant->width > max_width || variant->height > max_height)
+ continue;
+
+ break;
+ }
+ }
+
+ if (variant && variant->bandwidth >= min_bitrate)
+ return variant;
+
+ return variant_by_min;
+}
+#else
GstHLSVariantStream *
hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist *
- playlist, GstHLSVariantStream * current_variant, guint bitrate,
- guint min_bitrate)
+ playlist, gboolean iframe_variant, guint bitrate,
+ guint min_bitrate, GList * failed_variants)
{
- GstHLSVariantStream *variant = current_variant;
- GstHLSVariantStream *variant_by_min = current_variant;
+ GstHLSVariantStream *variant = NULL;
+ GstHLSVariantStream *variant_by_min = NULL;
GList *l;
/* variant lists are sorted low to high, so iterate from highest to lowest */
GstM3U8MediaSegment * current,
gboolean forward);
- GstM3U8MediaSegment *
- gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self);
+ gboolean
-gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self,
++gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self,
+ GstM3U8SeekResult *seek_result);
+
+ GstClockTime
+ gst_hls_media_playlist_get_end_stream_time (GstHLSMediaPlaylist * m3u8);
GstClockTime
gst_hls_media_playlist_get_duration (GstHLSMediaPlaylist * m3u8);
GstHLSMasterPlaylist * hls_master_playlist_new_from_data (gchar * data,
const gchar * base_uri);
- GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate_and_resolution (GstHLSMasterPlaylist *
- playlist, GstHLSVariantStream * current_variant, guint bitrate,
- guint min_bitrate, guint max_width, guint max_height);
+#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT
+#define gst_hls_master_playlist_get_variant_for_bitrate_and_resolution hls_master_playlist_get_variant_for_bitrate_and_resolution
++GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate_and_resolution (
++ GstHLSMasterPlaylist * playlist,
++ gboolean iframe_variant,
++ guint bitrate,
++ guint min_bitrate,
++ guint max_width,
++ guint max_height,
++ GList * failed_variants);
+#else
#define gst_hls_master_playlist_get_variant_for_bitrate hls_master_playlist_get_variant_for_bitrate
GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
- GstHLSVariantStream * current_variant,
- guint bitrate,
- guint min_bitrate);
+ gboolean iframe_variant,
+ guint bitrate,
+ guint min_bitrate,
+ GList * failed_variants);
+#endif
#define gst_hls_master_playlist_get_common_caps hls_master_playlist_get_common_caps
GstCaps * hls_master_playlist_get_common_caps (GstHLSMasterPlaylist *playlist);
gint notify; /* atomic */
- gboolean corked:1;
- gboolean stream_connected:1;
- gboolean operation_success:1;
- gboolean paused:1;
- gboolean in_read:1;
+ gboolean corked;
+ gboolean stream_connected;
+ gboolean operation_success;
+ gboolean paused;
+ gboolean in_read;
+#ifdef TIZEN_FEATURE_PULSE_MODIFICATION
+ gchar *latency;
+#endif /* TIZEN_FEATURE_PULSE_MODIFICATION */
+
GstStructure *properties;
pa_proplist *proplist;
+
+#if defined(TIZEN_FEATURE_PULSE_MODIFICATION) && defined(PCM_DUMP_ENABLE)
+ gint need_dump_output;
+ FILE *dump_fd_output;
+#endif
};
G_END_DECLS
img = vpx_codec_get_frame (&dec->decoder, &iter);
if (img) {
if (vpxclass->get_frame_format (dec, img, &fmt) == FALSE) {
+#ifndef TIZEN_FEATURE_VPX_MODIFICATION
vpx_img_free (img);
- GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
+#endif
+ GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
("Failed to decode frame"), ("Unsupported color format %d",
img->fmt));
+#ifdef TIZEN_FEATURE_VPX_MODIFICATION
+ vpx_img_free (img);
+#endif
gst_video_codec_frame_unref (frame);
return GST_FLOW_ERROR;
}
{
GstQTDemux *qtdemux = GST_QTDEMUX (object);
+#ifdef TIZEN_FEATURE_QTDEMUX_MODIFICATION
+ if (qtdemux->spherical_metadata) {
+ if (qtdemux->spherical_metadata->stitching_software)
+ free(qtdemux->spherical_metadata->stitching_software);
+ if (qtdemux->spherical_metadata->projection_type)
+ free(qtdemux->spherical_metadata->projection_type);
+ if (qtdemux->spherical_metadata->stereo_mode)
+ free(qtdemux->spherical_metadata->stereo_mode);
+
+ free(qtdemux->spherical_metadata);
+ qtdemux->spherical_metadata = NULL;
+ }
+#endif /* TIZEN_FEATURE_QTDEMUX_MODIFICATION */
+ g_clear_object (&qtdemux->adapter);
+ gst_clear_tag_list (&qtdemux->tag_list);
+ g_clear_pointer (&qtdemux->flowcombiner, gst_flow_combiner_unref);
- if (qtdemux->adapter) {
- g_object_unref (G_OBJECT (qtdemux->adapter));
- qtdemux->adapter = NULL;
- }
- gst_tag_list_unref (qtdemux->tag_list);
- gst_flow_combiner_free (qtdemux->flowcombiner);
g_queue_clear_full (&qtdemux->protection_event_queue,
(GDestroyNotify) gst_event_unref);
}
}
+ qtdemux_check_if_is_gapless_audio (qtdemux);
+
+#ifdef TIZEN_FEATURE_QTDEMUX_DURATION
+ if (!qtdemux->fragmented && (qtdemux->duration > tkhd_max_duration)) {
+ GST_INFO_OBJECT (qtdemux,
+ "Update duration: %" G_GUINT64_FORMAT " -> %" G_GUINT64_FORMAT,
+ qtdemux->duration, tkhd_max_duration);
+ qtdemux->duration = tkhd_max_duration;
+ }
+#endif
+
return ret;
}
QTDEMUX_STATE_BUFFER_MDAT /* Buffering the mdat atom */
};
-
+#ifdef TIZEN_FEATURE_QTDEMUX_MODIFICATION
+typedef struct _QtDemuxSphericalMetadata QtDemuxSphericalMetadata;
+#endif
+
typedef enum {
/* Regular behaviour */
VARIANT_NONE,
#define DEFAULT_MIN_TS_OFFSET MIN_TS_OFFSET_ROUND_OFF_COMP
#define DEFAULT_TS_OFFSET_SMOOTHING_FACTOR 0
#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+#define DEFAULT_RTSP_USE_BUFFERING FALSE
+#endif
+ #define DEFAULT_TIMEOUT_INACTIVE_SOURCES TRUE
enum
{
PROP_FEC_DECODERS,
PROP_FEC_ENCODERS,
PROP_UPDATE_NTP64_HEADER_EXT,
- PROP_USE_RTSP_BUFFERING /* use for player RTSP buffering */
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
++ PROP_USE_RTSP_BUFFERING, /* use for player RTSP buffering */
+#endif
+ PROP_TIMEOUT_INACTIVE_SOURCES,
};
#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
DEFAULT_UPDATE_NTP64_HEADER_EXT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+ g_object_class_install_property (gobject_class, PROP_USE_RTSP_BUFFERING,
+ g_param_spec_boolean ("use-rtsp-buffering", "Use RTSP buffering",
+ "Use RTSP buffering in RTP_JITTER_BUFFER_MODE_SLAVE buffer mode",
+ DEFAULT_RTSP_USE_BUFFERING,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
+ /**
+ * GstRtpBin:timeout-inactive-sources:
+ *
+ * Whether inactive sources should be timed out
+ *
+ * Since: 1.24
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TIMEOUT_INACTIVE_SOURCES,
+ g_param_spec_boolean ("timeout-inactive-sources",
+ "Time out inactive sources",
+ "Whether sources that don't receive RTP or RTCP packets for longer "
+ "than 5x RTCP interval should be removed",
+ DEFAULT_TIMEOUT_INACTIVE_SOURCES,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
gstelement_class->request_new_pad =
rtpbin->min_ts_offset_is_set = FALSE;
rtpbin->ts_offset_smoothing_factor = DEFAULT_TS_OFFSET_SMOOTHING_FACTOR;
rtpbin->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+ rtpbin->use_rtsp_buffering = FALSE;
+#endif
+ rtpbin->timeout_inactive_sources = DEFAULT_TIMEOUT_INACTIVE_SOURCES;
/* some default SDES entries */
cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
#define DEFAULT_ONVIF_RATE_CONTROL TRUE
#define DEFAULT_IS_LIVE TRUE
#define DEFAULT_IGNORE_X_SERVER_REPLY FALSE
+ #define DEFAULT_FORCE_NON_COMPLIANT_URL FALSE
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+#define DEFAULT_START_POSITION 0
+#define DEFAULT_STREAM_INFO_MESSAGE TRUE
+#endif
+
enum
{
PROP_0,
src->is_live = DEFAULT_IS_LIVE;
src->seek_seqnum = GST_SEQNUM_INVALID;
src->group_id = GST_GROUP_ID_INVALID;
+ src->prop_extra_http_request_headers =
+ gst_structure_new_empty ("extra-http-request-headers");
+ src->force_non_compliant_url = DEFAULT_FORCE_NON_COMPLIANT_URL;
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+ g_mutex_init (&(src)->pause_lock);
+ g_cond_init (&(src)->open_end);
+#endif
/* get a list of all extensions */
src->extensions = gst_rtsp_ext_list_get ();
if (control == NULL)
break;
+ if (g_strcmp0 (control, "*") == 0)
+ break;
+
/* only take fully qualified urls */
- if (g_str_has_prefix (control, "rtsp://"))
+ if (gst_uri_is_valid (control))
break;
}
- if (control) {
- g_free (src->conninfo.location);
- src->conninfo.location = g_strdup (control);
- /* make a connection for this, if there was a connection already, nothing
- * happens. */
- if (gst_rtsp_conninfo_connect (src, &src->conninfo, async) < 0) {
- GST_ERROR_OBJECT (src, "could not connect");
+
+ if (g_strcmp0 (control, "*") != 0) {
+ if (control) {
+ g_free (src->conninfo.location);
+ src->conninfo.location = g_strdup (control);
+ /* make a connection for this, if there was a connection already, nothing
+ * happens. */
+ if (gst_rtsp_conninfo_connect (src, &src->conninfo, async) < 0) {
+ GST_ERROR_OBJECT (src, "could not connect");
+ }
}
+ /* we need to keep the control url separate from the connection url because
+ * the rules for constructing the media control url need it */
+ g_free (src->control);
+ src->control = g_strdup (control);
}
- /* we need to keep the control url separate from the connection url because
- * the rules for constructing the media control url need it */
- g_free (src->control);
- src->control = g_strdup (control);
}
+#ifdef TIZEN_FEATURE_RTSP_MODIFICATION
+ src->is_audio_codec_supported = FALSE;
+ src->is_video_codec_supported = FALSE;
+#endif
+
/* create streams */
n_streams = gst_sdp_message_medias_len (sdp);
for (i = 0; i < n_streams; i++) {
}
}
+#ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
+static gboolean
+gst_video_flip_decide_allocation (GstBaseTransform * trans,
+ GstQuery * query)
+{
+ GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
+ GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
+
+ GST_WARNING_OBJECT (videoflip, "format[%s]", filter->out_info.finfo->name);
+
+ if (filter->out_info.finfo->format == GST_VIDEO_FORMAT_SN12) {
+ guint size;
+ GstStructure *config;
+ GstCaps *caps = NULL;
+ GstVideoInfo vinfo;
+
+ gst_query_parse_allocation (query, &caps, NULL);
+ if (!caps) {
+ GST_WARNING_OBJECT (videoflip, "caps failed");
+ return FALSE;
+ }
+
+ gst_video_info_init (&vinfo);
+ gst_video_info_from_caps (&vinfo, caps);
+
+ size = vinfo.size;
+
+ videoflip->pool = gst_tizen_buffer_pool_new ();
+ config = gst_buffer_pool_get_config (videoflip->pool);
+
+ gst_buffer_pool_config_set_params (config, caps, size,
+ TIZEN_BUFFER_POOL_MIN_BUFFERS, TIZEN_BUFFER_POOL_MAX_BUFFERS);
+ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+ gst_buffer_pool_set_config (videoflip->pool, config);
+
+ if (!gst_buffer_pool_set_active (videoflip->pool, TRUE)) {
+ gst_object_unref (videoflip->pool);
+ videoflip->pool = NULL;
+ GST_WARNING_OBJECT (videoflip, "Failed to activate pool");
+ return FALSE;
+ }
+
+ GST_WARNING_OBJECT (videoflip, "new buffer pool[%p]", videoflip->pool);
+ }
+
+ return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query);
+}
+
+static GstFlowReturn
+gst_video_flip_prepare_output_buffer (GstBaseTransform * trans,
+ GstBuffer *input, GstBuffer **outbuf)
+{
+ GstVideoFlip *videoflip = GST_VIDEO_FLIP (trans);
+ GstBuffer *buf = NULL;
+
+ if (!videoflip->pool)
+ return GST_BASE_TRANSFORM_CLASS (parent_class)->prepare_output_buffer (trans, input, outbuf);
+
+ if (gst_buffer_pool_acquire_buffer (videoflip->pool, &buf, 0) != GST_FLOW_OK) {
+ GST_ERROR_OBJECT (trans, "Buffer acquire failed");
+ return GST_FLOW_ERROR;
+ }
+
+ GST_DEBUG_OBJECT (videoflip, "acquired buffer[%p]", buf);
+
+ if (input != buf)
+ GST_BASE_TRANSFORM_CLASS (parent_class)->copy_metadata (trans, input, buf);
+
+ *outbuf = buf;
+
+ return GST_FLOW_OK;
+}
++#endif
+
static void
gst_video_flip_finalize (GObject * object)
{
GstVideoFlip *videoflip = GST_VIDEO_FLIP (object);
+
++#ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
+ if (videoflip->pool) {
+ GST_WARNING_OBJECT (videoflip, "free buffer pool[%p]", videoflip->pool);
+ gst_buffer_pool_set_active (videoflip->pool, FALSE);
+ gst_object_unref (videoflip->pool);
+ videoflip->pool = NULL;
+ }
++#endif
+ g_clear_pointer (&videoflip->stream_id, g_free);
- G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (videoflip));
+ G_OBJECT_CLASS (gst_video_flip_parent_class)->finalize (object);
+ }
+
+ static GstStateChangeReturn
+ gst_video_flip_change_state (GstElement * element, GstStateChange transition)
+ {
+ GstVideoFlip *videoflip = GST_VIDEO_FLIP (element);
+ GstStateChangeReturn result;
+
+ result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ g_clear_pointer (&videoflip->stream_id, g_free);
+ break;
+ default:
+ break;
+ }
+
+ return result;
}
- #endif
static void
gst_video_flip_constructed (GObject * object)
vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_video_flip_set_info);
vfilter_class->transform_frame =
GST_DEBUG_FUNCPTR (gst_video_flip_transform_frame);
- gobject_class->finalize = gst_video_flip_finalize;
+#ifdef TIZEN_FEATURE_VIDEOFLIP_TBM_SUPPORT
+ trans_class->decide_allocation = gst_video_flip_decide_allocation;
+ trans_class->prepare_output_buffer = gst_video_flip_prepare_output_buffer;
+#endif
gst_type_mark_as_plugin_api (GST_TYPE_VIDEO_FLIP_METHOD, 0);
}
if (mem)
gst_memory_unref (mem);
}
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+ if (group->surface) {
+ GST_INFO ("unref surface[%p]", group->surface);
+ tbm_surface_destroy (group->surface);
+ group->surface = NULL;
+ }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
- g_slice_free (GstV4l2MemoryGroup, group);
+ g_free (group);
}
static GstV4l2MemoryGroup *
static void gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
GstBuffer * buffer, gboolean queued);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+static void gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool,
+ GstBuffer * buffer);
+
+typedef struct _GstV4l2TizenBuffer GstV4l2TizenBuffer;
+struct _GstV4l2TizenBuffer {
+ int index;
+ GstBuffer *gst_buffer;
+ GstBuffer *v4l2_buffer;
+ GstV4l2BufferPool *v4l2_pool;
+};
+
+static void
+gst_v4l2_tizen_buffer_finalize (GstV4l2TizenBuffer *tizen_buffer)
+{
+ GstV4l2BufferPool *pool = NULL;
+
+ if (!tizen_buffer) {
+ GST_ERROR ("NULL buffer");
+ return;
+ }
+
+ pool = tizen_buffer->v4l2_pool;
+
+ gst_v4l2_buffer_pool_release_buffer (GST_BUFFER_POOL_CAST (pool), tizen_buffer->v4l2_buffer);
+
+ g_mutex_lock (&pool->buffer_lock);
+
+ pool->live_buffer_count--;
+
+ GST_DEBUG_OBJECT (pool, "release buffer[%d][tizen:%p,v4l2:%p,gst:%p], live[%d]",
+ tizen_buffer->index, tizen_buffer, tizen_buffer->v4l2_buffer,
+ tizen_buffer->gst_buffer, pool->live_buffer_count);
+
+ g_cond_signal (&pool->buffer_cond);
+
+ g_mutex_unlock (&pool->buffer_lock);
+
+ gst_object_unref (pool);
+
+ g_free(tizen_buffer);
+}
+
+static GstV4l2TizenBuffer *
+gst_v4l2_tizen_buffer_new (GstBuffer *v4l2_buffer, int index, GstV4l2BufferPool *v4l2_pool)
+{
+ GstV4l2TizenBuffer *tizen_buffer = NULL;
+ GstVideoInfo *info = NULL;
+ GstVideoMeta *videometa = NULL;
+ GstMemory *memory = NULL;
+
+ if (!v4l2_pool || !v4l2_pool->obj) {
+ GST_ERROR_OBJECT (v4l2_pool, "NULL V4L2 pool[%p] or obj", v4l2_pool);
+ return NULL;
+ }
+
+ info = &v4l2_pool->obj->info;
+
+ tizen_buffer = g_new0 (GstV4l2TizenBuffer, 1);
+ tizen_buffer->index = index;
+ tizen_buffer->v4l2_buffer = v4l2_buffer;
+ tizen_buffer->gst_buffer = gst_buffer_new ();
+ tizen_buffer->v4l2_pool = gst_object_ref (v4l2_pool);
+
+ memory = gst_tizen_allocator_alloc_surface (v4l2_pool->tallocator,
+ info, v4l2_pool->vallocator->groups[index]->surface, (gpointer)tizen_buffer,
+ (GDestroyNotify)gst_v4l2_tizen_buffer_finalize);
+
+ gst_buffer_append_memory (tizen_buffer->gst_buffer, memory);
+ gst_buffer_set_size (tizen_buffer->gst_buffer, v4l2_pool->vallocator->s_info.size);
+
+ videometa = gst_buffer_add_video_meta_full (tizen_buffer->gst_buffer, GST_VIDEO_FRAME_FLAG_NONE,
+ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
+ GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
+ info->offset, info->stride);
+ if (videometa) {
+ videometa->map = gst_tizen_video_meta_map;
+ videometa->unmap = gst_tizen_video_meta_unmap;
+ } else {
+ GST_WARNING_OBJECT (v4l2_pool, "videometa failed");
+ }
+
+ g_mutex_lock (&v4l2_pool->buffer_lock);
+
+ v4l2_pool->live_buffer_count++;
+
+ GST_DEBUG_OBJECT (v4l2_pool, "new buffer[tizen:%p,v4l2:%p,gst:%p], size[%d], live[%d]",
+ tizen_buffer, v4l2_buffer, tizen_buffer->gst_buffer,
+ v4l2_pool->vallocator->s_info.size, v4l2_pool->live_buffer_count);
+
+ g_mutex_unlock (&v4l2_pool->buffer_lock);
+
+ return tizen_buffer;
+}
+
+static void
+gst_v4l2_tizen_buffer_dump (tbm_surface_h surface)
+{
+ int i;
+ FILE *fp;
+ tbm_surface_info_s sinfo;
+
+ if (!surface) {
+ GST_WARNING ("NULL surface");
+ return;
+ }
+
+ memset (&sinfo, 0x0, sizeof(tbm_surface_info_s));
+
+ if (tbm_surface_get_info (surface, &sinfo) != TBM_ERROR_NONE) {
+ GST_ERROR ("get tbm surface[%p] info failed", surface);
+ return;
+ }
+
+ fp = fopen (TIZEN_BUFFER_DUMP_PATH, "a");
+ if (!fp) {
+ GST_ERROR ("file open failed[%s], errno[%d]", TIZEN_BUFFER_DUMP_PATH, errno);
+ return;
+ }
+
+ for (i = 0 ; i < sinfo.num_planes ; i++) {
+ GST_DEBUG ("[%d] %ux%u, stride[%u], size[%u], offset[%u]",
+ i, sinfo.width, sinfo.height, sinfo.planes[i].stride,
+ sinfo.planes[i].size, sinfo.planes[i].offset);
+ fwrite (sinfo.planes[i].ptr, 1, sinfo.planes[i].size, fp);
+ }
+
+ fclose(fp);
+}
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
+
static gboolean
- gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group)
+ gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group,
+ gboolean check_writable)
{
GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
gboolean valid = FALSE;
GstV4L2FormatFlags flags;
} GstV4L2FormatDesc;
+ /* *INDENT-OFF* */
+ #define MAP_FMT(v4l2_format, gst_fmt) V4L2_PIX_FMT_##v4l2_format, GST_VIDEO_FORMAT_##gst_fmt
static const GstV4L2FormatDesc gst_v4l2_formats[] = {
/* RGB formats */
- {V4L2_PIX_FMT_RGB332, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB565, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB565X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR666, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ABGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XBGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGRA32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGRX32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGBA32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGBX32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_ARGB32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_XRGB32, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (RGB332, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (ARGB555, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (XRGB555, RGB15), GST_V4L2_RAW},
+ {MAP_FMT (XRGB555X, RGB15), GST_V4L2_RAW},
+ {MAP_FMT (ARGB555X, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (RGB565, RGB16), GST_V4L2_RAW},
+ {MAP_FMT (RGB565X, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (BGR666, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (BGR24, BGR), GST_V4L2_RAW},
+ {MAP_FMT (RGB24, RGB), GST_V4L2_RAW},
+ {MAP_FMT (ABGR32, BGRA), GST_V4L2_RAW},
+ {MAP_FMT (XBGR32, BGRx), GST_V4L2_RAW},
+ {MAP_FMT (BGRA32, ABGR), GST_V4L2_RAW},
+ {MAP_FMT (BGRX32, xBGR), GST_V4L2_RAW},
+ {MAP_FMT (RGBA32, RGBA), GST_V4L2_RAW},
+ {MAP_FMT (RGBX32, RGBx), GST_V4L2_RAW},
+ {MAP_FMT (ARGB32, ARGB), GST_V4L2_RAW},
+ {MAP_FMT (XRGB32, xRGB), GST_V4L2_RAW},
/* Deprecated Packed RGB Image Formats (alpha ambiguity) */
- {V4L2_PIX_FMT_RGB444, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_BGR32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_RGB32, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (RGB444, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (RGB555, RGB15), GST_V4L2_RAW},
+ {MAP_FMT (RGB555X, BGR15), GST_V4L2_RAW},
+ {MAP_FMT (BGR32, BGRx), GST_V4L2_RAW},
+ {MAP_FMT (BGR32, BGRA), GST_V4L2_RAW},
+ {MAP_FMT (RGB32, xRGB), GST_V4L2_RAW},
+ {MAP_FMT (RGB32, ARGB), GST_V4L2_RAW},
/* Grey formats */
- {V4L2_PIX_FMT_GREY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y4, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y6, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y10, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y16_BE, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y10BPACK, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_INVZ, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (GREY, GRAY8), GST_V4L2_RAW},
+ {MAP_FMT (Y4, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (Y6, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (Y10, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (Y12, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (Y16, GRAY16_LE), GST_V4L2_RAW},
+ {MAP_FMT (Y16_BE, GRAY16_BE), GST_V4L2_RAW},
+ {MAP_FMT (Y10BPACK, UNKNOWN), GST_V4L2_RAW},
++ {MAP_FMT (INVZ, INVZ), GST_V4L2_RAW},
/* Palette formats */
- {V4L2_PIX_FMT_PAL8, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (PAL8, UNKNOWN), GST_V4L2_RAW},
/* Chrominance formats */
- {V4L2_PIX_FMT_UV8, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (UV8, UNKNOWN), GST_V4L2_RAW},
/* Luminance+Chrominance formats */
- {V4L2_PIX_FMT_YVU410, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVU420, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVU420M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUYV, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_UYVY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_VYUY, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV422P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV411P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_Y41P, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV444, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV555, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV565, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV32, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_YUV420M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_HM12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_M420, TRUE, GST_V4L2_RAW},
-
- /* two planes -- one Y, one Cr + Cb interleaved */
- {V4L2_PIX_FMT_NV12, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12MT, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12MT_16X16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12M_8L128, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV12M_10BE_8L128, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV21, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV21M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV16, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV16M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV61, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV61M, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV24, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_NV42, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_MM21, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (YVU410, YVU9), GST_V4L2_RAW},
+ {MAP_FMT (YVU420M, YV12), GST_V4L2_RAW},
+ {MAP_FMT (YVU420, YV12), GST_V4L2_RAW},
+ {MAP_FMT (YUYV, YUY2), GST_V4L2_RAW},
+ {MAP_FMT (YYUV, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YVYU, YVYU), GST_V4L2_RAW},
+ {MAP_FMT (UYVY, UYVY), GST_V4L2_RAW},
+ {MAP_FMT (VYUY, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV422M, Y42B), GST_V4L2_RAW},
+ {MAP_FMT (YUV422P, Y42B), GST_V4L2_RAW},
+ {MAP_FMT (YUV411P, Y41B), GST_V4L2_RAW},
+ {MAP_FMT (Y41P, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV444, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV555, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV565, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV32, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (YUV410, YUV9), GST_V4L2_RAW},
+ {MAP_FMT (YUV420M, I420), GST_V4L2_RAW},
+ {MAP_FMT (YUV420, I420), GST_V4L2_RAW},
++#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
++ {MAP_FMT (YUV420, S420), GST_V4L2_RAW},
++#endif
+ {MAP_FMT (HI240, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (M420, UNKNOWN), GST_V4L2_RAW},
+
+ /* two planes -- one Y, one Cr + Cb interleaved */
+ {MAP_FMT (NV12M, NV12), GST_V4L2_RAW},
+ {MAP_FMT (NV12, NV12), GST_V4L2_RAW},
++#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
++ {MAP_FMT (NV12, SN12), GST_V4L2_RAW},
++#endif
+ {MAP_FMT (NV12MT, NV12_64Z32), GST_V4L2_RAW},
+ {MAP_FMT (NV12MT_16X16, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (NV12_16L16, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (NV12M_8L128, NV12_8L128), GST_V4L2_RAW},
+ {MAP_FMT (NV12M_10BE_8L128, NV12_10BE_8L128), GST_V4L2_RAW},
+ {MAP_FMT (NV21M, NV21), GST_V4L2_RAW},
+ {MAP_FMT (NV21, NV21), GST_V4L2_RAW},
+ {MAP_FMT (NV16M, NV16), GST_V4L2_RAW},
+ {MAP_FMT (NV16, NV16), GST_V4L2_RAW},
+ {MAP_FMT (NV61M, NV61), GST_V4L2_RAW},
+ {MAP_FMT (NV61, NV61), GST_V4L2_RAW},
+ {MAP_FMT (NV24, NV24), GST_V4L2_RAW},
+ {MAP_FMT (NV42, UNKNOWN), GST_V4L2_RAW},
+ {MAP_FMT (MM21, NV12_16L32S), GST_V4L2_RAW},
/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
- {V4L2_PIX_FMT_SBGGR8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SGBRG8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SGRBG8, TRUE, GST_V4L2_RAW},
- {V4L2_PIX_FMT_SRGGB8, TRUE, GST_V4L2_RAW},
+ {MAP_FMT (SBGGR8, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGBRG8, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGRBG8, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SRGGB8, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SBGGR10, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGBRG10, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGRBG10, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SRGGB10, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SBGGR12, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGBRG12, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGRBG12, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SRGGB12, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SBGGR14, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGBRG14, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGRBG14, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SRGGB14, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SBGGR16, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGBRG16, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SGRBG16, ENCODED), GST_V4L2_BAYER},
+ {MAP_FMT (SRGGB16, ENCODED), GST_V4L2_BAYER},
/* compressed formats */
- {V4L2_PIX_FMT_MJPEG, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_JPEG, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_PJPG, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_DV, FALSE, GST_V4L2_TRANSPORT},
- {V4L2_PIX_FMT_MPEG, FALSE, GST_V4L2_TRANSPORT},
- {V4L2_PIX_FMT_FWHT, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_H264_NO_SC, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_H264_MVC, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_HEVC, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_MPEG1, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_MPEG2, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_MPEG4, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_XVID, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VC1_ANNEX_G, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VC1_ANNEX_L, FALSE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- {V4L2_PIX_FMT_VP9, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {MAP_FMT (MJPEG, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (JPEG, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (PJPG, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (DV, ENCODED), GST_V4L2_TRANSPORT},
+ {MAP_FMT (MPEG, ENCODED), GST_V4L2_TRANSPORT},
+ {MAP_FMT (FWHT, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (H264, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (H264_NO_SC, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (H264_MVC, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (HEVC, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (H263, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (MPEG1, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (MPEG2, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (MPEG4, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (XVID, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (VC1_ANNEX_G, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (VC1_ANNEX_L, ENCODED), GST_V4L2_CODEC},
+ {MAP_FMT (VP8, ENCODED), GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
+ {MAP_FMT (VP9, ENCODED), GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
/* Vendor-specific formats */
- {V4L2_PIX_FMT_WNVA, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
- {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
+ {MAP_FMT (WNVA, ENCODED), GST_V4L2_CODEC | GST_V4L2_RESOLUTION_AND_RATE},
+ {MAP_FMT (SN9C10X, ENCODED), GST_V4L2_CODEC | GST_V4L2_RESOLUTION_AND_RATE},
+ {MAP_FMT (PWC1, ENCODED), GST_V4L2_CODEC | GST_V4L2_RESOLUTION_AND_RATE},
+ {MAP_FMT (PWC2, ENCODED), GST_V4L2_CODEC | GST_V4L2_RESOLUTION_AND_RATE},
};
-
+ #undef MAP_FMT
+ /* *INDENT-ON* */
#define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
static GSList *gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object);
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
}
- switch (gst_v4l2_formats[i].format) {
+ switch (fourcc) {
+ case V4L2_PIX_FMT_RGB32:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
++ break;
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+ case V4L2_PIX_FMT_YUV420:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "S420", NULL);
+ break;
+ case V4L2_PIX_FMT_NV12:
+ alt_s = gst_structure_copy (structure);
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "SN12", NULL);
+ break;
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
- case V4L2_PIX_FMT_RGB32:
- alt_s = gst_structure_copy (structure);
- gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
- break;
- case V4L2_PIX_FMT_BGR32:
- alt_s = gst_structure_copy (structure);
- gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
default:
break;
}
}
if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
++#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
++ GST_WARNING_OBJECT (v4l2object->dbg_obj, "num planes: device %u vs expected %d",
++ format.fmt.pix_mp.num_planes, n_v4l_planes);
++#else
goto invalid_planes;
++#endif
/* used to check colorimetry and interlace mode fields presence */
- s = gst_caps_get_structure (caps, 0);
-
if (gst_v4l2_object_get_interlace_mode (format.fmt.pix.field,
&info.interlace_mode)) {
if (gst_structure_has_field (s, "interlace-mode")) {
GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
return FALSE;
}
++#ifndef TIZEN_FEATURE_V4L2_TBM_SUPPORT
invalid_planes:
{
GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
("Device wants %d planes", format.fmt.pix_mp.num_planes));
return FALSE;
}
++#endif
invalid_field:
{
enum v4l2_field wanted_field;
tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
format->pixelformat, template);
if (tmp) {
- gst_caps_append (ret, tmp);
-
/* Add a variant of the caps with the Interlaced feature so we can negotiate it if needed */
- add_alternate_variant (v4l2object, ret, gst_caps_get_structure (ret,
- gst_caps_get_size (ret) - 1));
+ gint i;
+ for (i = 0; i < gst_caps_get_size (tmp); i++) {
+ GstStructure *s = gst_caps_get_structure (tmp, i);
+ add_alternate_variant (v4l2object, interlaced_caps, s);
+ }
+
+ gst_caps_append (caps, tmp);
}
- gst_caps_append (ret, tmp);
+#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
+ if (format->pixelformat == V4L2_PIX_FMT_NV12 ||
+ format->pixelformat == V4L2_PIX_FMT_YUV420) {
+ GstStructure *alt_s = gst_structure_copy (template);
+
+ if (format->pixelformat == V4L2_PIX_FMT_NV12)
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "SN12", NULL);
+ else
+ gst_structure_set (alt_s, "format", G_TYPE_STRING, "S420", NULL);
+
+ tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
+ format->pixelformat, alt_s);
+
+ if (tmp)
++ gst_caps_append (caps, tmp);
+
+ gst_structure_free (alt_s);
+ }
+#endif /* TIZEN_FEATURE_V4L2_TBM_SUPPORT */
gst_structure_free (template);
}
* on slow USB firmwares. When this is set, gst_v4l2_set_format() will modify
* the caps to reflect what was negotiated during fixation */
gboolean skip_try_fmt_probes;
-
++
+ guint max_width;
+ guint max_height;
};
struct _GstV4l2ObjectClassHelper {
gst_caps_replace (&self->probed_srccaps, NULL);
self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture,
++#ifdef TIZEN_FEATURE_V4L2_TBM_SUPPORT
++ NULL);
++#else
gst_v4l2_object_get_raw_caps ());
++#endif
/* Create caps from the acquired format, remove the format field */
acquired_caps = gst_video_info_to_caps (&info);
GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps);
priv->blocking_msg_received = 0;
}
+ static void
+ stream_install_drop_probe (GstRTSPStream * stream, gpointer user_data)
+ {
+ if (!gst_rtsp_stream_is_complete (stream))
+ return;
+
+ gst_rtsp_stream_install_drop_probe (stream);
+ }
+
+ static void
+ media_streams_install_drop_probe (GstRTSPMedia * media)
+ {
+ GstRTSPMediaPrivate *priv = media->priv;
+
+ g_ptr_array_foreach (priv->streams, (GFunc) stream_install_drop_probe, NULL);
+ }
+
+#ifdef TIZEN_FEATURE_RTSP_SERVER_MODIFICATION
+void
+#else
static void
+#endif
gst_rtsp_media_set_status (GstRTSPMedia * media, GstRTSPMediaStatus status)
{
GstRTSPMediaPrivate *priv = media->priv;
}
}
-
+ /* Call with state_lock */
+ static gboolean
+ ensure_new_keyunit (GstRTSPMedia * media)
+ {
+ GstRTSPMediaPrivate *priv = media->priv;
+ gboolean preroll_ok;
+ gboolean is_blocking = FALSE;
++#ifdef TIZEN_FEATURE_RTSP_SERVER_MODIFICATION
++ GstRTSPMediaClass *klass = GST_RTSP_MEDIA_GET_CLASS (media);
++#endif
+ /* nothing to be done without complete senders */
+ if (get_num_complete_sender_streams (media) == 0) {
+ GST_DEBUG_OBJECT (media, "no complete senders, skipping force keyunit");
+ return TRUE;
+ }
+
+ is_blocking = media_streams_blocking (media);
+
+ /* if we unsuspend before the keyunit is expired remove the timer so that
+ * no future buffer is marked as expired */
+ if (is_blocking && !priv->keyunit_is_expired) {
+ GST_DEBUG_OBJECT (media, "using currently blocking keyunit");
+ g_source_destroy (priv->keyunit_expiration_source);
+ g_source_unref (priv->keyunit_expiration_source);
+ priv->keyunit_expiration_source = NULL;
+
+ return TRUE;
+ }
+
+ /* set the media to preparing, thus requiring a successful preroll before
+ * completing unsuspend. */
+ gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING);
+ GST_DEBUG_OBJECT (media, "ensuring new keyunit, doing preroll");
++#ifdef TIZEN_FEATURE_RTSP_SERVER_MODIFICATION
++ if (!klass->start_preroll (media))
++#else
+ if (!start_preroll (media))
++#endif
+ goto start_failed;
+
+ if (is_blocking) {
+ /* if we end up here then the keyunit has expired and the timer callback
+ * has been removed so reset the flag */
+ priv->keyunit_is_expired = FALSE;
+
+ /* install a probe that will drop the currently blocking keyunit on all
+ * complete streams. */
+ GST_DEBUG_OBJECT (media, "media is blocking. Installing drop probe");
+ media_streams_install_drop_probe (media);
+ }
+
+ /* force the keyunit from src */
+ GST_DEBUG_OBJECT (media, "sending force keyunit event");
+ gst_element_send_event (priv->element,
+ gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
+ TRUE, 0));
+
+ /* wait preroll */
+ g_rec_mutex_unlock (&priv->state_lock);
+ preroll_ok = wait_preroll (media);
+ g_rec_mutex_lock (&priv->state_lock);
+
+ if (!preroll_ok)
+ goto preroll_failed;
+
+ return TRUE;
+
+ start_failed:
+ {
+ GST_WARNING ("failed to preroll pipeline");
+ return FALSE;
+ }
+ preroll_failed:
+ {
+ GST_WARNING ("failed while waiting to preroll pipeline");
+ return FALSE;
+ }
+ }
+
/* call with state_lock */
static gboolean
default_unsuspend (GstRTSPMedia * media)
{GST_QUERY_DRAIN, "drain", 0},
{GST_QUERY_CONTEXT, "context", 0},
{GST_QUERY_BITRATE, "bitrate", 0},
+#ifdef TIZEN_PROFILE_TV
+ {GST_QUERY_RESOURCE, "resource", 0},
+#endif
{GST_QUERY_SELECTABLE, "selectable", 0},
+
{0, NULL, 0}
};
GST_API
gboolean gst_type_is_plugin_api (GType type, GstPluginAPIFlags *flags);
+#ifdef TIZEN_PROFILE_TV
+void gst_set_family_id_to_child (GstElement* child, int id);
+#endif
++
+ GST_API
+ guint gst_util_ceil_log2 (guint32 v);
+
+ GST_API
+ gint gst_util_filename_compare (const gchar *a, const gchar *b);
+
G_END_DECLS
#endif /* __GST_UTILS_H__ */
link_with : printf_lib,
install : true,
dependencies : [gobject_dep, gmodule_dep, glib_dep, mathlib, dl_dep,
- backtrace_deps, platform_deps, extra_deps, dlog_dep],
- backtrace_deps, platform_deps, network_deps, extra_deps],
++ backtrace_deps, platform_deps, network_deps, extra_deps, dlog_dep],
)
-
+gstreamer_extra_args = ['-DTIZEN_FEATURE_DISABLE_DEPRECATED_DECLARATION']
+if get_option('tv-profile')
+ gstreamer_extra_args += ['-DTIZEN_PROFILE_TV']
+endif
+
+ gst_compile_args = []
+ if static_build
+ gst_compile_args += ['-DGST_STATIC_COMPILATION']
+ endif
+
pkg_name = 'gstreamer-1.0'
library_def = {'lib': libgst}
pkgconfig.generate(libgst,
variables : pkgconfig_variables,
uninstalled_variables: pkgconfig_uninstalled_variables,
subdirs : pkgconfig_subdirs,
+ extra_cflags : gstreamer_extra_args,
name : pkg_name,
description : 'Streaming media framework',
+ extra_cflags: gst_compile_args,
)
if build_gir
#define DEFAULT_BLOCKSIZE 4096
#define DEFAULT_NUM_BUFFERS -1
#define DEFAULT_DO_TIMESTAMP FALSE
+#ifdef TIZEN_PROFILE_TV
+#define DEFAULT_SEGMENT_TIME -1
+#endif
+ /* FIXME 2.0: automatic_eos should probably be disabled by default,
+ * see https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1330 */
+ #define DEFAULT_AUTOMATIC_EOS TRUE
enum
{
#ifndef GST_REMOVE_DEPRECATED
PROP_TYPEFIND,
#endif
- PROP_DO_TIMESTAMP
+ PROP_DO_TIMESTAMP,
+#ifdef TIZEN_PROFILE_TV
- ,PROP_UPDATE_SEGMENT
- #endif
++ PROP_UPDATE_SEGMENT,
++#endif
+ PROP_AUTOMATIC_EOS
};
/* The basesrc implementation need to respect the following locking order:
g_param_spec_boolean ("do-timestamp", "Do timestamp",
"Apply current stream time to buffers", DEFAULT_DO_TIMESTAMP,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#ifdef TIZEN_PROFILE_TV
+ g_object_class_install_property (gobject_class, PROP_UPDATE_SEGMENT,
+ g_param_spec_int64 ("update-segment", "Update Segment",
+ "Timestamp that application want to set (-1 unlimited)",
+ -1, G_MAXINT64, DEFAULT_SEGMENT_TIME,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
+ /**
+ * GstBaseSrc:automatic-eos:
+ *
+ * See gst_base_src_set_automatic_eos()
+ *
+ * Since: 1.24
+ */
+ g_object_class_install_property (gobject_class, PROP_AUTOMATIC_EOS,
+ g_param_spec_boolean ("automatic-eos", "Automatic EOS",
+ "Automatically EOS when the segment is done", DEFAULT_AUTOMATIC_EOS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_src_change_state);
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_src_send_event);
case PROP_DO_TIMESTAMP:
gst_base_src_set_do_timestamp (src, g_value_get_boolean (value));
break;
+#ifdef TIZEN_PROFILE_TV
+ case PROP_UPDATE_SEGMENT:
+ gst_base_src_update_segment (src, g_value_get_int64 (value));
+ break;
+#endif
+ case PROP_AUTOMATIC_EOS:
+ gst_base_src_set_automatic_eos (src, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
* discard when the create function returned _OK. */
if (G_UNLIKELY (g_atomic_int_get (&src->priv->has_pending_eos))) {
if (ret == GST_FLOW_OK) {
+#ifdef TIZEN_FEATURE_TRUSTZONE
+ if (own_res_buf) {
+ /*tzappsrc patch : release handle when unref res_buf*/
+ if(bclass->tz_src_release_handle)
+ {
+ GST_INFO_OBJECT (src, "tzappsrc release the handle");
+ bclass->tz_src_release_handle(src,res_buf);
+ }
+ gst_buffer_unref (res_buf);
+ }
+#else
if (own_res_buf)
+ gst_buffer_unref (res_buf);
+#endif
+ gst_clear_buffer (&res_buf);
+ gst_clear_buffer_list (&src->priv->pending_bufferlist);
}
src->priv->forced_eos = TRUE;
goto eos;
void gst_base_src_submit_buffer_list (GstBaseSrc * src,
GstBufferList * buffer_list);
+ GST_BASE_API
+ gboolean gst_base_src_push_segment (GstBaseSrc * src,
+ const GstSegment * segment);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstBaseSrc, gst_object_unref)
+#ifdef TIZEN_PROFILE_TV
+GST_BASE_API
+void gst_base_src_update_segment (GstBaseSrc * src, gint64 timestamp);
+#endif
+
G_END_DECLS
#endif /* __GST_BASE_SRC_H__ */
- exe = executable('gst-plugin-scanner',
- 'gst-plugin-scanner.c',
- pie : true,
- c_args : gst_c_args,
- include_directories : [configinc],
- dependencies : [gst_dep, mathlib, gmodule_dep,],
- install_dir : helpers_install_dir,
- install: true,
- )
-
- meson.add_devenv({'GST_PLUGIN_SCANNER': exe.full_path()})
-
- # Used in test env setup to make tests find plugin scanner in build tree
- gst_scanner_dir = meson.current_build_dir()
-
- if bashcomp_found
- executable('gst-completion-helper',
- 'gst-completion-helper.c',
- c_args : gst_c_args,
- include_directories : [configinc],
- dependencies : [gst_dep],
- install_dir : helpers_install_dir,
- install_tag : 'bin',
- install: true,
- )
- endif
-
- # Check PTP support
- have_ptp = false
- if host_system == 'android'
- message('PTP not supported on Android because of permissions.')
- elif host_system == 'windows'
- message('PTP not supported on Windows, not ported yet.')
- elif host_system == 'ios'
- message('PTP not supported on iOS because of permissions.')
- elif ['linux', 'darwin', 'netbsd', 'freebsd', 'openbsd', 'kfreebsd', 'dragonfly', 'sunos', 'gnu', 'gnu/kfreebsd'].contains(host_system)
- message('PTP supported on ' + host_system + '.')
- have_ptp = true
- else
- message('PTP not supported on ' + host_system + ', not ported yet.')
- endif
-
- if have_ptp
- cdata.set('HAVE_PTP', 1, description : 'PTP support available')
-
- if cc.compiles('''#include <sys/ioctl.h>
- #include <net/if.h>
- int some_func (void) {
- struct ifreq ifr;
- struct ifconf ifc;
- ioctl(0, SIOCGIFCONF, &ifc);
- ioctl(0, SIOCGIFFLAGS, &ifr);
- ioctl(0, SIOCGIFHWADDR, &ifr);
- return ifr.ifr_hwaddr.sa_data[0];
- }''',
- name : 'SIOCGIFCONF, SIOCGIFFLAGS and SIOCGIFHWADDR available')
- cdata.set('HAVE_SIOCGIFCONF_SIOCGIFFLAGS_SIOCGIFHWADDR', 1,
- description : 'SIOCGIFCONF, SIOCGIFFLAGS and SIOCGIFHWADDR is available')
- endif
-
- if cc.compiles('''#include <ifaddrs.h>
- #include <net/if.h>
- #include <net/if_dl.h>
- int some_func (void) {
- struct ifaddrs *ifaddr;
- getifaddrs(&ifaddr);
- return (ifaddr->ifa_flags & IFF_LOOPBACK) && ifaddr->ifa_addr->sa_family != AF_LINK;
- }''', name : 'getifaddrs() and AF_LINK available')
- cdata.set('HAVE_GETIFADDRS_AF_LINK', 1,
- description : 'getifaddrs() and AF_LINK is available')
- endif
-
- setcap_prog = find_program('setcap', '/usr/sbin/setcap', '/sbin/setcap', required : false)
- cap_dep = dependency('libcap', required: false)
-
- # user/group to change to in gst-ptp-helper
- ptp_helper_setuid_user = get_option('ptp-helper-setuid-user')
- if ptp_helper_setuid_user != ''
- cdata.set_quoted('HAVE_PTP_HELPER_SETUID_USER', ptp_helper_setuid_user,
- description : 'PTP helper setuid user')
- endif
- ptp_helper_setuid_group = get_option('ptp-helper-setuid-group')
- if ptp_helper_setuid_group != ''
- cdata.set_quoted('HAVE_PTP_HELPER_SETUID_GROUP', ptp_helper_setuid_group,
- description : 'PTP helper setuid group')
- endif
-
- # how to install gst-ptp-helper
- with_ptp_helper_permissions = get_option('ptp-helper-permissions')
- if with_ptp_helper_permissions == 'auto'
- if setcap_prog.found() and cap_dep.found()
- with_ptp_helper_permissions = 'capabilities'
- else
- with_ptp_helper_permissions = 'setuid-root'
+ subdir('ptp')
+
+ gst_helpers = {
+ 'gst-plugin-scanner': {
+ 'files': files('gst-plugin-scanner.c'),
+ 'deps': [gst_dep, mathlib, gmodule_dep],
+ 'env': ['GST_PLUGIN_SCANNER', 'exe-full-path'],
+ 'install_dir': helpers_install_dir,
+ },
+ 'gst-completion-helper': {
+ 'files': files('gst-completion-helper.c'),
+ 'deps': [gst_dep],
+ 'install_dir': helpers_install_dir,
+ },
+ }
+
+ if not get_option('tools').disabled() and not static_build
+ foreach helper, data: gst_helpers
+ exe_name = '@0@'.format(helper)
+ exe = executable(exe_name,
+ data.get('files'),
+ install: data.get('install', true),
+ install_tag: 'bin',
+ install_dir: data.get('install_dir', get_option('bindir')),
+ include_directories : [configinc],
+ dependencies : data.get('deps', []),
++ pie : true,
+ c_args: data.get('extra_c_args', []) + ['-DG_LOG_DOMAIN="@0@"'.format(exe_name)],
+ )
+ if(data.has_key('env'))
+ env = data.get(('env'))
+ value = env[1]
+ if env[1] == 'exe-full-path'
+ value = exe.full_path()
+ endif
+ meson.add_devenv({env[0]: value})
endif
- endif
- message('How to install gst-ptp-helper: ' + with_ptp_helper_permissions)
- if with_ptp_helper_permissions == 'none'
- # nothing to do
- elif with_ptp_helper_permissions == 'setuid-root'
- cdata.set('HAVE_PTP_HELPER_SETUID', 1,
- description : 'Use setuid-root for permissions in PTP helper')
- elif with_ptp_helper_permissions == 'capabilities'
- if not setcap_prog.found()
- error('capabilities-based ptp-helper-permissions requested, but could not find setcap tool.')
- elif not cap_dep.found()
- error('capabilities-based ptp-helper-permissions requested, but could not find libcap.')
+ if data.has_key('man_page')
+ install_man(data.get('man_page'))
endif
- cdata.set('HAVE_PTP_HELPER_CAPABILITIES', 1,
- description : 'Use capabilities for permissions in PTP helper')
- else
- error('Unexpected ptp helper permissions value: ' + with_ptp_helper_permissions)
- endif
+ endforeach
+ endif
- exe = executable('gst-ptp-helper', 'gst-ptp-helper.c',
- pie : true,
- c_args : gst_c_args,
- include_directories : [configinc, libsinc],
- dependencies : [gst_dep, gio_dep, mathlib, cap_dep],
- install_dir : helpers_install_dir,
- install : true)
+ # Used in test env setup to make tests find plugin scanner in build tree
+ gst_scanner_dir = meson.current_build_dir()
- meson.add_install_script('ptp_helper_post_install.sh',
- helpers_install_dir, with_ptp_helper_permissions,
- setcap_prog.found() ? setcap_prog.full_path() : '')
- meson.add_devenv({'GST_PTP_HELPER': exe.full_path()})
- endif
install_data(['gst_gdb.py', 'glib_gobject_helper.py'],
install_dir : join_paths(get_option('datadir'), 'gstreamer-@0@'.format(apiversion), 'gdb'),
PROP_BUFFER_MODE,
PROP_BUFFER_SIZE,
PROP_APPEND,
+#ifdef TIZEN_FEATURE_FILESINK_MODIFICATION
+ PROP_CURRENT_BYTES,
+#endif
PROP_O_SYNC,
PROP_MAX_TRANSIENT_ERROR_TIMEOUT,
+ PROP_FILE_MODE,
PROP_LAST
};
"Size of buffer in number of bytes for line or full buffer-mode", 0,
G_MAXUINT, DEFAULT_BUFFER_SIZE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#ifdef TIZEN_FEATURE_FILESINK_MODIFICATION
+ g_object_class_install_property (gobject_class, PROP_CURRENT_BYTES,
+ g_param_spec_uint64 ("current-bytes", "Current bytes",
+ "downloaded bytes so far", 0,
+ G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
+ /**
+ * GstFileSink:file-mode
+ *
+ * Ability to specify file mode.
+ *
+ * Since: 1.24
+ */
+ g_object_class_install_property (gobject_class, PROP_FILE_MODE,
+ g_param_spec_enum ("file-mode", "File Mode",
+ "Specify file mode used to open file", GST_TYPE_FILE_SINK_FILE_MODE,
+ DEFAULT_FILE_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/**
* GstFileSink:append
*
case PROP_APPEND:
g_value_set_boolean (value, sink->append);
break;
+#ifdef TIZEN_FEATURE_FILESINK_MODIFICATION
+ case PROP_CURRENT_BYTES:
+ g_value_set_uint64(value, sink->current_pos);
+ break;
+#endif
+ case PROP_FILE_MODE:
+ g_value_set_enum (value, sink->file_mode);
+ break;
case PROP_O_SYNC:
g_value_set_boolean (value, sink->o_sync);
break;
endif
man_page = files('@0@-1.0.1'.format(tool))
- if not get_option('tools').disabled()
+ if not get_option('tools').disabled() and not static_build
executable(exe_name,
src_file,
+ pie : true,
install: true,
install_tag: 'bin',
include_directories : [configinc],