"ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 60 || DIE=1
version_check "automake" "$AUTOMAKE automake automake-1.11 automake-1.10" \
"ftp://ftp.gnu.org/pub/gnu/automake/" 1 10 || DIE=1
-version_check "autopoint" "autopoint" \
- "ftp://ftp.gnu.org/pub/gnu/gettext/" 0 17 || DIE=1
version_check "libtoolize" "libtoolize libtoolize15 glibtoolize" \
"ftp://ftp.gnu.org/pub/gnu/libtool/" 1 5 0 || DIE=1
version_check "pkg-config" "" \
toplevel_check $srcfile
-# autopoint
-# older autopoint (< 0.12) has a tendency to complain about mkinstalldirs
-if test -x mkinstalldirs; then rm mkinstalldirs; fi
-# first remove patch if necessary, then run autopoint, then reapply
-if test -f po/Makefile.in.in;
-then
- patch -p0 -R --forward < common/gettext.patch
-fi
-tool_run "$autopoint" "--force" "patch -p0 < common/gettext.patch"
-patch -p0 < common/gettext.patch
-
# aclocal
if test -f acinclude.m4; then rm acinclude.m4; fi
*) BUILD_CHECK=yes ;;
esac
])
+
+dnl use dlog --------------------------------------------------------------------------
+AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]),
+[
+ case "${enableval}" in
+ yes) USE_DLOG=yes ;;
+ no) USE_DLOG=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;;
+ esac
+],[USE_DLOG=no])
+
+if test "x$USE_DLOG" = "xyes"; then
+ PKG_CHECK_MODULES(DLOG, dlog)
+ AC_SUBST(DLOG_CFLAGS)
+ AC_SUBST(DLOG_LIBS)
+fi
+AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes")
+dnl end --------------------------------------------------------------------
+
dnl bit of a misnomer, but keep the conditional named like this so we don't
dnl have to change too much elsewhere
AM_CONDITIONAL(HAVE_CHECK, test "x$BUILD_CHECK" = "xyes")
--- /dev/null
+gstreamer0.10 (0.10.36-1slp2+11) unstable; urgency=low
+
+ * [queue2]add posix_fadvise because of page cache free after streaming
+ * Tag: gstreamer0.10_0.10.36-1slp2+11
+
+ -- Jihae Yi <jihae.yi@samsung.com> Mon, 29 Apr 2013 17:53:45 +0900
+
+gstreamer0.10 (0.10.36-1slp2+10) unstable; urgency=low
+
+ * [filesink] Call posix_fadvise not to use page cache
+ * Tag: gstreamer0.10_0.10.36-1slp2+10
+
+ -- Jeongmo Yang <jm80.yang@samsung.com> Mon, 22 Apr 2013 17:53:23 +0900
+
+gstreamer0.10 (0.10.36-1slp2+9) unstable; urgency=low
+
+ * [queue] flush queue when empty-buffers is set as TRUE
+ * Tag: gstreamer0.10_0.10.36-1slp2+9
+
+ -- Jeongmo Yang <jm80.yang@samsung.com> Thu, 24 Jan 2013 20:31:39 +0900
+
+gstreamer0.10 (0.10.36-1slp2+7) unstable; urgency=low
+
+ * [baseparse] Modify to do not calculate zero padding in first frame
+ * Git: framework/multimedia/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+7
+
+ -- Sunghyun Eum <sunghyun.eum@samsung.com> Fri, 16 Nov 2012 11:38:36 +0900
+
+gstreamer0.10 (0.10.36-1slp2+6) unstable; urgency=low
+
+ * [gststructure] Add null check code for avoid seg. fault
+ * Git: framework/multimedia/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+6
+
+ -- Sunghyun Eum <sunghyun.eum@samsung.com> Tue, 23 Oct 2012 14:23:12 +0900
+
+gstreamer0.10 (0.10.36-1slp2+5) unstable; urgency=low
+
+ * [baseparse] Add get baseparser pad_mode param function for aac duration
+ * Git: framework/multimedia/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+5
+
+ -- Sunghyun Eum <sunghyun.eum@samsung.com> Thu, 04 Oct 2012 23:31:38 +0900
+
+gstreamer0.10 (0.10.36-1slp2+4) unstable; urgency=low
+
+ * [baseparse] Add get baseparser private param function for amr index table
+ * Git: framework/multimedia/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+4
+
+ -- Sunghyun Eum <sunghyun.eum@samsung.com> Fri, 28 Sep 2012 18:02:03 +0900
+
+gstreamer0.10 (0.10.36-1slp2+3) unstable; urgency=low
+
+ * add default smack manifest
+ * Git: framework/multimedia/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+3
+
+ -- Sangchul Lee <sc11.lee@samsung.com> Fri, 21 Sep 2012 13:12:24 +0900
+
+gstreamer0.10 (0.10.36-1slp2+2) unstable; urgency=low
+
+ * Remove unused library
+ * Git: slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+2
+
+ -- Jeongmo Yang <jm80.yang@samsung.com> Fri, 20 Jul 2012 11:56:47 +0900
+
+gstreamer0.10 (0.10.36-1slp2+1) unstable; urgency=low
+
+ * Upgrade 0.10.34 to 0.10.36
+ * Git: slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.36-1slp2+1
+
+ -- Hyunseok Lee <hs7388.lee@samsung.com> Wed, 27 Jun 2012 20:39:51 +0900
+
+gstreamer0.10 (0.10.34-10slp2+19) unstable; urgency=low
+
+ * [elementfactory] fix first parameter type of g_atomic_pointer_compare_and_exchange() from (gpointer) to (gpointer *)
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+19
+
+ -- Sangchul Lee <sc11.lee@samsung.com> Mon, 18 Jun 2012 18:01:25 +0900
+
+gstreamer0.10 (0.10.34-10slp2+18) unstable; urgency=low
+
+ * [baseparse] Changed baseparse to support unified reverse trickplay
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+18
+
+ -- Naveen Ch <naveen.ch@samsung.com> Mon, 02 Apr 2012 17:20:23 +0900
+
+gstreamer0.10 (0.10.34-10slp2+17) unstable; urgency=low
+
+ * [Filesink] add to get current bytes for progressive download
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+17
+
+ -- Younghwan Ahn <younghwan_.an@samsung.com> Fri, 09 Mar 2012 11:46:23 +0900
+
+gstreamer0.10 (0.10.34-10slp2+16) unstable; urgency=low
+
+ * [Queue2] change high-limit/low-limit to double from int
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+16
+
+ -- YeJin Cho <cho.yejin@samsung.com> Thu, 12 Jan 2012 17:16:02 +0900
+
+gstreamer0.10 (0.10.34-10slp2+15) unstable; urgency=low
+
+ * [Queue2] Fix to add range after receiving new segment
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+15
+
+ -- YeJin Cho <cho.yejin@samsung.com> Mon, 26 Dec 2011 12:12:03 +0900
+
+gstreamer0.10 (0.10.34-10slp2+14) unstable; urgency=low
+
+ * [Queue2] Fix to drop buffers to be written before receiving the new segment event after sending seek event
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+14
+
+ -- YeJin Cho <cho.yejin@samsung.com> Wed, 21 Dec 2011 18:47:28 +0900
+
+gstreamer0.10 (0.10.34-10slp2+13) unstable; urgency=low
+
+ * [Queue2] Fix to update buffering right before sink pad is activated
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+13
+
+ -- YeJin Cho <cho.yejin@samsung.com> Thu, 17 Nov 2011 17:01:22 +0900
+
+gstreamer0.10 (0.10.34-10slp2+12) unstable; urgency=low
+
+ * [Queue2] Enable file-ring-buffer for limited memory
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+12
+
+ -- YeJin Cho <cho.yejin@samsung.com> Mon, 07 Nov 2011 18:13:35 +0900
+
+gstreamer0.10 (0.10.34-10slp2+11) unstable; urgency=low
+
+ * [Queue2] Remove unused signal
+ * [Queue2] Fix to update buffering message when high/low threshold are changed.
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+11
+
+ -- YeJin Cho <cho.yejin@samsung.com> Mon, 24 Oct 2011 15:01:12 +0900
+
+gstreamer0.10 (0.10.34-10slp2+10) unstable; urgency=low
+
+ * [Queue2] Remove usleep
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+10
+
+ -- YeJin Cho <cho.yejin@samsung.com> Thu, 06 Oct 2011 18:18:37 +0900
+
+gstreamer0.10 (0.10.34-10slp2+9) unstable; urgency=low
+
+ * [Queue2] Fix to file i/o mechanism for fast buffering
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+9
+
+ -- YeJin Cho <cho.yejin@samsung.com> Tue, 04 Oct 2011 21:22:41 +0900
+
+gstreamer0.10 (0.10.34-10slp2+8) unstable; urgency=low
+
+ * [Queue2] Fix to enable updated queue2 for streaming
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+8
+
+ -- YeJin Cho <cho.yejin@samsung.com> Wed, 17 Aug 2011 14:04:02 +0900
+
+gstreamer0.10 (0.10.34-10slp2+7) unstable; urgency=low
+
+ * Fix to enable GST_DISABLE_LOADSAVE to enable sami subtitle
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+7
+
+ -- YeJin Cho <cho.yejin@samsung.com> Wed, 10 Aug 2011 14:12:20 +0900
+
+gstreamer0.10 (0.10.34-10slp2+6) unstable; urgency=low
+
+ * Fix duration issue
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+6
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Thu, 07 Jul 2011 15:31:42 +0900
+
+gstreamer0.10 (0.10.34-10slp2+5) unstable; urgency=low
+
+ * Rollback baseparse merge
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+5
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Thu, 09 Jun 2011 14:24:02 +0900
+
+gstreamer0.10 (0.10.34-10slp2+4) unstable; urgency=low
+
+ * remove old files
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+4
+
+ -- Younghwan Ahn <younghwan_.an@samsung.com> Wed, 08 Jun 2011 16:56:17 +0900
+
+gstreamer0.10 (0.10.34-10slp2+3) unstable; urgency=low
+
+ * update changelog
+ * Git: 165.213.180.234:slp/pkgs/g/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+3
+
+ -- Younghwan Ahn <younghwan_.an@samsung.com> Tue, 07 Jun 2011 20:33:39 +0900
+
+gstreamer0.10 (0.10.34-10slp2+2) unstable; urgency=low
+
+ * fix queue2 temp for http streaming
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+2
+
+ -- YeJin Cho <cho.yejin@samsung.com> Tue, 07 Jun 2011 16:39:08 +0900
+
+gstreamer0.10 (0.10.34-10slp2+1) unstable; urgency=low
+
+ * upgrade 33 to 34
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.34-10slp2+1
+
+ -- nosurprises <nosurprises@nosurprises-desktop> Mon, 23 May 2011 11:59:59 +0900
+
+gstreamer0.10 (0.10.33-10slp2+1) lucid; urgency=low
+
+ * upgrade 25 to 33
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.33-10slp2+1
+
+ -- Younghwan Ahn <younghwan_.an@samsung.com> Thu, 12 May 2011 19:29:11 +0900
+
+gstreamer0.10 (0.10.25-10slp2+11) unstable; urgency=low
+
+ * Fix for as-needed
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.25-10slp2+11
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Wed, 24 Nov 2010 21:02:28 +0900
+
+gstreamer0.10 (0.10.25-10slp2+10) unstable; urgency=low
+
+ * Add dbg-package, fPIC, as-needed
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.25-10slp2+10
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Fri, 19 Nov 2010 11:26:34 +0900
+
+gstreamer0.10 (0.10.25-10slp2+9) unstable; urgency=low
+
+ * Add "keep-last-buffer" property to basesink for capturing last buffer
+ * Git: 165.213.180.234:/git/slp/pkgs/gstreamer0.10
+ * Tag: gstreamer0.10_0.10.25-10slp2+9
+
+ -- Jeongmo Yang <jm80.yang@samsung.com> Wed, 25 Aug 2010 11:56:59 +0900
+
+gstreamer0.10 (0.10.25-10slp2+8) unstable; urgency=low
+
+ * remove old dlog dependency
+ * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/gstreamer-0.10.25
+ * Tag: gstreamer0.10_0.10.25-10slp2+8
+
+ -- YoungHwan Ahn <younghwan_.an@samsung.com> Mon, 28 Jun 2010 15:23:18 +0900
+
+gstreamer0.10 (0.10.25-10slp2+7) unstable; urgency=low
+
+ * Call gst_base_sink_set_last_buffer with NULL after render()
+ * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/gstreamer-0.10.25
+ * Tag: gstreamer0.10_0.10.25-10slp2+7
+
+ -- Wonhyung Cho <wh01.cho@samsung.com> Wed, 09 Jun 2010 21:42:47 +0900
+
+gstreamer0.10 (0.10.25-10slp2+6) unstable; urgency=low
+
+ * Add libmm-ta-dev to dev package
+ * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/gstreamer-0.10.25
+ * Tag: gstreamer0.10_0.10.25-10slp2+6
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Mon, 10 May 2010 20:51:03 +0900
+
+gstreamer0.10 (0.10.25-10slp2+5) unstable; urgency=low
+
+ * Add SDK package
+ * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/gstreamer-0.10.25
+ * Tag: gstreamer0.10_0.10.25-10slp2+5
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Mon, 10 May 2010 14:05:21 +0900
+
+gstreamer0.10 (0.10.25-9slp2+2) unstable; urgency=low
+
+ * Move ta include to internal
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Thu, 06 May 2010 11:07:35 +0900
+
+gstreamer0.10 (0.10.25-9slp2+1) unstable; urgency=low
+
+ * Replace ta-dev with ta-sdk-dev package
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Tue, 04 May 2010 20:04:04 +0900
+
+gstreamer0.10 (0.10.25-9slp2+0) unstable; urgency=low
+
+ * Change package naming rule
+
+ -- Seungbae Shin <seungbae.shin@samsung.com> Thu, 25 Mar 2010 15:06:39 +0900
+
+gstreamer0.10 (0.10.25-9) unstable; urgency=low
+
+ * Modify gstbasesrc to make base loop not compete with state change with _MMCAMCORDER_MODIFIED_DQBUF feature
+
+ -- Wonhyung Cho <wh01.cho@samsung.com> Mon, 22 Mar 2010 13:55:56 +0900
+
+gstreamer0.10 (0.10.25-8) unstable; urgency=low
+
+ * Email violation
+
+ -- Wonhyung Cho <wh01.cho@samsung.com> Fri, 05 Feb 2010 19:30:02 +0900
+
+gstreamer0.10 (0.10.25-7) unstable; urgency=low
+
+ * Fix seg fault error while on capturing
+
+ -- Wonhyung Cho <wh01.cho@samsung.com> Tue, 02 Feb 2010 14:34:44 +0900
+
+gstreamer0.10 (0.10.25-6) unstable; urgency=low
+
+ * [H0100077084] Fix audio breaks bug when pause->resume
+
+ -- Shin Seung Bae <seungbae.shin@samsung.com> Wed, 20 Jan 2010 20:39:39 +0900
+
+gstreamer0.10 (0.10.25-5) unstable; urgency=low
+
+ * Remove bison check in build-dep section
+
+ -- Shin Seung Bae <seungbae.shin@samsung.com> Tue, 29 Dec 2009 11:34:59 +0900
+
+gstreamer0.10 (0.10.25-4) unstable; urgency=low
+
+ * Fix wrong dependancy about libmm-ta
+
+ -- Wonhyung <wh01.cho@samsung.com> Tue, 22 Dec 2009 18:24:30 +0900
+
+gstreamer0.10 (0.10.25-3) unstable; urgency=low
+
+ * Enable empty-buffers property of gstqueue
+
+ -- Wonhyung <wh01.cho@samsung.com> Tue, 22 Dec 2009 17:52:38 +0900
+
+gstreamer0.10 (0.10.25-2) unstable; urgency=low
+
+ * Removed unnecessary folder 'debian_opensrc'
+
+ -- Myungjae Lee <mjae.lee@samsung.com> Thu, 27 Nov 2009 15:36:00 +0900
+
+gstreamer0.10 (0.10.25-1) unstable; urgency=low
+
+ * Changed initial version from 0.10.22 to 0.10.25
+
+ -- Myungjae Lee <mjae.lee@samsung.com> Thu, 13 Nov 2009 13:31:00 +0900
+
+gstreamer0.10 (0.10.22-2) unstable; urgency=low
+
+ * Uploaded source files
+
+ -- Myungjae Lee <mjae.lee@samsung.com> Thu, 12 Nov 2009 19:44:11 +0900
+
+gstreamer0.10 (0.10.22-1) unstable; urgency=low
+
+ * Initial release.
+
+ -- Myungjae Lee <mjae.lee@samsung.com> Thu, 12 Nov 2009 18:51:00 +0900
--- /dev/null
+Source: gstreamer0.10
+Section: libs
+Priority: optional
+Maintainer: Shin Seung Bae <seungbae.shin@samsung.com>, JongHyuk Choi <jhchoi.choi@samsung.com>
+Uploaders: Shin Seung Bae <seungbae.shin@samsung.com>, JongHyuk Choi <jhchoi.choi@samsung.com>, Hyunseok Lee <hs7388.lee@samsung.com>, YoungHwan Ahn <younghwan_.an@samsung.com>, Jeongmo Yang <jm80.yang@samsung.com>, Naveen Ch <naveen.ch@samsung.com>
+Build-Depends: debhelper (>= 5),
+ autotools-dev,
+ libxml2-dev (>= 2.6.0),
+ zlib1g-dev (>= 1:1.1.4),
+ libglib2.0-dev (>= 2.12),
+ pkg-config (>= 0.11.0),
+ libmm-ta-dev
+Standards-Version: 3.8.0
+
+Package: libgstreamer0.10-0
+Architecture: any
+Section: libs
+Depends: ${shlibs:Depends}, libmm-ta
+Suggests: gstreamer0.10-tools,
+ gstreamer0.10-plugins
+Description: Core GStreamer libraries and elements
+ 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 package contains the core library and elements.
+
+Package: libgstreamer0.10-dev
+XB-Public-Package: no
+Architecture: any
+Section: libdevel
+Depends: libmm-ta-dev, libgstreamer0.10-sdk-dev
+Description: GStreamer core SDK development files
+ 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 package contains SDK development files for the core library and
+ elements.
+
+
+Package: libgstreamer0.10-sdk-dev
+Architecture: any
+Section: libdevel
+Depends: libgstreamer0.10-0 (= ${binary:Version}),
+ libc6-dev | libc-dev,
+ pkg-config,
+ libglib2.0-dev,
+ libxml2-dev,
+ libmm-ta-sdk-dev,
+ ${shlibs:Depends}
+Replaces: gstreamer-tools (<< 0.10.20-2)
+Recommends: debhelper
+Suggests: gstreamer0.10-doc
+Description: GStreamer core development files
+ 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 package contains development files for the core library and
+ elements.
+
+Package: gstreamer0.10-tools
+Architecture: any
+Section: utils
+Depends: ${shlibs:Depends},
+ pkg-config,
+ libgstreamer0.10-0 (>= 0.10.21.3)
+Suggests: gstreamer0.10-plugins-base
+Description: Tools for use with 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 plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This package contains versioned command-line tools for GStreamer.
+
+Package: gstreamer-tools
+Architecture: any
+Section: utils
+Depends: ${shlibs:Depends},
+ gstreamer0.10-tools | gstreamer0.8-tools
+Conflicts: gstreamer0.8-tools (<< 0.8.11-2)
+Description: Tools for use with 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 plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This package contains unversioned command-line tools for GStreamer
+ that work with different major/minor versions of GStreamer.
+
+Package: libgstreamer0.10-0-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libgstreamer0.10-0 (= ${Source-Version})
+Description: Core GStreamer libraries and elements (unstripped)
--- /dev/null
+This package was debianized by David I. Lehn <dlehn@debian.org> on
+Mon, 15 Jan 2001 18:21:37 -0500.
+
+It was downloaded from <http://gstreamer.freedesktop.org/>.
+
+Upstream Authors:
+
+ Erik Walthinsen <omegahacker@users.sourceforge.net>
+ Wim Taymans <wim.taymans@chello.be>
+ Richard Boulton <richard@tartarus.org>
+ and many more...
+
+Copyright:
+
+ This package is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+On Debian GNU/Linux systems, the complete text of the GNU Lesser General
+Public License can be found in `/usr/share/common-licenses/LGPL'.
+
--- /dev/null
+usr/bin/gst-inspect
+usr/bin/gst-launch
--- /dev/null
+usr/bin/gst-inspect-0.10
+usr/bin/gst-launch-0.10
--- /dev/null
+usr/lib/gstreamer-0.10/*.so*
+usr/lib/*.so*
--- /dev/null
+usr/include
--- /dev/null
+usr/lib/*.{a,la}
+usr/lib/gstreamer-0.10/*.{a,la}
+usr/lib/pkgconfig
+usr/share/aclocal
--- /dev/null
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# Include dpatch stuff
+include /usr/share/dpatch/dpatch.make
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+# fixit : need to check
+CFLAGS += -Wall -g -fPIC \
+ -DGST_EXT_AV_RECORDING \
+ -DGST_EXT_QUEUE_ENHANCEMENT \
+ -DGST_EXT_CURRENT_BYTES \
+ -D_VSP_SPEED_
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+# shared library versions, option 1
+version=0.10.22
+major=1
+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
+#version=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+#major=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+LDFLAGS += -Wl,--hash-style=both -Wl,--as-needed
+
+config.status:
+ dh_testdir
+ ./autogen.sh
+
+ ./configure --prefix=/usr \
+ --disable-valgrind \
+ --without-check \
+ --disable-static \
+ --disable-rpath \
+ --disable-libtool-lock \
+ --disable-alloc-trace \
+ --disable-gcov \
+ --disable-nls \
+ --disable-examples \
+ --disable-tests \
+ --disable-failing-tests \
+ --disable-docbook \
+ --disable-gtk-doc \
+ --disable-registry-update \
+ --disable-loadsave \
+ --with-html-dir=/tmp/dump \
+ $(CONFIGURE_OPTIONS) \
+ CFLAGS="$(CFLAGS)" \
+ LDFLAGS="$(LDFLAGS)"
+
+
+build: build-stamp
+build-stamp: patch-stamp config.status
+ dh_testdir
+
+ $(MAKE)
+ touch build-stamp
+
+clean: clean1 unpatch
+clean1:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp patch-stamp
+
+ -$(MAKE) distclean
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/tmp
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_install --sourcedir=debian/tmp --list-missing
+ dh_link
+ dh_strip --dbg-package=libgstreamer0.10-0-dbg
+ dh_compress
+ dh_fixperms
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install patch unpatch clean clean1
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\" \
-DGST_DISABLE_DEPRECATED \
$(VALGRIND_CFLAGS) \
+ $(DLOG_CFLAGS) \
$(GST_ALL_CFLAGS)
+if USE_DLOG
+libgstreamer_@GST_MAJORMINOR@_la_CFLAGS += -DUSE_DLOG
+endif
+
libgstreamer_@GST_MAJORMINOR@_la_LIBADD = \
$(GST_PARSE_LA) \
$(GST_ALL_LIBS) \
$(WIN32_LIBS) \
$(XML_LIBS) \
$(LIBM) \
- -lmm_ta
+ $(DLOG_LIBS)
libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = \
$(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
#include <locale.h> /* for LC_ALL */
#include "gst.h"
-#include <mm_ta/mm_ta.h>
-
#define GST_CAT_DEFAULT GST_CAT_GST_INIT
{
GError *err = NULL;
- MMTA_INIT();
-
-__ta__("gst_init",
if (!gst_init_check (argc, argv, &err)) {
g_print ("Could not initialize GStreamer: %s\n",
err ? err->message : "unknown error occurred");
}
exit (1);
}
-)
-
}
/**
gst_deinitialized = TRUE;
GST_INFO ("deinitialized GStreamer");
- MMTA_RELEASE();
-
}
/**
{
GstBinClass *klass;
GstBin *bin;
+#ifdef GST_EXT_BASIC_MODIFICATION
+ int ret = 0;
+ GError *error = NULL;
+#endif /* GST_EXT_BASIC_MODIFICATION */
/* ref was taken */
bin = data->bin;
klass = GST_BIN_GET_CLASS (bin);
GST_DEBUG_OBJECT (bin, "pushing continue on thread pool");
+#ifdef GST_EXT_BASIC_MODIFICATION
+ ret = g_thread_pool_push (klass->pool, data, &error);
+ GST_DEBUG_OBJECT (bin, "g_thread_pool_push ret %d", ret);
+ if (!ret && error) {
+ GST_ERROR_OBJECT (bin, "error message %s", error->message);
+ g_error_free(error);
+ }
+#else /* GST_EXT_BASIC_MODIFICATION */
g_thread_pool_push (klass->pool, data, NULL);
+#endif /* GST_EXT_BASIC_MODIFICATION */
}
/* an element started an async state change, if we were not busy with a state
#include "gstutils.h"
#include "gstminiobject.h"
#include "gstversion.h"
+#ifdef GST_EXT_AV_RECORDING
+#include "gstvalue.h"
+#endif /* GST_EXT_AV_RECORDING */
struct _GstBufferPrivate
{
gst_buffer_make_metadata_writable (GstBuffer * buf)
{
GstBuffer *ret;
+#ifdef GST_EXT_AV_RECORDING
+ GstStructure *structure = NULL;
+ guint32 format = 0;
+ GstCaps *buf_caps = gst_buffer_get_caps(buf);
+
+ if (buf_caps) {
+ structure = gst_caps_get_structure(buf_caps, 0);
+ if (structure) {
+ gst_structure_get_fourcc(structure, "format", &format);
+ if (format == GST_MAKE_FOURCC('S', 'R', '3', '2') ||
+ format == GST_MAKE_FOURCC('I', 'T', 'L', 'V') ||
+ format == GST_MAKE_FOURCC('S', '4', '2', '0') ||
+ format == GST_MAKE_FOURCC('S', 'U', 'Y', 'V') ||
+ format == GST_MAKE_FOURCC('S', 'Y', 'V', 'Y') ||
+ format == GST_MAKE_FOURCC('S', 'N', '2', '1') ||
+ format == GST_MAKE_FOURCC('S', 'T', '1', '2') ||
+ format == GST_MAKE_FOURCC('S', 'N', '1', '2') ||
+ format == GST_MAKE_FOURCC('S', 'V', '1', '2')) {
+ GST_CAT_INFO(GST_CAT_BUFFER, "It's zero copy buffer. return itself.");
+ gst_caps_unref(buf_caps);
+ buf_caps = NULL;
+ return buf;
+ }
+ }
+ gst_caps_unref(buf_caps);
+ buf_caps = NULL;
+ }
+#endif /* GST_EXT_AV_RECORDING */
if (gst_buffer_is_metadata_writable (buf)) {
ret = buf;
GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) - 1);
#endif
+ if (GST_CAPS_REFCOUNT_VALUE (caps) > 10000) {
+ GST_WARNING(" refcount = %d \n",GST_CAPS_REFCOUNT_VALUE (caps));
+ return;
+ }
+
g_return_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0);
/* if we ended up with the refcount at zero, free the caps */
#include "gst-i18n-lib.h"
#include "glib-compat-private.h"
-#include <mm_ta/mm_ta.h>
-
/* Element signals and args */
enum
{
oclass = GST_ELEMENT_GET_CLASS (element);
sprintf( szMsg, "gst_element_get_state (%s)", GST_ELEMENT_NAME(element) );
- MMTA_ACUM_ITEM_BEGIN(szMsg, FALSE );
if (oclass->get_state)
result = (oclass->get_state) (element, state, pending, timeout);
- MMTA_ACUM_ITEM_END( szMsg, FALSE );
-
return result;
}
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
sprintf(szDebugMsg, "set %s state %s to %s", GST_ELEMENT_NAME (element), gst_element_state_get_name(GST_STATE (element)), gst_element_state_get_name(state) );
- MMTA_ACUM_ITEM_BEGIN(szDebugMsg, FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->set_state)
result = (oclass->set_state) (element, state);
- MMTA_ACUM_ITEM_END(szDebugMsg, FALSE);
-
return result;
}
#include "glib-compat-private.h"
-#include <mm_ta/mm_ta.h>
-
GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
#define GST_CAT_DEFAULT element_factory_debug
g_return_val_if_fail (factory != NULL, NULL);
-__ta__(__tafmt__("Creating Element %s(name:%s)", GST_PLUGIN_FEATURE_NAME (factory), name),
-
-
newfactory =
GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
(factory)));
GST_DEBUG ("created element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
-) // __ta__
-
return element;
/* ERRORS */
#endif /* __sgi__ */
#endif
+#if defined(USE_DLOG) && defined(GST_EXT_BASIC_MODIFICATION)
+#include <dlog.h>
+
+//#define _SLOG(class, format, arg...) \
+ //(SLOG(class, "GST_LOG" ,"%s:%s(%d)>"format, __MODULE__, __func__, __LINE__, ##arg))
+#endif
+
+
static void gst_debug_reset_threshold (gpointer category, gpointer unused);
static void gst_debug_reset_all_thresholds (void);
levelcolor = levelcolormap[level];
#define PRINT_FMT " %s"PID_FMT"%s "PTR_FMT" %s%s%s %s"CAT_FMT"%s %s\n"
+
+#if defined(USE_DLOG) && defined(GST_EXT_BASIC_MODIFICATION)
+ SLOG(LOG_WARN, "GST_LOG",
+ "%" GST_TIME_FORMAT PRINT_FMT, GST_TIME_ARGS (elapsed),
+ pidcolor, pid, clear, g_thread_self (), levelcolor,
+ gst_debug_level_get_name (level), clear, color,
+ gst_debug_category_get_name (category), file, line, function, obj,
+ clear, gst_debug_message_get (message));
+#else
fprintf (log_file, "%" GST_TIME_FORMAT PRINT_FMT, GST_TIME_ARGS (elapsed),
pidcolor, pid, clear, g_thread_self (), levelcolor,
gst_debug_level_get_name (level), clear, color,
gst_debug_category_get_name (category), file, line, function, obj,
clear, gst_debug_message_get (message));
fflush (log_file);
+#endif
+
#undef PRINT_FMT
g_free (color);
#else
* thing. */
static GStaticMutex win_print_mutex = G_STATIC_MUTEX_INIT;
const gint clear = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+
#define SET_COLOR(c) G_STMT_START { \
if (log_file == stderr) \
SetConsoleTextAttribute (GetStdHandle (STD_ERROR_HANDLE), (c)); \
} else {
/* no color, all platforms */
#define PRINT_FMT " "PID_FMT" "PTR_FMT" %s "CAT_FMT" %s\n"
+
+ /* Tizen doesn't care about Win32 */
+#if defined(USG_DLOG) && defined(GST_EXT_BASIC_MODIFICATION) && !defined(G_OS_WIN32)
+ SLOG(LOG_WARN, "GST_LOG",
+ "%" GST_TIME_FORMAT PRINT_FMT, GST_TIME_ARGS (elapsed),
+ pid, g_thread_self (), gst_debug_level_get_name (level),
+ gst_debug_category_get_name (category), file, line, function, obj,
+ gst_debug_message_get (message));
+#else
fprintf (log_file, "%" GST_TIME_FORMAT PRINT_FMT, GST_TIME_ARGS (elapsed),
pid, g_thread_self (), gst_debug_level_get_name (level),
gst_debug_category_get_name (category), file, line, function, obj,
gst_debug_message_get (message));
fflush (log_file);
+#endif
+
#undef PRINT_FMT
}
#include "glib-compat-private.h"
#include <gst/gst.h>
-#include <mm_ta/mm_ta.h>
-
#define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING
}
}
-__ta__(__tafmt__("load plugin %s", filename),
-
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"",
filename);
gst_default_registry_add_plugin (plugin);
}
-) //__ta__
-
g_static_mutex_unlock (&gst_plugin_loading_mutex);
return plugin;
GstStructureField *field;
guint i, len;
+#ifdef GST_EXT_BASIC_MODIFICATION
+ g_return_val_if_fail (structure != NULL, NULL);
+ g_return_val_if_fail (structure->fields != NULL, NULL);
+#endif
len = structure->fields->len;
for (i = 0; i < len; i++) {
LARGE_INTEGER start;
LARGE_INTEGER frequency;
#endif /* G_OS_WIN32 */
+
+ wait_jitter_adjust_func wait_jitter_adjust;
+ gpointer adjust_user_data;
+ wait_jitter_adjust_func wait_jitter_revert;
+ gpointer revert_user_data;
};
+/* consider after adjust , no need to wait again */
+#define GST_SYSTEM_CLOCK_WAIT_ADJUST(clock) \
+ if(clock->priv->wait_jitter_adjust) { \
+ clock->priv->wait_jitter_adjust(clock, clock->priv->adjust_user_data); \
+ wait_twice = FALSE; }
+
+#define GST_SYSTEM_CLOCK_WAIT_REVERT(clock) \
+ if(clock->priv->wait_jitter_revert) \
+ clock->priv->wait_jitter_revert(clock, clock->priv->revert_user_data);
+
#define GST_SYSTEM_CLOCK_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_SYSTEM_CLOCK, \
GstSystemClockPrivate))
clock->priv->clock_type = DEFAULT_CLOCK_TYPE;
clock->priv->timer = gst_poll_new_timer ();
+ gst_system_clock_wait_adjust(clock, NULL, NULL);
+ gst_system_clock_wait_revert(clock, NULL, NULL);
+
#ifdef G_OS_WIN32
QueryPerformanceFrequency (&clock->priv->frequency);
/* can be 0 if the hardware does not have hardware support */
GstClockTime entryt, now;
GstClockTimeDiff diff;
GstClockReturn status;
+ gboolean wait_twice = TRUE;
if (G_UNLIKELY (GET_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED))
return GST_CLOCK_UNSCHEDULED;
/* need to call the overridden method because we want to sync against the time
* of the clock, whatever the subclass uses as a clock. */
+
+ GST_SYSTEM_CLOCK_WAIT_ADJUST(sysclock);
now = gst_clock_get_time (clock);
+ GST_SYSTEM_CLOCK_WAIT_REVERT(sysclock);
/* get the time of the entry */
entryt = GST_CLOCK_ENTRY_TIME (entry);
/* reschedule if gst_poll_wait returned early or we have to reschedule after
* an unlock*/
- now = gst_clock_get_time (clock);
- diff = GST_CLOCK_DIFF (now, entryt);
+ if(wait_twice) {
+ now = gst_clock_get_time (clock);
+ diff = GST_CLOCK_DIFF (now, entryt);
+ } else
+ diff = 0;
if (diff <= 0) {
/* timeout, this is fine, we can report success now */
}
GST_OBJECT_UNLOCK (clock);
}
+
+void
+gst_system_clock_wait_adjust(GstClock *clock,
+ wait_jitter_adjust_func wait_jitter_adjust, gpointer user_data)
+{
+ GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST(clock);
+
+ GST_OBJECT_LOCK(sysclock);
+ sysclock->priv->wait_jitter_adjust = wait_jitter_adjust;
+ sysclock->priv->adjust_user_data = user_data;
+ GST_OBJECT_UNLOCK(sysclock);
+}
+
+void
+gst_system_clock_wait_revert(GstClock *clock,
+ wait_jitter_adjust_func wait_jitter_revert, gpointer user_data)
+{
+ GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST(clock);
+
+ GST_OBJECT_LOCK(sysclock);
+ sysclock->priv->wait_jitter_revert = wait_jitter_revert;
+ sysclock->priv->revert_user_data = user_data;
+ GST_OBJECT_UNLOCK(sysclock);
+}
gpointer _gst_reserved[GST_PADDING];
};
-GType gst_system_clock_get_type (void);
+GType gst_system_clock_get_type (void);
-GstClock* gst_system_clock_obtain (void);
+GstClock* gst_system_clock_obtain (void);
+
+
+typedef void (*wait_jitter_adjust_func)(GstClock *clock, gpointer user_data);
+
+void gst_system_clock_wait_adjust(GstClock *clock,
+ wait_jitter_adjust_func wait_jitter_adjust, gpointer user_data);
+
+void gst_system_clock_wait_revert(GstClock *clock,
+ wait_jitter_adjust_func wait_jitter_revert, gpointer user_data);
G_END_DECLS
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+ <assign>
+ <filesystem path="/usr/bin/*" label="_" exec_label="none" />
+ </assign>
+</manifest>
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+ <assign>
+ <filesystem path="/usr/bin/*" label="_" exec_label="none" />
+ <filesystem path="/usr/libexec/gstreamer-0.10/gst-plugin-scanner" label="_" exec_label="none" />
+ </assign>
+</manifest>
#define GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC (1 << 0)
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+#define MIN_FRAMES_TO_POST_BITRATE 1
+#else
#define MIN_FRAMES_TO_POST_BITRATE 10
+#endif
+
#define TARGET_DIFFERENCE (20 * GST_SECOND)
GST_DEBUG_CATEGORY_STATIC (gst_base_parse_debug);
gboolean detecting;
GList *detect_buffers;
guint detect_buffers_size;
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ GstActivateMode expected_pad_mode; /* to get pad mode early */
+ gboolean first_frame; /* check first frame in base parser */
+ gint64 remove_from_total; /* remove zero padding */
+ gboolean accurate_index_seek;
+#endif
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ /* added for ALP mode (using 32KB Gstbuffer) */
+ guint32 alp_mp3_mode;
+
+ guint32 alp_seek_on;
+ /* ALP - for frame number */
+ guint32 alp_frame_1st;
+ guint32 alp_frame_count;
+ guint32 alp_frame_in_buffer;
+ guint32 alp_buffer_count;
+ guint32 alp_frame_avgbitrate;
+ /* ALP - for duration */
+ guint64 alp_duration_frame;
+ guint64 alp_duration_buffer;
+ guint64 alp_duration_buf_total;
+ guint64 alp_estimated_duration;
+ /* ALP - for position and byte count */
+ guint32 alp_size_frame_total;
+ guint32 alp_size_buf_one;
+ guint64 alp_size_buf_total;
+ guint32 alp_size_frame_1st;
+#endif
+#ifdef GST_EXT_BASEPARSE_ENABLE_WFD
+ /* added for wi-fi display mode */
+ gboolean wfd_mode;
+#endif
};
typedef struct _GstBaseParseSeek
parse->priv->adapter = gst_adapter_new ();
parse->priv->pad_mode = GST_ACTIVATE_NONE;
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ parse->priv->expected_pad_mode = GST_ACTIVATE_NONE;
+#endif
+
+#ifdef GST_EXT_BASEPARSE_ENABLE_WFD
+ parse->priv->wfd_mode = FALSE;
+#endif
#if !GLIB_CHECK_VERSION (2, 31, 0)
g_static_mutex_init (&parse->priv->index_lock);
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
parse->priv->last_offset = 0;
+#ifdef GST_EXT_BASEPARSER_MODIFICATION /* to do not calculate zero padding or something */
+ parse->priv->first_frame = TRUE;
+ parse->priv->remove_from_total = 0;
+ parse->priv->accurate_index_seek = TRUE;
+#endif
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ parse->priv->alp_mp3_mode = 0;
+ parse->priv->alp_seek_on = 0;
+
+ parse->priv->alp_frame_1st = 0;
+ parse->priv->alp_frame_count = 0;
+ parse->priv->alp_frame_in_buffer = 0;
+ parse->priv->alp_buffer_count = 0;
+
+ parse->priv->alp_duration_frame = 0;
+ parse->priv->alp_duration_buffer = 0;
+ parse->priv->alp_duration_buf_total = 0;
+
+ parse->priv->alp_size_frame_total = 0;
+ parse->priv->alp_size_buf_one = 0;
+ parse->priv->alp_size_buf_total = 0;
+ parse->priv->alp_size_frame_1st = 0;
+#endif
if (parse->priv->pending_segment) {
gst_event_unref (parse->priv->pending_segment);
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
parse->priv->frame._private_flags |=
GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC;
+#ifdef GST_EXT_BASEPARSE_ENABLE_WFD
+ if (parse->priv->wfd_mode) {
+ parse->priv->offset = 0;
+ parse->priv->sync_offset = 0;
+ }
+#endif
gst_base_parse_frame_free (&parse->priv->frame);
break;
if (!parse->priv->framecount)
return FALSE;
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_frame_1st) {
+ /* For duration, Estimation of spf using 1st frame */
+ duration = parse->priv->alp_duration_frame / GST_USECOND;
+ bytes = parse->priv->alp_size_frame_1st;
+ GST_DEBUG_OBJECT (parse, "bytes (%" G_GINT64_FORMAT ") frame_duration (%" G_GINT64_FORMAT ")", bytes, duration);
+ } else {
+ duration = parse->priv->acc_duration / GST_USECOND;
+ bytes = parse->priv->bytecount;
+ }
+#else
+ duration = parse->priv->acc_duration / GST_USECOND;
+ bytes = parse->priv->bytecount;
+#endif
+#else
duration = parse->priv->acc_duration / GST_MSECOND;
bytes = parse->priv->bytecount;
+#endif
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ GST_DEBUG_OBJECT (parse, "duration (%" G_GINT64_FORMAT ") <-- acc_duration (%" G_GINT64_FORMAT ")", duration, parse->priv->acc_duration);
+ GST_DEBUG_OBJECT (parse, "bytecount (%" G_GINT64_FORMAT ") framecount (%" G_GINT64_FORMAT ")", bytes, parse->priv->framecount);
+#endif
if (G_UNLIKELY (!duration || !bytes))
return FALSE;
if (dest_format == GST_FORMAT_TIME) {
/* BYTES -> TIME conversion */
GST_DEBUG_OBJECT (parse, "converting bytes -> time");
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ src_value = src_value - parse->priv->remove_from_total;
+#endif
*dest_value = gst_util_uint64_scale (src_value, duration, bytes);
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ *dest_value /= GST_USECOND;
+#endif
*dest_value *= GST_MSECOND;
GST_DEBUG_OBJECT (parse, "conversion result: %" G_GINT64_FORMAT " ms",
*dest_value / GST_MSECOND);
} else if (src_format == GST_FORMAT_TIME) {
if (dest_format == GST_FORMAT_BYTES) {
GST_DEBUG_OBJECT (parse, "converting time -> bytes");
- *dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes,
- duration);
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ *dest_value = gst_util_uint64_scale (src_value / GST_USECOND, bytes, duration);
+#else
+ *dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes, duration);
+#endif
GST_DEBUG_OBJECT (parse,
"time %" G_GINT64_FORMAT " ms in bytes = %" G_GINT64_FORMAT,
src_value / GST_MSECOND, *dest_value);
gst_message_new_duration (GST_OBJECT (parse),
GST_FORMAT_TIME, dest_value));
parse->priv->estimated_drift = 0;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ parse->priv->alp_estimated_duration = dest_value;
+ GST_INFO_OBJECT (parse, "[message] dest_value(%" GST_TIME_FORMAT") estimated duration to (%" G_GUINT64_FORMAT")",
+ GST_TIME_ARGS (dest_value), (parse->priv->estimated_duration));
+ }
+#endif
}
parse->priv->estimated_duration = dest_value;
GST_LOG_OBJECT (parse,
if (taglist == NULL)
taglist = gst_tag_list_new ();
- parse->priv->posted_avg_bitrate = parse->priv->avg_bitrate;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_frame_1st) {
+ if (parse->priv->bitrate) {
+ parse->priv->avg_bitrate = parse->priv->bitrate;
+ } else {
+ parse->priv->posted_avg_bitrate = parse->priv->alp_frame_avgbitrate;
+ parse->priv->avg_bitrate = parse->priv->alp_frame_avgbitrate;
+ }
+ } else {
+ parse->priv->posted_avg_bitrate = parse->priv->avg_bitrate;
+ }
+#else
+ parse->priv->posted_avg_bitrate = parse->priv->avg_bitrate;
+#endif
gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE,
parse->priv->avg_bitrate, NULL);
}
}
/* some one-time start-up */
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ if (parse->priv->alp_frame_1st) { //[need again check] parse->priv->framecount =0
+ gst_base_parse_check_seekability (parse);
+ gst_base_parse_check_upstream (parse);
+ }
+ } else {
+ if (G_UNLIKELY (!parse->priv->framecount)) {
+ gst_base_parse_check_seekability (parse);
+ gst_base_parse_check_upstream (parse);
+ }
+ }
+#else
if (G_UNLIKELY (!parse->priv->framecount)) {
gst_base_parse_check_seekability (parse);
gst_base_parse_check_upstream (parse);
}
+#endif
- GST_LOG_OBJECT (parse,
- "parsing frame at offset %" G_GUINT64_FORMAT
- " (%#" G_GINT64_MODIFIER "x) of size %d",
- GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET (buffer),
- GST_BUFFER_SIZE (buffer));
+ GST_LOG_OBJECT (parse, "parsing frame at offset %" G_GUINT64_FORMAT " (%#" G_GINT64_MODIFIER "x) of size %d",
+ GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET (buffer), GST_BUFFER_SIZE (buffer));
/* use default handler to provide initial (upstream) metadata */
gst_base_parse_parse_frame (parse, frame);
/* subclass must play nice */
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ if (parse->priv->first_frame) {
+ parse->priv->remove_from_total = GST_BUFFER_OFFSET (buffer);
+ GST_DEBUG_OBJECT (parse, "first frame has offset %" G_GINT64_FORMAT ". remove from total", parse->priv->remove_from_total);
+ parse->priv->first_frame = FALSE;
+ }
+#endif
+
/* check if subclass/format can provide ts.
* If so, that allows and enables extra seek and duration determining options */
if (G_UNLIKELY (parse->priv->first_frame_offset < 0 && ret == GST_FLOW_OK)) {
/* again use default handler to add missing metadata;
* we may have new information on frame properties */
gst_base_parse_parse_frame (parse, frame);
- if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
- GST_BUFFER_DURATION_IS_VALID (buffer)) {
- parse->priv->next_ts =
- GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ if (parse->priv->alp_mp3_mode) {
+ GST_INFO_OBJECT (parse, "framecount(%" G_GINT64_FORMAT "): next_ts(%" GST_TIME_FORMAT ") frame_duration(%" GST_TIME_FORMAT ")",
+ parse->priv->framecount, GST_TIME_ARGS(parse->priv->next_ts), GST_TIME_ARGS(parse->priv->frame_duration));
+ }
+#endif
+
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && GST_BUFFER_DURATION_IS_VALID (buffer)) {
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ /*push_frame --> move to here for SEEK test */
+ GST_BUFFER_TIMESTAMP (buffer) = parse->priv->alp_duration_buf_total;
+ GST_BUFFER_DURATION (buffer) = parse->priv->alp_duration_buffer;
+ }
+#endif
+ parse->priv->next_ts = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
+
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ if (parse->priv->alp_mp3_mode) {
+ GST_INFO_OBJECT (parse, "Update : next_ts(%" GST_TIME_FORMAT ") = timestamp(%" GST_TIME_FORMAT ") + duration(%" GST_TIME_FORMAT ")",
+ GST_TIME_ARGS(parse->priv->next_ts), GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS( GST_BUFFER_DURATION (buffer)));
+ }
+#endif
+
} else {
/* we lost track, do not produce bogus time next time around
* (probably means parser subclass has given up on parsing as well) */
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
}
- if (parse->priv->upstream_seekable && parse->priv->exact_position &&
- GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
- gst_base_parse_add_index_entry (parse, offset,
- GST_BUFFER_TIMESTAMP (buffer),
- !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ /* for NEXT Play */
+ if (parse->priv->alp_seek_on) {
+ offset = parse->priv->alp_size_buf_total;
+ parse->priv->alp_seek_on = 0;
+ }
+ if (parse->priv->upstream_seekable && parse->priv->exact_position && GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
+ gst_base_parse_add_index_entry (parse, offset, parse->priv->alp_duration_buf_total,
+ !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
+ }
+ } else {
+ if (parse->priv->upstream_seekable && parse->priv->exact_position && GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
+ gst_base_parse_add_index_entry (parse, offset, GST_BUFFER_TIMESTAMP (buffer),
+ !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
+ }
+ }
+#else
+ if (parse->priv->upstream_seekable && parse->priv->exact_position && GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
+ gst_base_parse_add_index_entry (parse, offset, GST_BUFFER_TIMESTAMP (buffer),
+ !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
+ }
+#endif
/* First buffers are dropped, this means that the subclass needs more
* frames to decide on the format and queues them internally */
}
}
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ if (parse->priv->alp_mp3_mode) {
+ GST_INFO_OBJECT (parse, "-----------------------------");
+ GST_INFO_OBJECT (parse, "[ALP] alp_size_buf_one(%d) alp_size_buf_total(%" G_GUINT64_FORMAT ")",parse->priv->alp_size_buf_one, parse->priv->alp_size_buf_total);
+ GST_INFO_OBJECT (parse, "[ALP] alp_duration_buf_total(%" GST_TIME_FORMAT ")", GST_TIME_ARGS(parse->priv->alp_duration_buf_total));
+ GST_INFO_OBJECT (parse, "[GBUF] size(%d) offset(%" G_GUINT64_FORMAT ")",GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer));
+ GST_INFO_OBJECT (parse, "[GBUF] timestamp(%" GST_TIME_FORMAT ") duration(%" GST_TIME_FORMAT ")",
+ GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION (buffer)));
+ GST_INFO_OBJECT (parse, "-----------------------------");
+ }
+#endif
+
return gst_base_parse_push_frame (parse, frame);
}
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
/* update stats */
- parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
- if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
- parse->priv->framecount++;
- if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
- parse->priv->acc_duration += GST_BUFFER_DURATION (buffer);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
+ } else {
+ parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
+ if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
+ parse->priv->framecount++;
+ if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
+ parse->priv->acc_duration += GST_BUFFER_DURATION (buffer);
+ }
+ }
+ }
+#else
+ parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
+ if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
+ parse->priv->framecount++;
+ if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
+ parse->priv->acc_duration += GST_BUFFER_DURATION (buffer);
+ }
}
+#endif
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ if (parse->priv->alp_mp3_mode) {
+ GST_INFO_OBJECT (parse, "frame(%"G_GUINT64_FORMAT") bytecount(%"G_GUINT64_FORMAT") acc_duration(%"GST_TIME_FORMAT")",
+ parse->priv->framecount, parse->priv->bytecount, GST_TIME_ARGS(parse->priv->acc_duration));
}
+#endif
+
/* 0 means disabled */
- if (parse->priv->update_interval < 0)
- parse->priv->update_interval = 50;
- else if (parse->priv->update_interval > 0 &&
- ((parse->priv->framecount-1) % parse->priv->update_interval) == 0)
- gst_base_parse_update_duration (parse);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ if (parse->priv->update_interval < 0)
+ parse->priv->update_interval = 50;
+ else if (parse->priv->update_interval > 0 && parse->priv->framecount > 0)
+ gst_base_parse_update_duration (parse);
+ } else {
+ if (parse->priv->update_interval < 0)
+ parse->priv->update_interval = 50;
+ else if (parse->priv->update_interval > 0 && ((parse->priv->framecount-1) % parse->priv->update_interval) == 0)
+ gst_base_parse_update_duration (parse);
+ }
+#else
+ if (parse->priv->update_interval < 0)
+ parse->priv->update_interval = 50;
+ else if (parse->priv->update_interval > 0 && ((parse->priv->framecount-1) % parse->priv->update_interval) == 0)
+ gst_base_parse_update_duration (parse);
+#endif
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
last_start = last_stop = GST_BUFFER_TIMESTAMP (buffer);
* (following newsegment) */
gst_base_parse_update_bitrates (parse, frame);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode)
+ parse->priv->alp_frame_1st = 0;
+#endif
+
if (G_UNLIKELY (parse->priv->pending_events)) {
GList *l;
parse->priv->detect_buffers = NULL;
parse->priv->detect_buffers_size = 0;
} else {
- parse->priv->detect_buffers =
- g_list_append (parse->priv->detect_buffers, buffer);
- parse->priv->detect_buffers_size += GST_BUFFER_SIZE (buffer);
+ if(G_LIKELY (buffer)) {
+ parse->priv->detect_buffers =
+ g_list_append (parse->priv->detect_buffers, buffer);
+ parse->priv->detect_buffers_size += GST_BUFFER_SIZE (buffer);
+ }
return GST_FLOW_OK;
}
} else {
* fragment coming later, hopefully subclass skips efficiently ... */
timestamp = gst_adapter_prev_timestamp (parse->priv->adapter, NULL);
outbuf = gst_adapter_take_buffer (parse->priv->adapter, skip);
- outbuf = gst_buffer_make_metadata_writable (outbuf);
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- parse->priv->buffers_pending =
- g_slist_prepend (parse->priv->buffers_pending, outbuf);
+ if(G_LIKELY(outbuf)){
+ outbuf = gst_buffer_make_metadata_writable (outbuf);
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+ parse->priv->buffers_pending =
+ g_slist_prepend (parse->priv->buffers_pending, outbuf);
+ }
outbuf = NULL;
} else {
gst_adapter_flush (parse->priv->adapter, skip);
/* FIXME: Would it be more efficient to make a subbuffer instead? */
outbuf = gst_adapter_take_buffer (parse->priv->adapter, fsize);
+ if(G_UNLIKELY(!outbuf))
+ goto adapter_underflow;
outbuf = gst_buffer_make_metadata_writable (outbuf);
/* Subclass may want to know the data offset */
old_min_size, min_size));
return GST_FLOW_ERROR;
}
+adapter_underflow:
+ {
+ GST_ERROR_OBJECT (parse, "Failed to adapter take buffer adapter->size:%d, fsize:%d.",
+ parse->priv->adapter->size,fsize);
+ return GST_FLOW_ERROR;
+ }
}
/* pull @size bytes at current offset,
}
/* refill the cache */
- ret =
- gst_pad_pull_range (parse->sinkpad, parse->priv->offset, MAX (size,
- 64 * 1024), &parse->priv->cache);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode)
+ ret = gst_pad_pull_range (parse->sinkpad, parse->priv->offset, MAX (size, 32 * 1024), &parse->priv->cache);
+ else
+ ret = gst_pad_pull_range (parse->sinkpad, parse->priv->offset, MAX (size, 64 * 1024), &parse->priv->cache);
+#else
+ ret = gst_pad_pull_range (parse->sinkpad, parse->priv->offset, MAX (size, 64 * 1024), &parse->priv->cache);
+#endif
+
if (ret != GST_FLOW_OK) {
parse->priv->cache = NULL;
return ret;
* maybe it does not need this much, but in the latter case, we know we are
* in pull mode here and might as well try to read and supply more anyway
* (so does the buffer caching mechanism) */
- fsize = 64 * 1024;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ fsize = 32 * 1024;
+ } else {
+ fsize = 64 * 1024;
+ }
+#else
+ fsize = 64 * 1024;
+#endif
while (TRUE) {
gboolean res;
old_min_size = min_size;
ret = gst_base_parse_pull_range (parse, min_size, &buffer);
+
if (ret != GST_FLOW_OK)
goto done;
GST_ERROR_OBJECT (parse, "Failed to detect format but draining");
return GST_FLOW_ERROR;
} else {
- fsize += 64 * 1024;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ fsize += 32 * 1024;
+ } else {
+ fsize += 64 * 1024;
+ }
+#else
+ fsize += 64 * 1024;
+#endif
gst_buffer_unref (buffer);
continue;
}
skip = -1;
gst_base_parse_frame_update (parse, frame, buffer);
res = klass->check_valid_frame (parse, frame, &fsize, &skip);
+
gst_buffer_replace (&frame->buffer, NULL);
if (res) {
parse->priv->drain = FALSE;
parse->priv->discont = TRUE;
/* something changed at least; nullify loop check */
if (fsize == G_MAXUINT)
- fsize = old_min_size + 64 * 1024;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ fsize = old_min_size + 32 * 1024;
+ } else {
+ fsize = old_min_size + 64 * 1024;
+ }
+#else
+ fsize = old_min_size + 64 * 1024;
+#endif
old_min_size = 0;
}
/* skip == 0 should imply subclass set min_size to need more data;
}
parse->priv->offset += fsize;
-
frame->buffer = outbuf;
+#ifdef GST_BASEPARSE_ALP_EXYNOS_LOG
+ if (parse->priv->alp_mp3_mode) {
+ GST_INFO_OBJECT (parse, "-----------------------------");
+ GST_INFO_OBJECT (parse, "[ALP] offset(%" G_GUINT64_FORMAT ") += fsize(%d)",parse->priv->offset, fsize);
+ GST_INFO_OBJECT (parse, "[ALP] alp_mp3_mode(%d) alp_frame_1st(%d)",parse->priv->alp_mp3_mode, parse->priv->alp_frame_1st);
+ GST_INFO_OBJECT (parse, "[ALP] alp_frame_in_buffer(%d) alp_duration_frame(%" G_GUINT64_FORMAT ")",parse->priv->alp_frame_in_buffer, parse->priv->alp_duration_frame);
+ GST_INFO_OBJECT (parse, "[ALP] alp_frame_count(%d) alp_duration_frame(%" GST_TIME_FORMAT ")",parse->priv->alp_frame_count, GST_TIME_ARGS(parse->priv->alp_duration_frame));
+ GST_INFO_OBJECT (parse, "[ALP] alp_buffer_count(%d) alp_duration_buffer(%" GST_TIME_FORMAT ")",parse->priv->alp_buffer_count, GST_TIME_ARGS(parse->priv->alp_duration_buffer));
+ GST_INFO_OBJECT (parse, "[ALP] alp_size_buf_one(%d) alp_size_buf_total(%" G_GUINT64_FORMAT ")",parse->priv->alp_size_buf_one, parse->priv->alp_size_buf_total);
+ GST_INFO_OBJECT (parse, "[ALP] alp_duration_buf_total(%" GST_TIME_FORMAT ")",GST_TIME_ARGS( parse->priv->alp_duration_buf_total));
+ GST_INFO_OBJECT (parse, "-----------------------------");
+ GST_INFO_OBJECT (parse, "[OBUF] szie(%d) offset(%" G_GUINT64_FORMAT ")",GST_BUFFER_SIZE (outbuf), GST_BUFFER_OFFSET (outbuf));
+ GST_INFO_OBJECT (parse, "-----------------------------");
+ }
+#endif
+
done:
return ret;
parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (parse, "sink activate push %d", active);
-
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ /* to know early what is the mode */
+ parse->priv->expected_pad_mode = active ? GST_ACTIVATE_PUSH : GST_ACTIVATE_NONE;
+#endif
result = gst_base_parse_activate (parse, active);
if (result)
parse = GST_BASE_PARSE (gst_pad_get_parent (sinkpad));
GST_DEBUG_OBJECT (parse, "activate pull %d", active);
-
+#ifdef GST_EXT_BASEPARSER_MODIFICATION
+ /* to know early what is the mode */
+ parse->priv->expected_pad_mode = active ? GST_ACTIVATE_PULL : GST_ACTIVATE_NONE;
+#endif
result = gst_base_parse_activate (parse, active);
if (result) {
res = gst_base_parse_convert (parse, parse->priv->duration_fmt,
parse->priv->duration, format, (gint64 *) duration);
} else if (format == GST_FORMAT_TIME && parse->priv->estimated_duration != -1) {
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ GST_LOG_OBJECT (parse, "using ALP estimated duration");
+ *duration = parse->priv->alp_estimated_duration;
+ } else {
+ GST_LOG_OBJECT (parse, "using estimated duration");
+ *duration = parse->priv->estimated_duration;
+ }
+#else
GST_LOG_OBJECT (parse, "using estimated duration");
*duration = parse->priv->estimated_duration;
+#endif
res = TRUE;
}
* and the requested segment is maintained exactly, not adjusted any way */
accurate = flags & GST_SEEK_FLAG_ACCURATE;
+#ifndef GST_EXT_BASEPARSER_MODIFICATION
/* maybe we can be accurate for (almost) free */
gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE, &start_ts);
if (seeksegment.last_stop <= start_ts + TARGET_DIFFERENCE) {
GST_DEBUG_OBJECT (parse, "accurate seek possible");
accurate = TRUE;
}
+#else
+ if ( parse->priv->accurate_index_seek) {
+ /* maybe we can be accurate for (almost) free */
+ gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE, &start_ts);
+ if (seeksegment.last_stop <= start_ts + TARGET_DIFFERENCE) {
+ GST_DEBUG_OBJECT (parse, "accurate seek possible");
+ accurate = TRUE;
+ }
+ } else {
+ GST_DEBUG_OBJECT (parse, "accurate seek FALSE");
+ accurate = FALSE;
+ }
+#endif
+
if (accurate) {
GstClockTime startpos = seeksegment.last_stop;
else
startpos -= parse->priv->lead_in_ts;
seekpos = gst_base_parse_find_offset (parse, startpos, TRUE, &start_ts);
- seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
- NULL);
+ seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE, NULL);
} else {
start_ts = seeksegment.last_stop;
dstformat = GST_FORMAT_BYTES;
"seek stop %" G_GINT64_FORMAT " in bytes: %" G_GINT64_FORMAT,
seeksegment.stop, seekstop);
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+ if (parse->priv->alp_mp3_mode) {
+ /* seek event on, so update new information */
+ parse->priv->alp_seek_on = 1;
+ parse->priv->alp_size_buf_total = seekpos;
+ parse->priv->alp_duration_buf_total = start_ts;
+ GST_INFO_OBJECT (parse, "[SEEK] seek start alp_duration_buf_total (%" GST_TIME_FORMAT ") in alp_size_buf_total: %" G_GINT64_FORMAT, GST_TIME_ARGS(start_ts), seekpos);
+ }
+#endif
+
if (parse->priv->pad_mode == GST_ACTIVATE_PULL) {
gint64 last_stop;
seek event (in bytes) to upstream. Segment / flush handling happens
in corresponding src event handlers */
GST_DEBUG_OBJECT (parse, "seek in PUSH mode");
- if (seekstop >= 0 && seekpos <= seekpos)
+ if (seekstop >= 0)
seekstop = seekpos;
new_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
GST_SEEK_TYPE_SET, seekpos, stop_type, seekstop);
return result;
}
+
+#ifdef GST_EXT_BASEPARSER_MODIFICATION /* get baseparse private param. ex. for amr index table, aac duration */
+void
+gst_base_parse_get_upstream_size (GstBaseParse * parse, gint64 * upstream_size)
+{
+ GST_BASE_PARSE_INDEX_LOCK (parse);
+ *upstream_size = parse->priv->upstream_size;
+ GST_INFO_OBJECT (parse, "get upstream_size param for child parser : (%"G_GUINT64_FORMAT")", parse->priv->upstream_size);
+ GST_BASE_PARSE_INDEX_UNLOCK (parse);
+}
+
+void
+gst_base_parse_get_index_last_offset (GstBaseParse * parse, gint64 * index_last_offset)
+{
+ GST_BASE_PARSE_INDEX_LOCK (parse);
+ *index_last_offset = parse->priv->index_last_offset;
+ GST_INFO_OBJECT (parse, "get index_last_offset param for child parser : (%"G_GUINT64_FORMAT")", parse->priv->index_last_offset);
+ GST_BASE_PARSE_INDEX_UNLOCK (parse);
+}
+
+void
+gst_base_parse_get_index_last_ts (GstBaseParse * parse, GstClockTime * index_last_ts)
+{
+ GST_BASE_PARSE_INDEX_LOCK (parse);
+ *index_last_ts = parse->priv->index_last_ts;
+ GST_INFO_OBJECT (parse, "get index_last_ts param for child parser : (%"GST_TIME_FORMAT")", GST_TIME_ARGS(parse->priv->index_last_ts));
+ GST_BASE_PARSE_INDEX_UNLOCK (parse);
+}
+
+void
+gst_base_parse_get_pad_mode (GstBaseParse * parse, GstActivateMode * pad_mode)
+{
+ GST_BASE_PARSE_INDEX_LOCK (parse);
+ *pad_mode = parse->priv->expected_pad_mode;
+ GST_INFO_OBJECT (parse, "get pad_mode param for child parse: mode num (%d)", parse->priv->expected_pad_mode);
+ GST_BASE_PARSE_INDEX_UNLOCK (parse);
+}
+
+void
+gst_base_parse_set_seek_mode (GstBaseParse * parse, gboolean seek_mode)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->accurate_index_seek= seek_mode;
+ if (seek_mode)
+ GST_INFO_OBJECT (parse, "accurate seek mode ON");
+ else
+ GST_INFO_OBJECT (parse, "accurate seek mode OFF - for large file (over 50MByte)");
+}
+#endif
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+void
+gst_base_parse_get_initial_frame (GstBaseParse * parse, gboolean *initialized)
+{
+ GST_BASE_PARSE_INDEX_LOCK (parse);
+ if(parse->priv->framecount == 0) {
+ *initialized = FALSE;
+ GST_INFO_OBJECT (parse, "get only initial frame indicator - framecount is always 0 (%d)", parse->priv->framecount);
+ } else {
+ *initialized = TRUE;
+ }
+ GST_BASE_PARSE_INDEX_UNLOCK (parse);
+}
+
+void
+gst_base_parse_set_alp_mode (GstBaseParse * parse, gboolean alp_mde)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->alp_mp3_mode= alp_mde;
+ if (alp_mde) {
+ GST_INFO_OBJECT (parse, "=============================");
+ GST_INFO_OBJECT (parse, "ALP MP3 SET alp_mp3_mode [%d]", parse->priv->alp_mp3_mode);
+ GST_INFO_OBJECT (parse, "=============================");
+ }
+}
+
+void
+gst_base_parse_set_1st_frame (GstBaseParse * parse, guint frame_1st, gint bpf)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->alp_frame_1st = frame_1st;
+ parse->priv->alp_size_frame_1st = bpf;
+ GST_INFO_OBJECT (parse, "SET alp_frame_1st flag (%d), bpf_1st (%d)", parse->priv->alp_frame_1st, parse->priv->alp_size_frame_1st);
+}
+
+void
+gst_base_parse_set_frame_info (GstBaseParse * parse, guint32 count, gint64 duration, guint32 avgbitrate)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->alp_frame_in_buffer = count;
+ parse->priv->alp_duration_frame = duration;
+ parse->priv->alp_frame_avgbitrate = avgbitrate;
+
+ parse->priv->alp_frame_count += count;
+ parse->priv->framecount = parse->priv->alp_frame_count;
+ GST_INFO_OBJECT (parse, "SET alp_frame_count(%d) VS parse->framecount(%d) avgbitrate(%d)", parse->priv->alp_frame_count, parse->priv->framecount, avgbitrate);
+ GST_INFO_OBJECT (parse, " parse->framecount(%"G_GUINT64_FORMAT") parse->offset(%"G_GUINT64_FORMAT")", parse->priv->framecount, parse->priv->offset);
+}
+
+void
+gst_base_parse_set_buffer_info (GstBaseParse * parse, guint32 count, gint64 duration)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->alp_buffer_count = count;
+ parse->priv->alp_duration_buffer = duration;
+ parse->priv->acc_duration += duration;
+
+ if (parse->priv->offset == 0) {
+ parse->priv->alp_duration_buf_total = 0; //reset for continue next play
+ } else {
+ if(parse->priv->alp_seek_on) {
+ parse->priv->alp_seek_on = 1; // don't need update of timestamp!!!!!!
+ } else {
+ parse->priv->alp_duration_buf_total += duration;
+ }
+ }
+ GST_INFO_OBJECT (parse, "SET alp_buffer_count(%d) alp_duration_buf_total(%"GST_TIME_FORMAT") ", parse->priv->alp_buffer_count, GST_TIME_ARGS(parse->priv->alp_duration_buf_total));
+}
+
+void
+gst_base_parse_set_buffer_size (GstBaseParse * parse, guint32 byte_offset)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->alp_size_buf_one = byte_offset;
+ if (parse->priv->offset == 0) {
+ parse->priv->alp_size_buf_total = 0; //reset for continue next play -if I don't used this, then don't operate 'continue play'
+ }
+ else {
+ if(parse->priv->alp_seek_on) {
+ parse->priv->alp_seek_on = 1; // don't need update of total buffer size !!!!!! --> need next module
+ } else {
+ parse->priv->alp_size_buf_total += byte_offset;
+ }
+ }
+ GST_INFO_OBJECT (parse, "SET alp_size_buf_one(%d) alp_size_buf_total(%"G_GUINT64_FORMAT")", parse->priv->alp_size_buf_one, parse->priv->alp_size_buf_total);
+}
+#endif
+
+#ifdef GST_EXT_BASEPARSE_ENABLE_WFD
+void
+gst_base_parse_set_wfd_mode (GstBaseParse * parse, gboolean wfd_mode)
+{
+ g_return_if_fail (parse != NULL);
+ parse->priv->wfd_mode = wfd_mode;
+ if (wfd_mode)
+ GST_INFO_OBJECT (parse, "WFD mode is enabled");
+}
+#endif
#define GST_IS_BASE_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASE_PARSE))
#define GST_BASE_PARSE_CAST(obj) ((GstBaseParse *)(obj))
+#define GST_BASEPARSE_ALP_EXYNOS_MP3
+//#define GST_BASEPARSE_ALP_EXYNOS_LOG
+
/**
* GST_BASE_PARSE_SRC_PAD:
* @obj: base parse instance
gboolean key,
gboolean force);
+#ifdef GST_EXT_BASEPARSER_MODIFICATION /* get baseparse private param */
+void gst_base_parse_get_upstream_size (GstBaseParse * parse,
+ gint64 * upstream_size);
+
+void gst_base_parse_get_index_last_offset (GstBaseParse * parse,
+ gint64 * index_last_offset);
+
+void gst_base_parse_get_index_last_ts (GstBaseParse * parse,
+ GstClockTime * index_last_ts);
+
+void gst_base_parse_get_pad_mode (GstBaseParse * parse,
+ GstActivateMode * pad_mode);
+void gst_base_parse_set_seek_mode (GstBaseParse * parse,
+ gboolean seek_mode);
+#endif
+
+
+#ifdef GST_BASEPARSE_ALP_EXYNOS_MP3
+void gst_base_parse_get_initial_frame (GstBaseParse * parse, gboolean *initialized);
+void gst_base_parse_set_alp_mode (GstBaseParse * parse, gboolean alp_mde);
+void gst_base_parse_set_1st_frame (GstBaseParse * parse, guint frame_1st, gint bpf);
+void gst_base_parse_set_frame_info (GstBaseParse * parse, guint32 count, gint64 duration, guint32 avgbitrate);
+void gst_base_parse_set_buffer_info (GstBaseParse * parse, guint32 count, gint64 duration);
+void gst_base_parse_set_buffer_size (GstBaseParse * parse, guint32 byte_offset);
+#endif
+
G_END_DECLS
#endif /* __GST_BASE_PARSE_H__ */
#include "gstbasesink.h"
#include <gst/gstmarshal.h>
#include <gst/gst-i18n-lib.h>
+#include <gst/gstsystemclock.h>
GST_DEBUG_CATEGORY_STATIC (gst_base_sink_debug);
#define GST_CAT_DEFAULT gst_base_sink_debug
/* for throttling and QoS */
GstClockTime earliest_in_time;
GstClockTime throttle_time;
+
+#ifdef _VSP_SPEED_
+ /* parameters using by vsp */
+ gboolean vsp_enabled;
+ gdouble vsp_speed;
+ /* similar as segment.start */
+ gint64 vsp_position;
+ /* store orignal segment.stop */
+ gint64 vsp_stop;
+ gint64 vsp_last_position;
+ /* similiar as base_time */
+ gint64 vsp_last_rtime;
+ /* basesink act as parent of videosink */
+ gboolean vsp_video;
+#endif
+
+ /* clock calibration */
+
+ gboolean cc_enabled;
+ struct {
+ gboolean is_video_sink;
+ /* if it is prepared to do calibration */
+ gboolean do_clock_calibration;
+ GstClockTime last_expecting_render;
+ GstClockTime cur_expecting_render;
+ GstClockTime last_actually_render;
+ GstClockTime cur_actually_render;
+ /* the threshold determine whether to do cc */
+ GstClockTimeDiff cc_threshold;
+ /* the adjustment */
+ GstClockTimeDiff cc_time;
+ /* the accumulation of cc */
+ GstClockTimeDiff cc_accumulation;
+ /* cc_stat temporarily */
+ guint cc_stats[10];
+ }CC;
};
+/* Fake clock type to simulate audioclock */
+typedef GstClockTime (*GstFakeFunc) (GstClock *clock, gpointer user_data);
+typedef struct {
+ GstSystemClock clock;
+ GstFakeFunc fake_func;
+ gpointer fake_data;
+}GstFakeClock;
+
+typedef struct {
+ GstFakeFunc old_fake_func;
+ gpointer old_fake_data;
+ GstFakeFunc new_fake_func;
+ gpointer new_fake_data;
+}GstFakeData;
+
+
#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
/* generic running average, this has a neutral window size */
#define DEFAULT_ENABLE_LAST_BUFFER TRUE
#define DEFAULT_THROTTLE_TIME 0
+#ifdef _VSP_SPEED_
+#define DEFAULT_VSP_SPEED 1.0f
+#endif
+
+#define DEFAULT_CC_TIME (10 * GST_MSECOND)
+#define DEFAULT_CC_THRESHOLD (1 * GST_MSECOND)
+#define DEFAULT_ENABLE_CC TRUE
+
enum
{
PROP_0,
PROP_BLOCKSIZE,
PROP_RENDER_DELAY,
PROP_THROTTLE_TIME,
+ /* enable cc feature or not */
+ PROP_ENABLE_CC,
PROP_LAST
};
static GstFlowReturn gst_base_sink_preroll_object (GstBaseSink * basesink,
guint8 obj_type, GstMiniObject * obj);
+/* CC use */
+static void
+basesink_cc_initialize(GstBaseSink *basesink);
+static void
+basesink_cc_uninitialize(GstBaseSink *basesink);
+static void
+basesink_cc_is_video_sink(GstBaseSink *basesink, gboolean is_video_sink);
+static void
+basesink_cc_do_clock_calibration(GstBaseSink *basesink, gboolean do_or_not);
+static GstClockTime
+basesink_cc_fake_clock_func(GstClock *clock, gpointer user_data);
+static void
+basesink_cc_wait_jitter_adjust(GstClock *clock, gpointer user_data);
+static void
+basesink_cc_wait_jitter_revert(GstClock *clock, gpointer user_data);
+static GstClockReturn
+basesink_cc_wait_calibrated_clock (GstBaseSink *sink, GstClockTime time, GstClockTimeDiff *jitter);
+static GstClockReturn
+basesink_cc_clock_calibration_wait (GstBaseSink *basesink, GstClockID id, GstClockTimeDiff *jitter);
+
+
static void
gst_base_sink_class_init (GstBaseSinkClass * klass)
{
"The time to keep between rendered buffers (unused)", 0, G_MAXUINT64,
DEFAULT_THROTTLE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_ENABLE_CC,
+ g_param_spec_boolean ("enable-cc", "Enable Clock Calibration",
+ "Enable the cc property", DEFAULT_ENABLE_CC,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_sink_change_state);
gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_sink_send_event);
priv->cached_clock_id = NULL;
g_atomic_int_set (&priv->enable_last_buffer, DEFAULT_ENABLE_LAST_BUFFER);
priv->throttle_time = DEFAULT_THROTTLE_TIME;
+ priv->cc_enabled = DEFAULT_ENABLE_CC;
+
+#ifdef _VSP_SPEED_
+ /* vsp default */
+ priv->vsp_enabled = FALSE;
+ priv->vsp_speed = DEFAULT_VSP_SPEED;
+ priv->vsp_position = 0;
+ priv->vsp_stop = -1;
+ priv->vsp_last_position = 0;
+ priv->vsp_last_rtime = 0;
+ priv->vsp_video = FALSE;
+#endif
GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
}
return res;
}
+gboolean
+gst_base_sink_is_cc_enabled(GstBaseSink * sink)
+{
+ gboolean res;
+
+ g_return_val_if_fail (GST_IS_BASE_SINK (sink), FALSE);
+
+ res = g_atomic_int_get (&sink->priv->cc_enabled);
+ return res;
+}
+
+void
+gst_base_sink_set_cc_enabled (GstBaseSink * sink, gboolean enabled)
+{
+ g_return_if_fail (GST_IS_BASE_SINK (sink));
+
+ g_atomic_int_set (&sink->priv->cc_enabled, enabled);
+}
+
+
static void
gst_base_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
case PROP_THROTTLE_TIME:
gst_base_sink_set_throttle_time (sink, g_value_get_uint64 (value));
break;
+ case PROP_ENABLE_CC:
+ gst_base_sink_set_cc_enabled(sink, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_THROTTLE_TIME:
g_value_set_uint64 (value, gst_base_sink_get_throttle_time (sink));
break;
+ case PROP_ENABLE_CC:
+ g_value_set_boolean(value, gst_base_sink_is_cc_enabled (sink));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
* We protect with the OBJECT_LOCK so that we can use the values to
* safely answer a POSITION query. */
GST_OBJECT_LOCK (basesink);
+
+#ifdef _VSP_SPEED_
+ /* update segment according to video/audio */
+ if(basesink->priv->vsp_enabled) {
+
+ if(basesink->priv->vsp_video) {
+
+ rate = basesink->priv->vsp_speed;
+
+ } else {
+
+ basesink->priv->vsp_stop = stop;
+ if(stop != -1) {
+ stop = start + (stop - start) / basesink->priv->vsp_speed;
+ }
+ }
+ }
+#endif
+
gst_segment_set_newsegment_full (segment, update, rate, arate, format, start,
stop, time);
return time;
}
+static void
+basesink_cc_initialize(GstBaseSink *basesink)
+{
+ GstBaseSinkPrivate *priv;
+
+ GST_OBJECT_LOCK(basesink);
+
+#define SYSCLK_RESET(priv); \
+ priv = basesink->priv; \
+ priv->CC.is_video_sink = FALSE; \
+ priv->CC.do_clock_calibration = FALSE; \
+ priv->CC.last_expecting_render = 0; \
+ priv->CC.cur_expecting_render = 0; \
+ priv->CC.last_actually_render = 0; \
+ priv->CC.cur_actually_render = 0; \
+ priv->CC.cc_threshold = DEFAULT_CC_THRESHOLD; \
+ priv->CC.cc_time = DEFAULT_CC_TIME; \
+ priv->CC.cc_accumulation = 0; \
+ for(int i = 0; i < 10; ++i) priv->CC.cc_stats[i] = 0; \
+ priv->start = GST_CLOCK_TIME_NONE;
+
+ SYSCLK_RESET(priv);
+
+ GST_OBJECT_UNLOCK(basesink);
+}
+
+static void
+basesink_cc_uninitialize(GstBaseSink *basesink)
+{
+ GstBaseSinkPrivate *priv;
+ GST_OBJECT_LOCK(basesink);
+
+ SYSCLK_RESET(priv);
+
+ GST_OBJECT_UNLOCK(basesink);
+}
+
+static void
+basesink_cc_is_video_sink(GstBaseSink *basesink, gboolean is_video_sink)
+{
+ GST_OBJECT_LOCK(basesink);
+ basesink->priv->CC.is_video_sink = is_video_sink;
+ GST_OBJECT_UNLOCK(basesink);
+}
+
+static void
+basesink_cc_do_clock_calibration(GstBaseSink *basesink, gboolean do_or_not)
+{
+ GST_OBJECT_LOCK(basesink);
+ basesink->priv->CC.do_clock_calibration = do_or_not;
+ GST_OBJECT_UNLOCK(basesink);
+}
+
+static GstClockTime
+basesink_cc_fake_clock_func(GstClock *clock, gpointer user_data)
+{
+ GstClockTime result, a_result, s_result;
+ GstFakeData *p_fake_data;
+ GstBaseSink *basesink;
+ GstBaseSinkPrivate *priv;
+ GstClockTime expecting_actually_render;
+ GstClockTimeDiff jitter, expecting_jitter;
+
+ p_fake_data = (GstFakeData *)user_data;
+ basesink = (GstBaseSink *)p_fake_data->new_fake_data;
+ priv = basesink->priv;
+
+ a_result = p_fake_data->old_fake_func(clock,p_fake_data->old_fake_data);
+
+ /* check if need do CC */
+ if(!priv->CC.do_clock_calibration) {
+ result = a_result;
+ goto done;
+ }
+
+ expecting_actually_render = priv->CC.last_actually_render
+ + priv->CC.cur_expecting_render - priv->CC.last_expecting_render;
+ s_result = gst_util_get_timestamp();
+
+ /* we hope to wait the value of expecting_jitter */
+ expecting_jitter = expecting_actually_render - s_result;
+ /* while if a_result , we will wait the value of jitter */
+ jitter = priv->CC.cur_expecting_render - a_result;
+
+ if(expecting_actually_render <= s_result) {
+ result = priv->CC.cur_expecting_render;
+ GST_LOG("we are late , render ASAP");
+ goto done;
+ }
+
+ /* audioclock flushes , handle this to avoid discard frame */
+ /*
+ if(jitter < 0) {
+ result = priv->CC.cur_expecting_render - priv->CC.cc_time;
+ GST_LOG("audio clock flush");
+ goto done;
+ }
+ */
+
+ /* do real clock calibration using cc_time */
+ if(jitter - expecting_jitter < priv->CC.cc_time
+ && jitter - expecting_jitter > - priv->CC.cc_time) {
+
+ /* adjust jitter to expecting_jitter */
+ result = priv->CC.cur_expecting_render - expecting_jitter;
+ } else if(jitter - expecting_jitter > priv->CC.cc_time) {
+
+ result = a_result + priv->CC.cc_time;
+ } else
+ result = a_result - priv->CC.cc_time;
+
+ GST_LOG("jitter=%"GST_TIME_FORMAT",expecting_jitter=%"GST_TIME_FORMAT",new jitter=%"GST_TIME_FORMAT,
+ GST_TIME_ARGS(jitter),
+ GST_TIME_ARGS(expecting_jitter),
+ GST_TIME_ARGS(priv->CC.cur_expecting_render - result));
+done:
+ priv->CC.cc_accumulation += (result - a_result);
+ return result;
+}
+
+static void
+basesink_cc_wait_jitter_adjust(GstClock *clock, gpointer user_data)
+{
+ GstFakeClock *p_fake_clock;
+ GstFakeData *p_fake_data;
+ p_fake_clock = (GstFakeClock *)clock;
+ p_fake_data = (GstFakeData *)user_data;
+ p_fake_clock->fake_func = p_fake_data->new_fake_func;
+ p_fake_clock->fake_data = p_fake_data;
+}
+
+static void
+basesink_cc_wait_jitter_revert(GstClock *clock, gpointer user_data)
+{
+ GstFakeClock *p_fake_clock;
+ GstFakeData *p_fake_data;
+ p_fake_clock = (GstFakeClock *)clock;
+ p_fake_data = (GstFakeData *)user_data;
+ p_fake_clock->fake_func = p_fake_data->old_fake_func;
+ p_fake_clock->fake_data = p_fake_data->old_fake_data;
+
+ /* revert to default */
+ gst_system_clock_wait_adjust(clock, NULL, NULL);
+ gst_system_clock_wait_revert(clock, NULL, NULL);
+}
+
+
+static GstClockReturn
+basesink_cc_clock_calibration_wait (GstBaseSink *basesink, GstClockID id, GstClockTimeDiff *jitter)
+{
+ GstClock *clock;
+ /* local visible , global effective */
+ static GstFakeData fake_data = {0,};
+ GstFakeClock *p_fake_clock;
+ GstClockReturn result;
+
+ g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
+
+ clock = GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) id);
+
+ p_fake_clock = (GstFakeClock *)clock;
+
+ fake_data.old_fake_func = p_fake_clock->fake_func;
+ fake_data.old_fake_data = p_fake_clock->fake_data;
+ fake_data.new_fake_func = basesink_cc_fake_clock_func;
+ fake_data.new_fake_data = basesink;
+
+ gst_system_clock_wait_adjust(clock, basesink_cc_wait_jitter_adjust, &fake_data);
+ gst_system_clock_wait_revert(clock, basesink_cc_wait_jitter_revert, &fake_data);
+
+ return gst_clock_id_wait(id, jitter);
+}
+
/**
* gst_base_sink_wait_clock:
* @sink: the sink
gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
GstClockTimeDiff * jitter)
{
- GstClockReturn ret;
- GstClock *clock;
- GstClockTime base_time;
-
- if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time)))
- goto invalid_time;
-
- GST_OBJECT_LOCK (sink);
- if (G_UNLIKELY (!sink->sync))
- goto no_sync;
-
- if (G_UNLIKELY ((clock = GST_ELEMENT_CLOCK (sink)) == NULL))
- goto no_clock;
-
- base_time = GST_ELEMENT_CAST (sink)->base_time;
- GST_LOG_OBJECT (sink,
- "time %" GST_TIME_FORMAT ", base_time %" GST_TIME_FORMAT,
- GST_TIME_ARGS (time), GST_TIME_ARGS (base_time));
-
- /* add base_time to running_time to get the time against the clock */
- time += base_time;
-
- /* Re-use existing clockid if available */
- /* FIXME: Casting to GstClockEntry only works because the types
- * are the same */
- if (G_LIKELY (sink->priv->cached_clock_id != NULL
- && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
- cached_clock_id) == clock)) {
- if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
- time)) {
- gst_clock_id_unref (sink->priv->cached_clock_id);
- sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time);
- }
- } else {
- if (sink->priv->cached_clock_id != NULL)
- gst_clock_id_unref (sink->priv->cached_clock_id);
- sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time);
- }
- GST_OBJECT_UNLOCK (sink);
-
- /* A blocking wait is performed on the clock. We save the ClockID
- * so we can unlock the entry at any time. While we are blocking, we
- * release the PREROLL_LOCK so that other threads can interrupt the
- * entry. */
- sink->clock_id = sink->priv->cached_clock_id;
- /* release the preroll lock while waiting */
+#define GST_BASE_SINK_WAIT_CLOCK_BEGIN \
+ GstClockReturn ret; \
+ GstClock *clock; \
+ GstClockTime base_time; \
+ \
+ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) \
+ goto invalid_time; \
+ \
+ GST_OBJECT_LOCK (sink); \
+ if (G_UNLIKELY (!sink->sync)) \
+ goto no_sync; \
+ \
+ if (G_UNLIKELY ((clock = GST_ELEMENT_CLOCK (sink)) == NULL)) \
+ goto no_clock; \
+ \
+ base_time = GST_ELEMENT_CAST (sink)->base_time; \
+ GST_LOG_OBJECT (sink, \
+ "time %" GST_TIME_FORMAT ", base_time %" GST_TIME_FORMAT, \
+ GST_TIME_ARGS (time), GST_TIME_ARGS (base_time)); \
+ \
+ /* add base_time to running_time to get the time against the clock */ \
+ time += base_time; \
+ \
+ /* Re-use existing clockid if available */ \
+ /* FIXME: Casting to GstClockEntry only works because the types \
+ * are the same */ \
+ if (G_LIKELY (sink->priv->cached_clock_id != NULL \
+ && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv-> \
+ cached_clock_id) == clock)) { \
+ if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id, \
+ time)) { \
+ gst_clock_id_unref (sink->priv->cached_clock_id); \
+ sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time); \
+ } \
+ } else { \
+ if (sink->priv->cached_clock_id != NULL) \
+ gst_clock_id_unref (sink->priv->cached_clock_id); \
+ sink->priv->cached_clock_id = gst_clock_new_single_shot_id (clock, time); \
+ } \
+ GST_OBJECT_UNLOCK (sink); \
+ \
+ /* A blocking wait is performed on the clock. We save the ClockID \
+ * so we can unlock the entry at any time. While we are blocking, we \
+ * release the PREROLL_LOCK so that other threads can interrupt the \
+ * entry. */ \
+ sink->clock_id = sink->priv->cached_clock_id; \
+ /* release the preroll lock while waiting */ \
GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+ GST_BASE_SINK_WAIT_CLOCK_BEGIN
ret = gst_clock_id_wait (sink->priv->cached_clock_id, jitter);
- GST_PAD_PREROLL_LOCK (sink->sinkpad);
- sink->clock_id = NULL;
-
- return ret;
+#define GST_BASE_SINK_WAIT_CLOCK_END \
+ GST_PAD_PREROLL_LOCK (sink->sinkpad); \
+ sink->clock_id = NULL; \
+ \
+ return ret; \
+ \
+ /* no syncing needed */ \
+invalid_time: \
+ { \
+ GST_DEBUG_OBJECT (sink, "time not valid, no sync needed"); \
+ return GST_CLOCK_BADTIME; \
+ } \
+no_sync: \
+ { \
+ GST_DEBUG_OBJECT (sink, "sync disabled"); \
+ GST_OBJECT_UNLOCK (sink); \
+ return GST_CLOCK_BADTIME; \
+ } \
+no_clock: \
+ { \
+ GST_DEBUG_OBJECT (sink, "no clock, can't sync"); \
+ GST_OBJECT_UNLOCK (sink); \
+ return GST_CLOCK_BADTIME; \
+ }
+
+ GST_BASE_SINK_WAIT_CLOCK_END
+}
- /* no syncing needed */
-invalid_time:
- {
- GST_DEBUG_OBJECT (sink, "time not valid, no sync needed");
- return GST_CLOCK_BADTIME;
- }
-no_sync:
- {
- GST_DEBUG_OBJECT (sink, "sync disabled");
- GST_OBJECT_UNLOCK (sink);
- return GST_CLOCK_BADTIME;
- }
-no_clock:
- {
- GST_DEBUG_OBJECT (sink, "no clock, can't sync");
- GST_OBJECT_UNLOCK (sink);
- return GST_CLOCK_BADTIME;
- }
+GstClockReturn
+basesink_cc_wait_calibrated_clock (GstBaseSink *sink, GstClockTime time,
+ GstClockTimeDiff *jitter)
+{
+/* instance must be subclass of type . return TRUE on success
+no depends on GST_BASE_LIBS (no call GST_IS_AUDIO_CLOCK(clock)) */
+#define _G_TYPE_MUST_BE_SUB(instance, type) ({ \
+ GTypeInstance *__inst;__inst = (GTypeInstance*) instance; \
+ GType __t;__t = type; \
+ gboolean __r; \
+ if(!__inst || !__inst->g_class) \
+ __r = FALSE; \
+ else if( (__inst->g_class->g_type != __t) \
+ && g_type_check_instance_is_a (__inst, __t)) \
+ __r = TRUE; \
+ else \
+ __r = FALSE; \
+ __r; \
+ })
+
+ GstClockTimeDiff expecting_interval, actually_interval;
+
+ GST_BASE_SINK_WAIT_CLOCK_BEGIN
+
+ if(sink->priv->CC.is_video_sink
+ && _G_TYPE_MUST_BE_SUB(clock, GST_TYPE_SYSTEM_CLOCK)) {
+
+ GST_OBJECT_LOCK(sink);
+ sink->priv->CC.cur_expecting_render = time;
+ sink->priv->CC.last_actually_render = sink->priv->CC.cur_actually_render;
+ GST_OBJECT_UNLOCK(sink);
+
+ expecting_interval = sink->priv->CC.cur_expecting_render
+ - sink->priv->CC.last_expecting_render;
+
+ ret = basesink_cc_clock_calibration_wait(sink, sink->priv->cached_clock_id, jitter);
+
+ GST_OBJECT_LOCK(sink);
+ sink->priv->CC.last_expecting_render = time;
+ sink->priv->CC.cur_actually_render = gst_util_get_timestamp();
+ GST_OBJECT_UNLOCK(sink);
+
+ actually_interval = sink->priv->CC.cur_actually_render
+ - sink->priv->CC.last_actually_render;
+
+ /* cosume speed smaller than cc_threshold , consider it is proper timing to do cc */
+ if(!sink->priv->CC.do_clock_calibration) {
+ if(actually_interval - expecting_interval < sink->priv->CC.cc_threshold
+ && actually_interval - expecting_interval > -sink->priv->CC.cc_threshold)
+ {
+ GST_WARNING("Timing to do CC");
+ basesink_cc_do_clock_calibration(sink, TRUE);
+ }
+ }
+
+ }
+ else
+ ret = gst_clock_id_wait (sink->priv->cached_clock_id, jitter);
+
+ GST_BASE_SINK_WAIT_CLOCK_END
}
/**
/* This function will return immediately if start == -1, no clock
* or sync is disabled with GST_CLOCK_BADTIME. */
- status = gst_base_sink_wait_clock (basesink, stime, &jitter);
+
+ if(priv->cc_enabled)
+ status = basesink_cc_wait_calibrated_clock(basesink, stime, &jitter);
+ else
+ status = gst_base_sink_wait_clock (basesink, stime, &jitter);
GST_DEBUG_OBJECT (basesink, "clock returned %d, jitter %c%" GST_TIME_FORMAT,
status, (jitter < 0 ? '-' : ' '), GST_TIME_ARGS (ABS (jitter)));
priv = basesink->priv;
if (start) {
- priv->start = gst_util_get_timestamp ();
+
+ GstClockTime now = gst_util_get_timestamp ();
+
+ if(priv->CC.is_video_sink && GST_CLOCK_TIME_IS_VALID(priv->start)) {
+
+ int index = (GST_TIME_AS_MSECONDS(now - priv->start) % GST_MSECOND) / 10;
+ if(index >= 0 && index < 10) {
+ priv->CC.cc_stats[index]++;
+ GST_LOG("index(%d) , count(%d)", index, priv->CC.cc_stats[index]);
+ }
+ }
+
+ priv->start = now;
} else {
GstClockTime elapsed;
gst_event_unref (event);
break;
+#ifdef _VSP_SPEED_
+ case GST_EVENT_CUSTOM_DOWNSTREAM:
+ {
+ GValue * value;
+ GstStructure *structure = event->structure;
+ if(gst_structure_has_name(structure,"vsp/enable")) {
+ value = gst_structure_get_value(structure,"enable");
+ gboolean enabled = g_value_get_boolean (value);
+
+ GST_OBJECT_LOCK(basesink);
+ basesink->priv->vsp_enabled = enabled;
+ GST_OBJECT_UNLOCK(basesink);
+
+ GST_DEBUG("vsp/enable:enabled=%d",enabled);
+
+ gst_event_unref (event);
+
+ break;
+ } else if(gst_structure_has_name(structure,"vsp/speed")) {
+ GstClock *clock = GST_ELEMENT_CLOCK (basesink);
+ value = gst_structure_get_value(structure,"speed");
+ gdouble speed = g_value_get_double (value);
+ value = gst_structure_get_value(structure,"position");
+ gint64 position = g_value_get_int64 (value);
+
+ GST_DEBUG("vsp/speed:speed=%2f,position=%lld",speed,position);
+
+ GST_OBJECT_LOCK(basesink);
+
+ /* update segment.stop as streaming time has been changed by audiovsp */
+ /* formula: stop1 = rtime0 + (stop - stime1) / speed1
+ * stop2 = rtime0 + (stime2 - stime2) / speed1 + (stop - stime2) / speed2
+ * ......
+ */
+
+#define UPDATE_SEGMENT(stop) \
+ if(GST_CLOCK_TIME_IS_VALID(stop)) { \
+ if(!GST_CLOCK_TIME_IS_VALID(basesink->priv->vsp_stop)) { \
+ basesink->priv->vsp_stop = stop; \
+ } \
+ stop = stop \
+ + (basesink->priv->vsp_stop - position) \
+ * (1/speed - 1/basesink->priv->vsp_speed); \
+ }
+
+ UPDATE_SEGMENT(basesink->abidata.ABI.clip_segment->stop);
+ UPDATE_SEGMENT(basesink->segment.stop);
+
+ basesink->priv->vsp_speed = speed;
+ basesink->priv->vsp_position = position;
+ basesink->priv->vsp_last_rtime = clock ? gst_clock_get_time(clock) : 0;
+
+ GST_OBJECT_UNLOCK(basesink);
+
+ gst_event_unref (event);
+ break;
+ }
+ /* no break here,let it go down */
+ }
+#endif
default:
/* other events are sent to queue or subclass depending on if they
* are serialized. */
/* check if the buffer needs to be dropped, we first ask the subclass for the
* start and end */
- if (bclass->get_times)
+ if (bclass->get_times) {
bclass->get_times (basesink, time_buf, &start, &end);
+ }
if (!GST_CLOCK_TIME_IS_VALID (start)) {
/* if the subclass does not want sync, we use our own values so that we at
* least clip the buffer to the segment */
gst_base_sink_get_times (basesink, time_buf, &start, &end);
}
+#ifdef _VSP_SPEED_
+ else {
+ basesink->priv->vsp_video = TRUE;
+ basesink_cc_is_video_sink(basesink,TRUE);
+ }
+#else
+ else
+ basesink_cc_is_video_sink(basesink,TRUE);
+#endif
GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT
", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
}
}
+#ifdef _VSP_SPEED_
+static gboolean
+gst_base_sink_perform_custom_upstream(GstBaseSink *basesink, GstPad *pad, GstEvent *event)
+{
+ GValue * value;
+ GstStructure *structure = event->structure;
+ gboolean result = FALSE;
+
+ /* only handle in video case */
+ if(basesink->priv->vsp_video
+ && gst_structure_has_name(structure,"application/speed")) {
+ value = gst_structure_get_value(structure,"enable");
+ basesink->priv->vsp_enabled = g_value_get_boolean (value);
+
+ result = TRUE;
+ }
+ return result;
+}
+
+static gboolean
+gst_base_sink_perform_speed(GstBaseSink *basesink, GstPad *pad, GstEvent **event)
+{
+ gboolean result = FALSE;
+ gdouble rate;
+ GstFormat format;
+ GstSeekFlags flags;
+ GstSeekType start_type, stop_type;
+ gint64 start, stop;
+
+ gst_event_parse_seek (*event, &rate, &format, &flags, &start_type, &start,
+ &stop_type, &stop);
+ /* only handle in video case */
+ if(basesink->priv->vsp_video
+ && basesink->priv->vsp_enabled) {
+
+ if(basesink->priv->vsp_speed != rate) {
+
+ if(format != GST_FORMAT_TIME) {
+ result = FALSE;
+ goto done;
+ }
+
+ /* need to update segment.start && segment.rate */
+ basesink->priv->vsp_speed = rate;
+ gst_base_sink_event(pad,
+ gst_event_new_new_segment (TRUE, rate, format,
+ start, stop, start));
+ result = TRUE;
+ } else {
+ /* forward seek with rate = 1.0 */
+ gst_event_unref(*event);
+
+ *event = gst_event_new_seek(1.0,
+ format,flags,start_type,start,stop_type,stop);
+ }
+ }
+
+done:
+ return result;
+}
+#endif
+
/* send an event to our sinkpad peer. */
static gboolean
gst_base_sink_send_event (GstElement * element, GstEvent * event)
/* in pull mode we will execute the seek */
if (mode == GST_ACTIVATE_PULL)
result = gst_base_sink_perform_seek (basesink, pad, event);
+#ifdef _VSP_SPEED_
+ else {
+ result = gst_base_sink_perform_speed (basesink, pad, &event);
+ if(result)
+ forward = FALSE;
+ }
+#endif
break;
case GST_EVENT_STEP:
result = gst_base_sink_perform_step (basesink, pad, event);
forward = FALSE;
break;
+#ifdef _VSP_SPEED_
+ case GST_EVENT_CUSTOM_UPSTREAM:
+ result = gst_base_sink_perform_custom_upstream (basesink, pad, event);
+ if(result)
+ forward = FALSE;
+#endif
default:
break;
}
GST_DEBUG_OBJECT (basesink, "using last seen timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (last));
*cur = last;
+
+#ifdef _VSP_SPEED_
+ GST_OBJECT_LOCK(basesink);
+ if(basesink->priv->vsp_enabled && !basesink->priv->vsp_video)
+ *cur = basesink->priv->vsp_last_position;
+ GST_OBJECT_UNLOCK(basesink);
+#endif
} else {
if (oformat != tformat) {
/* convert accum, time and duration to time */
* rate and applied rate. */
base += accum;
base += latency;
+
if (GST_CLOCK_DIFF (base, now) < 0)
base = now;
if (rate < 0.0)
time += duration;
+#ifdef _VSP_SPEED_
+ GST_OBJECT_LOCK(basesink);
+ if(basesink->priv->vsp_enabled && !basesink->priv->vsp_video) {
+
+ /* always assign vsp_last_rtime a valid value */
+ if(basesink->priv->vsp_last_rtime <= 0)
+ basesink->priv->vsp_last_rtime = base;
+
+ *cur = basesink->priv->vsp_position
+ + gst_guint64_to_gdouble (now - basesink->priv->vsp_last_rtime)
+ * basesink->priv->vsp_speed;
+ basesink->priv->vsp_last_position = *cur;
+ /* did trust segment when vsp enabled as set-speed op did not send newsegment now */
+ last = -1;
+ }
+ else
+#endif
*cur = time + gst_guint64_to_gdouble (now - base) * rate;
+#ifdef _VSP_SPEED_
+ GST_OBJECT_UNLOCK(basesink);
+#endif
+
if (in_paused) {
/* never report less than segment values in paused */
if (last != -1)
} else {
/* never report more than last seen position in playing */
if (last != -1)
- *cur = MIN (last, *cur);
+ *cur = MIN (last, *cur);
}
GST_DEBUG_OBJECT (basesink,
priv->have_latency = TRUE;
}
GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+
+ /* initialize cc structure */
+ basesink_cc_initialize(basesink);
+
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
GST_PAD_PREROLL_LOCK (basesink->sinkpad);
* And it should be unmarked, since e.g. losing our position upon flush
* does not really change state to PAUSED ... */
g_atomic_int_set (&basesink->priv->to_playing, FALSE);
+#ifdef _VSP_SPEED_
+ if(GST_IS_SYSTEM_CLOCK(GST_ELEMENT_CLOCK(basesink))) {
+ priv->vsp_last_rtime = gst_clock_get_time(GST_ELEMENT_CLOCK(basesink));
+ }
+#endif
break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
g_atomic_int_set (&basesink->priv->to_playing, FALSE);
GST_DEBUG_OBJECT (basesink, "PAUSED to READY, don't need_preroll");
}
GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+
+ /* unitialize cc structure */
+ basesink_cc_uninitialize(basesink);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
if (bclass->stop) {
#define DEFAULT_TYPEFIND FALSE
#define DEFAULT_DO_TIMESTAMP FALSE
-#ifdef GST_EXT_MODIFIED_DQBUF
-#define DEFAULT_YIELD_TIME 200
-#endif /* GST_EXT_MODIFIED_DQBUF */
-
enum
{
PROP_0,
src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
-#ifdef GST_EXT_MODIFIED_DQBUF
- if ((src->live_running) && (!src->blive_play)) {
- sched_yield();
- usleep(DEFAULT_YIELD_TIME);
- }
-#endif /* GST_EXT_MODIFIED_DQBUF */
-
GST_LIVE_LOCK (src);
if (G_UNLIKELY (src->priv->flushing))
bclass->unlock (basesrc);
}
-#ifdef GST_EXT_MODIFIED_DQBUF
- basesrc->blive_play = live_play;
-#endif /* GST_EXT_MODIFIED_DQBUF */
-
/* we are now able to grab the LIVE lock, when we get it, we can be
* waiting for PLAYING while blocked in the LIVE cond or we can be waiting
* for the clock. */
GCond *live_cond;
gboolean is_live;
gboolean live_running;
-#ifdef GST_EXT_MODIFIED_DQBUF
- gboolean blive_play;
-#endif /* GST_EXT_MODIFIED_DQBUF */
/* MT-protected (with LOCK) */
gint blocksize; /* size of buffers when operating push based */
pads->eospads = 0;
pads->started = FALSE;
+#ifdef WFD_MODE
+ pads->wfd_mode = FALSE;
+ pads->first_collect = TRUE;
+#endif
+
/* members to manage the pad list */
pads->abidata.ABI.pad_lock = g_mutex_new ();
pads->abidata.ABI.pad_cookie = 0;
* we can get a busy loop here if the element does not pop from the collect
* function
*/
+#ifdef WFD_MODE
+ if (pads->wfd_mode) {
+ /* Call plugin's callback for any stream in turn.
+ CAUTION : This is specific for mpegtsmux for wifi display */
+ if (pads->first_collect) {
+ GST_WARNING("This is first collect...");
+ if (pads->queuedpads + pads->eospads >= pads->numpads) {
+ GST_WARNING("This is first to collect all streams...calling %s", GST_DEBUG_FUNCPTR_NAME (pads->func));
+ flow_ret = pads->func (pads, pads->user_data);
+
+ pads->first_collect = FALSE;
+ }
+ } else {
+ if (pads->queuedpads > 0) {
+ GST_DEBUG ("One of all active pads (%d, %d, %d) have data, calling %s",
+ pads->queuedpads, pads->eospads, pads->numpads, GST_DEBUG_FUNCPTR_NAME (pads->func));
+ flow_ret = pads->func (pads, pads->user_data);
+ }
+ }
+ } else {
+ while (((pads->queuedpads + pads->eospads) >= pads->numpads)) {
+ GST_DEBUG ("All active pads (%d + %d >= %d) have data, calling %s",
+ pads->queuedpads, pads->eospads, pads->numpads,
+ GST_DEBUG_FUNCPTR_NAME (pads->func));
+ flow_ret = pads->func (pads, pads->user_data);
+ collected = TRUE;
+
+ /* break on error */
+ if (flow_ret != GST_FLOW_OK)
+ break;
+ /* Don't keep looping after telling the element EOS or flushing */
+ if (pads->queuedpads == 0)
+ break;
+ }
+ if (!collected)
+ GST_DEBUG ("Not all active pads (%d) have data, continuing",
+ pads->numpads);
+ }
+#else
while (((pads->queuedpads + pads->eospads) >= pads->numpads)) {
GST_DEBUG ("All active pads (%d + %d >= %d) have data, calling %s",
pads->queuedpads, pads->eospads, pads->numpads,
if (!collected)
GST_DEBUG ("Not all active pads (%d) have data, continuing",
pads->numpads);
+#endif
}
return flow_ret;
}
goto unlock_done;
}
}
+
+#ifdef WFD_MODE
+void
+gst_collect_pads_set_wfd_mode(GstCollectPads * pads, gboolean mode)
+{
+ g_return_if_fail (pads != NULL);
+ g_return_if_fail (GST_IS_COLLECT_PADS (pads));
+
+ GST_OBJECT_LOCK (pads);
+ pads->wfd_mode = mode;
+ GST_OBJECT_UNLOCK (pads);
+}
+#endif
+
#define GST_IS_COLLECT_PADS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLLECT_PADS))
#define GST_IS_COLLECT_PADS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLLECT_PADS))
+#define WFD_MODE
+
typedef struct _GstCollectData GstCollectData;
typedef struct _GstCollectPads GstCollectPads;
typedef struct _GstCollectPadsPrivate GstCollectPadsPrivate;
/* with LOCK and PAD_LOCK*/
gboolean started;
+#ifdef WFD_MODE
+ /* mode for wifi display : If wfd is true, pads collection is working differently */
+ gboolean wfd_mode;
+ gboolean first_collect;
+#endif
/*< private >*/
union {
struct {
guint gst_collect_pads_flush (GstCollectPads *pads, GstCollectData *data,
guint size);
+#ifdef WFD_MODE
+void gst_collect_pads_set_wfd_mode (GstCollectPads * pads, gboolean mode);
+#endif
+
G_END_DECLS
#endif /* __GST_COLLECT_PADS_H__ */
}
}
+#ifdef GST_EXT_DATA_QUEUE_MODIFICATION
+static gboolean
+_gst_data_queue_wait_non_empty (GstDataQueue * queue)
+{
+ while (gst_data_queue_locked_is_empty (queue)) {
+ queue->abidata.ABI.waiting_add = TRUE;
+ g_cond_wait (queue->item_add, queue->qlock);
+ queue->abidata.ABI.waiting_add = FALSE;
+ if (queue->flushing)
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
/**
* gst_data_queue_pop:
* @queue: a #GstDataQueue.
g_signal_emit (queue, gst_data_queue_signals[SIGNAL_EMPTY], 0);
GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
+#ifdef GST_EXT_DATA_QUEUE_MODIFICATION
+ if (!_gst_data_queue_wait_non_empty (queue))
+ goto flushing;
+#else
while (gst_data_queue_locked_is_empty (queue)) {
queue->abidata.ABI.waiting_add = TRUE;
g_cond_wait (queue->item_add, queue->qlock);
if (queue->flushing)
goto flushing;
}
+#endif
}
/* Get the item from the GQueue */
}
}
+#ifdef GST_EXT_DATA_QUEUE_MODIFICATION
+/**
+ * gst_data_queue_peek:
+ * @queue: a #GstDataQueue.
+ * @item: pointer to store the returned #GstDataQueueItem.
+ *
+ * Retrieves the first @item available on the @queue without removing it.
+ * If the queue is currently empty, the call will block until at least
+ * one item is available, OR the @queue is set to the flushing state.
+ * MT safe.
+ *
+ * Returns: #TRUE if an @item was successfully retrieved from the @queue.
+ *
+ * Since: 1.2.0
+ */
+gboolean
+gst_data_queue_peek (GstDataQueue * queue, GstDataQueueItem ** item)
+{
+ g_return_val_if_fail (GST_IS_DATA_QUEUE (queue), FALSE);
+ g_return_val_if_fail (item != NULL, FALSE);
+
+ GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
+
+ STATUS (queue, "before peeking");
+
+ if (gst_data_queue_locked_is_empty (queue)) {
+ GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
+ if (G_LIKELY (queue->emptycallback))
+ queue->emptycallback (queue, queue->checkdata);
+ else
+ g_signal_emit (queue, gst_data_queue_signals[SIGNAL_EMPTY], 0);
+ GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
+
+ if (!_gst_data_queue_wait_non_empty (queue))
+ goto flushing;
+ }
+
+ /* Get the item from the GQueue */
+ *item = g_queue_peek_head (queue->queue);
+
+ STATUS (queue, "after peeking");
+ GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
+
+ return TRUE;
+
+ /* ERRORS */
+flushing:
+ {
+ GST_DEBUG ("queue:%p, we are flushing", queue);
+ GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
+ return FALSE;
+ }
+}
+#endif
+
/**
* gst_data_queue_drop_head:
* @queue: The #GstDataQueue to drop an item from.
gboolean gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item);
gboolean gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item);
+#ifdef GST_EXT_DATA_QUEUE_MODIFICATION
+gboolean gst_data_queue_peek (GstDataQueue * queue, GstDataQueueItem ** item);
+#endif
void gst_data_queue_flush (GstDataQueue * queue);
void gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing);
helpersdir=$(libexecdir)/gstreamer-$(GST_MAJORMINOR)
gst_plugin_scanner_SOURCES = gst-plugin-scanner.c
-gst_plugin_scanner_CFLAGS = $(GST_OBJ_CFLAGS)
+gst_plugin_scanner_CFLAGS = $(GST_OBJ_CFLAGS) -pie
gst_plugin_scanner_LDADD = $(GST_OBJ_LIBS)
Android.mk: Makefile.am
--- /dev/null
+[Unit]
+Description=GStreamer Registry
+ConditionPathExists=!/home/app/.gstreamer-0.10/registry.bin
+
+[Service]
+Type=oneshot
+Environment=GST_REGISTRY=/home/app/.gstreamer-0.10/registry.bin
+User=app
+Group=app
+ExecStartPre=/bin/mkdir -p /home/app/.gstreamer-0.10
+ExecStart=/usr/bin/gst-inspect-0.10
+
+[Install]
+WantedBy=multi-user.target
Name: gstreamer
Summary: GStreamer streaming media framework runtime
-Version: 0.10.36
-Release: 2
+Version: 0.10.37
+Release: 44
Group: Applications/Multimedia
-License: LGPLv2+
+License: LGPL-2.0+
Source0: %{name}-%{version}.tar.gz
+Source1: gstreamer-registry.service
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libxml-2.0)
-BuildRequires: pkgconfig(mm-ta)
+BuildRequires: pkgconfig(dlog)
BuildRequires: bison
BuildRequires: flex
%build
+./autogen.sh --noconfigure
+
export CFLAGS+=" -Wall -g -fPIC\
-DGST_EXT_AV_RECORDING\
-DGST_EXT_QUEUE_ENHANCEMENT\
+ -DGST_EXT_MQ_MODIFICATION\
-DGST_EXT_CURRENT_BYTES\
- -DGST_EXT_MODIFIED_DQBUF"
+ -DGST_EXT_BASEPARSER_MODIFICATION\
+ -DGST_EXT_BASIC_MODIFICATION\
+ -D_VSP_SPEED_\
+ -DGST_EXT_DATA_QUEUE_MODIFICATION\
+ -DGST_EXT_BASEPARSE_ENABLE_WFD"
%configure --prefix=/usr\
--disable-valgrind\
--disable-gtk-doc\
--disable-registry-update\
--disable-loadsave\
- --with-html-dir=/tmp/dump
+ --with-html-dir=/tmp/dump\
+ --enable-dlog
+
+make -v
make %{?jobs:-j%jobs}
%install
rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp COPYING %{buildroot}/usr/share/license/%{name}
+mkdir -p %{buildroot}%{_libdir}/systemd/system
+install -m 644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/gstreamer-registry.service
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+ln -s ../gstreamer-registry.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/gstreamer-registry.service
%make_install
rm -rf %{buildroot}/tmp/dump
%files
+%manifest gstreamer.manifest
%defattr(-,root,root,-)
%doc AUTHORS COPYING NEWS README RELEASE TODO
%{_libdir}/libgstreamer-0.10.so.*
%doc %{_mandir}/man1/gst-launch-0.10.*
%doc %{_mandir}/man1/gst-typefind-0.10.*
%doc %{_mandir}/man1/gst-xmlinspect-0.10.*
-
+/usr/share/license/%{name}
+%{_libdir}/systemd/system/gstreamer-registry.service
+%{_libdir}/systemd/system/multi-user.target.wants/gstreamer-registry.service
%files devel
%defattr(-,root,root,-)
%{_libdir}/pkgconfig/gstreamer-net-0.10.pc
%files tools
+%manifest gstreamer-tools.manifest
%defattr(-,root,root,-)
%{_bindir}/gst-feedback
%{_bindir}/gst-inspect
Requires: gstreamer-@GST_MAJORMINOR@
Version: @VERSION@
Libs: -L${libdir} -lgstbase-@GST_MAJORMINOR@
-Cflags: -I${includedir} -DGST_EXT_MODIFIED_DQBUF
+Cflags: -I${includedir} -DGST_EXT_BASEPARSER_MODIFICATION
#include <unistd.h>
#endif
+#ifdef GST_EXT_AV_RECORDING
+#include <fcntl.h> /* for posix_fadvise */
+#endif /* GST_EXT_AV_RECORDING */
+
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
break;
}
case GST_EVENT_EOS:
+#ifdef GST_EXT_AV_RECORDING
+ GST_WARNING_OBJECT(filesink, "GST_EVENT_EOS received");
+#endif /* GST_EXT_AV_RECORDING */
if (fflush (filesink->file))
goto flush_failed;
+#ifdef GST_EXT_AV_RECORDING
+ GST_WARNING_OBJECT(filesink, "fflush done");
+#endif /* GST_EXT_AV_RECORDING */
break;
default:
break;
GstFileSink *filesink;
guint size;
guint8 *data;
+#ifdef GST_EXT_AV_RECORDING
+ int ret = 0;
+#endif /* GST_EXT_AV_RECORDING */
filesink = GST_FILE_SINK (sink);
goto handle_error;
filesink->current_pos += size;
+#ifdef GST_EXT_AV_RECORDING
+ ret = posix_fadvise(fileno((FILE *)filesink->file), 0, 0, POSIX_FADV_DONTNEED);
+ if (ret) {
+ GST_WARNING_OBJECT(filesink, "posix_fadvise failed : ret %x", ret);
+ }
+#endif /* GST_EXT_AV_RECORDING */
}
return GST_FLOW_OK;
gst_query_set_uri (query, src->uri);
ret = TRUE;
break;
+ case GST_QUERY_CUSTOM: {
+ GstStructure *s;
+ gchar * file_path;
+ s = gst_query_get_structure (query);
+ if (gst_structure_has_name (s, "FileSrcURI")) {
+ gchar *uri;
+ GValue value = { 0 };
+
+ g_value_init (&value, G_TYPE_STRING);
+ file_path = g_strdup_printf ("%s://%s", "file", src->filename);
+ g_value_set_string (&value, file_path);
+
+ GST_INFO_OBJECT (src, "Received supported custom query");
+ gst_structure_set_value (s, "file-uri", &value);
+ ret = TRUE;
+ } else {
+ GST_WARNING_OBJECT (src,"Unsupported query");
+ ret = FALSE;
+ }
+ break;
+ }
default:
ret = FALSE;
break;
* <para>
* The default queue size limits are 5 buffers, 10MB of data, or
* two second worth of data, whichever is reached first. Note that the number
- * of buffers will dynamically grow depending on the fill level of
+ * of buffers will dynamically grow depending on the fill level of
* other queues.
* </para>
* <para>
#define DEFAULT_EXTRA_SIZE_BUFFERS 5
#define DEFAULT_EXTRA_SIZE_TIME 3 * GST_SECOND
+#define INCREASE_WINDOW 1 * 1024 * 1024
+
#define DEFAULT_USE_BUFFERING FALSE
#define DEFAULT_LOW_PERCENT 10
#define DEFAULT_HIGH_PERCENT 99
PROP_MAX_SIZE_BYTES,
PROP_MAX_SIZE_BUFFERS,
PROP_MAX_SIZE_TIME,
+#ifdef GST_EXT_MQ_MODIFICATION
+ PROP_CURR_SIZE_BYTES,
+#endif
PROP_USE_BUFFERING,
PROP_LOW_PERCENT,
PROP_HIGH_PERCENT,
* size) is higher than the boundary values which can be set through the
* GObject properties.
*
- * This can be used as an indicator of pre-roll.
+ * This can be used as an indicator of pre-roll.
*/
gst_multi_queue_signals[SIGNAL_OVERRUN] =
g_signal_new ("overrun", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
g_param_spec_uint64 ("max-size-time", "Max. size (ns)",
"Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64,
DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
+#ifdef GST_EXT_MQ_MODIFICATION
+ g_object_class_install_property (gobject_class, PROP_CURR_SIZE_BYTES,
+ g_param_spec_uint ("curr-size-bytes", "Current buffered size (kB)",
+ "buffered amount of data in the queue (bytes)",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+#endif
g_object_class_install_property (gobject_class, PROP_EXTRA_SIZE_BYTES,
g_param_spec_uint ("extra-size-bytes", "Extra Size (kB)",
"Amount of data the queues can grow if one of them is empty (bytes, 0=disable)"
/**
* GstMultiQueue:use-buffering
- *
+ *
* Enable the buffering option in multiqueue so that BUFFERING messages are
* emited based on low-/high-percent thresholds.
*
DEFAULT_USE_BUFFERING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstMultiQueue:low-percent
- *
+ *
* Low threshold percent for buffering to start.
*
* Since: 0.10.26
DEFAULT_LOW_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstMultiQueue:high-percent
- *
+ *
* High threshold percent for buffering to finish.
*
* Since: 0.10.26
/**
* GstMultiQueue:sync-by-running-time
- *
+ *
* If enabled multiqueue will synchronize deactivated or not-linked streams
* to the activated and linked streams by taking the running time.
* Otherwise multiqueue will synchronize the deactivated or not-linked
}
}
+#ifdef GST_EXT_MQ_MODIFICATION
+static guint
+get_current_size_bytes (GstMultiQueue * mq)
+{
+ GList *tmp;
+ GstClockTime highest = GST_CLOCK_TIME_NONE;
+ GstClockTime lowest = GST_CLOCK_TIME_NONE;
+ guint current_size_bytes = 0;
+
+ for (tmp = mq->queues; tmp; tmp = g_list_next (tmp)) {
+ GstSingleQueue *sq = (GstSingleQueue *) tmp->data;
+ GstDataQueueSize size;
+
+ gst_data_queue_get_level (sq->queue, &size);
+
+ current_size_bytes += size.bytes;
+
+ GST_DEBUG_OBJECT (mq,
+ "queue %d: bytes %u/%u, time %" G_GUINT64_FORMAT "/%"
+ G_GUINT64_FORMAT, sq->id, size.bytes, sq->max_size.bytes,
+ sq->cur_time, sq->max_size.time);
+ }
+
+ GST_INFO_OBJECT (mq, "current_size_bytes : %u", current_size_bytes);
+
+ return current_size_bytes;
+}
+#endif
+
static void
gst_multi_queue_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
case PROP_MAX_SIZE_TIME:
g_value_set_uint64 (value, mq->max_size.time);
break;
+#ifdef GST_EXT_MQ_MODIFICATION
+ case PROP_CURR_SIZE_BYTES:
+ g_value_set_uint (value, get_current_size_bytes(mq));
+ break;
+#endif
case PROP_USE_BUFFERING:
g_value_set_boolean (value, mq->use_buffering);
break;
gint percent, tmp;
gboolean post = FALSE;
- /* nothing to dowhen we are not in buffering mode */
+ /* nothing to do when we are not in buffering mode */
if (!mq->use_buffering)
return;
+#ifdef GST_EXT_MQ_MODIFICATION
+ GstCaps *caps = GST_PAD_CAPS(sq->sinkpad);
+ GstStructure *s;
+
+ /* skip checking the text queue. */
+ if ((caps) &&
+ (s = gst_caps_get_structure (caps, 0)) &&
+ (g_strrstr (gst_structure_get_name (s), "text"))) {
+ return;
+ }
+#endif
+
gst_data_queue_get_level (sq->queue, &size);
GST_DEBUG_OBJECT (mq,
G_GUINT64_FORMAT, sq->id, size.visible, sq->max_size.visible,
size.bytes, sq->max_size.bytes, sq->cur_time, sq->max_size.time);
+ GST_INFO_OBJECT (mq, "queue %d: cached time %u sec, byte %u",
+ sq->id, (guint)(sq->cur_time/GST_SECOND), size.bytes);
+
/* get bytes and time percentages and take the max */
if (sq->is_eos) {
percent = 100;
/* make sure it increases */
percent = MAX (mq->percent, percent);
+#ifndef GST_EXT_MQ_MODIFICATION
if (percent == mq->percent)
/* don't post if nothing changed */
post = FALSE;
else
/* else keep last value we posted */
- mq->percent = percent;
+#endif
+ mq->percent = percent;
+
} else {
if (percent < mq->low_percent) {
mq->buffering = TRUE;
}
/* calculate the diff between running time on the sink and src of the queue.
- * This is the total amount of time in the queue.
+ * This is the total amount of time in the queue.
* WITH LOCK TAKEN */
static void
update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
{
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
- /* if no timestamp is set, assume it's continuous with the previous
+ /* if no timestamp is set, assume it's continuous with the previous
* time */
if (timestamp == GST_CLOCK_TIME_NONE)
timestamp = segment->last_stop;
/* If we're not-linked, we do some extra work because we might need to
* wait before pushing. If we're linked but there's a gap in the IDs,
- * or it's the first loop, or we just passed the previous highid,
- * we might need to wake some sleeping pad up, so there's extra work
+ * or it's the first loop, or we just passed the previous highid,
+ * we might need to wake some sleeping pad up, so there's extra work
* there too */
if (sq->srcresult == GST_FLOW_NOT_LINKED
|| (sq->last_oldid == G_MAXUINT32) || (newid != (sq->last_oldid + 1))
lowest = sq->nextid;
} else if (sq->srcresult != GST_FLOW_UNEXPECTED) {
/* If we don't have a global highid, or the global highid is lower than
- * this single queue's last outputted id, store the queue's one,
+ * this single queue's last outputted id, store the queue's one,
* unless the singlequeue is at EOS (srcresult = UNEXPECTED) */
if ((highid == G_MAXUINT32) || (sq->oldid > highid))
highid = sq->oldid;
lowest = sq->next_time;
} else if (sq->srcresult != GST_FLOW_UNEXPECTED) {
/* If we don't have a global highid, or the global highid is lower than
- * this single queue's last outputted id, store the queue's one,
+ * this single queue's last outputted id, store the queue's one,
* unless the singlequeue is at EOS (srcresult = UNEXPECTED) */
if (highest == GST_CLOCK_TIME_NONE || sq->last_time > highest)
highest = sq->last_time;
GST_LOG_OBJECT (mq, "Single Queue %d is full", sq->id);
+ if(mq->max_size.bytes < DEFAULT_EXTRA_SIZE_BYTES) {
+ GST_LOG_OBJECT (mq, "increasing the queue size");
+ GST_MULTI_QUEUE_MUTEX_LOCK (mq);
+ mq->max_size.bytes = mq->max_size.bytes + INCREASE_WINDOW;
+ SET_CHILD_PROPERTY (mq, bytes);
+ GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
+ }
+
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
for (tmp = mq->queues; tmp; tmp = g_list_next (tmp)) {
GstSingleQueue *oq = (GstSingleQueue *) tmp->data;
break;
#ifdef GST_EXT_AV_RECORDING
case PROP_EMPTY_BUFFERS:
- queue->empty_buffers = g_value_get_boolean (value);
+ {
+ gboolean empty_buffers = g_value_get_boolean (value);
+
+ GST_INFO("set empty buffer : %d", empty_buffers);
+
+ if (empty_buffers) {
+ GST_INFO("flush queue");
+ gst_queue_locked_flush(queue);
+ }
+
+ queue->empty_buffers = empty_buffers;
+
+ GST_INFO("done");
break;
+ }
#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
#include "gst/glib-compat-private.h"
#include <string.h>
-
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+#include <fcntl.h>
+#endif
#ifdef G_OS_WIN32
#include <io.h> /* lseek, open, close, read */
#undef lseek
#endif
#define DEFAULT_RING_BUFFER_MAX_SIZE 0
#ifdef GST_EXT_QUEUE_ENHANCEMENT
-#define DEFAULT_FILE_BUFFER_MAX_SIZE 0
+#define DEFAULT_FILE_BUFFER_MAX_SIZE 0
+
+#define MAX_NUM_OF_BUFFER_PAD 4
+#define DEFAULT_BUFFER_PAD_SIZE (256*1024)
+#define DEFAULT_CURRENT_LEVEL_PAD_SIZE (50*1024)
+
+guint64 buffer_pad_size[MAX_NUM_OF_BUFFER_PAD] =
+ {(1.5*1024*1024), (1*1024*1024), (512*1024), (256*1024)};
#endif
enum
static void update_cur_level (GstQueue2 * queue, GstQueue2Range * range);
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+static void gst_queue2_update_buffer_pad_size(GstQueue2 * queue);
+static gboolean change_current_range(GstQueue2 * queue, GstQueue2Range *req_range, guint64 offset, guint length);
+#endif
+
typedef enum
{
GST_QUEUE2_ITEM_TYPE_UNKNOWN = 0,
queue->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;
#ifdef GST_EXT_QUEUE_ENHANCEMENT
queue->file_buffer_max_size = DEFAULT_FILE_BUFFER_MAX_SIZE;
+ queue->buffer_pad_size = DEFAULT_BUFFER_PAD_SIZE;
+ queue->latest_seek_pos = 0;
#endif
GST_DEBUG_OBJECT (queue,
"range [%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT "] (rb [%"
G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT "])(fb [%"
G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT "]), reading %" G_GUINT64_FORMAT
- " current range? %s", walk->offset, walk->writing_pos, walk->rb_offset, walk->rb_writing_pos,
+ " current range? %s", walk->offset, walk->writing_pos, walk->rb_offset, walk->rb_writing_pos,
walk->fb_offset, walk->fb_writing_pos, walk->reading_pos,
walk == queue->current ? "**y**" : " n ");
#else
} else {
percent = GET_PERCENT (bytes, 0);
}
+
+ GST_DEBUG_OBJECT (queue, "bytes filled %d percent", (gint) percent);
+ GST_DEBUG_OBJECT (queue, "time filled %d percent", GET_PERCENT (time, 0));
+ GST_DEBUG_OBJECT (queue, "buffers filled %d percent", GET_PERCENT (buffers, 0));
+ GST_DEBUG_OBJECT (queue, "filled %d percent", GET_PERCENT (rate_time, 0));
#else
if (!QUEUE_IS_USING_RING_BUFFER (queue)) {
percent = GET_PERCENT (bytes, 0);
queue->cur_level.rate_time =
queue->cur_level.bytes / queue->byte_in_rate * GST_SECOND;
}
+
GST_DEBUG_OBJECT (queue, "rates: in %f, time %" GST_TIME_FORMAT,
queue->byte_in_rate, GST_TIME_ARGS (queue->cur_level.rate_time));
+ GST_INFO_OBJECT (queue, "byte_in_rate : %.2f KBps", (queue->byte_in_rate/1024));
}
static void
perform_seek_to_offset (GstQueue2 * queue, guint64 offset)
{
GstEvent *event;
- gboolean res;
+ gboolean res = TRUE;
GST_QUEUE2_MUTEX_UNLOCK (queue);
- GST_DEBUG_OBJECT (queue, "Seeking to %" G_GUINT64_FORMAT, offset);
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if (queue->latest_seek_pos == offset) {
+ GST_DEBUG_OBJECT (queue, "Duplicated request to %" G_GUINT64_FORMAT", in: %f", offset, queue->byte_in_rate);
+ GST_QUEUE2_MUTEX_LOCK (queue);
+ return res;
+ } else {
+ GST_INFO_OBJECT (queue, "Seeking to %" G_GUINT64_FORMAT", in: %f", offset, queue->byte_in_rate);
+ }
+ queue->latest_seek_pos = offset;
+#endif
event =
gst_event_new_seek (1.0, GST_FORMAT_BYTES,
return res;
}
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+static void
+gst_queue2_update_buffer_pad_size(GstQueue2 * queue)
+{
+ guint idx = 0;
+
+ for (idx=0 ; idx < MAX_NUM_OF_BUFFER_PAD ; idx++) {
+ if ((guint64)queue->byte_in_rate > buffer_pad_size[idx])
+ break;
+ }
+
+ if (idx < MAX_NUM_OF_BUFFER_PAD)
+ queue->buffer_pad_size = buffer_pad_size[idx];
+ else
+ queue->buffer_pad_size = DEFAULT_BUFFER_PAD_SIZE;
+
+ GST_DEBUG_OBJECT(queue, "new pad size = %lld", queue->buffer_pad_size);
+}
+
+/* To reduce http server connection we do not change current range repeatedly. */
+static gboolean
+change_current_range(GstQueue2 * queue, GstQueue2Range *req_range, guint64 offset, guint length)
+{
+ guint64 curr_level = 0;
+ guint64 curr_min_level = 0;
+
+ if (queue->current->writing_pos > queue->current->reading_pos)
+ curr_level = queue->current->writing_pos - queue->current->reading_pos;
+
+ gst_queue2_update_buffer_pad_size (queue);
+ curr_min_level = MIN((queue->max_level.bytes*0.05), DEFAULT_CURRENT_LEVEL_PAD_SIZE);
+
+ GST_DEBUG_OBJECT(queue, " curr[w%"G_GUINT64_FORMAT", r%"G_GUINT64_FORMAT
+ ", d%"G_GUINT64_FORMAT", m%"G_GUINT64_FORMAT
+ "] u[%"G_GUINT64_FORMAT"] [%s]",
+ queue->current->writing_pos, queue->current->reading_pos,
+ curr_level, curr_min_level,
+ queue->upstream_size, (queue->is_eos)?"EOS":"---");
+
+ if ((queue->is_eos) ||
+ (queue->current->writing_pos >= queue->upstream_size))
+ return TRUE;
+
+ if ((queue->current->writing_pos < req_range->writing_pos)
+ && (offset+length < (queue->current->writing_pos + queue->buffer_pad_size)))
+ return FALSE;
+
+ if (curr_level >= curr_min_level)
+ {
+ GST_DEBUG_OBJECT (queue, "Range Switching");
+ return TRUE;
+ }
+ else
+ {
+ GST_DEBUG_OBJECT (queue, "No Switching.. keep receiving data in the same range..");
+ return FALSE;
+ }
+}
+#endif
+
/* see if there is enough data in the file to read a full buffer */
static gboolean
gst_queue2_have_data (GstQueue2 * queue, guint64 offset, guint length)
if ((range = find_range (queue, offset))) {
if (queue->current != range) {
GST_DEBUG_OBJECT (queue, "switching ranges, do seek to range position");
+
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if ((QUEUE_IS_USING_RING_BUFFER (queue)) ||
+ (QUEUE_IS_USING_FILE_RING_BUFFER (queue)) ||
+ (change_current_range(queue, range, offset, length)))
+ {
+ perform_seek_to_offset (queue, range->writing_pos);
+ }
+
+ if (offset + length <= range->writing_pos)
+ return TRUE;
+ else
+ return FALSE;
+
+#else
perform_seek_to_offset (queue, range->writing_pos);
+#endif
+
#ifdef GST_EXT_QUEUE_ENHANCEMENT
return FALSE;
#endif
- }
+ }
GST_INFO_OBJECT (queue, "cur_level.bytes %u (max %" G_GUINT64_FORMAT ")",
queue->cur_level.bytes, QUEUE_MAX_BYTES (queue));
"requested data is within range, wait for data");
return FALSE;
}
- } else if (offset > queue->current->writing_pos && offset < queue->current->writing_pos + 200000) {
- GST_INFO_OBJECT (queue, "wait for data");
- return FALSE;
+ } else {
+
+ gst_queue2_update_buffer_pad_size (queue);
+
+ if (offset > queue->current->writing_pos && offset < queue->current->writing_pos + queue->buffer_pad_size) {
+ GST_INFO_OBJECT (queue, "wait for data");
+ update_cur_pos (queue, queue->current, offset + length);
+ update_in_rates (queue);
+ return FALSE;
+ }
}
#else
} else if (offset < queue->current->writing_pos + 200000) {
guint8 *ring_buffer;
size_t res;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ int ret = 0;
+#endif
+
ring_buffer = queue->ring_buffer;
if (QUEUE_IS_USING_TEMP_FILE (queue) && FSEEK_FILE (queue->temp_file, offset))
length, offset);
if (QUEUE_IS_USING_TEMP_FILE (queue)) {
res = fread (dst, 1, length, queue->temp_file);
+ /* [queue2]add posix_fadvise because of page cache free after streaming */
+ #ifdef GST_EXT_QUEUE_ENHANCEMENT
+ ret = posix_fadvise(fileno((FILE *)queue->temp_file), 0, 0, POSIX_FADV_DONTNEED);
+ if (ret != 0){
+ GST_WARNING_OBJECT(queue,"posix_fadvise failed : ret %x",ret);
+ }
+ #endif
} else {
memcpy (dst, ring_buffer + offset, length);
res = length;
guint64 rpos;
#ifdef GST_EXT_QUEUE_ENHANCEMENT
guint64 fb_size;
+ GstQueue2Range* read_range = NULL;
#endif
/* allocate the output buffer of the requested size */
remaining = length;
while (remaining > 0) {
+
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if(!(read_range = find_range (queue, offset)))
+ read_range = queue->current;
+#endif
+
/* configure how much/whether to read */
if (!gst_queue2_have_data (queue, rpos, remaining)) {
read_length = 0;
queue->current->max_reading_pos = rpos;
update_cur_level (queue, queue->current);
}
+
+ /* update the buffering */
+ if (queue->use_buffering)
+ {
+ update_buffering (queue);
+ }
#endif
+
GST_DEBUG_OBJECT (queue, "waiting for add");
GST_QUEUE2_WAIT_ADD_CHECK (queue, queue->srcresult, out_flushing);
continue;
}
/* set range reading_pos to actual reading position for this read */
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if((!QUEUE_IS_USING_RING_BUFFER (queue)) &&
+ (!QUEUE_IS_USING_FILE_RING_BUFFER(queue)))
+ read_range->reading_pos = rpos;
+ else
+ read_range->reading_pos = rpos;
+#else
queue->current->reading_pos = rpos;
+#endif
/* configure how much and from where to read */
if (QUEUE_IS_USING_RING_BUFFER (queue)) {
#ifdef GST_EXT_QUEUE_ENHANCEMENT
} else if (QUEUE_IS_USING_FILE_RING_BUFFER(queue)){
file_offset =
- (queue->current->fb_offset + (rpos -
- queue->current->offset)) % fb_size;
+ (read_range->fb_offset + (rpos -
+ read_range->offset)) % fb_size;
if (file_offset + read_length > fb_size) {
block_length = fb_size - file_offset;
block_length = read_length;
remaining -= read_return;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if((!QUEUE_IS_USING_RING_BUFFER (queue)) &&
+ (!QUEUE_IS_USING_FILE_RING_BUFFER(queue)))
+ {
+ rpos = (read_range->reading_pos += read_return);
+ update_cur_pos (queue, read_range, read_range->reading_pos);
+ }
+ else
+ {
+ rpos = (read_range->reading_pos += read_return);
+ update_cur_pos (queue, read_range, read_range->reading_pos);
+ }
+#else
rpos = (queue->current->reading_pos += read_return);
update_cur_pos (queue, queue->current, queue->current->reading_pos);
+#endif
}
GST_QUEUE2_SIGNAL_DEL (queue);
GST_DEBUG_OBJECT (queue, "%u bytes left to read", remaining);
*buffer = buf;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ /* update the buffering */
+ if (queue->use_buffering)
+ update_buffering (queue);
+#endif
+
return GST_FLOW_OK;
/* ERRORS */
guint64 writing_pos, new_writing_pos;
GstQueue2Range *range, *prev, *next;
#ifdef GST_EXT_QUEUE_ENHANCEMENT
- guint fb_size;
+ guint64 merged_writing_pos = 0;
+ guint64 merged_max_read_pos = 0;
+
+ guint64 fb_size;
#endif
if (QUEUE_IS_USING_RING_BUFFER (queue))
#ifdef GST_EXT_QUEUE_ENHANCEMENT
else if (QUEUE_IS_USING_FILE_RING_BUFFER(queue)) {
gint64 space;
-
+
/* calculate the space in the ring buffer not used by data from
* the current range */
while (queue->file_buffer_max_size <= queue->cur_level.bytes + 1024*200) {
}
}
#endif
- else {
+ else {
to_write = size;
new_writing_pos = writing_pos + to_write;
}
* is a lot of data in the range we merged with to avoid reading it all
* again. */
queue->current->next = next->next;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ merged_writing_pos = next->writing_pos;
+ merged_max_read_pos = next->max_reading_pos;
+#endif
g_slice_free (GstQueue2Range, next);
debug_ranges (queue);
#endif
} else {
queue->current->writing_pos = writing_pos = new_writing_pos;
+
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if (merged_writing_pos != 0) {
+ if (queue->current->writing_pos + (50*1024) < merged_writing_pos) {
+ queue->current->writing_pos = merged_writing_pos;
+ queue->current->max_reading_pos = merged_max_read_pos;
+ GST_INFO_OBJECT (queue, "merged writing position : %lld, read: %lld", merged_writing_pos, merged_max_read_pos);
+ perform_seek_to_offset(queue, queue->current->writing_pos);
+ } else {
+ GST_INFO_OBJECT (queue, "keep waiting.");
+ if (queue->current->writing_pos < merged_max_read_pos)
+ queue->current->max_reading_pos = queue->current->writing_pos;
+ }
+ }
+#endif
}
update_cur_level (queue, queue->current);
queue->cur_level.bytes, QUEUE_MAX_BYTES (queue));
GST_QUEUE2_SIGNAL_ADD (queue);
- };
+ }
return TRUE;
return ret;
}
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+static gboolean
+gst_queue2_handle_buffering_query(GstQueue2 *queue, GstQuery * query)
+{
+ GstFormat format;
+ gint64 start, stop, range_start, range_stop;
+ gint percent;
+ gint64 estimated_total, buffering_left;
+ GstFormat peer_fmt;
+ gint64 duration;
+ gboolean peer_res, is_buffering, is_eos;
+ gdouble byte_in_rate, byte_out_rate;
+ gint64 peer_pos;
+
+ byte_in_rate = queue->byte_in_rate;
+ byte_out_rate = queue->byte_out_rate;
+ is_buffering = queue->is_buffering;
+ is_eos = queue->is_eos;
+ percent = queue->buffering_percent;
+
+ GST_DEBUG_OBJECT (queue, "byte_in_rate %f", byte_in_rate);
+ GST_DEBUG_OBJECT (queue, "byte_out_rate %f", byte_out_rate);
+ GST_DEBUG_OBJECT (queue, "percent %d", percent);
+ GST_DEBUG_OBJECT (queue, "eos? %s, buffering? %s", (is_eos)?"OO":"XX", (is_buffering)?"OO":"XX");
+
+ /* get duration of upstream in bytes */
+ peer_fmt = GST_FORMAT_BYTES;
+ peer_res = gst_pad_query_peer_duration (queue->sinkpad, &peer_fmt, &duration);
+ if (peer_res)
+ peer_res = gst_pad_query_peer_position(queue->sinkpad, &peer_fmt, &peer_pos);
+
+ GST_DEBUG_OBJECT (queue, "duration %lld, peer_pos %lld", duration, peer_pos);
+
+ /* calculate remaining and total download time */
+ if (peer_res && byte_in_rate > 0.0) {
+ estimated_total = (duration * 1000) / byte_in_rate;
+ buffering_left = ((duration - peer_pos) * 1000) / byte_in_rate;
+ } else {
+ estimated_total = -1;
+ buffering_left = -1;
+ }
+
+ GST_DEBUG_OBJECT (queue, "estimated %" G_GINT64_FORMAT ", left %"
+ G_GINT64_FORMAT, estimated_total, buffering_left);
+
+ gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL);
+
+ switch (format) {
+ case GST_FORMAT_PERCENT:
+ /* we need duration */
+ if (!peer_res)
+ return FALSE;
+
+ /* get our available data relative to the duration */
+ if (duration != -1 && duration != 0)
+ {
+ GST_DEBUG_OBJECT (queue, "cur_level byte %d", queue->cur_level.bytes);
+ GST_DEBUG_OBJECT (queue, "cur_level buffers %d", queue->cur_level.buffers);
+ GST_DEBUG_OBJECT (queue, "cur_level time %lld", queue->cur_level.time);
+
+ start = GST_FORMAT_PERCENT_MAX * (peer_pos - queue->cur_level.bytes) / duration;
+ stop = GST_FORMAT_PERCENT_MAX * peer_pos / duration;
+ }
+ else
+ {
+ start = 0;
+ stop = -1;
+ }
+
+ GST_DEBUG_OBJECT (queue, "start %lld, stop %lld", start, stop);
+ break;
+ case GST_FORMAT_BYTES:
+ start = 0;
+ stop = peer_pos;
+ break;
+
+ default:
+ start = -1;
+ stop = -1;
+ break;
+ }
+
+ /* fill out the buffered ranges */
+ switch (format) {
+ case GST_FORMAT_PERCENT:
+ if (duration == -1 || duration ==0) {
+ range_start = 0;
+ range_stop = 0;
+ break;
+ }
+
+ range_start = 100 * (peer_pos - queue->cur_level.bytes) / duration;
+ range_stop = 100 * peer_pos / duration;
+ break;
+ case GST_FORMAT_BYTES:
+ range_start = (peer_pos - queue->cur_level.bytes);
+ range_stop = peer_pos;
+ break;
+ default:
+ range_start = -1;
+ range_stop = -1;
+ break;
+ }
+
+ GST_DEBUG_OBJECT (queue,
+ "range starting at %" G_GINT64_FORMAT " and finishing at %"
+ G_GINT64_FORMAT, range_start, range_stop);
+
+ gst_query_add_buffering_range (query, range_start, range_stop);
+
+ gst_query_set_buffering_percent (query, is_buffering, percent);
+ gst_query_set_buffering_range (query, format, start, stop,
+ estimated_total);
+ gst_query_set_buffering_stats (query, GST_BUFFERING_DOWNLOAD,
+ byte_in_rate, byte_out_rate, buffering_left);
+
+ return TRUE;
+}
+#endif
+
static gboolean
gst_queue2_handle_src_query (GstPad * pad, GstQuery * query)
{
/* FIXME - is this condition correct? what should ring buffer do? */
if (QUEUE_IS_USING_QUEUE (queue)) {
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if (!gst_queue2_handle_buffering_query(queue, query))
+ goto peer_failed;
+#else
/* no temp file, just forward to the peer */
if (!gst_queue2_peer_query (queue, queue->sinkpad, query))
goto peer_failed;
GST_DEBUG_OBJECT (queue, "buffering forwarded to peer");
+#endif
} else {
gint64 start, stop, range_start, range_stop;
guint64 writing_pos;
if (peer_res && byte_in_rate > 0.0) {
estimated_total = (duration * 1000) / byte_in_rate;
buffering_left = ((duration - writing_pos) * 1000) / byte_in_rate;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if (is_eos)
+ buffering_left = 0;
+#endif
} else {
estimated_total = -1;
buffering_left = -1;
range_stop = 100 * queued_ranges->writing_pos / duration;
break;
case GST_FORMAT_BYTES:
- range_start = queued_ranges->offset;
+#ifdef GST_EXT_QUEUE_ENHANCEMENT
+ if (queued_ranges->reading_pos > 0)
+ range_start = queued_ranges->reading_pos;
+ else
+#endif
+ range_start = queued_ranges->offset;
range_stop = queued_ranges->writing_pos;
break;
default:
gboolean temp_remove;
#ifdef GST_EXT_QUEUE_ENHANCEMENT
gboolean temp_unlink;
+ guint64 buffer_pad_size;
+ guint64 latest_seek_pos;
#endif
FILE *temp_file;
/* list of downloaded areas and the current area */
# make sure each versioned tool has the right source file and flags
if !GST_DISABLE_LOADSAVE
gst_xmllaunch_@GST_MAJORMINOR@_SOURCES = gst-launch.c tools.h
-gst_xmllaunch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED
+gst_xmllaunch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED -pie
gst_xmllaunch_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
endif
if !GST_DISABLE_PARSE
gst_launch_@GST_MAJORMINOR@_SOURCES = gst-launch.c tools.h
-gst_launch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED
+gst_launch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED -pie
gst_launch_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
endif
gst_inspect_@GST_MAJORMINOR@_SOURCES = gst-inspect.c tools.h
-gst_inspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
+gst_inspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -pie
gst_inspect_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
gst_typefind_@GST_MAJORMINOR@_SOURCES = gst-typefind.c tools.h
-gst_typefind_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
+gst_typefind_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -pie
gst_typefind_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
gst_xmlinspect_@GST_MAJORMINOR@_SOURCES = gst-xmlinspect.c tools.h
-gst_xmlinspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
+gst_xmlinspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -pie
gst_xmlinspect_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
gst-feedback-@GST_MAJORMINOR@: gst-feedback-m.m
command_output ()
{
- echo "+++ $1"
+ /bin/echo "+++ $1"
$1
}
-echo "GStreamer feedback script."
-echo "Please attach the output of this script to your bug reports."
-echo "Bug reports should go into Gnome's bugzilla (http://bugzilla.gnome.org)"
-echo
+/bin/echo "GStreamer feedback script."
+/bin/echo "Please attach the output of this script to your bug reports."
+/bin/echo "Bug reports should go into Gnome's bugzilla (http://bugzilla.gnome.org)"
+/bin/echo
-echo "+ SYSTEM INFORMATION"
+/bin/echo "+ SYSTEM INFORMATION"
command_output "uname -a"
if test -f /etc/redhat-release; then
- echo "+++ distribution: Red Hat"
- cat /etc/redhat-release
+ /bin/echo "+++ distribution: Red Hat"
+ /bin/cat /etc/redhat-release
fi
if test -f /etc/debian_version; then
- echo "+++ distribution: Debian"
- cat /etc/debian_version
+ /bin/echo "+++ distribution: Debian"
+ /bin/cat /etc/debian_version
fi
command_output "cat /etc/issue"
-echo
+/bin/echo
-echo "+ USER INFORMATION"
+/bin/echo "+ USER INFORMATION"
command_output "id"
-echo
+/bin/echo
-echo "+ PKG-CONFIG INFORMATION"
+/bin/echo "+ PKG-CONFIG INFORMATION"
for mm in 0.6 0.7 0.8
do
- echo "+ $mm"
+ /bin/echo "+ $mm"
command_output "pkg-config --version"
command_output "pkg-config gstreamer-$mm --modversion" 2>/dev/null
command_output "pkg-config gstreamer-$mm --cflags" 2>/dev/null
command_output "pkg-config gstreamer-libs-$mm --modversion" 2>/dev/null
command_output "pkg-config gstreamer-libs-$mm --cflags" 2>/dev/null
command_output "pkg-config gstreamer-libs-$mm --libs" 2>/dev/null
- echo
+ /bin/echo
done
for mm in 0.9 0.10
gstreamer-dataprotocol gstreamer-plugins-base gstreamer-net\
gst-python
do
- echo "+ $mm"
+ /bin/echo "+ $mm"
command_output "pkg-config $module-$mm --modversion" 2>/dev/null
command_output "pkg-config $module-$mm --cflags" 2>/dev/null
command_output "pkg-config $module-$mm --libs" 2>/dev/null
- echo
+ /bin/echo
done
done
-echo "+ GSTREAMER INFORMATION (unversioned)"
+/bin/echo "+ GSTREAMER INFORMATION (unversioned)"
command_output "which gst-inspect"
command_output "gst-inspect"
command_output "gst-inspect fakesrc"
command_output "gst-launch fakesrc num-buffers=5 ! fakesink"
for mm in 0.6 0.7 0.8 0.9 0.10
do
- echo "+ GSTREAMER INFORMATION ($mm)"
+ /bin/echo "+ GSTREAMER INFORMATION ($mm)"
command_output "which gst-inspect-$mm"
command_output "gst-inspect-$mm"
command_output "gst-inspect-$mm fakesrc"
command_output "gst-launch-$mm fakesrc num-buffers=5 ! fakesink"
done
-echo "++ looking for gstreamer libraries in common locations"
+/bin/echo "++ looking for gstreamer libraries in common locations"
for dirs in /usr/lib /usr/local/lib; do
if test -d $dirs; then
- find $dirs -name libgstreamer* | grep so
+ /bin/find $dirs -name libgstreamer* | grep so
fi
done
echo "++ looking for gstreamer headers in common locations"
for dirs in /usr/include /usr/local/include; do
if test -d $dirs; then
- find $dirs -name gst.h
+ /bin/find $dirs -name gst.h
fi
done
-echo "+ GSTREAMER PLUG-INS INFORMATION"
+/bin/echo "+ GSTREAMER PLUG-INS INFORMATION"
command_output "gst-inspect volume"
for mm in 0.6 0.7 0.8 0.9 0.10
do
command_output "gst-inspect-$mm volume"
done
-echo "++ looking for gstreamer volume plugin in common locations"
+/bin/echo "++ looking for gstreamer volume plugin in common locations"
for dirs in /usr/lib /usr/local/lib; do
if test -d $dirs; then
- find $dirs -name libgstvolume* | grep so
+ /bin/find $dirs -name libgstvolume* | grep so
fi
done
echo "++ looking for gstreamer headers in common locations"
for dirs in /usr/include /usr/local/include; do
if test -d $dirs; then
- find $dirs -name audio.h
+ /bin/find $dirs -name audio.h
fi
done
gst_data_queue_limits_changed
gst_data_queue_new
gst_data_queue_new_full
+ gst_data_queue_peek
gst_data_queue_pop
gst_data_queue_push
gst_data_queue_set_flushing