From: jk7744.park Date: Sun, 1 Feb 2015 04:44:16 +0000 (+0900) Subject: tizen 2.3 release X-Git-Tag: submit/tizen_2.3/20150202.062637^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.3;p=framework%2Fmultimedia%2Fgst-plugins-ext0.10.git tizen 2.3 release --- diff --git a/wearable/AUTHORS b/AUTHORS similarity index 100% rename from wearable/AUTHORS rename to AUTHORS diff --git a/wearable/COPYING b/COPYING similarity index 100% rename from wearable/COPYING rename to COPYING diff --git a/wearable/INSTALL b/INSTALL similarity index 100% rename from wearable/INSTALL rename to INSTALL diff --git a/wearable/Makefile.am b/Makefile.am similarity index 67% rename from wearable/Makefile.am rename to Makefile.am index e8e3e20..e75ed8c 100755 --- a/wearable/Makefile.am +++ b/Makefile.am @@ -5,12 +5,12 @@ aclocaldir = $(datadir)/aclocal SUBDIRS = common -if GST_EXT_USE_EXT_ENCODEBIN -SUBDIRS += encodebin +if GST_EXT_USE_EXT_PIFFDEMUX +SUBDIRS += piffdemux endif -if GST_EXT_USE_EXT_AVSYSTEM -SUBDIRS += avsystem +if GST_EXT_USE_EXT_ENCODEBIN +SUBDIRS += encodebin endif if GST_EXT_USE_EXT_EVASIMAGESINK @@ -25,6 +25,12 @@ if GST_EXT_USE_EXT_XVIMAGESRC SUBDIRS += xvimagesrc endif +if GST_EXT_USE_EXT_DRMSRC +SUBDIRS += drmsrc +endif +if GST_EXT_USE_EXT_SUBMUX +SUBDIRS += submux +endif if GST_EXT_USE_EXT_TOGGLE SUBDIRS += toggle endif @@ -41,18 +47,26 @@ if GST_EXT_USE_EXT_AUDIOEQ SUBDIRS += audioeq endif +if GST_EXT_USE_EXT_SSDEMUX +SUBDIRS += ssdemux +endif + if GST_EXT_USE_EXT_DASHDEMUX SUBDIRS += dashdemux endif +if GST_EXT_USE_EXT_HLSDEMUX2 +SUBDIRS += hlsdemux2 +endif + DIST_SUBDIRS = common -if GST_EXT_USE_EXT_ENCODEBIN -DIST_SUBDIRS += encodebin +if GST_EXT_USE_EXT_PIFFDEMUX +DIST_SUBDIRS += piffdemux endif -if GST_EXT_USE_EXT_AVSYSTEM -DIST_SUBDIRS += avsystem +if GST_EXT_USE_EXT_ENCODEBIN +DIST_SUBDIRS += encodebin endif if GST_EXT_USE_EXT_EVASIMAGESINK @@ -63,14 +77,28 @@ if GST_EXT_USE_EXT_XVIMAGESRC DIST_SUBDIRS += xvimagesrc endif +if GST_EXT_USE_EXT_DRMSRC +DIST_SUBDIRS += drmsrc +endif +if GST_EXT_USE_EXT_SUBMUX +DIST_SUBDIRS += submux +endif if GST_EXT_USE_EXT_TOGGLE DIST_SUBDIRS += toggle endif +if GST_EXT_USE_EXT_SSDEMUX +DIST_SUBDIRS += ssdemux +endif + if GST_EXT_USE_EXT_DASHDEMUX DIST_SUBDIRS += dashdemux endif +if GST_EXT_USE_EXT_HLSDEMUX2 +DIST_SUBDIRS += hlsdemux2 +endif + EXTRA_DIST = \ gstreamer.spec gstreamer.spec.in \ configure.ac autogen.sh depcomp \ diff --git a/wearable/NEWS b/NEWS similarity index 100% rename from wearable/NEWS rename to NEWS diff --git a/wearable/PLUGINS b/PLUGINS similarity index 100% rename from wearable/PLUGINS rename to PLUGINS diff --git a/wearable/README b/README similarity index 100% rename from wearable/README rename to README diff --git a/wearable/aclocal.m4 b/aclocal.m4 similarity index 100% rename from wearable/aclocal.m4 rename to aclocal.m4 diff --git a/wearable/toggle/Makefile.am b/audioeq/Makefile.am similarity index 100% rename from wearable/toggle/Makefile.am rename to audioeq/Makefile.am diff --git a/wearable/audioeq/src/Makefile.am b/audioeq/src/Makefile.am similarity index 100% rename from wearable/audioeq/src/Makefile.am rename to audioeq/src/Makefile.am diff --git a/wearable/audioeq/src/gstaudioeq.c b/audioeq/src/gstaudioeq.c similarity index 100% rename from wearable/audioeq/src/gstaudioeq.c rename to audioeq/src/gstaudioeq.c diff --git a/wearable/audioeq/src/gstaudioeq.h b/audioeq/src/gstaudioeq.h similarity index 100% rename from wearable/audioeq/src/gstaudioeq.h rename to audioeq/src/gstaudioeq.h diff --git a/wearable/pdpushsrc/Makefile.am b/audiotp/Makefile.am similarity index 100% rename from wearable/pdpushsrc/Makefile.am rename to audiotp/Makefile.am diff --git a/wearable/audiotp/src/Makefile.am b/audiotp/src/Makefile.am similarity index 100% rename from wearable/audiotp/src/Makefile.am rename to audiotp/src/Makefile.am diff --git a/wearable/audiotp/src/gstaudiotp.c b/audiotp/src/gstaudiotp.c similarity index 100% rename from wearable/audiotp/src/gstaudiotp.c rename to audiotp/src/gstaudiotp.c diff --git a/wearable/audiotp/src/gstaudiotp.h b/audiotp/src/gstaudiotp.h similarity index 100% rename from wearable/audiotp/src/gstaudiotp.h rename to audiotp/src/gstaudiotp.h diff --git a/wearable/autogen.sh b/autogen.sh similarity index 100% rename from wearable/autogen.sh rename to autogen.sh diff --git a/wearable/autoregen.sh b/autoregen.sh similarity index 100% rename from wearable/autoregen.sh rename to autoregen.sh diff --git a/wearable/common/ChangeLog b/common/ChangeLog similarity index 100% rename from wearable/common/ChangeLog rename to common/ChangeLog diff --git a/wearable/common/Makefile.am b/common/Makefile.am similarity index 100% rename from wearable/common/Makefile.am rename to common/Makefile.am diff --git a/wearable/common/c-to-xml.py b/common/c-to-xml.py similarity index 100% rename from wearable/common/c-to-xml.py rename to common/c-to-xml.py diff --git a/wearable/common/check-exports b/common/check-exports similarity index 100% rename from wearable/common/check-exports rename to common/check-exports diff --git a/wearable/common/check.mak b/common/check.mak similarity index 100% rename from wearable/common/check.mak rename to common/check.mak diff --git a/wearable/common/coverage/coverage-report-entry.pl b/common/coverage/coverage-report-entry.pl similarity index 100% rename from wearable/common/coverage/coverage-report-entry.pl rename to common/coverage/coverage-report-entry.pl diff --git a/wearable/common/coverage/coverage-report.pl b/common/coverage/coverage-report.pl similarity index 100% rename from wearable/common/coverage/coverage-report.pl rename to common/coverage/coverage-report.pl diff --git a/wearable/common/coverage/coverage-report.xsl b/common/coverage/coverage-report.xsl similarity index 100% rename from wearable/common/coverage/coverage-report.xsl rename to common/coverage/coverage-report.xsl diff --git a/wearable/common/coverage/lcov.mak b/common/coverage/lcov.mak similarity index 100% rename from wearable/common/coverage/lcov.mak rename to common/coverage/lcov.mak diff --git a/wearable/common/gettext.patch b/common/gettext.patch similarity index 100% rename from wearable/common/gettext.patch rename to common/gettext.patch diff --git a/wearable/common/glib-gen.mak b/common/glib-gen.mak similarity index 100% rename from wearable/common/glib-gen.mak rename to common/glib-gen.mak diff --git a/wearable/common/gst-autogen.sh b/common/gst-autogen.sh similarity index 100% rename from wearable/common/gst-autogen.sh rename to common/gst-autogen.sh diff --git a/wearable/common/gst-xmlinspect.py b/common/gst-xmlinspect.py similarity index 100% rename from wearable/common/gst-xmlinspect.py rename to common/gst-xmlinspect.py diff --git a/wearable/common/gst.supp b/common/gst.supp similarity index 100% rename from wearable/common/gst.supp rename to common/gst.supp diff --git a/wearable/common/gstdoc-scangobj b/common/gstdoc-scangobj similarity index 100% rename from wearable/common/gstdoc-scangobj rename to common/gstdoc-scangobj diff --git a/wearable/common/gtk-doc-plugins.mak b/common/gtk-doc-plugins.mak similarity index 100% rename from wearable/common/gtk-doc-plugins.mak rename to common/gtk-doc-plugins.mak diff --git a/wearable/common/gtk-doc.mak b/common/gtk-doc.mak similarity index 100% rename from wearable/common/gtk-doc.mak rename to common/gtk-doc.mak diff --git a/wearable/common/m4/Makefile.am b/common/m4/Makefile.am similarity index 100% rename from wearable/common/m4/Makefile.am rename to common/m4/Makefile.am diff --git a/wearable/common/m4/README b/common/m4/README similarity index 100% rename from wearable/common/m4/README rename to common/m4/README diff --git a/wearable/common/m4/as-ac-expand.m4 b/common/m4/as-ac-expand.m4 similarity index 100% rename from wearable/common/m4/as-ac-expand.m4 rename to common/m4/as-ac-expand.m4 diff --git a/wearable/common/m4/as-auto-alt.m4 b/common/m4/as-auto-alt.m4 similarity index 100% rename from wearable/common/m4/as-auto-alt.m4 rename to common/m4/as-auto-alt.m4 diff --git a/wearable/common/m4/as-compiler-flag.m4 b/common/m4/as-compiler-flag.m4 similarity index 100% rename from wearable/common/m4/as-compiler-flag.m4 rename to common/m4/as-compiler-flag.m4 diff --git a/wearable/common/m4/as-compiler.m4 b/common/m4/as-compiler.m4 similarity index 100% rename from wearable/common/m4/as-compiler.m4 rename to common/m4/as-compiler.m4 diff --git a/wearable/common/m4/as-docbook.m4 b/common/m4/as-docbook.m4 similarity index 100% rename from wearable/common/m4/as-docbook.m4 rename to common/m4/as-docbook.m4 diff --git a/wearable/common/m4/as-gcc-inline-assembly.m4 b/common/m4/as-gcc-inline-assembly.m4 similarity index 100% rename from wearable/common/m4/as-gcc-inline-assembly.m4 rename to common/m4/as-gcc-inline-assembly.m4 diff --git a/wearable/common/m4/as-libtool-tags.m4 b/common/m4/as-libtool-tags.m4 similarity index 100% rename from wearable/common/m4/as-libtool-tags.m4 rename to common/m4/as-libtool-tags.m4 diff --git a/wearable/common/m4/as-libtool.m4 b/common/m4/as-libtool.m4 similarity index 100% rename from wearable/common/m4/as-libtool.m4 rename to common/m4/as-libtool.m4 diff --git a/wearable/common/m4/as-python.m4 b/common/m4/as-python.m4 similarity index 100% rename from wearable/common/m4/as-python.m4 rename to common/m4/as-python.m4 diff --git a/wearable/common/m4/as-scrub-include.m4 b/common/m4/as-scrub-include.m4 similarity index 100% rename from wearable/common/m4/as-scrub-include.m4 rename to common/m4/as-scrub-include.m4 diff --git a/wearable/common/m4/as-version.m4 b/common/m4/as-version.m4 similarity index 100% rename from wearable/common/m4/as-version.m4 rename to common/m4/as-version.m4 diff --git a/wearable/common/m4/ax_create_stdint_h.m4 b/common/m4/ax_create_stdint_h.m4 similarity index 100% rename from wearable/common/m4/ax_create_stdint_h.m4 rename to common/m4/ax_create_stdint_h.m4 diff --git a/wearable/common/m4/check.m4 b/common/m4/check.m4 similarity index 100% rename from wearable/common/m4/check.m4 rename to common/m4/check.m4 diff --git a/wearable/common/m4/gettext.m4 b/common/m4/gettext.m4 similarity index 100% rename from wearable/common/m4/gettext.m4 rename to common/m4/gettext.m4 diff --git a/wearable/common/m4/glib-gettext.m4 b/common/m4/glib-gettext.m4 similarity index 100% rename from wearable/common/m4/glib-gettext.m4 rename to common/m4/glib-gettext.m4 diff --git a/wearable/common/m4/gst-arch.m4 b/common/m4/gst-arch.m4 similarity index 100% rename from wearable/common/m4/gst-arch.m4 rename to common/m4/gst-arch.m4 diff --git a/wearable/common/m4/gst-args.m4 b/common/m4/gst-args.m4 similarity index 100% rename from wearable/common/m4/gst-args.m4 rename to common/m4/gst-args.m4 diff --git a/wearable/common/m4/gst-check.m4 b/common/m4/gst-check.m4 similarity index 100% rename from wearable/common/m4/gst-check.m4 rename to common/m4/gst-check.m4 diff --git a/wearable/common/m4/gst-debuginfo.m4 b/common/m4/gst-debuginfo.m4 similarity index 100% rename from wearable/common/m4/gst-debuginfo.m4 rename to common/m4/gst-debuginfo.m4 diff --git a/wearable/common/m4/gst-default.m4 b/common/m4/gst-default.m4 similarity index 100% rename from wearable/common/m4/gst-default.m4 rename to common/m4/gst-default.m4 diff --git a/wearable/common/m4/gst-doc.m4 b/common/m4/gst-doc.m4 similarity index 100% rename from wearable/common/m4/gst-doc.m4 rename to common/m4/gst-doc.m4 diff --git a/wearable/common/m4/gst-error.m4 b/common/m4/gst-error.m4 similarity index 100% rename from wearable/common/m4/gst-error.m4 rename to common/m4/gst-error.m4 diff --git a/wearable/common/m4/gst-feature.m4 b/common/m4/gst-feature.m4 similarity index 100% rename from wearable/common/m4/gst-feature.m4 rename to common/m4/gst-feature.m4 diff --git a/wearable/common/m4/gst-function.m4 b/common/m4/gst-function.m4 similarity index 100% rename from wearable/common/m4/gst-function.m4 rename to common/m4/gst-function.m4 diff --git a/wearable/common/m4/gst-gettext.m4 b/common/m4/gst-gettext.m4 similarity index 100% rename from wearable/common/m4/gst-gettext.m4 rename to common/m4/gst-gettext.m4 diff --git a/wearable/common/m4/gst-glib2.m4 b/common/m4/gst-glib2.m4 similarity index 100% rename from wearable/common/m4/gst-glib2.m4 rename to common/m4/gst-glib2.m4 diff --git a/wearable/common/m4/gst-libxml2.m4 b/common/m4/gst-libxml2.m4 similarity index 100% rename from wearable/common/m4/gst-libxml2.m4 rename to common/m4/gst-libxml2.m4 diff --git a/wearable/common/m4/gst-parser.m4 b/common/m4/gst-parser.m4 similarity index 100% rename from wearable/common/m4/gst-parser.m4 rename to common/m4/gst-parser.m4 diff --git a/wearable/common/m4/gst-plugin-docs.m4 b/common/m4/gst-plugin-docs.m4 similarity index 100% rename from wearable/common/m4/gst-plugin-docs.m4 rename to common/m4/gst-plugin-docs.m4 diff --git a/wearable/common/m4/gst-plugindir.m4 b/common/m4/gst-plugindir.m4 similarity index 100% rename from wearable/common/m4/gst-plugindir.m4 rename to common/m4/gst-plugindir.m4 diff --git a/wearable/common/m4/gst-valgrind.m4 b/common/m4/gst-valgrind.m4 similarity index 100% rename from wearable/common/m4/gst-valgrind.m4 rename to common/m4/gst-valgrind.m4 diff --git a/wearable/common/m4/gst-x11.m4 b/common/m4/gst-x11.m4 similarity index 100% rename from wearable/common/m4/gst-x11.m4 rename to common/m4/gst-x11.m4 diff --git a/wearable/common/m4/gst.m4 b/common/m4/gst.m4 similarity index 100% rename from wearable/common/m4/gst.m4 rename to common/m4/gst.m4 diff --git a/wearable/common/m4/gtk-doc.m4 b/common/m4/gtk-doc.m4 similarity index 100% rename from wearable/common/m4/gtk-doc.m4 rename to common/m4/gtk-doc.m4 diff --git a/wearable/common/m4/iconv.m4 b/common/m4/iconv.m4 similarity index 100% rename from wearable/common/m4/iconv.m4 rename to common/m4/iconv.m4 diff --git a/wearable/common/m4/isc-posix.m4 b/common/m4/isc-posix.m4 similarity index 100% rename from wearable/common/m4/isc-posix.m4 rename to common/m4/isc-posix.m4 diff --git a/wearable/common/m4/lib-ld.m4 b/common/m4/lib-ld.m4 similarity index 100% rename from wearable/common/m4/lib-ld.m4 rename to common/m4/lib-ld.m4 diff --git a/wearable/common/m4/lib-link.m4 b/common/m4/lib-link.m4 similarity index 100% rename from wearable/common/m4/lib-link.m4 rename to common/m4/lib-link.m4 diff --git a/wearable/common/m4/lib-prefix.m4 b/common/m4/lib-prefix.m4 similarity index 100% rename from wearable/common/m4/lib-prefix.m4 rename to common/m4/lib-prefix.m4 diff --git a/wearable/common/m4/libtool.m4 b/common/m4/libtool.m4 similarity index 100% rename from wearable/common/m4/libtool.m4 rename to common/m4/libtool.m4 diff --git a/wearable/common/m4/ltoptions.m4 b/common/m4/ltoptions.m4 similarity index 100% rename from wearable/common/m4/ltoptions.m4 rename to common/m4/ltoptions.m4 diff --git a/wearable/common/m4/ltsugar.m4 b/common/m4/ltsugar.m4 similarity index 100% rename from wearable/common/m4/ltsugar.m4 rename to common/m4/ltsugar.m4 diff --git a/wearable/common/m4/ltversion.m4 b/common/m4/ltversion.m4 similarity index 100% rename from wearable/common/m4/ltversion.m4 rename to common/m4/ltversion.m4 diff --git a/wearable/common/m4/lt~obsolete.m4 b/common/m4/lt~obsolete.m4 similarity index 100% rename from wearable/common/m4/lt~obsolete.m4 rename to common/m4/lt~obsolete.m4 diff --git a/wearable/common/m4/pkg.m4 b/common/m4/pkg.m4 similarity index 100% rename from wearable/common/m4/pkg.m4 rename to common/m4/pkg.m4 diff --git a/wearable/common/m4/progtest.m4 b/common/m4/progtest.m4 similarity index 100% rename from wearable/common/m4/progtest.m4 rename to common/m4/progtest.m4 diff --git a/wearable/common/mangle-tmpl.py b/common/mangle-tmpl.py similarity index 100% rename from wearable/common/mangle-tmpl.py rename to common/mangle-tmpl.py diff --git a/wearable/common/plugins.xsl b/common/plugins.xsl similarity index 100% rename from wearable/common/plugins.xsl rename to common/plugins.xsl diff --git a/wearable/common/po.mak b/common/po.mak similarity index 100% rename from wearable/common/po.mak rename to common/po.mak diff --git a/wearable/common/release.mak b/common/release.mak similarity index 100% rename from wearable/common/release.mak rename to common/release.mak diff --git a/wearable/common/scangobj-merge.py b/common/scangobj-merge.py similarity index 100% rename from wearable/common/scangobj-merge.py rename to common/scangobj-merge.py diff --git a/wearable/common/upload.mak b/common/upload.mak similarity index 100% rename from wearable/common/upload.mak rename to common/upload.mak diff --git a/wearable/common/win32.mak b/common/win32.mak similarity index 100% rename from wearable/common/win32.mak rename to common/win32.mak diff --git a/wearable/compile b/compile similarity index 100% rename from wearable/compile rename to compile diff --git a/wearable/config.guess b/config.guess similarity index 100% rename from wearable/config.guess rename to config.guess diff --git a/wearable/config.h.in b/config.h.in similarity index 100% rename from wearable/config.h.in rename to config.h.in diff --git a/wearable/config.sub b/config.sub similarity index 100% rename from wearable/config.sub rename to config.sub diff --git a/wearable/configure b/configure similarity index 100% rename from wearable/configure rename to configure diff --git a/mobile/configure.ac b/configure.ac old mode 100644 new mode 100755 similarity index 77% rename from mobile/configure.ac rename to configure.ac index 60d51b0..c5a82ed --- a/mobile/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_INIT(extension, 1.0) - + dnl versions of gstreamer and plugins-base GST_MAJORMINOR=0.10 GST_REQUIRED=0.10.0 @@ -39,10 +39,10 @@ AC_PROG_LIBTOOL dnl decide on error flags AS_COMPILER_FLAG(-Wall, GST_WALL="yes", GST_WALL="no") - + if test "x$GST_WALL" = "xyes"; then GST_ERROR="$GST_ERROR -Wall" - + # if test "x$GST_PLUGIN_CVS" = "xyes"; then # AS_COMPILER_FLAG(-Werror,GST_ERROR="$GST_ERROR -Werror",GST_ERROR="$GST_ERROR") # fi @@ -195,9 +195,14 @@ AC_SUBST(TBM_CFLAGS) AC_SUBST(TBM_LIBS) dnl use time analysis module -PKG_CHECK_MODULES(MMTA, mm-ta) -AC_SUBST(MMTA_CFLAGS) -AC_SUBST(MMTA_LIBS) + +PKG_CHECK_MODULES(XML2, libxml-2.0) +AC_SUBST(XML2_CFLAGS) +AC_SUBST(XML2_LIBS) + +PKG_CHECK_MODULES(NATIVE_BUFFER, native-buffer) +AC_SUBST(NATIVE_BUFFER_CFLAGS) +AC_SUBST(NATIVE_BUFFER_LIBS) dnl required package for evasimagesink/evaspixmapsink PKG_CHECK_MODULES(EFL, [ @@ -294,6 +299,10 @@ PKG_CHECK_MODULES(TBM, libtbm) AC_SUBST(TBM_CFLAGS) AC_SUBST(TBM_LIBS) +PKG_CHECK_MODULES(VCONF, vconf) +AC_SUBST(VCONF_CFLAGS) +AC_SUBST(VCONF_LIBS) + dnl PKG_CHECK_MODULES(UDEVMGR, unified-dev-mgr) dnl AC_SUBST(UDEVMGR_CFLAGS) dnl AC_SUBST(UDEVMGR_LIBS) @@ -310,18 +319,6 @@ AC_ARG_ENABLE(ext-encodebin, AC_HELP_STRING([--enable-ext-encodebin], [using enc [GST_EXT_USE_EXT_ENCODEBIN=yes]) AM_CONDITIONAL(GST_EXT_USE_EXT_ENCODEBIN, test "x$GST_EXT_USE_EXT_ENCODEBIN" = "xyes") -dnl use ext-avsystem -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-avsystem, AC_HELP_STRING([--enable-ext-avsystem], [using avsystem]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_AVSYSTEM=yes ;; - no) GST_EXT_USE_EXT_AVSYSTEM=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-avsystem) ;; - esac - ], - [GST_EXT_USE_EXT_AVSYSTEM=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AVSYSTEM, test "x$GST_EXT_USE_EXT_AVSYSTEM" = "xyes") - dnl use ext-evasimagesink -------------------------------------------------------------------------- AC_ARG_ENABLE(ext-evasimagesink, AC_HELP_STRING([--enable-ext-evasimagesink], [using evasimagesink]), [ @@ -358,30 +355,16 @@ AC_ARG_ENABLE(ext-xvimagesrc, AC_HELP_STRING([--enable-ext-xvimagesrc], [using x [GST_EXT_USE_EXT_XVIMAGESRC=yes]) AM_CONDITIONAL(GST_EXT_USE_EXT_XVIMAGESRC, test "x$GST_EXT_USE_EXT_XVIMAGESRC" = "xyes") -dnl use ext-gstreamer-audio ------------------------------------------------------------------- -AC_ARG_ENABLE(ext-gstreamer-audio, AC_HELP_STRING([--enable-ext-gstreamer-audio], [using gstreamer-audio]), +AC_ARG_ENABLE(pcmdump, AC_HELP_STRING([--enable-pcmdump], [pcm dump]), [ case "${enableval}" in - yes) GST_EXT_USE_EXT_AVSYSAUDIO=yes ;; - no) GST_EXT_USE_EXT_AVSYSAUDIO=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-gstreamer-audio) ;; + yes) PCM_DUMP_ENABLE=yes ;; + no) PCM_DUMP_ENABLE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-pcmdump) ;; esac ], - [GST_EXT_USE_EXT_AVSYSAUDIO=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AVSYSAUDIO, test "x$GST_EXT_USE_EXT_AVSYSAUDIO" = "xyes") - -if test "x$GST_EXT_USE_EXT_AVSYSAUDIO" = "xyes"; then - HAVE_AVSYSAUDIO=NO - PKG_CHECK_MODULES(AVSYSAUDIO, avsysaudio, HAVE_AVSYSAUDIO="yes", [ - HAVE_AVSYSAUDIO="no" - AC_MSG_RESULT(no) - ]) - if test "x$HAVE_AVSYSAUDIO" = "xno"; then - AC_MSG_ERROR(no avsysaudio package found) - fi - AC_SUBST(AVSYSAUDIO_CFLAGS) - AC_SUBST(AVSYSAUDIO_LIBS) -fi + [PCM_DUMP_ENABLE=no]) +AM_CONDITIONAL([PCM_DUMP_ENABLE], [test "x$PCM_DUMP_ENABLE" = "xyes"]) dnl use ext-drmsrc -------------------------------------------------------------------------- AC_ARG_ENABLE(ext-drmsrc, AC_HELP_STRING([--enable-ext-drmsrc], [using drmsrc]), @@ -394,6 +377,28 @@ AC_ARG_ENABLE(ext-drmsrc, AC_HELP_STRING([--enable-ext-drmsrc], [using drmsrc]), ], [GST_EXT_USE_EXT_DRMSRC=yes]) AM_CONDITIONAL(GST_EXT_USE_EXT_DRMSRC, test "x$GST_EXT_USE_EXT_DRMSRC" = "xyes") + +if test "x$GST_EXT_USE_EXT_DRMSRC" = "xyes"; then + PKG_CHECK_MODULES(DRM_CLIENT, drm-client) + AC_SUBST(DRM_CLIENT_CFLAGS) + AC_SUBST(DRM_CLIENT_LIBS) + PKG_CHECK_MODULES(DRM_TRUSTED, drm-trusted) + AC_SUBST(DRM_TRUSTED_CFLAGS) + AC_SUBST(DRM_TRUSTED_LIBS) +fi + +dnl use ext-submux -------------------------------------------------------------------------- +AC_ARG_ENABLE(ext-submux, AC_HELP_STRING([--enable-ext-submux], [using submux]), + [ + case "${enableval}" in + yes) GST_EXT_USE_EXT_SUBMUX=yes ;; + no) GST_EXT_USE_EXT_SUBMUX=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-submux) ;; + esac + ], + [GST_EXT_USE_EXT_SUBMUX=yes]) +AM_CONDITIONAL(GST_EXT_USE_EXT_SUBMUX, test "x$GST_EXT_USE_EXT_SUBMUX" = "xyes") + dnl use ext-toggle -------------------------------------------------------------------------- AC_ARG_ENABLE(ext-toggle, AC_HELP_STRING([--enable-ext-toggle], [using toggle]), [ @@ -448,19 +453,81 @@ AC_ARG_ENABLE(ext-audioeq, AC_HELP_STRING([--enable-ext-audioeq], [using audioeq yes) GST_EXT_USE_EXT_AUDIOEQ=yes ;; no) GST_EXT_USE_EXT_AUDIOEQ=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-audioeq) ;; - esac + esac ], [GST_EXT_USE_EXT_AUDIOEQ=yes]) AM_CONDITIONAL(GST_EXT_USE_EXT_AUDIOEQ, test "x$GST_EXT_USE_EXT_AUDIOEQ" = "xyes") +dnl use ext-piffdemux -------------------------------------------------------------------------- +AC_ARG_ENABLE(ext-piffdemux, AC_HELP_STRING([--enable-ext-piffdemux], [using piffdemux]), +[ + case "${enableval}" in + yes) GST_EXT_USE_EXT_PIFFDEMUX=yes ;; + no) GST_EXT_USE_EXT_PIFFDEMUX=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-piffdemux) ;; + esac + ], + [GST_EXT_USE_EXT_PIFFDEMUX=yes]) +AM_CONDITIONAL(GST_EXT_USE_EXT_PIFFDEMUX, test "x$GST_EXT_USE_EXT_PIFFDEMUX" = "xyes") + +#if test "x$GST_EXT_USE_EXT_PIFFDEMUX" = "xyes"; then +# PKG_CHECK_MODULES(DRM_CLIENT, drm-client) +# AC_SUBST(DRM_CLIENT_CFLAGS) +# AC_SUBST(DRM_CLIENT_LIBS) +# PKG_CHECK_MODULES(DRM_TRUSTED, drm-trusted) +# AC_SUBST(DRM_TRUSTED_CFLAGS) +# AC_SUBST(DRM_TRUSTED_LIBS) +#fi + +dnl use ext-ssdemux -------------------------------------------------------------------------- +AC_ARG_ENABLE(ext-ssdemux, AC_HELP_STRING([--enable-ext-ssdemux], [using ssdemux]), +[ + case "${enableval}" in + yes) GST_EXT_USE_EXT_SSDEMUX=yes ;; + no) GST_EXT_USE_EXT_SSDEMUX=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-ssdemux) ;; + esac + ], + [GST_EXT_USE_EXT_SSDEMUX=yes]) +AM_CONDITIONAL(GST_EXT_USE_EXT_SSDEMUX, test "x$GST_EXT_USE_EXT_SSDEMUX" = "xyes") + +dnl use ext-dashdemux ----------------------------------------------------------------------- +AC_ARG_ENABLE(ext-dashdemux, AC_HELP_STRING([--enable-ext-dashdemux], [using dashdemux]), + [ + case "${enableval}" in + yes) GST_EXT_USE_EXT_DASHDEMUX=yes ;; + no) GST_EXT_USE_EXT_DASHDEMUX=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-dashdemux) ;; + esac + ], + [GST_EXT_USE_EXT_DASHDEMUX=yes]) +AM_CONDITIONAL(GST_EXT_USE_EXT_DASHDEMUX, test "x$GST_EXT_USE_EXT_DASHDEMUX" = "xyes") + +dnl use ext-hlsdemux2 ----------------------------------------------------------------------- +AC_ARG_ENABLE(ext-hlsdemux2, AC_HELP_STRING([--enable-ext-hlsdemux2], [using hlsdemux2]), + [ + case "${enableval}" in + yes) GST_EXT_USE_EXT_HLSDEMUX2=yes ;; + no) GST_EXT_USE_EXT_HLSDEMUX2=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-hlsdemux2) ;; + esac + ] + [GST_EXT_USE_EXT_HLSDEMUX2=yes]) +AM_CONDITIONAL(GST_EXT_USE_EXT_HLSDEMUX2, test "x$GST_EXT_USE_EXT_HLSDEMUX2" = "xyes") + +if test "x$GST_EXT_USE_EXT_HLSDEMUX2" = "xyes"; then + dnl crypto for hlsdemux + PKG_CHECK_MODULES(CRYPTO, libcrypto) + AC_SUBST(CRYPTO_CFLAGS) + AC_SUBST(CRYPTO_LIBS) +fi + AC_OUTPUT( Makefile common/Makefile common/m4/Makefile -avsystem/Makefile pdpushsrc/Makefile pdpushsrc/src/Makefile -avsystem/src/Makefile encodebin/Makefile encodebin/src/Makefile evasimagesink/Makefile @@ -472,8 +539,18 @@ toggle/Makefile toggle/src/Makefile drmsrc/Makefile drmsrc/src/Makefile +submux/Makefile +submux/src/Makefile audiotp/Makefile audiotp/src/Makefile audioeq/Makefile audioeq/src/Makefile +piffdemux/Makefile +piffdemux/src/Makefile +ssdemux/Makefile +ssdemux/src/Makefile +dashdemux/Makefile +dashdemux/src/Makefile +hlsdemux2/Makefile +hlsdemux2/src/Makefile ) diff --git a/wearable/control.in b/control.in similarity index 100% rename from wearable/control.in rename to control.in diff --git a/wearable/evasimagesink/Makefile.am b/dashdemux/Makefile.am old mode 100644 new mode 100755 similarity index 100% rename from wearable/evasimagesink/Makefile.am rename to dashdemux/Makefile.am diff --git a/wearable/dashdemux/src/Makefile.am b/dashdemux/src/Makefile.am similarity index 90% rename from wearable/dashdemux/src/Makefile.am rename to dashdemux/src/Makefile.am index 892762d..643c7b2 100644 --- a/wearable/dashdemux/src/Makefile.am +++ b/dashdemux/src/Makefile.am @@ -6,6 +6,7 @@ libgstdashdemux_la_SOURCES = \ gstdashdemux.c \ gstfragment.c \ gsturidownloader.c \ + gstdownloadrate.c \ gstplugin.c # headers we need but don't want installed @@ -14,7 +15,8 @@ noinst_HEADERS = \ gstfragmented.h \ gstfragment.h \ gstdashdemux.h \ - gsturidownloader.h + gsturidownloader.h \ + gstdownloadrate.h # compiler and linker flags used to compile this plugin, set in configure.ac libgstdashdemux_la_CFLAGS = $(GST_CFLAGS) diff --git a/wearable/dashdemux/src/Makefile.in b/dashdemux/src/Makefile.in similarity index 100% rename from wearable/dashdemux/src/Makefile.in rename to dashdemux/src/Makefile.in diff --git a/wearable/dashdemux/src/glibcompat.h b/dashdemux/src/glibcompat.h similarity index 100% rename from wearable/dashdemux/src/glibcompat.h rename to dashdemux/src/glibcompat.h diff --git a/wearable/dashdemux/src/gstdashdemux.c b/dashdemux/src/gstdashdemux.c similarity index 55% rename from wearable/dashdemux/src/gstdashdemux.c rename to dashdemux/src/gstdashdemux.c index d3460e1..ba6fe2b 100755 --- a/wearable/dashdemux/src/gstdashdemux.c +++ b/dashdemux/src/gstdashdemux.c @@ -167,7 +167,6 @@ enum { PROP_0, - PROP_MIN_BUFFERING_TIME, PROP_MAX_BUFFERING_TIME, PROP_BANDWIDTH_USAGE, PROP_MAX_BITRATE, @@ -175,12 +174,21 @@ enum }; /* Default values for properties */ -#define DEFAULT_MIN_BUFFERING_TIME 5 /* in seconds */ #define DEFAULT_MAX_BUFFERING_TIME 30 /* in seconds */ #define DEFAULT_BANDWIDTH_USAGE 0.8 /* 0 to 1 */ #define DEFAULT_MAX_BITRATE 24000000 /* in bit/s */ #define DEFAULT_FAILED_COUNT 3 +#define DOWNLOAD_RATE_HISTORY_MAX 3 +#define DOWNLOAD_RATE_TIME_MAX 3 * GST_SECOND + +/* Custom internal event to signal end of period */ +#define GST_EVENT_DASH_EOP GST_EVENT_MAKE_TYPE(81, GST_EVENT_TYPE_DOWNSTREAM | GST_EVENT_TYPE_SERIALIZED) +static GstEvent * +gst_event_new_dash_eop (void) +{ + return gst_event_new_custom (GST_EVENT_DASH_EOP, NULL); +} /* GObject */ @@ -202,18 +210,16 @@ static gboolean gst_dash_demux_src_query (GstPad * pad, GstQuery * query); static void gst_dash_demux_stream_loop (GstDashDemux * demux); static void gst_dash_demux_download_loop (GstDashDemux * demux); static void gst_dash_demux_stop (GstDashDemux * demux); -static void gst_dash_demux_pause_stream_task (GstDashDemux * demux); static void gst_dash_demux_resume_stream_task (GstDashDemux * demux); static void gst_dash_demux_resume_download_task (GstDashDemux * demux); static gboolean gst_dash_demux_setup_all_streams (GstDashDemux * demux); -static gboolean gst_dash_demux_select_representations (GstDashDemux * demux, - guint64 current_bitrate); -static gboolean gst_dash_demux_get_next_fragment_set (GstDashDemux * demux); +static gboolean gst_dash_demux_select_representations (GstDashDemux * demux); +static GstCaps *gst_dash_demux_get_input_caps (GstDashDemux * demux, GstActiveStream * stream); +static gboolean gst_dash_demux_get_next_fragment (GstDashDemux * demux, GstActiveStream **fragment_stream, GstClockTime *selected_ts); +static void gst_dash_demux_clear_streams(GstDashDemux * demux); static void gst_dash_demux_reset (GstDashDemux * demux, gboolean dispose); static GstClockTime gst_dash_demux_get_buffering_time (GstDashDemux * demux); -static float gst_dash_demux_get_buffering_ratio (GstDashDemux * demux); -static GstBuffer *gst_dash_demux_merge_buffer_list (GstFragment * fragment); static void _do_init (GType type) @@ -268,10 +274,12 @@ gst_dash_demux_dispose (GObject * obj) } gst_object_unref (demux->download_task); g_static_rec_mutex_free (&demux->download_lock); - g_mutex_free(demux->download_timed_lock); demux->download_task = NULL; } + g_cond_clear (&demux->download_cond); + g_mutex_clear (&demux->download_mutex); + if (demux->downloader != NULL) { g_object_unref (demux->downloader); demux->downloader = NULL; @@ -279,8 +287,6 @@ gst_dash_demux_dispose (GObject * obj) gst_dash_demux_reset (demux, TRUE); - g_queue_free (demux->queue); - G_OBJECT_CLASS (parent_class)->dispose (obj); } @@ -297,12 +303,6 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass) gobject_class->get_property = gst_dash_demux_get_property; gobject_class->dispose = gst_dash_demux_dispose; - g_object_class_install_property (gobject_class, PROP_MIN_BUFFERING_TIME, - g_param_spec_uint ("min-buffering-time", "Minimum buffering time", - "Minimum number of seconds of buffer accumulated before playback", - 1, G_MAXUINT, DEFAULT_MIN_BUFFERING_TIME, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_MAX_BUFFERING_TIME, g_param_spec_uint ("max-buffering-time", "Maximum buffering time", "Maximum number of seconds of buffer accumulated during playback", @@ -326,6 +326,48 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass) GST_DEBUG_FUNCPTR (gst_dash_demux_change_state); } +static gboolean +_check_queue_full (GstDataQueue * q, guint visible, guint bytes, guint64 time, + GstDashDemux *demux) +{ + return time > demux->max_buffering_time; +} + +static void +_data_queue_item_destroy (GstDataQueueItem * item) +{ + gst_mini_object_unref (item->object); + g_free (item); +} + +static void +gst_dash_demux_stream_push_event (GstDashDemuxStream * stream, + GstEvent *event) +{ + GstDataQueueItem *item = g_new0 (GstDataQueueItem, 1); + + item->object = GST_MINI_OBJECT_CAST (event); + item->destroy = (GDestroyNotify) _data_queue_item_destroy; + + gst_data_queue_push (stream->queue, item); +} + +static void +gst_dash_demux_stream_push_data (GstDashDemuxStream * stream, + GstBuffer * buffer) +{ + GstDataQueueItem *item = g_new0 (GstDataQueueItem, 1); + + item->object = GST_MINI_OBJECT_CAST (buffer); + item->duration = GST_BUFFER_DURATION (buffer); + item->visible = TRUE; + item->size = GST_BUFFER_SIZE (buffer); + + item->destroy = (GDestroyNotify) _data_queue_item_destroy; + + gst_data_queue_push (stream->queue, item); +} + static void gst_dash_demux_init (GstDashDemux * demux, GstDashDemuxClass * klass) { @@ -341,18 +383,20 @@ gst_dash_demux_init (GstDashDemux * demux, GstDashDemuxClass * klass) demux->downloader = gst_uri_downloader_new (); /* Properties */ - demux->min_buffering_time = DEFAULT_MIN_BUFFERING_TIME * GST_SECOND; demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME * GST_SECOND; demux->bandwidth_usage = DEFAULT_BANDWIDTH_USAGE; demux->max_bitrate = DEFAULT_MAX_BITRATE; - demux->queue = g_queue_new (); + demux->max_video_width = 0; + demux->max_video_height = 0; + /* Updates task */ g_static_rec_mutex_init (&demux->download_lock); demux->download_task = gst_task_create ((GstTaskFunction) gst_dash_demux_download_loop, demux); gst_task_set_lock (demux->download_task, &demux->download_lock); - demux->download_timed_lock = g_mutex_new (); + g_cond_init (&demux->download_cond); + g_mutex_init (&demux->download_mutex); /* Streaming task */ g_static_rec_mutex_init (&demux->stream_lock); @@ -369,9 +413,6 @@ gst_dash_demux_set_property (GObject * object, guint prop_id, GstDashDemux *demux = GST_DASH_DEMUX (object); switch (prop_id) { - case PROP_MIN_BUFFERING_TIME: - demux->min_buffering_time = g_value_get_uint (value) * GST_SECOND; - break; case PROP_MAX_BUFFERING_TIME: demux->max_buffering_time = g_value_get_uint (value) * GST_SECOND; break; @@ -394,13 +435,8 @@ gst_dash_demux_get_property (GObject * object, guint prop_id, GValue * value, GstDashDemux *demux = GST_DASH_DEMUX (object); switch (prop_id) { - case PROP_MIN_BUFFERING_TIME: - g_value_set_uint (value, demux->min_buffering_time); - demux->min_buffering_time *= GST_SECOND; - break; case PROP_MAX_BUFFERING_TIME: - g_value_set_uint (value, demux->max_buffering_time); - demux->max_buffering_time *= GST_SECOND; + g_value_set_uint (value, demux->max_buffering_time / GST_SECOND); break; case PROP_BANDWIDTH_USAGE: g_value_set_float (value, demux->bandwidth_usage); @@ -420,18 +456,14 @@ gst_dash_demux_change_state (GstElement * element, GstStateChange transition) GstStateChangeReturn ret; GstDashDemux *demux = GST_DASH_DEMUX (element); + GST_DEBUG_OBJECT (demux, "changing state %s - %s", + gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)), + gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition))); + switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: gst_dash_demux_reset (demux, FALSE); break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - /* Start the streaming loop in paused only if we already received - the manifest. It might have been stopped if we were in PAUSED - state and we filled our queue with enough cached fragments - */ - if (demux->client->mpd_node != NULL) - gst_dash_demux_resume_stream_task (demux); - break; default: break; } @@ -439,9 +471,6 @@ gst_dash_demux_change_state (GstElement * element, GstStateChange transition) ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - gst_dash_demux_pause_stream_task (demux); - break; case GST_STATE_CHANGE_PAUSED_TO_READY: demux->cancelled = TRUE; gst_dash_demux_stop (demux); @@ -455,19 +484,16 @@ gst_dash_demux_change_state (GstElement * element, GstStateChange transition) } void -gst_dash_demux_clear_queue (GstDashDemux * demux) +gst_dash_demux_flush_stream_queues (GstDashDemux * demux) { - while (!g_queue_is_empty (demux->queue)) { - GList *listfragment = g_queue_pop_head (demux->queue); - guint j = 0; - while (j < g_list_length (listfragment)) { - GstFragment *fragment = g_list_nth_data (listfragment, j); - g_object_unref (fragment); - j++; - } - g_list_free (listfragment); + GSList *it; + GstDashDemuxStream *stream; + for(it = demux->streams; it; it=it->next) + { + stream = it->data; + gst_data_queue_set_flushing(stream->queue, TRUE); + gst_data_queue_flush(stream->queue); } - g_queue_clear (demux->queue); } static gboolean @@ -486,13 +512,15 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) GstSeekType start_type, stop_type; gint64 start, stop; GList *list; - GstClockTime current_pos, target_pos; - guint current_sequence, current_period; + GstClockTime current_pos = GST_CLOCK_TIME_NONE; + GstClockTime target_pos; + guint current_period; GstActiveStream *stream; - GstMediaSegment *chunk; - GstStreamPeriod *period; + GstStreamPeriod *period = NULL; guint nb_active_stream; - guint stream_idx; + guint stream_idx = 0; + guint *seek_idx = NULL; /*Seek positions on each stream*/ + gboolean end_of_mpd = FALSE; if (gst_mpd_client_is_live (demux->client)) { GST_WARNING_OBJECT (demux, "Received seek event for live stream"); @@ -525,6 +553,11 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) break; } } + if(target_pos == current_pos + period->duration) { + /*Seeking to the end of MPD*/ + end_of_mpd = TRUE; + goto seeking; + } if (list == NULL) { GST_WARNING_OBJECT (demux, "Could not find seeked Period"); return FALSE; @@ -537,25 +570,31 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) return FALSE; } - stream = gst_mpdparser_get_active_stream_by_index (demux->client, 0); - current_pos = 0; - for (list = g_list_first (stream->segments); list; - list = g_list_next (list)) { - chunk = list->data; - current_pos = chunk->start_time; - current_sequence = chunk->number; - if (current_pos <= target_pos - && target_pos < current_pos + chunk->duration) { - break; - } + /*select the requested segments for all streams*/ + nb_active_stream = gst_mpdparser_get_nb_active_stream (demux->client); + seek_idx = g_malloc0(sizeof(gint)*nb_active_stream); + gint video_idx = gst_mpd_client_get_video_active_stream_id(demux->client); + if(video_idx >= 0) { + /*Seeking on video stream firstly.*/ + GstClockTime segment_start; + segment_start = gst_mpd_client_stream_find_segment(demux->client, video_idx, + target_pos, &seek_idx[video_idx]); + if(!GST_CLOCK_TIME_IS_VALID(segment_start)) + goto no_segment; + target_pos = segment_start; } - //GST_MPD_CLIENT_UNLOCK (demux->client); - - if (list == NULL) { - GST_WARNING_OBJECT (demux, "Could not find seeked fragment"); - return FALSE; + /*Seeking on non video streams*/ + for (stream_idx = 0; stream_idx < nb_active_stream; stream_idx++) { + if (video_idx != stream_idx) { + GstClockTime stream_start = gst_mpd_client_stream_find_segment(demux->client, + stream_idx, target_pos, &seek_idx[stream_idx]); + if(!GST_CLOCK_TIME_IS_VALID (stream_start)) { + goto no_segment; + } + } } +seeking: /* We can actually perform the seek */ nb_active_stream = gst_mpdparser_get_nb_active_stream (demux->client); @@ -563,7 +602,9 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) GST_DEBUG_OBJECT (demux, "sending flush start"); stream_idx = 0; while (stream_idx < nb_active_stream) { - gst_pad_push_event (demux->srcpad[stream_idx], + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, stream_idx); + dash_stream->need_header = TRUE; + gst_pad_push_event (dash_stream->srcpad, gst_event_new_flush_start ()); stream_idx++; } @@ -572,32 +613,48 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) /* Stop the demux */ demux->cancelled = TRUE; gst_dash_demux_stop (demux); + GST_DEBUG_OBJECT (demux, "joining tasks"); + gst_task_join (demux->stream_task); + gst_task_join (demux->download_task); + GST_DEBUG_OBJECT (demux, "tasks was joined"); /* Wait for streaming to finish */ g_static_rec_mutex_lock (&demux->stream_lock); - /* Clear the buffering queue */ - /* FIXME: allow seeking in the buffering queue */ - gst_dash_demux_clear_queue (demux); - //GST_MPD_CLIENT_LOCK (demux->client); - GST_DEBUG_OBJECT (demux, "Seeking to sequence %d", current_sequence); - /* Update the current sequence on all streams */ - gst_mpd_client_set_segment_index_for_all_streams (demux->client, - current_sequence); - /* Calculate offset in the next fragment */ - demux->position = gst_mpd_client_get_current_position (demux->client); - demux->position_shift = start - demux->position; - demux->need_segment = TRUE; + demux->end_of_period = end_of_mpd; //GST_MPD_CLIENT_UNLOCK (demux->client); + + for (stream_idx = 0; stream_idx < nb_active_stream; stream_idx++) { + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, stream_idx); + GstCaps *caps = gst_pad_get_negotiated_caps (dash_stream->srcpad); + if(caps) { + gst_caps_replace (&dash_stream->input_caps, NULL); + gst_caps_unref (caps); + } + if(!end_of_mpd) { + GST_DEBUG_OBJECT (demux, "Seeking to sequence %d on stream %d", seek_idx[stream_idx], stream_idx); + stream = gst_mpdparser_get_active_stream_by_index (demux->client, stream_idx); + gst_mpd_client_set_segment_index(stream, seek_idx[stream_idx]); + } + gst_data_queue_set_flushing(dash_stream->queue, FALSE); + dash_stream->start_time = target_pos; + dash_stream->download_end_of_period = end_of_mpd; + dash_stream->stream_end_of_period = end_of_mpd; + dash_stream->stream_eos = end_of_mpd; + dash_stream->need_segment = TRUE; + } + if(!end_of_mpd) + g_free(seek_idx); + if (flags & GST_SEEK_FLAG_FLUSH) { GST_DEBUG_OBJECT (demux, "Sending flush stop on all pad"); - stream_idx = 0; - while (stream_idx < nb_active_stream) { - gst_pad_push_event (demux->srcpad[stream_idx], + + for (stream_idx = 0; stream_idx < nb_active_stream; stream_idx++) { + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, stream_idx); + gst_pad_push_event (dash_stream->srcpad, gst_event_new_flush_stop ()); - stream_idx++; } } @@ -608,6 +665,12 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) g_static_rec_mutex_unlock (&demux->stream_lock); return TRUE; +no_segment: + { + GST_WARNING_OBJECT (demux, "Could not find seeked fragment on stream %d", stream_idx); + g_free(seek_idx); + return FALSE; + } } default: break; @@ -617,21 +680,25 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) } static gboolean -gst_dash_demux_setup_all_streams (GstDashDemux * demux) +gst_dash_demux_setup_mpdparser_streams (GstDashDemux * demux, GstMpdClient *client) { GList *listLang = NULL; guint i, nb_audio; gchar *lang; - GST_MPD_CLIENT_LOCK (demux->client); + GST_MPD_CLIENT_LOCK (client); /* clean old active stream list, if any */ - gst_active_streams_free (demux->client); + gst_active_streams_free (client); - if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_VIDEO, "")) + if (!gst_mpd_client_setup_streaming (client, GST_STREAM_VIDEO, "")) { GST_INFO_OBJECT (demux, "No video adaptation set found"); + } else { + gst_mpd_client_get_max_video_dimensions(client, &demux->max_video_width, + &demux->max_video_height); + } nb_audio = - gst_mpdparser_get_list_and_nb_of_audio_language (demux->client, + gst_mpdparser_get_list_and_nb_of_audio_language (client, &listLang); if (nb_audio == 0) nb_audio = 1; @@ -639,17 +706,61 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux) for (i = 0; i < nb_audio; i++) { lang = (gchar *) g_list_nth_data (listLang, i); - if (gst_mpdparser_get_nb_adaptationSet (demux->client) > 1) - if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_AUDIO, + if (gst_mpdparser_get_nb_adaptationSet (client) > 1) + if (!gst_mpd_client_setup_streaming (client, GST_STREAM_AUDIO, lang)) GST_INFO_OBJECT (demux, "No audio adaptation set found"); - if (gst_mpdparser_get_nb_adaptationSet (demux->client) > nb_audio) - if (!gst_mpd_client_setup_streaming (demux->client, + if (gst_mpdparser_get_nb_adaptationSet (client) > nb_audio) + if (!gst_mpd_client_setup_streaming (client, GST_STREAM_APPLICATION, lang)) GST_INFO_OBJECT (demux, "No application adaptation set found"); } - GST_MPD_CLIENT_UNLOCK (demux->client); + GST_MPD_CLIENT_UNLOCK (client); + return TRUE; +} + +static gboolean +gst_dash_demux_setup_all_streams (GstDashDemux * demux) +{ + guint i; + if( !gst_dash_demux_setup_mpdparser_streams(demux, demux->client)) + return FALSE; + + GST_DEBUG_OBJECT (demux, "Creating dashdemux streams"); + gst_dash_demux_clear_streams(demux); + for ( i =0; i < gst_mpdparser_get_nb_active_stream (demux->client); i++) { + GstDashDemuxStream *dash_stream; + GstCaps *caps; + GstActiveStream *active_stream; + dash_stream = g_new0(GstDashDemuxStream, 1); + demux->streams = g_slist_append(demux->streams, dash_stream); + dash_stream->idx = i; + dash_stream->queue = gst_data_queue_new ((GstDataQueueCheckFullFunction) _check_queue_full, demux); + dash_stream->need_header = TRUE; + dash_stream->need_segment = TRUE; + dash_stream->start_time = GST_CLOCK_TIME_NONE; + gst_download_rate_init (&dash_stream->dnl_rate); + gst_download_rate_set_max_length (&dash_stream->dnl_rate, + DOWNLOAD_RATE_HISTORY_MAX); + gst_download_rate_set_aver_period (&dash_stream->dnl_rate, + DOWNLOAD_RATE_TIME_MAX); + /*Create stream pad*/ + active_stream = gst_mpdparser_get_active_stream_by_index(demux->client, i); + caps = gst_dash_demux_get_input_caps(demux, active_stream); + dash_stream->srcpad = gst_pad_new_from_static_template (&srctemplate, NULL); + gst_pad_set_event_function (dash_stream->srcpad, + GST_DEBUG_FUNCPTR (gst_dash_demux_src_event)); + gst_pad_set_query_function (dash_stream->srcpad, + GST_DEBUG_FUNCPTR (gst_dash_demux_src_query)); + gst_pad_set_element_private (dash_stream->srcpad, demux); + gst_pad_set_active (dash_stream->srcpad, TRUE); + gst_pad_set_caps (dash_stream->srcpad, caps); + gst_caps_unref(caps); + gst_element_add_pad (GST_ELEMENT (demux), gst_object_ref (dash_stream->srcpad)); + } + /* Send 'no-more-pads' to have decodebin create the new group */ + gst_element_no_more_pads (GST_ELEMENT (demux)); return TRUE; } @@ -699,6 +810,7 @@ gst_dash_demux_sink_event (GstPad * pad, GstEvent * event) (NULL)); return FALSE; } + gst_buffer_unref (demux->manifest); demux->manifest = NULL; @@ -840,188 +952,20 @@ static void gst_dash_demux_stop (GstDashDemux * demux) { gst_uri_downloader_cancel (demux->downloader); + gst_dash_demux_flush_stream_queues (demux); if (GST_TASK_STATE (demux->download_task) != GST_TASK_STOPPED) { GST_TASK_SIGNAL (demux->download_task); gst_task_stop (demux->download_task); + g_mutex_lock (&demux->download_mutex); + g_cond_signal (&demux->download_cond); + g_mutex_unlock (&demux->download_mutex); } if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED) { GST_TASK_SIGNAL (demux->stream_task); gst_task_stop (demux->stream_task); } } -#ifdef DASHDEMUX_MODIFICATION -static void -_update_caps(GstDashDemux * demux, guint nb_adaptation_set) -{ - guint i = 0; - GstCaps *caps; - - /* Create and activate new pads */ - i = 0; - while (i < nb_adaptation_set) { - caps = gst_pad_get_caps(demux->srcpad[i]); - if(caps){ - caps = gst_caps_make_writable(caps); - gst_caps_replace(&caps,demux->output_caps[i]); - } - else{ - caps = demux->output_caps[i]; - } - gst_pad_use_fixed_caps (demux->srcpad[i]); - gst_pad_set_caps (demux->srcpad[i], caps); - gst_caps_unref(caps); - i++; - } -} - -static void -_add_pads(GstDashDemux * demux, guint nb_adaptation_set) -{ - guint i = 0; - - /* Create and activate new pads */ - i = 0; - while (i < nb_adaptation_set) { - demux->srcpad[i] = gst_pad_new_from_static_template (&srctemplate, NULL); - gst_pad_set_event_function (demux->srcpad[i], - GST_DEBUG_FUNCPTR (gst_dash_demux_src_event)); - gst_pad_set_query_function (demux->srcpad[i], - GST_DEBUG_FUNCPTR (gst_dash_demux_src_query)); - gst_pad_set_element_private (demux->srcpad[i], demux); - gst_pad_set_active (demux->srcpad[i], TRUE); - gst_pad_set_caps (demux->srcpad[i], demux->output_caps[i]); - gst_caps_unref(demux->output_caps[i]); - gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad[i]); - i++; - } - /* Send 'no-more-pads' to have decodebin create the new group */ - gst_element_no_more_pads (GST_ELEMENT (demux)); -} - -static gboolean -_needs_caps_update (GstDashDemux * demux, GList * fragment) -{ - - gboolean update_caps = FALSE; - guint i = 0; - while (i < g_list_length (fragment)) { - GstFragment *newFragment = g_list_nth_data (fragment, i); - if (newFragment == NULL) { - continue; - } - GstCaps *srccaps = NULL; - demux->output_caps[i] = gst_fragment_get_caps (newFragment); - if (G_LIKELY (demux->srcpad[i])) - srccaps = gst_pad_get_negotiated_caps (demux->srcpad[i]); - if (G_UNLIKELY (!srccaps - || (!gst_caps_is_equal_fixed (demux->output_caps[i], srccaps)) - || demux->need_segment)) { - update_caps = TRUE; - } - if (G_LIKELY (srccaps)) - gst_caps_unref (srccaps); - i++; - } - return update_caps; -} - -#else -/* switch_pads: - * - * Called when switching from one set of representations to another, but - * only if one of the new representations requires different downstream - * elements (see the next function). - * - * This function first creates the new pads, then sends a no-more-pads - * event (that will tell decodebin to create a new group), then sends - * EOS on the old pads to trigger the group switch. - * - */ -static void -switch_pads (GstDashDemux * demux, guint nb_adaptation_set) -{ - GstPad *oldpad[MAX_LANGUAGES]; - guint i = 0; - /* Remember old pads */ - while (i < nb_adaptation_set) { - oldpad[i] = demux->srcpad[i]; - if (oldpad[i]) { - GST_DEBUG_OBJECT (demux, - "Switching pads (oldpad:%p)" GST_PTR_FORMAT, oldpad[i]); - } - i++; - } - /* Create and activate new pads */ - i = 0; - while (i < nb_adaptation_set) { - demux->srcpad[i] = gst_pad_new_from_static_template (&srctemplate, NULL); - gst_pad_set_event_function (demux->srcpad[i], - GST_DEBUG_FUNCPTR (gst_dash_demux_src_event)); - gst_pad_set_query_function (demux->srcpad[i], - GST_DEBUG_FUNCPTR (gst_dash_demux_src_query)); - gst_pad_set_element_private (demux->srcpad[i], demux); - gst_pad_set_active (demux->srcpad[i], TRUE); - gst_pad_set_caps (demux->srcpad[i], demux->output_caps[i]); - gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad[i]); - i++; - } - /* Send 'no-more-pads' to have decodebin create the new group */ - gst_element_no_more_pads (GST_ELEMENT (demux)); - /* Push out EOS on all old pads to switch to the new group */ - i = 0; - while (i < nb_adaptation_set) { - if (oldpad[i]) { - gst_pad_push_event (oldpad[i], gst_event_new_eos ()); - gst_pad_set_active (oldpad[i], FALSE); - gst_element_remove_pad (GST_ELEMENT (demux), oldpad[i]); - } - i++; - } -} - -/* needs_pad_switch: - * - * Figure out if the newly selected representations require a new set - * of demuxers and decoders or if we can carry on with the existing ones. - * - * Basically, we look at the list of fragments we need to push downstream, - * and compare their caps with those of the corresponding src pads. - * - * As soon as one fragment requires a new set of caps, we need to switch - * all decoding pads to recreate a whole decoding group as we cannot - * move pads between groups (FIXME: or can we ?). - * - * FIXME: redundant with need_add_header - * - */ -static gboolean -needs_pad_switch (GstDashDemux * demux, GList * fragment) -{ - - gboolean switch_pad = FALSE; - guint i = 0; - while (i < g_list_length (fragment)) { - GstFragment *newFragment = g_list_nth_data (fragment, i); - if (newFragment == NULL) { - continue; - } - GstCaps *srccaps = NULL; - demux->output_caps[i] = gst_fragment_get_caps (newFragment); - if (G_LIKELY (demux->srcpad[i])) - srccaps = gst_pad_get_negotiated_caps (demux->srcpad[i]); - if (G_UNLIKELY (!srccaps - || (!gst_caps_is_equal_fixed (demux->output_caps[i], srccaps)) - || demux->need_segment)) { - switch_pad = TRUE; - } - if (G_LIKELY (srccaps)) - gst_caps_unref (srccaps); - i++; - } - return switch_pad; -} -#endif /* gst_dash_demux_stream_loop: * @@ -1046,100 +990,115 @@ needs_pad_switch (GstDashDemux * demux, GList * fragment) static void gst_dash_demux_stream_loop (GstDashDemux * demux) { - GList *listfragment; GstFlowReturn ret; - GstBufferList *buffer_list; - guint nb_adaptation_set = 0; - GstActiveStream *stream; - - /* Wait until the next scheduled push downstream */ - if (g_cond_timed_wait (GST_TASK_GET_COND (demux->stream_task), - demux->stream_timed_lock, &demux->next_push)) { - goto quit; - } + GstActiveStream *active_stream; + GstDashDemuxStream *selected_stream = NULL; + GstClockTime min_ts = GST_CLOCK_TIME_NONE; + guint i = 0; + gboolean eos = TRUE; + gboolean eop = TRUE; - if (g_queue_is_empty (demux->queue)) { - if (demux->end_of_manifest) - goto end_of_manifest; + for (i = 0; i < g_slist_length (demux->streams); i++) { + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, i); + GstBuffer *buffer; + GstDataQueueItem *item; - return; - } + if (dash_stream->stream_eos) { + GST_DEBUG_OBJECT (demux, "Stream %d is eos, skipping", dash_stream->idx); + continue; + } - if (GST_STATE (demux) == GST_STATE_PLAYING) { - if (!demux->end_of_manifest - && gst_dash_demux_get_buffering_time (demux) < - demux->min_buffering_time) { - /* Warn we are below our threshold: this will eventually pause - * the pipeline */ - gst_element_post_message (GST_ELEMENT (demux), - gst_message_new_buffering (GST_OBJECT (demux), - 100 * gst_dash_demux_get_buffering_ratio (demux))); + if (dash_stream->stream_end_of_period) { + GST_DEBUG_OBJECT (demux, "Stream %d is eop, skipping", dash_stream->idx); + eos = FALSE; + continue; } - } - listfragment = g_queue_pop_head (demux->queue); - nb_adaptation_set = g_list_length (listfragment); -#ifdef DASHDEMUX_MODIFICATION - /* Figure out if we need to create pads or update caps */ - gboolean caps_changed = _needs_caps_update (demux, listfragment); - if (caps_changed) { - if(demux->srcpad[0] == NULL) - { - _add_pads(demux,nb_adaptation_set); - demux->need_segment = TRUE; - }else{ - _update_caps(demux,nb_adaptation_set); + eos = FALSE; + eop = FALSE; + + if (!gst_data_queue_peek (dash_stream->queue, &item)) + goto flushing; + + if(GST_IS_BUFFER(item->object)) { + buffer = GST_BUFFER(item->object); + if(GST_BUFFER_TIMESTAMP(buffer) < min_ts || + !GST_CLOCK_TIME_IS_VALID(min_ts)) { + min_ts = GST_BUFFER_TIMESTAMP(buffer); + selected_stream = dash_stream; + } else if (!GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (item->object))) { + selected_stream = dash_stream; + break; + } + } else { + selected_stream = dash_stream; + break; } } -#else - /* Figure out if we need to create/switch pads */ - gboolean switch_pad = needs_pad_switch (demux, listfragment); - if (switch_pad) { - switch_pads (demux, nb_adaptation_set); - demux->need_segment = TRUE; - } -#endif - guint i = 0; - for (i = 0; i < nb_adaptation_set; i++) { - GstFragment *fragment = g_list_nth_data (listfragment, i); - stream = gst_mpdparser_get_active_stream_by_index (demux->client, i); - if (demux->need_segment) { - GstClockTime start = fragment->start_time + demux->position_shift; - /* And send a newsegment */ - GST_DEBUG_OBJECT (demux, "Sending new-segment. segment start:%" - GST_TIME_FORMAT, GST_TIME_ARGS (start)); - gst_pad_push_event (demux->srcpad[i], - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - start, GST_CLOCK_TIME_NONE, start)); - demux->position_shift = 0; - } - GST_DEBUG_OBJECT (demux, "Pushing fragment #%d", fragment->index); - buffer_list = gst_fragment_get_buffer_list (fragment); - g_object_unref (fragment); - ret = gst_pad_push_list (demux->srcpad[i], buffer_list); - if ((ret != GST_FLOW_OK) && (stream->mimeType == GST_STREAM_VIDEO)) - goto error_pushing; - } - demux->need_segment = FALSE; - g_list_free (listfragment); - GST_STATE_LOCK(demux); - if (GST_STATE (demux) == GST_STATE_PLAYING) { - /* Wait for the duration of a fragment before resuming this task */ - g_get_current_time (&demux->next_push); - g_time_val_add (&demux->next_push, - gst_mpd_client_get_next_fragment_duration (demux->client) - / GST_SECOND * G_USEC_PER_SEC); - GST_DEBUG_OBJECT (demux, "Next push scheduled at %s", - g_time_val_to_iso8601 (&demux->next_push)); + if(selected_stream) { + GstBuffer *buffer; + GstDataQueueItem *item; + + if (!gst_data_queue_pop (selected_stream->queue, &item)) + goto end; + if ( GST_IS_BUFFER (item->object)) { + buffer = GST_BUFFER(item->object); + active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, selected_stream->idx); + + if (selected_stream->need_segment) { + if(!GST_CLOCK_TIME_IS_VALID (selected_stream->start_time)) { + if(GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))){ + selected_stream->start_time = GST_BUFFER_TIMESTAMP (buffer); + } else { + selected_stream->start_time = 0; + } + } + /* And send a newsegment */ + GST_DEBUG_OBJECT (demux, "Sending new-segment stream #%d. segment start:%" + GST_TIME_FORMAT, selected_stream->idx, GST_TIME_ARGS (selected_stream->start_time)); + gst_pad_push_event (selected_stream->srcpad, + gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + selected_stream->start_time, GST_CLOCK_TIME_NONE, selected_stream->start_time)); + selected_stream->need_segment = FALSE; + } + + GST_DEBUG_OBJECT (demux, "Pushing fragment #%llu (stream %d) ts=%"GST_TIME_FORMAT, GST_BUFFER_OFFSET (buffer), + selected_stream->idx, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); + ret = gst_pad_push (selected_stream->srcpad, gst_buffer_ref(buffer) ); + item->destroy (item); + if ((ret != GST_FLOW_OK) && (active_stream->mimeType == GST_STREAM_VIDEO)) + goto error_pushing; + } else { + GstEvent *event = GST_EVENT (item->object); + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { + selected_stream->stream_eos = TRUE; + selected_stream->stream_end_of_period = TRUE; + } else if (GST_EVENT_TYPE (event) == GST_EVENT_DASH_EOP) { + selected_stream->stream_end_of_period = TRUE; + } + + if (GST_EVENT_TYPE (item->object) != GST_EVENT_DASH_EOP) { + gst_pad_push_event (selected_stream->srcpad, + gst_event_ref (GST_EVENT_CAST (item->object))); + } + + item->destroy (item); + } } else { - /* The pipeline is now set up, wait until playback begins */ - GST_INFO_OBJECT (demux, "Pausing streaming task"); - gst_task_pause (demux->stream_task); + if (eos) { + goto end_of_manifest; + } else if (eop) { + /*TODO Switch to next period*/ + } } - GST_STATE_UNLOCK(demux); -quit: +end: + return; + +flushing: { + GST_INFO_OBJECT (demux, "Queue is flushing. Stopped streaming task"); + gst_task_stop (demux->stream_task); return; } @@ -1148,7 +1107,8 @@ end_of_manifest: GST_INFO_OBJECT (demux, "Reached end of manifest, sending EOS"); guint i = 0; for (i = 0; i < gst_mpdparser_get_nb_active_stream (demux->client); i++) { - gst_pad_push_event (demux->srcpad[i], gst_event_new_eos ()); + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, i); + gst_pad_push_event (dash_stream->srcpad, gst_event_new_eos ()); } GST_INFO_OBJECT (demux, "Stopped streaming task"); gst_task_stop (demux->stream_task); @@ -1167,18 +1127,37 @@ error_pushing: } static void +gst_dash_demux_clear_streams(GstDashDemux * demux) { + guint i = 0; + gst_dash_demux_flush_stream_queues (demux); + for (i = 0; i < g_slist_length(demux->streams); i++) { + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, i); + gst_download_rate_deinit (&dash_stream->dnl_rate); + if (dash_stream->input_caps) { + gst_caps_unref (dash_stream->input_caps); + dash_stream->input_caps = NULL; + } + if (dash_stream->srcpad) { + gst_object_unref (dash_stream->srcpad); + dash_stream->srcpad = NULL; + } + /*TODO consider unref stream->output_caps*/ + g_object_unref (dash_stream->queue); + } + if(demux->streams) { + g_slist_free(demux->streams); + demux->streams = NULL; + } +} + +static void gst_dash_demux_reset (GstDashDemux * demux, gboolean dispose) { + gint stream_idx; demux->end_of_period = FALSE; - demux->end_of_manifest = FALSE; demux->cancelled = FALSE; - guint i = 0; - for (i = 0; i < MAX_LANGUAGES; i++) - if (demux->input_caps[i]) { - gst_caps_unref (demux->input_caps[i]); - demux->input_caps[i] = NULL; - } + gst_dash_demux_clear_streams(demux); if (demux->manifest) { gst_buffer_unref (demux->manifest); @@ -1192,74 +1171,218 @@ gst_dash_demux_reset (GstDashDemux * demux, gboolean dispose) demux->client = gst_mpd_client_new (); } - gst_dash_demux_clear_queue (demux); - demux->last_manifest_update = GST_CLOCK_TIME_NONE; - demux->position = 0; - demux->position_shift = 0; - demux->need_segment = TRUE; + for (stream_idx = 0; stream_idx < g_slist_length (demux->streams); stream_idx++) { + GstDashDemuxStream *dash_stream = g_slist_nth_data (demux->streams, stream_idx); + dash_stream->need_segment = TRUE; + } } static GstClockTime gst_dash_demux_get_buffering_time (GstDashDemux * demux) { GstClockTime buffer_time = 0; - GList *listfragment; - GstFragment *first_fragment, *last_fragment; + GSList *it; + GstDashDemuxStream *stream; + GstDataQueueSize queue_size; - if (g_queue_is_empty (demux->queue)) - return 0; + for(it=demux->streams; it; it=it->next) { + stream = it->data; + gst_data_queue_get_level(stream->queue, &queue_size); - /* get first fragment */ - listfragment = g_queue_peek_head (demux->queue); - first_fragment = listfragment->data; - /* get last fragment */ - listfragment = g_queue_peek_tail (demux->queue); - last_fragment = listfragment->data; - - if (first_fragment && last_fragment) { - buffer_time = last_fragment->stop_time - first_fragment->start_time; + if (queue_size.time > 0) { + buffer_time = queue_size.time; + break; + } } return buffer_time; } -static float -gst_dash_demux_get_buffering_ratio (GstDashDemux * demux) +static gboolean +gst_dash_demux_update_manifest(GstDashDemux *demux) { + GstFragment *download; + GstBuffer *buffer; + GstClockTime duration, now = gst_util_get_timestamp(); + gint64 update_period = demux->client->mpd_node->minimumUpdatePeriod; + + if (update_period == -1) { + GST_DEBUG_OBJECT (demux, "minimumUpdatePeriod unspecified, will not update MPD"); + return TRUE; + } + + /* init reference time for manifest file updates */ + if (!GST_CLOCK_TIME_IS_VALID (demux->last_manifest_update)) + demux->last_manifest_update = now; + + /* update the manifest file */ + if (now >= demux->last_manifest_update + update_period * GST_MSECOND) { + GST_DEBUG_OBJECT (demux, "Updating manifest file from URL %s", + demux->client->mpd_uri); + download = + gst_uri_downloader_fetch_uri (demux->downloader, + demux->client->mpd_uri); + if (download == NULL) { + GST_WARNING_OBJECT (demux, + "Failed to update the manifest file from URL %s", + demux->client->mpd_uri); + } else { + GstMpdClient *new_client = NULL; + guint period_idx; + const gchar *period_id; + GSList *iter; + + buffer = gst_fragment_get_buffer(download); + g_object_unref (download); + /* parse the manifest file */ + if (buffer == NULL) { + GST_WARNING_OBJECT (demux, "Error validating the manifest."); + return TRUE; + } + + new_client = gst_mpd_client_new (); + new_client->mpd_uri = g_strdup (demux->client->mpd_uri); + if (!gst_mpd_parse (new_client, + (gchar *) GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { + /* In most cases, this will happen if we set a wrong url in the + * source element and we have received the 404 HTML response instead of + * the manifest */ + GST_WARNING_OBJECT (demux, "Error parsing the manifest."); + gst_buffer_unref (buffer); + return TRUE; + } + + gst_buffer_unref (buffer); + GST_DEBUG_OBJECT (demux, "Updating manifest"); + + period_id = gst_mpd_client_get_period_id (demux->client); + period_idx = gst_mpd_client_get_period_index (demux->client); + + /* setup video, audio and subtitle streams, starting from current Period */ + if (!gst_mpd_client_setup_media_presentation (new_client)) { + /* TODO */ + } + + if (period_idx) { + /*If more than one period exists.*/ + if (!gst_mpd_client_set_period_id (new_client, period_id)) { + GST_DEBUG_OBJECT (demux, + "Error setting up the updated manifest file"); + return FALSE; + } + } else { + if (!gst_mpd_client_set_period_index (new_client, period_idx)) { + GST_DEBUG_OBJECT (demux, + "Error setting up the updated manifest file"); + return FALSE; + } + } + + if (!gst_dash_demux_setup_mpdparser_streams (demux, new_client)) { + GST_ERROR_OBJECT (demux, "Failed to setup streams on manifest " + "update"); + return FALSE; + } + + /* update the streams to play from the next segment */ + for (iter = demux->streams; iter; iter = g_slist_next (iter)) { + GstDashDemuxStream *demux_stream = iter->data; + GstActiveStream *new_stream; + GstClockTime ts; + + new_stream = gst_mpdparser_get_active_stream_by_index (new_client, + demux_stream->idx); + + if (!new_stream) { + GST_DEBUG_OBJECT (demux, + "Stream of index %d is missing from manifest update", + demux_stream->idx); + return FALSE; + } + + if (gst_mpd_client_get_next_fragment_timestamp (demux->client, + demux_stream->idx, &ts)) { + gst_mpd_client_stream_seek (new_client, demux_stream->idx, ts); + + } else + if (gst_mpd_client_get_last_fragment_timestamp (demux->client, + demux_stream->idx, &ts)) { + /* try to set to the old timestamp + 1 */ + gst_mpd_client_stream_seek (new_client, demux_stream->idx, ts+1); + } + } + + /*Remember download failed count*/ + new_client->download_failed_count = demux->client->download_failed_count; + + gst_mpd_client_free (demux->client); + demux->client = new_client; + + /* Send an updated duration message */ + duration = + gst_mpd_client_get_media_presentation_duration (demux->client); + + if (duration != GST_CLOCK_TIME_NONE) { + GST_DEBUG_OBJECT (demux, + "Sending duration message : %" GST_TIME_FORMAT, + GST_TIME_ARGS (duration)); + gst_element_post_message (GST_ELEMENT (demux), + gst_message_new_duration(GST_OBJECT (demux), GST_FORMAT_TIME, duration)); + } else { + GST_DEBUG_OBJECT (demux, + "mediaPresentationDuration unknown, can not send the duration message"); + } + demux->last_manifest_update = gst_util_get_timestamp (); + GST_DEBUG_OBJECT (demux, "Manifest file successfully updated"); + } + } + return TRUE; +} + +static void +gst_dash_demux_download_wait (GstDashDemux * demux, GstClockTime time_diff) { - float buffering_time = gst_dash_demux_get_buffering_time (demux); - if (buffering_time >= demux->min_buffering_time) { - return 1.0; - } else - return buffering_time / demux->min_buffering_time; + gint64 end_time = g_get_monotonic_time () + time_diff / GST_USECOND; + + GST_DEBUG_OBJECT (demux, "Download waiting for %" GST_TIME_FORMAT, + GST_TIME_ARGS (time_diff)); + g_cond_wait_until (&demux->download_cond, &demux->download_mutex, end_time); + GST_DEBUG_OBJECT (demux, "Download finished waiting"); } -static GstBuffer * -gst_dash_demux_merge_buffer_list (GstFragment * fragment) +static void +gst_dash_demux_check_live(GstDashDemux* demux, GstActiveStream *fragment_stream, + GstClockTime fragment_ts) { - GstBufferList *list; - GstBufferListIterator *it; - GstBuffer *buffer, *ret = NULL; - GstAdapter *adapter; - gsize size; - - adapter = gst_adapter_new (); - list = gst_fragment_get_buffer_list (fragment); - it = gst_buffer_list_iterate (list); - while (gst_buffer_list_iterator_next_group (it)) { - while ((buffer = gst_buffer_list_iterator_next (it)) != NULL) { - gst_adapter_push (adapter, gst_buffer_ref (buffer)); - } + gint64 time_diff; + gint pos; + + pos = + gst_mpd_client_check_time_position (demux->client, fragment_stream, + fragment_ts, &time_diff); + GST_DEBUG_OBJECT (demux, + "Checked position for fragment ts %" GST_TIME_FORMAT + ", res: %d, diff: %" G_GINT64_FORMAT, GST_TIME_ARGS (fragment_ts), + pos, time_diff); + + time_diff *= GST_USECOND; + if (pos < 0) { + /* we're behind, try moving to the 'present' */ + GDateTime *now = g_date_time_new_now_utc (); + + GST_DEBUG_OBJECT (demux, + "Falling behind live stream, moving forward"); + gst_mpd_client_seek_to_time(demux->client, now); + g_date_time_unref (now); + + } else if (pos > 0) { + /* we're ahead, wait a little */ + + GST_DEBUG_OBJECT (demux, "Waiting for next segment to be created"); + gst_dash_demux_download_wait (demux, time_diff); + } else { + demux->client->download_failed_count++; } - gst_buffer_list_iterator_free (it); - gst_buffer_list_unref (list); - size = gst_adapter_available (adapter); - if (size > 0) - ret = gst_adapter_take_buffer (adapter, size); - GST_DEBUG ("Extracted a buffer of size %d from the fragment", size); - g_object_unref (adapter); - - return ret; } /* gst_dash_demux_download_loop: @@ -1293,157 +1416,57 @@ gst_dash_demux_merge_buffer_list (GstFragment * fragment) void gst_dash_demux_download_loop (GstDashDemux * demux) { - GstClock *clock = gst_element_get_clock (GST_ELEMENT (demux)); - gint64 update_period = demux->client->mpd_node->minimumUpdatePeriod; - - /* Wait until the next scheduled download */ - if (g_cond_timed_wait (GST_TASK_GET_COND (demux->download_task), - demux->download_timed_lock, &demux->next_download)) { - goto quit; + GstActiveStream *fragment_stream = NULL; + GstClockTime fragment_ts; + if ( gst_mpd_client_is_live (demux->client) && demux->client->mpd_uri != NULL ) { + if (!gst_dash_demux_update_manifest(demux)) + goto end_of_manifest; } - if (clock && gst_mpd_client_is_live (demux->client) - && demux->client->mpd_uri != NULL && update_period != -1) { - GstFragment *download; - GstBuffer *buffer; - GstClockTime duration, now = gst_clock_get_time (clock); - - /* init reference time for manifest file updates */ - if (!GST_CLOCK_TIME_IS_VALID (demux->last_manifest_update)) - demux->last_manifest_update = now; - - /* update the manifest file */ - if (now >= demux->last_manifest_update + update_period * GST_MSECOND) { - GST_DEBUG_OBJECT (demux, "Updating manifest file from URL %s", - demux->client->mpd_uri); - download = - gst_uri_downloader_fetch_uri (demux->downloader, - demux->client->mpd_uri); - if (download == NULL) { - GST_WARNING_OBJECT (demux, - "Failed to update the manifest file from URL %s", - demux->client->mpd_uri); + /* try to switch to another set of representations if needed */ + gst_dash_demux_select_representations (demux); + + /* fetch the next fragment */ + while (!gst_dash_demux_get_next_fragment (demux, &fragment_stream, &fragment_ts)) { + if (demux->end_of_period) { + GST_INFO_OBJECT (demux, "Reached the end of the Period"); + /* setup video, audio and subtitle streams, starting from the next Period */ + if (!gst_mpd_client_set_period_index (demux->client, + gst_mpd_client_get_period_index (demux->client) + 1) + || !gst_dash_demux_setup_all_streams (demux)) { + GST_INFO_OBJECT (demux, "Reached the end of the manifest file"); + gst_task_start (demux->stream_task); + goto end_of_manifest; + } + /* start playing from the first segment of the new period */ + gst_mpd_client_set_segment_index_for_all_streams (demux->client, 0); + demux->end_of_period = FALSE; + } else if (!demux->cancelled) { + gst_uri_downloader_reset (demux->downloader); + if(gst_mpd_client_is_live (demux->client)) { + gst_dash_demux_check_live (demux, fragment_stream, fragment_ts); } else { - buffer = gst_dash_demux_merge_buffer_list (download); - g_object_unref (download); - /* parse the manifest file */ - if (buffer == NULL) { - GST_WARNING_OBJECT (demux, "Error validating the manifest."); - } else if (!gst_mpd_parse (demux->client, - (gchar *) GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { - /* In most cases, this will happen if we set a wrong url in the - * source element and we have received the 404 HTML response instead of - * the manifest */ - GST_WARNING_OBJECT (demux, "Error parsing the manifest."); - gst_buffer_unref (buffer); - } else { - GstActiveStream *stream; - guint segment_index; - - gst_buffer_unref (buffer); - stream = gst_mpdparser_get_active_stream_by_index (demux->client, 0); - segment_index = gst_mpd_client_get_segment_index (stream); - /* setup video, audio and subtitle streams, starting from first Period */ - if (!gst_mpd_client_setup_media_presentation (demux->client) || - !gst_mpd_client_set_period_index (demux->client, - gst_mpd_client_get_period_index (demux->client)) - || !gst_dash_demux_setup_all_streams (demux)) { - GST_DEBUG_OBJECT (demux, - "Error setting up the updated manifest file"); - goto end_of_manifest; - } - /* continue playing from the the next segment */ - /* FIXME: support multiple streams with different segment duration */ - gst_mpd_client_set_segment_index_for_all_streams (demux->client, - segment_index); - - /* Send an updated duration message */ - duration = - gst_mpd_client_get_media_presentation_duration (demux->client); - - if (duration != GST_CLOCK_TIME_NONE) { - GST_DEBUG_OBJECT (demux, - "Sending duration message : %" GST_TIME_FORMAT, - GST_TIME_ARGS (duration)); - gst_element_post_message (GST_ELEMENT (demux), - gst_message_new_duration (GST_OBJECT (demux), GST_FORMAT_TIME, - duration)); - } else { - GST_DEBUG_OBJECT (demux, - "mediaPresentationDuration unknown, can not send the duration message"); - } - demux->last_manifest_update += update_period * GST_MSECOND; - GST_DEBUG_OBJECT (demux, "Manifest file successfully updated"); - } + demux->client->download_failed_count++; } - } - } - - - /* Target buffering time MUST at least exceeds mimimum buffering time - * by the duration of a fragment, but SHOULD NOT exceed maximum - * buffering time */ - GstClockTime target_buffering_time = - demux->min_buffering_time + - gst_mpd_client_get_next_fragment_duration (demux->client); - if (demux->max_buffering_time > target_buffering_time) - target_buffering_time = demux->max_buffering_time; - if (!demux->end_of_manifest - && gst_dash_demux_get_buffering_time (demux) < target_buffering_time) { - if (GST_STATE (demux) != GST_STATE_PLAYING) { - /* Signal our buffering status (this will eventually restart the - * pipeline when we have reached 100 %) */ - gst_element_post_message (GST_ELEMENT (demux), - gst_message_new_buffering (GST_OBJECT (demux), - 100 * gst_dash_demux_get_buffering_ratio (demux))); - } - /* try to switch to another set of representations if needed */ - gst_dash_demux_select_representations (demux, - demux->bandwidth_usage * demux->dnl_rate * - gst_dash_demux_get_buffering_ratio (demux)); - - /* fetch the next fragment */ - while (!gst_dash_demux_get_next_fragment_set (demux)) { - if (demux->end_of_period) { - GST_INFO_OBJECT (demux, "Reached the end of the Period"); - /* setup video, audio and subtitle streams, starting from the next Period */ - if (!gst_mpd_client_set_period_index (demux->client, - gst_mpd_client_get_period_index (demux->client) + 1) - || !gst_dash_demux_setup_all_streams (demux)) { - GST_INFO_OBJECT (demux, "Reached the end of the manifest file"); - demux->end_of_manifest = TRUE; - if (GST_STATE (demux) != GST_STATE_PLAYING) { - /* Restart the pipeline regardless of the current buffering level */ - gst_element_post_message (GST_ELEMENT (demux), - gst_message_new_buffering (GST_OBJECT (demux), 100)); - } - gst_task_start (demux->stream_task); - goto end_of_manifest; - } - /* start playing from the first segment of the new period */ - gst_mpd_client_set_segment_index_for_all_streams (demux->client, 0); - demux->end_of_period = FALSE; - } else if (!demux->cancelled) { - demux->client->update_failed_count++; - if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) { - GST_WARNING_OBJECT (demux, "Could not fetch the next fragment"); - goto quit; - } else { - goto error_downloading; - } - } else { + if (demux->client->download_failed_count < DEFAULT_FAILED_COUNT) { + GST_WARNING_OBJECT (demux, "Could not fetch the next fragment"); goto quit; + } else if (gst_mpd_client_set_next_baseURL_for_stream (demux->client)) { + GST_INFO_OBJECT (demux, "Current baseURL is %s. Trying to select another", + gst_mpdparser_get_baseURL (demux->client)); + demux->client->download_failed_count = 0; + } else { + goto error_downloading; } + } else { + goto quit; } - GST_INFO_OBJECT (demux, "Internal buffering : %" PRIu64 " s", - gst_dash_demux_get_buffering_time (demux) / GST_SECOND); - demux->client->update_failed_count = 0; - } else { - /* schedule the next download in 100 ms */ - g_get_current_time (&demux->next_download); - g_time_val_add (&demux->next_download, 100000); } + GST_INFO_OBJECT (demux, "Internal buffering : %" PRIu64 " s", + gst_dash_demux_get_buffering_time (demux) / GST_SECOND); + demux->client->download_failed_count = 0; + quit: { @@ -1467,25 +1490,15 @@ error_downloading: } static void -gst_dash_demux_pause_stream_task (GstDashDemux * demux) -{ - /* Send a signal to the stream task so that it pauses itself */ - GST_TASK_SIGNAL (demux->stream_task); - /* Pause it explicitly (if it was not in the COND) */ - gst_task_pause (demux->stream_task); -} - -static void gst_dash_demux_resume_stream_task (GstDashDemux * demux) { - g_get_current_time (&demux->next_push); gst_task_start (demux->stream_task); } static void gst_dash_demux_resume_download_task (GstDashDemux * demux) { - g_get_current_time (&demux->next_download); + gst_uri_downloader_reset(demux->downloader); gst_task_start (demux->download_task); } @@ -1502,25 +1515,36 @@ gst_dash_demux_resume_download_task (GstDashDemux * demux) * Returns TRUE if a new set of representations has been selected */ static gboolean -gst_dash_demux_select_representations (GstDashDemux * demux, guint64 bitrate) +gst_dash_demux_select_representations (GstDashDemux * demux) { - GstActiveStream *stream = NULL; + GstDashDemuxStream *stream = NULL; + GstActiveStream *active_stream = NULL; GList *rep_list = NULL; + GSList *iter; gint new_index; gboolean ret = FALSE; - guint i = 0; - while (i < gst_mpdparser_get_nb_active_stream (demux->client)) { - stream = gst_mpdparser_get_active_stream_by_index (demux->client, i); - if (!stream) + GST_MPD_CLIENT_LOCK (demux->client); + for (iter = demux->streams; iter; iter = g_slist_next (iter)) { + guint64 bitrate; + + stream = iter->data; + active_stream = + gst_mpdparser_get_active_stream_by_index (demux->client, stream->idx); + if (!active_stream) return FALSE; /* retrieve representation list */ - if (stream->cur_adapt_set) - rep_list = stream->cur_adapt_set->Representations; + if (active_stream->cur_adapt_set) + rep_list = active_stream->cur_adapt_set->Representations; if (!rep_list) return FALSE; + bitrate = gst_download_rate_get_current_rate (&stream->dnl_rate) * + demux->bandwidth_usage; + + GST_DEBUG_OBJECT (demux, "Trying to change bitrate to %" G_GUINT64_FORMAT, bitrate); + /* get representation index with current max_bandwidth */ new_index = gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate); @@ -1529,22 +1553,23 @@ gst_dash_demux_select_representations (GstDashDemux * demux, guint64 bitrate) if (new_index == -1) new_index = 0; - if (new_index != stream->representation_idx) { - GST_MPD_CLIENT_LOCK (demux->client); - ret = - gst_mpd_client_setup_representation (demux->client, stream, - g_list_nth_data (rep_list, new_index)); - GST_MPD_CLIENT_UNLOCK (demux->client); - if (ret) { + if (new_index != active_stream->representation_idx) { + GstRepresentationNode *rep = g_list_nth_data (rep_list, new_index); + GST_INFO_OBJECT (demux, "Changing representation idx: %d %d %u", + stream->idx, new_index, rep->bandwidth); + if (gst_mpd_client_setup_representation (demux->client, active_stream, + rep)) { + ret = TRUE; + stream->need_header = TRUE; GST_INFO_OBJECT (demux, "Switching bitrate to %d", - stream->cur_representation->bandwidth); + active_stream->cur_representation->bandwidth); } else { GST_WARNING_OBJECT (demux, "Can not switch representation, aborting..."); } } - i++; } + GST_MPD_CLIENT_UNLOCK (demux->client); return ret; } @@ -1571,64 +1596,28 @@ gst_dash_demux_get_next_header (GstDashDemux * demux, guint stream_idx) fragment = gst_uri_downloader_fetch_uri (demux->downloader, next_header_uri); g_free (next_header_uri); + g_free (initializationURL); return fragment; } -static GstBufferListItem -gst_dash_demux_add_buffer_cb (GstBuffer ** buffer, - guint group, guint idx, gpointer user_data) -{ - GstFragment *frag = GST_FRAGMENT (user_data); - /* This buffer still belongs to the original fragment */ - /* so we need to increase refcount */ - gst_fragment_add_buffer (frag, gst_buffer_ref (*buffer)); - return GST_BUFFER_LIST_CONTINUE; -} - -/* Since we cannot add headers after the chunk has been downloaded, we have to recreate a new fragment */ -static GstFragment * -gst_dash_demux_prepend_header (GstDashDemux * demux, - GstFragment * frag, GstFragment * header) -{ - GstFragment *res = gst_fragment_new (); - res->name = g_strdup (frag->name); - res->download_start_time = frag->download_start_time; - res->download_stop_time = frag->download_stop_time; - res->start_time = frag->start_time; - res->stop_time = frag->stop_time; - res->index = frag->index; - res->discontinuous = frag->discontinuous; - - GstBufferList *list; - list = gst_fragment_get_buffer_list (header); - gst_buffer_list_foreach (list, gst_dash_demux_add_buffer_cb, res); - gst_buffer_list_unref (list); - list = gst_fragment_get_buffer_list (frag); - gst_buffer_list_foreach (list, gst_dash_demux_add_buffer_cb, res); - gst_buffer_list_unref (list); - - res->completed = TRUE; - - return res; -} - static GstCaps * gst_dash_demux_get_video_input_caps (GstDashDemux * demux, GstActiveStream * stream) { - guint width = 0, height = 0; + guint width = 0, height = 0, bandwidth = 0; const gchar *mimeType = NULL; GstCaps *caps = NULL; if (stream == NULL) return NULL; #ifdef DASHDEMUX_MODIFICATION - /* caps need to inlcude resolution */ + /* caps need to inlcude resolution and bandwidth */ width = gst_mpd_client_get_video_stream_width (stream); height = gst_mpd_client_get_video_stream_height (stream); + bandwidth = gst_mpd_client_get_video_stream_bandwidth (stream); #else - /* if bitstreamSwitching is true we dont need to swich pads on resolution change */ + /* if bitstreamSwitching is true we dont need to swich pads on resolution change */ if (!gst_mpd_client_get_bitstream_switching_flag (stream)) { width = gst_mpd_client_get_video_stream_width (stream); height = gst_mpd_client_get_video_stream_height (stream); @@ -1644,6 +1633,12 @@ gst_dash_demux_get_video_input_caps (GstDashDemux * demux, G_TYPE_INT, height, NULL); } + if (bandwidth > 0) + gst_caps_set_simple (caps, "bandwidth", G_TYPE_INT, bandwidth, NULL); + + gst_caps_set_simple (caps, "max-width", G_TYPE_INT, demux->max_video_width, "max-height", + G_TYPE_INT, demux->max_video_height, NULL); + /* add ContentProtection to caps */ if ( stream->cur_adapt_set->RepresentationBase->ContentProtection != NULL){ GList *list; @@ -1728,41 +1723,23 @@ gst_dash_demux_get_application_input_caps (GstDashDemux * demux, static GstCaps * gst_dash_demux_get_input_caps (GstDashDemux * demux, GstActiveStream * stream) { + GstCaps *caps; switch (stream->mimeType) { case GST_STREAM_VIDEO: - return gst_dash_demux_get_video_input_caps (demux, stream); + caps = gst_dash_demux_get_video_input_caps (demux, stream); + break; case GST_STREAM_AUDIO: - return gst_dash_demux_get_audio_input_caps (demux, stream); + caps = gst_dash_demux_get_audio_input_caps (demux, stream); + break; case GST_STREAM_APPLICATION: - return gst_dash_demux_get_application_input_caps (demux, stream); + caps = gst_dash_demux_get_application_input_caps (demux, stream); + break; default: return GST_CAPS_NONE; } -} - -static gboolean -need_add_header (GstDashDemux * demux) -{ - GstActiveStream *stream; - GstCaps *caps; - guint stream_idx = 0; - gboolean switch_caps = FALSE; - while (stream_idx < gst_mpdparser_get_nb_active_stream (demux->client)) { - stream = - gst_mpdparser_get_active_stream_by_index (demux->client, stream_idx); - if (stream == NULL) - return FALSE; - caps = gst_dash_demux_get_input_caps (demux, stream); - if (!demux->input_caps[stream_idx] - || !gst_caps_is_equal (caps, demux->input_caps[stream_idx])) { - switch_caps = TRUE; - gst_caps_unref (caps); - break; - } - gst_caps_unref (caps); - stream_idx++; - } - return switch_caps; + /*Need to signal downstream elements about dash*/ + gst_caps_set_simple(caps, "variant", G_TYPE_STRING, "dash-fragmented", NULL); + return caps; } /* gst_dash_demux_get_next_fragment_set: @@ -1775,90 +1752,151 @@ need_add_header (GstDashDemux * demux) * */ static gboolean -gst_dash_demux_get_next_fragment_set (GstDashDemux * demux) +gst_dash_demux_get_next_fragment (GstDashDemux * demux,GstActiveStream **fragment_stream, + GstClockTime *selected_ts) { GstActiveStream *stream; + GstDashDemuxStream *dash_stream; + GstDashDemuxStream *selected_stream = NULL; GstFragment *download, *header; - GList *fragment_set; gchar *next_fragment_uri; GstClockTime duration; GstClockTime timestamp; + GstClockTime min_timestamp = GST_CLOCK_TIME_NONE; gboolean discont; GTimeVal now; GTimeVal start; GstClockTime diff; guint64 size_buffer = 0; + GstBuffer *buffer; + guint stream_idx; + gboolean end_of_period = TRUE; - g_get_current_time (&start); - /* Figure out if we will need to switch pads, thus requiring a new - * header to initialize the new decoding chain - * FIXME: redundant with needs_pad_switch */ - gboolean need_header = need_add_header (demux); - guint stream_idx = 0; - fragment_set = NULL; - /* Get the fragment corresponding to each stream index */ - while (stream_idx < gst_mpdparser_get_nb_active_stream (demux->client)) { - if (!gst_mpd_client_get_next_fragment (demux->client, - stream_idx, &discont, &next_fragment_uri, &duration, ×tamp)) { - GST_INFO_OBJECT (demux, "This Period doesn't contain more fragments"); - demux->end_of_period = TRUE; - return FALSE; + /*Select stream with smallest progress*/ + for (stream_idx = 0; stream_idx < g_slist_length (demux->streams); stream_idx++) { + dash_stream = g_slist_nth_data (demux->streams, stream_idx); + + if (dash_stream->download_end_of_period) + continue; + + if (gst_mpd_client_get_next_fragment_timestamp (demux->client, stream_idx, ×tamp)) { + if( timestamp < min_timestamp || !GST_CLOCK_TIME_IS_VALID(min_timestamp) ) { + selected_stream = dash_stream; + min_timestamp = timestamp; + } + } else { + GstEvent *event = NULL; + + GST_INFO_OBJECT (demux, + "This Period doesn't contain more fragments for stream %u", + dash_stream->idx); + + /* check if this is live and we should wait for more data */ + if (gst_mpd_client_is_live (demux->client) + && demux->client->mpd_node->minimumUpdatePeriod != -1) { + end_of_period = FALSE; + continue; + } + + if (gst_mpd_client_has_next_period (demux->client)) { + event = gst_event_new_dash_eop (); + } else { + GST_DEBUG_OBJECT (demux, + "No more fragments or periods for this stream, setting EOS"); + event = gst_event_new_eos (); + } + dash_stream->download_end_of_period = TRUE; + gst_dash_demux_stream_push_event (dash_stream, event); } + } + + if (selected_ts) + *selected_ts = min_timestamp; + if (fragment_stream && selected_stream) + *fragment_stream = gst_mpdparser_get_active_stream_by_index (demux->client, selected_stream->idx); + /* Fetch next fragment from selected stream */ + if(selected_stream) { - GST_INFO_OBJECT (demux, "Fetching next fragment %s", next_fragment_uri); + if (!gst_mpd_client_get_next_fragment (demux->client, + selected_stream->idx, &discont, &next_fragment_uri, &duration, ×tamp)) { + GST_WARNING_OBJECT (demux, "Failed to download fragment for stream %d", selected_stream->idx); + } else { - download = gst_uri_downloader_fetch_uri (demux->downloader, - next_fragment_uri); - g_free (next_fragment_uri); + g_get_current_time (&start); + GST_INFO_OBJECT (demux, "Fetching next fragment stream=%d ts=%"GST_TIME_FORMAT" url=%s", + selected_stream->idx, GST_TIME_ARGS(timestamp), next_fragment_uri); - if (download == NULL) - return FALSE; + stream = gst_mpdparser_get_active_stream_by_index (demux->client, selected_stream->idx); - download->start_time = timestamp; - download->stop_time = timestamp + duration; + end_of_period = FALSE; - stream = - gst_mpdparser_get_active_stream_by_index (demux->client, stream_idx); - if (stream == NULL) - return FALSE; + download = gst_uri_downloader_fetch_uri (demux->downloader, + next_fragment_uri); + g_free (next_fragment_uri); + + if (stream == NULL) + return FALSE; + + if (download == NULL) { + guint segment_idx = gst_mpd_client_get_segment_index ( stream ); + if(segment_idx > 0) { + /*Move to previous segment if download failed*/ + gst_mpd_client_set_segment_index (stream, segment_idx - 1); + } + return FALSE; + } + + download->start_time = timestamp; + download->stop_time = timestamp + duration; - download->index = gst_mpd_client_get_segment_index (stream) - 1; + download->index = gst_mpd_client_get_segment_index (stream) - 1; - GstCaps *caps = gst_dash_demux_get_input_caps (demux, stream); + GstCaps *caps = gst_dash_demux_get_input_caps (demux, stream); + buffer = gst_fragment_get_buffer (download); + g_return_val_if_fail (buffer != NULL, FALSE); - if (need_header) { - /* Store the new input caps for that stream */ - gst_caps_replace (&demux->input_caps[stream_idx], caps); - GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT, - demux->input_caps[stream_idx]); - /* We need to fetch a new header */ - if ((header = gst_dash_demux_get_next_header (demux, stream_idx)) == NULL) { - GST_INFO_OBJECT (demux, "Unable to fetch header"); + if (selected_stream->need_header) { + /* Store the new input caps for that stream */ + gst_caps_replace (&dash_stream->input_caps, caps); + GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT, + dash_stream->input_caps); + + /* We need to fetch a new header */ + if ((header = gst_dash_demux_get_next_header (demux, selected_stream->idx)) == NULL) { + GST_INFO_OBJECT (demux, "Unable to fetch header"); + } else { + /* Replace fragment buffer with a new one including the header */ + GstBuffer *header_buffer = gst_fragment_get_buffer(header); + buffer = gst_buffer_join(header_buffer, buffer); + g_object_unref (header); + selected_stream->need_header = FALSE; + } } else { - /* Replace fragment with a new one including the header */ - GstFragment *new_fragment = - gst_dash_demux_prepend_header (demux, download, header); - g_object_unref (header); - g_object_unref (download); - download = new_fragment; + gst_caps_unref (caps); } - } else - gst_caps_unref (caps); - gst_fragment_set_caps (download, demux->input_caps[stream_idx]); - fragment_set = g_list_append (fragment_set, download); - size_buffer += gst_fragment_get_buffer_size (download); - stream_idx++; + g_get_current_time (&now); + g_object_unref (download); + + gst_buffer_set_caps(buffer, dash_stream->input_caps); + GST_BUFFER_TIMESTAMP(buffer) = timestamp; + GST_BUFFER_DURATION(buffer) = duration; + GST_BUFFER_OFFSET(buffer) = gst_mpd_client_get_segment_index (stream) - 1; + size_buffer = GST_BUFFER_SIZE (buffer); + /* Push fragment into the queue */ + gst_dash_demux_stream_push_data (selected_stream, buffer); + diff = (GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (start)); + gst_download_rate_add_rate (&selected_stream->dnl_rate, size_buffer, diff, duration); + GST_DEBUG_OBJECT (demux, + "Stream: %d Download rate = %" G_GUINT64_FORMAT " Kbits/s (%" G_GUINT64_FORMAT + " Ko in %.2f s)\n", selected_stream->idx, + gst_download_rate_get_current_rate (&selected_stream->dnl_rate) / 1000, + size_buffer / 1024, + ((double) diff / GST_SECOND)); + } } - /* Push fragment set into the queue */ - g_queue_push_tail (demux->queue, fragment_set); - /* Wake the download task up */ - GST_TASK_SIGNAL (demux->download_task); - g_get_current_time (&now); - diff = (GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (start)); - demux->dnl_rate = (size_buffer * 8) / ((double) diff / GST_SECOND); - GST_INFO_OBJECT (demux, - "Download rate = %" PRIu64 " Kbits/s (%" PRIu64 " Ko in %.2f s)", - demux->dnl_rate / 1000, size_buffer / 1024, ((double) diff / GST_SECOND)); - return TRUE; + + demux->end_of_period = end_of_period; + + return !end_of_period; } diff --git a/wearable/dashdemux/src/gstdashdemux.h b/dashdemux/src/gstdashdemux.h similarity index 76% rename from wearable/dashdemux/src/gstdashdemux.h rename to dashdemux/src/gstdashdemux.h index ec5d8ec..9e3fe6c 100755 --- a/wearable/dashdemux/src/gstdashdemux.h +++ b/dashdemux/src/gstdashdemux.h @@ -29,12 +29,11 @@ #define __GST_DASH_DEMUX_H__ #define DASHDEMUX_MODIFICATION #include -#include -#include -#include +#include #include "gstmpdparser.h" #include "gstfragmented.h" #include "gsturidownloader.h" +#include "gstdownloadrate.h" G_BEGIN_DECLS #define GST_TYPE_DASH_DEMUX \ @@ -50,6 +49,23 @@ G_BEGIN_DECLS // typedef struct _GstDashDemux GstDashDemux; typedef struct _GstDashDemuxClass GstDashDemuxClass; +typedef struct _GstDashDemuxStream GstDashDemuxStream; + +struct _GstDashDemuxStream { + guint idx; + GstPad *srcpad; + GstCaps *output_caps; + GstCaps *input_caps; + GstDataQueue *queue; + GstClockTime start_time; + gboolean download_end_of_period; + gboolean stream_end_of_period; + gboolean stream_eos; + gboolean need_header; + gboolean need_segment; + GstDownloadRate dnl_rate; +}; + #define MAX_LANGUAGES 20 /** * GstDashDemux: @@ -60,19 +76,17 @@ struct _GstDashDemux { GstElement parent; GstPad *sinkpad; - GstPad *srcpad[MAX_LANGUAGES]; /*Video/Audio/Application src pad */ - GstCaps *output_caps[MAX_LANGUAGES]; /*Video/Audio/Application output buf caps */ - GstCaps *input_caps[MAX_LANGUAGES]; /*Video/Audio/Application input caps */ + GSList *streams; + gint max_video_width; + gint max_video_height; GstBuffer *manifest; GstUriDownloader *downloader; GstMpdClient *client; /* MPD client */ - GQueue *queue; /* Video/Audio/Application List of fragment storing the fetched fragments */ gboolean end_of_period; gboolean end_of_manifest; /* Properties */ - GstClockTime min_buffering_time; /* Minimum buffering time accumulated before playback */ GstClockTime max_buffering_time; /* Maximum buffering time accumulated during playback */ gfloat bandwidth_usage; /* Percentage of the available bandwidth to use */ guint64 max_bitrate; /* max of bitrate supported by target decoder */ @@ -81,24 +95,16 @@ struct _GstDashDemux GstTask *stream_task; GStaticRecMutex stream_lock; GMutex *stream_timed_lock; - GTimeVal next_push; /* Time of the next push */ /* Download task */ GstTask *download_task; GStaticRecMutex download_lock; - gboolean cancelled; - GMutex *download_timed_lock; - GTimeVal next_download; /* Time of the next download */ + volatile gboolean cancelled; + GMutex download_mutex; + GCond download_cond; /* Manifest update */ GstClockTime last_manifest_update; - - /* Position in the stream */ - GstClockTime position; - GstClockTime position_shift; - gboolean need_segment; - /* Download rate */ - guint64 dnl_rate; }; struct _GstDashDemuxClass diff --git a/dashdemux/src/gstdownloadrate.c b/dashdemux/src/gstdownloadrate.c new file mode 100644 index 0000000..9913e0a --- /dev/null +++ b/dashdemux/src/gstdownloadrate.c @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) 2011 Andoni Morales Alastruey + * Copyright (C) 2012 Smart TV Alliance + * Author: Louis-Francis Ratté-Boulianne , Collabora Ltd. + * + * gstfragment.c: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include "gstdownloadrate.h" + +static void +_gst_download_rate_check_remove_rates (GstDownloadRate * rate) +{ + if (rate->max_length == 0) + return; + + while (g_queue_get_length (&rate->queue) > rate->max_length) { + guint bitrate = GPOINTER_TO_UINT (g_queue_pop_head (&rate->queue)); + + rate->total -= bitrate; + } +} + +void +gst_download_rate_init (GstDownloadRate * rate) +{ + g_queue_init (&rate->queue); + g_mutex_init (&rate->mutex); + rate->total = 0; + rate->max_length = 0; + rate->aver_period = 0; +} + +void +gst_download_rate_deinit (GstDownloadRate * rate) +{ + gst_download_rate_clear (rate); + g_mutex_clear (&rate->mutex); +} + +void +gst_download_rate_set_max_length (GstDownloadRate * rate, gint max_length) +{ + g_mutex_lock (&rate->mutex); + rate->max_length = max_length; + _gst_download_rate_check_remove_rates (rate); + g_mutex_unlock (&rate->mutex); +} + +gint +gst_download_rate_get_max_length (GstDownloadRate * rate) +{ + guint ret; + g_mutex_lock (&rate->mutex); + ret = rate->max_length; + g_mutex_unlock (&rate->mutex); + + return ret; +} + +void + gst_download_rate_set_aver_period (GstDownloadRate * rate, guint64 aver_period) +{ + g_mutex_lock (&rate->mutex); + rate->aver_period = aver_period; + _gst_download_rate_check_remove_rates (rate); + g_mutex_unlock (&rate->mutex); +} + +GstClockTime +gst_download_rate_get_aver_period (GstDownloadRate * rate) +{ + guint64 ret; + g_mutex_lock (&rate->mutex); + ret = rate->aver_period; + g_mutex_unlock (&rate->mutex); + + return ret; +} + +void +gst_download_rate_clear (GstDownloadRate * rate) +{ + g_mutex_lock (&rate->mutex); + g_queue_clear (&rate->queue); + rate->total = 0; + g_mutex_unlock (&rate->mutex); +} + +void +gst_download_rate_add_rate (GstDownloadRate * rate, guint bytes, guint64 time, GstClockTime duration) +{ + guint64 bitrate; + g_mutex_lock (&rate->mutex); + + /* convert from bytes / nanoseconds to bits per second */ + bitrate = G_GUINT64_CONSTANT (8000000000) * bytes / ((double) time); + g_queue_push_tail (&rate->queue, GUINT_TO_POINTER ((guint) bitrate)); + rate->total += bitrate; + + if ( duration * rate->max_length > rate->aver_period ) + rate->max_length = + duration < rate->aver_period ? rate->aver_period / duration : 1; + + _gst_download_rate_check_remove_rates (rate); + g_mutex_unlock (&rate->mutex); +} + +guint64 +gst_download_rate_get_current_rate (GstDownloadRate * rate) +{ + guint64 ret; + g_mutex_lock (&rate->mutex); + if (g_queue_get_length (&rate->queue)) + ret = rate->total / g_queue_get_length (&rate->queue); + else + ret = 0; + g_mutex_unlock (&rate->mutex); + + return ret; +} diff --git a/dashdemux/src/gstdownloadrate.h b/dashdemux/src/gstdownloadrate.h new file mode 100644 index 0000000..e4da338 --- /dev/null +++ b/dashdemux/src/gstdownloadrate.h @@ -0,0 +1,58 @@ +/* GStreamer + * Copyright (C) 2012 Smart TV Alliance + * Author: Thiago Sousa Santos , Collabora Ltd. + * + * gstdownloadrate.h: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_DOWNLOAD_RATE_H__ +#define __GST_DOWNLOAD_RATE_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstDownloadRate GstDownloadRate; + +struct _GstDownloadRate +{ + GQueue queue; + GMutex mutex; + + gint max_length; + guint64 aver_period; + guint64 total; +}; + +void gst_download_rate_init (GstDownloadRate * rate); +void gst_download_rate_deinit (GstDownloadRate * rate); + +void gst_download_rate_set_max_length (GstDownloadRate * rate, gint max_length); +gint gst_download_rate_get_max_length (GstDownloadRate * rate); + +void gst_download_rate_set_aver_period (GstDownloadRate * rate, GstClockTime aver_period); +GstClockTime gst_download_rate_get_aver_period (GstDownloadRate * rate); + +void gst_download_rate_clear (GstDownloadRate * rate); +void gst_download_rate_add_rate (GstDownloadRate * rate, guint bytes, guint64 time, GstClockTime duration); + +guint64 gst_download_rate_get_current_rate (GstDownloadRate * rate); + +G_END_DECLS +#endif /* __GST_DOWNLOAD_RATE_H__ */ diff --git a/wearable/dashdemux/src/gstfragment.c b/dashdemux/src/gstfragment.c similarity index 60% rename from wearable/dashdemux/src/gstfragment.c rename to dashdemux/src/gstfragment.c index c820c8f..2102726 100755 --- a/wearable/dashdemux/src/gstfragment.c +++ b/dashdemux/src/gstfragment.c @@ -21,6 +21,7 @@ #include #include +#include #include "glibcompat.h" #include "gstfragmented.h" #include "gstfragment.h" @@ -43,11 +44,8 @@ enum struct _GstFragmentPrivate { - GstBufferList *buffer_list; - guint64 size; - GstBufferListIterator *buffer_iterator; - GstCaps *caps; - G_MUTEX lock; + GstBuffer *buffer; + GstAdapter *adapter; }; G_DEFINE_TYPE (GstFragment, gst_fragment, G_TYPE_OBJECT); @@ -56,24 +54,6 @@ static void gst_fragment_dispose (GObject * object); static void gst_fragment_finalize (GObject * object); static void -gst_fragment_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec) -{ - GstFragment *fragment = GST_FRAGMENT (object); - - switch (property_id) { - case PROP_CAPS: - gst_fragment_set_caps (fragment, g_value_get_boxed (value)); - break; - - default: - /* We don't have any other property... */ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void gst_fragment_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { @@ -96,14 +76,6 @@ gst_fragment_get_property (GObject * object, g_value_set_boolean (value, fragment->discontinuous); break; - case PROP_BUFFER_LIST: - g_value_set_object (value, gst_fragment_get_buffer_list (fragment)); - break; - - case PROP_CAPS: - g_value_set_boxed (value, gst_fragment_get_caps (fragment)); - break; - default: /* We don't have any other property... */ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -120,7 +92,6 @@ gst_fragment_class_init (GstFragmentClass * klass) g_type_class_add_private (klass, sizeof (GstFragmentPrivate)); - gobject_class->set_property = gst_fragment_set_property; gobject_class->get_property = gst_fragment_get_property; gobject_class->dispose = gst_fragment_dispose; gobject_class->finalize = gst_fragment_finalize; @@ -142,15 +113,6 @@ gst_fragment_class_init (GstFragmentClass * klass) g_param_spec_uint64 ("duration", "Fragment duration", "Duration of the fragment", 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, PROP_BUFFER_LIST, - g_param_spec_object ("buffer-list", "Buffer List", - "A list with the fragment's buffers", GST_TYPE_FRAGMENT, - G_PARAM_READABLE)); - - g_object_class_install_property (gobject_class, PROP_CAPS, - g_param_spec_boxed ("caps", "Fragment caps", - "The caps of the fragment's buffer. (NULL = detect)", GST_TYPE_CAPS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -160,11 +122,7 @@ gst_fragment_init (GstFragment * fragment) fragment->priv = priv = GST_FRAGMENT_GET_PRIVATE (fragment); - G_MUTEX_INIT (fragment->priv->lock); - priv->buffer_list = gst_buffer_list_new (); - priv->size = 0; - priv->buffer_iterator = gst_buffer_list_iterate (priv->buffer_list); - gst_buffer_list_iterator_add_group (priv->buffer_iterator); + priv->adapter = gst_adapter_new (); fragment->download_start_time = g_get_real_time (); fragment->start_time = 0; fragment->stop_time = 0; @@ -186,7 +144,6 @@ gst_fragment_finalize (GObject * gobject) GstFragment *fragment = GST_FRAGMENT (gobject); g_free (fragment->name); - G_MUTEX_CLEAR (fragment->priv->lock); G_OBJECT_CLASS (gst_fragment_parent_class)->finalize (gobject); } @@ -196,70 +153,44 @@ gst_fragment_dispose (GObject * object) { GstFragmentPrivate *priv = GST_FRAGMENT (object)->priv; - if (priv->buffer_list != NULL) { - gst_buffer_list_iterator_free (priv->buffer_iterator); - gst_buffer_list_unref (priv->buffer_list); - priv->buffer_list = NULL; - priv->size = 0; + if (priv->buffer != NULL) { + gst_buffer_unref (priv->buffer); + priv->buffer = NULL; } - if (priv->caps != NULL) { - gst_caps_unref (priv->caps); - priv->caps = NULL; + if (priv->adapter != NULL) { + g_object_unref (priv->adapter); + priv->adapter = NULL; } G_OBJECT_CLASS (gst_fragment_parent_class)->dispose (object); } -GstBufferList * -gst_fragment_get_buffer_list (GstFragment * fragment) +GstBuffer * +gst_fragment_get_buffer (GstFragment * fragment) { g_return_val_if_fail (fragment != NULL, NULL); if (!fragment->completed) return NULL; - gst_buffer_list_ref (fragment->priv->buffer_list); - return fragment->priv->buffer_list; -} - -void -gst_fragment_set_caps (GstFragment * fragment, GstCaps * caps) -{ - g_return_if_fail (fragment != NULL); - - G_MUTEX_LOCK (fragment->priv->lock); - gst_caps_replace (&fragment->priv->caps, caps); - G_MUTEX_UNLOCK (fragment->priv->lock); -} - -GstCaps * -gst_fragment_get_caps (GstFragment * fragment) -{ - g_return_val_if_fail (fragment != NULL, NULL); - - if (!fragment->completed) - return NULL; - - G_MUTEX_LOCK (fragment->priv->lock); - if (fragment->priv->caps == NULL) { - GstBuffer *buf = gst_buffer_list_get (fragment->priv->buffer_list, 0, 0); - fragment->priv->caps = gst_type_find_helper_for_buffer (NULL, buf, NULL); + if(!fragment->priv->buffer) { + fragment->priv->buffer = gst_adapter_take_buffer(fragment->priv->adapter, + gst_adapter_available(fragment->priv->adapter)); } - gst_caps_ref (fragment->priv->caps); - G_MUTEX_UNLOCK (fragment->priv->lock); - return fragment->priv->caps; + return gst_buffer_ref(fragment->priv->buffer); } guint64 -gst_fragment_get_buffer_size (GstFragment * fragment) +gst_fragment_get_total_size (GstFragment * fragment) { g_return_val_if_fail (fragment != NULL, 0); - if (!fragment->completed) - return 0; - return fragment->priv->size; + if (fragment->priv->buffer) + return GST_BUFFER_SIZE(fragment->priv->buffer); + + return gst_adapter_available(fragment->priv->adapter); } @@ -275,7 +206,6 @@ gst_fragment_add_buffer (GstFragment * fragment, GstBuffer * buffer) return FALSE; } - gst_buffer_list_iterator_add (fragment->priv->buffer_iterator, buffer); - fragment->priv->size = fragment->priv->size + GST_BUFFER_SIZE (buffer); + gst_adapter_push(fragment->priv->adapter, buffer); return TRUE; } diff --git a/wearable/dashdemux/src/gstfragment.h b/dashdemux/src/gstfragment.h similarity index 90% rename from wearable/dashdemux/src/gstfragment.h rename to dashdemux/src/gstfragment.h index e6f7088..3068943 100755 --- a/wearable/dashdemux/src/gstfragment.h +++ b/dashdemux/src/gstfragment.h @@ -60,10 +60,8 @@ struct _GstFragmentClass GType gst_fragment_get_type (void); -guint64 gst_fragment_get_buffer_size (GstFragment * fragment); -GstBufferList * gst_fragment_get_buffer_list (GstFragment *fragment); -void gst_fragment_set_caps (GstFragment * fragment, GstCaps * caps); -GstCaps * gst_fragment_get_caps (GstFragment * fragment); +guint64 gst_fragment_get_total_size (GstFragment * fragment); +GstBuffer *gst_fragment_get_buffer(GstFragment *fragment); gboolean gst_fragment_add_buffer (GstFragment *fragment, GstBuffer *buffer); GstFragment * gst_fragment_new (void); diff --git a/wearable/dashdemux/src/gstfragmented.h b/dashdemux/src/gstfragmented.h similarity index 100% rename from wearable/dashdemux/src/gstfragmented.h rename to dashdemux/src/gstfragmented.h diff --git a/wearable/dashdemux/src/gstmpdparser.c b/dashdemux/src/gstmpdparser.c similarity index 87% rename from wearable/dashdemux/src/gstmpdparser.c rename to dashdemux/src/gstmpdparser.c index 474a9ac..1d835be 100755 --- a/wearable/dashdemux/src/gstmpdparser.c +++ b/dashdemux/src/gstmpdparser.c @@ -110,7 +110,7 @@ static gint convert_to_millisecs (gint decimals, gint pos); static int strncmp_ext (const char *s1, const char *s2); static GstStreamPeriod *gst_mpdparser_get_stream_period (GstMpdClient * client); static gchar *gst_mpdparser_parse_baseURL (GstMpdClient * client); -static gchar *gst_mpdparser_get_segmentURL_for_range (gchar * url, +static gchar *gst_mpdparser_get_segmentURL_for_range (const gchar *url, GstRange * range); static gchar *gst_mpdparser_get_mediaURL (GstMpdClient * client, GstSegmentURLNode * segmentURL); @@ -122,9 +122,7 @@ static gboolean gst_mpd_client_add_media_segment (GstActiveStream * stream, GstSegmentURLNode * url_node, guint number, guint start, GstClockTime start_time, GstClockTime duration); static const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType); -static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client); -static void gst_mpd_client_set_segment_index (GstActiveStream * stream, - guint segment_idx); +static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client, GstActiveStream * stream); /* Adaptation Set */ static GstAdaptationSetNode @@ -145,7 +143,7 @@ static GstRepresentationNode *gst_mpdparser_get_highest_representation (GList * Representations); static GstRepresentationNode *gst_mpdparser_get_representation_with_max_bandwidth (GList * - Representations, gint max_bandwidth); + Representations, guint64 max_bandwidth); #endif static GstSegmentBaseType *gst_mpdparser_get_segment_base (GstPeriodNode * Period, GstAdaptationSetNode * AdaptationSet, @@ -903,7 +901,6 @@ gst_mpdparser_parse_baseURL_node (GList ** list, xmlNode * a_node) GST_LOG ("content of BaseURL node:"); new_base_url->baseURL = gst_mpdparser_get_xml_node_content (a_node); - GST_LOG ("attributes of BaseURL node:"); new_base_url->serviceLocation = gst_mpdparser_get_xml_prop_string (a_node, "serviceLocation"); @@ -1233,6 +1230,8 @@ gst_mpdparser_parse_representation_base_type (GstRepresentationBaseType ** gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "width", 0); representation_base->height = gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "height", 0); + representation_base->bandwidth = + gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "bandwidth", 0); representation_base->sar = gst_mpdparser_get_xml_prop_ratio (a_node, "sar"); representation_base->frameRate = gst_mpdparser_get_xml_prop_framerate (a_node, "frameRate"); @@ -1865,10 +1864,13 @@ gst_mpdparser_get_segment_base (GstPeriodNode * Period, gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations, - gint max_bandwidth) + guint64 max_bandwidth) { GList *list = NULL, *best = NULL; GstRepresentationNode *representation; + guint64 best_bandwidth = 0; + + GST_DEBUG ("max bandwidth %" G_GUINT64_FORMAT, max_bandwidth); if (Representations == NULL) return -1; @@ -1877,9 +1879,11 @@ gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations, return 0; for (list = g_list_first (Representations); list; list = g_list_next (list)) { - representation = (GstRepresentationNode *) list->data; - if (representation && representation->bandwidth <= max_bandwidth) { + representation = (GstRepresentationNode *) list->data; + if (representation && representation->bandwidth <= max_bandwidth && + representation->bandwidth > best_bandwidth) { best = list; + best_bandwidth = representation->bandwidth; } } @@ -2267,13 +2271,14 @@ gst_mpdparser_free_active_stream (GstActiveStream * active_stream) if (active_stream) { g_list_foreach (active_stream->segments, (GFunc) gst_mpdparser_free_media_segment, NULL); - g_list_free (active_stream->segments); + if (active_stream->segments) + g_list_free (active_stream->segments); g_slice_free (GstActiveStream, active_stream); } } static gchar * -gst_mpdparser_get_segmentURL_for_range (gchar * url, GstRange * range) +gst_mpdparser_get_segmentURL_for_range (const gchar * url, GstRange * range) { gchar *segmentURL; @@ -2416,28 +2421,28 @@ gst_mpdparser_parse_baseURL (GstMpdClient * client) /* FIXME: this simple implementation is not fully compliant with RFC 3986 */ if ((list = client->mpd_node->BaseURLs) != NULL) { - baseURL = g_list_nth_data (list, stream->baseURL_idx); + baseURL = g_list_nth_data (list, stream->mpd_baseURL_idx); if (!baseURL) { baseURL = list->data; } baseURL_array[0] = baseURL->baseURL; } if ((list = stream_period->period->BaseURLs) != NULL) { - baseURL = g_list_nth_data (list, stream->baseURL_idx); + baseURL = g_list_nth_data (list, stream->period_baseURL_idx); if (!baseURL) { baseURL = list->data; } baseURL_array[1] = baseURL->baseURL; } if ((list = stream->cur_adapt_set->BaseURLs) != NULL) { - baseURL = g_list_nth_data (list, stream->baseURL_idx); + baseURL = g_list_nth_data (list, stream->adaptset_baseURL_idx); if (!baseURL) { baseURL = list->data; } baseURL_array[2] = baseURL->baseURL; } if ((list = stream->cur_representation->BaseURLs) != NULL) { - baseURL = g_list_nth_data (list, stream->baseURL_idx); + baseURL = g_list_nth_data (list, stream->repr_baseURL_idx); if (!baseURL) { baseURL = list->data; } @@ -2459,22 +2464,17 @@ gst_mpdparser_parse_baseURL (GstMpdClient * client) } } - GST_DEBUG ("selected baseURL with index %d: %s", stream->baseURL_idx, ret); - return ret; } static GstClockTime -gst_mpd_client_get_segment_duration (GstMpdClient * client) +gst_mpd_client_get_segment_duration (GstMpdClient * client, GstActiveStream *stream) { - GstActiveStream *stream; GstStreamPeriod *stream_period; GstMultSegmentBaseType *base = NULL; GstClockTime duration; guint timescale; - stream = - gst_mpdparser_get_active_stream_by_index (client, client->stream_idx); g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE); stream_period = gst_mpdparser_get_stream_period (client); g_return_val_if_fail (stream_period != NULL, GST_CLOCK_TIME_NONE); @@ -2511,6 +2511,8 @@ gst_mpd_client_new () client = g_new0 (GstMpdClient, 1); client->lock = g_mutex_new (); + client->download_failed_count = 0; + return client; } @@ -2586,8 +2588,6 @@ gst_mpd_parse (GstMpdClient * client, const gchar * data, gint size) } /* free the document */ xmlFreeDoc (doc); - /* cleanup function for the XML library */ - xmlCleanupParser (); /* dump XML library memory for debugging */ xmlMemoryDump (); } @@ -2612,19 +2612,50 @@ gst_mpdparser_get_baseURL (GstMpdClient * client) return stream->baseURL; } -GstMediaSegment * +gboolean gst_mpdparser_get_chunk_by_index (GstMpdClient * client, guint indexStream, - guint indexChunk) + guint indexChunk, GstMediaSegment *segment) { GstActiveStream *stream; /* select stream */ - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (client->active_streams != NULL, NULL); + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (segment != NULL, FALSE); + g_return_val_if_fail (client->active_streams != NULL, FALSE); stream = g_list_nth_data (client->active_streams, indexStream); - g_return_val_if_fail (stream != NULL, NULL); + g_return_val_if_fail (stream != NULL, FALSE); + + if(stream->segments) { + GstMediaSegment *list_segment; + if ( indexChunk >= g_list_length (stream->segments)) + return FALSE; + list_segment = g_list_nth_data (stream->segments, indexChunk); + memcpy (segment, list_segment, sizeof (GstMediaSegment)); + } else { + GstClockTime duration; + GstStreamPeriod *stream_period; + GstClockTime start_time; + stream_period = gst_mpdparser_get_stream_period (client); + g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType->SegmentTimeline == NULL, FALSE); + g_return_val_if_fail (stream_period != NULL, FALSE); + g_return_val_if_fail (stream_period->period != NULL, FALSE); + + duration = gst_mpd_client_get_segment_duration (client, stream); + if (!GST_CLOCK_TIME_IS_VALID (duration)) + return FALSE; + + start_time = duration * indexChunk; + if (GST_CLOCK_TIME_IS_VALID (stream_period->start) && GST_CLOCK_TIME_IS_VALID (stream_period->duration) + && start_time >= stream_period->start + stream_period->duration) + return FALSE; - return (GstMediaSegment *) g_list_nth_data (stream->segments, indexChunk); + segment->number = indexChunk + stream->cur_seg_template->MultSegBaseType->startNumber; + segment->start_time = start_time; + segment->duration = duration; + segment->SegmentURL = NULL; + } + + return TRUE; } static gboolean @@ -2760,7 +2791,7 @@ gst_mpd_client_setup_representation (GstMpdClient * client, } } } else { - duration = gst_mpd_client_get_segment_duration (client); + duration =gst_mpd_client_get_segment_duration (client, stream); if (!GST_CLOCK_TIME_IS_VALID (duration)) return FALSE; @@ -2832,19 +2863,7 @@ gst_mpd_client_setup_representation (GstMpdClient * client, } } } else { - duration = gst_mpd_client_get_segment_duration (client); - if (!GST_CLOCK_TIME_IS_VALID (duration) - || !GST_CLOCK_TIME_IS_VALID (PeriodEnd)) - return FALSE; - - while (PeriodStart + start_time < PeriodEnd) { - if (!gst_mpd_client_add_media_segment (stream, NULL, i, 0, start_time, - duration)) { - return FALSE; - } - i++; - start_time += duration; - } + /*The segment is created on demand with the template, no need to build a list */ } } } @@ -2908,6 +2927,8 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client) } else if (idx == 0 && client->mpd_node->type == GST_MPD_FILE_TYPE_STATIC) { /* first period of a static MPD file, start time is 0 */ start = 0; + } else if (gst_mpd_client_is_live (client)) { + /*it should be a live stream, let this pass.*/ } else { /* this is an 'Early Available Period' */ goto early; @@ -2928,6 +2949,8 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client) /* last Period of the Media Presentation */ duration = client->mpd_node->mediaPresentationDuration * GST_MSECOND - start; + } else if (gst_mpd_client_is_live (client)) { + /*it should be a live stream, let this pass.*/ } else { /* Invalid MPD file! */ goto syntax_error; @@ -3054,14 +3077,17 @@ gst_mpd_client_setup_streaming (GstMpdClient * client, } client->active_streams = g_list_append (client->active_streams, stream); - stream->baseURL_idx = 0; + stream->mpd_baseURL_idx = 0; + stream->period_baseURL_idx = 0; + stream->adaptset_baseURL_idx = 0; + stream->repr_baseURL_idx = 0; + stream->mimeType = mimeType; stream->cur_adapt_set = adapt_set; /* retrive representation list */ if (stream->cur_adapt_set != NULL) rep_list = stream->cur_adapt_set->Representations; - #if 0 /* fast start */ representation = @@ -3093,12 +3119,69 @@ gst_mpd_client_setup_streaming (GstMpdClient * client, } gboolean +gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, + guint stream_idx, GstClockTime * ts) +{ + GstActiveStream *stream; + gint segment_idx; + GstMediaSegment currentChunk; + + GST_DEBUG ("Stream index: %i", stream_idx); + stream = g_list_nth_data (client->active_streams, stream_idx); + g_return_val_if_fail (stream != NULL, 0); + + GST_MPD_CLIENT_LOCK (client); + segment_idx = gst_mpd_client_get_segment_index (stream); + GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx); + + + if (!gst_mpdparser_get_chunk_by_index (client, stream_idx, segment_idx, ¤tChunk)) { + GST_MPD_CLIENT_UNLOCK (client); + return FALSE; + } + + *ts = currentChunk.start_time; + GST_MPD_CLIENT_UNLOCK (client); + + return TRUE; +} + +gboolean +gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client, + guint stream_idx, GstClockTime * ts) +{ + GstActiveStream *stream; + gint segment_idx = 0; + GstMediaSegment currentChunk; + + GST_DEBUG ("Stream index: %i", stream_idx); + stream = g_list_nth_data (client->active_streams, stream_idx); + g_return_val_if_fail (stream != NULL, 0); + + GST_MPD_CLIENT_LOCK (client); + if (stream->segments) + segment_idx = g_list_length (stream->segments) - 1; + GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx); + + if (!gst_mpdparser_get_chunk_by_index (client, stream_idx, segment_idx, + ¤tChunk)) { + GST_MPD_CLIENT_UNLOCK (client); + return FALSE; + } + + *ts = currentChunk.start_time; + GST_MPD_CLIENT_UNLOCK (client); + + return TRUE; +} + +gboolean gst_mpd_client_get_next_fragment (GstMpdClient * client, guint indexStream, gboolean * discontinuity, gchar ** uri, GstClockTime * duration, GstClockTime * timestamp) { GstActiveStream *stream = NULL; - GstMediaSegment *currentChunk; + GstMediaSegment currentChunk; gchar *mediaURL = NULL; guint segment_idx; @@ -3114,25 +3197,23 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client, segment_idx = gst_mpd_client_get_segment_index (stream); GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx); - currentChunk = - gst_mpdparser_get_chunk_by_index (client, indexStream, segment_idx); - if (currentChunk == NULL) { + if (!gst_mpdparser_get_chunk_by_index (client, indexStream, segment_idx, ¤tChunk)) { GST_MPD_CLIENT_UNLOCK (client); return FALSE; } - if (currentChunk->SegmentURL != NULL) { - mediaURL = gst_mpdparser_get_mediaURL (client, currentChunk->SegmentURL); + if (currentChunk.SegmentURL != NULL) { + mediaURL = gst_mpdparser_get_mediaURL (client, currentChunk.SegmentURL); } else if (stream->cur_seg_template != NULL) { mediaURL = gst_mpdparser_build_URL_from_template (stream->cur_seg_template->media, - stream->cur_representation->id, currentChunk->number, - stream->cur_representation->bandwidth, currentChunk->start); + stream->cur_representation->id, currentChunk.number, + stream->cur_representation->bandwidth, currentChunk.start); } - *timestamp = currentChunk->start_time; - *duration = currentChunk->duration; - *discontinuity = segment_idx != currentChunk->number; + *timestamp = currentChunk.start_time; + *duration = currentChunk.duration; + *discontinuity = segment_idx != currentChunk.number; if (mediaURL == NULL) { /* single segment with URL encoded in the baseURL syntax element */ *uri = g_strdup (gst_mpdparser_get_baseURL (client)); @@ -3196,21 +3277,25 @@ gst_mpd_client_get_next_header (GstMpdClient * client, const gchar ** uri, return *uri == NULL ? FALSE : TRUE; } -GstClockTime -gst_mpd_client_get_current_position (GstMpdClient * client) +gboolean +gst_mpd_client_get_stream_current_position (GstMpdClient * client, guint stream_idx, GstClockTime *ts) { GstActiveStream *stream; - GstMediaSegment *media_segment; - - stream = g_list_nth_data (client->active_streams, client->stream_idx); - g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE); - - media_segment = - g_list_nth_data (stream->segments, - gst_mpd_client_get_segment_index (stream)); - g_return_val_if_fail (media_segment != NULL, GST_CLOCK_TIME_NONE); + GstMediaSegment media_segment; + stream = gst_mpdparser_get_active_stream_by_index( client, stream_idx); + g_return_val_if_fail (stream != NULL, FALSE); + if(!gst_mpdparser_get_chunk_by_index(client, stream_idx, + gst_mpd_client_get_segment_index (stream), &media_segment)) + { + return FALSE; + } - return media_segment->start_time; + if (GST_CLOCK_TIME_IS_VALID (media_segment.start_time)) { + *ts = media_segment.start_time; + return TRUE; + } else { + return FALSE; + } } GstClockTime @@ -3218,15 +3303,26 @@ gst_mpd_client_get_next_fragment_duration (GstMpdClient * client) { GstActiveStream *stream; GstMediaSegment *media_segment; + gint seg_idx; stream = g_list_nth_data (client->active_streams, client->stream_idx); g_return_val_if_fail (stream != NULL, 0); + seg_idx = gst_mpd_client_get_segment_index (stream); - media_segment = - g_list_nth_data (stream->segments, - gst_mpd_client_get_segment_index (stream)); + if(stream->segments) { + media_segment = + g_list_nth_data (stream->segments, seg_idx); + return media_segment == NULL ? 0 : media_segment->duration; + } else { + GstClockTime duration = + gst_mpd_client_get_segment_duration (client, stream); + g_return_val_if_fail (stream->cur_seg_template->MultSegBaseType-> + SegmentTimeline == NULL, 0); - return media_segment == NULL ? 0 : media_segment->duration; + if (GST_CLOCK_TIME_IS_VALID (duration)) + return duration; + return 0; + } } GstClockTime @@ -3281,6 +3377,66 @@ gst_mpd_client_get_period_index (GstMpdClient * client) return period_idx; } +gboolean +gst_mpd_client_set_period_id (GstMpdClient * client, const gchar * period_id) +{ + GstStreamPeriod *next_stream_period; + gboolean ret = FALSE; + GList *iter; + gint index = 0; + + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (client->periods != NULL, FALSE); + g_return_val_if_fail (period_id != NULL, FALSE); + + GST_MPD_CLIENT_LOCK (client); + for (iter = client->periods; iter; iter = g_list_next (iter)) { + next_stream_period = iter->data; + + if (next_stream_period->period->id + && strcmp (next_stream_period->period->id, period_id) == 0) { + client->period_idx = index; + ret = TRUE; + break; + } + index++; + } + GST_MPD_CLIENT_UNLOCK (client); + + return ret; +} + +const gchar * +gst_mpd_client_get_period_id (GstMpdClient * client) +{ + GstStreamPeriod *period; + gchar *period_id = NULL; + + g_return_val_if_fail (client != NULL, 0); + GST_MPD_CLIENT_LOCK (client); + period = g_list_nth_data (client->periods, client->period_idx); + if (period && period->period) + period_id = period->period->id; + GST_MPD_CLIENT_UNLOCK (client); + + return period_id; +} + +gboolean +gst_mpd_client_has_next_period (GstMpdClient * client) +{ + GList *next_stream_period; + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (client->periods != NULL, FALSE); + + GST_MPD_CLIENT_LOCK (client); + next_stream_period = + g_list_nth_data (client->periods, client->period_idx + 1); + GST_MPD_CLIENT_UNLOCK (client); + + return next_stream_period != NULL; +} + void gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, guint segment_idx) @@ -3300,7 +3456,51 @@ gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, } } -static void +gboolean +gst_mpd_client_set_next_baseURL_for_stream (GstMpdClient * client) +{ + GstActiveStream *stream; + GstStreamPeriod *stream_period; + GList *list; + + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (client->active_streams != NULL, FALSE); + + stream = g_list_nth_data (client->active_streams, + client->stream_idx); + g_return_val_if_fail (stream != NULL, FALSE); + stream_period = gst_mpdparser_get_stream_period (client); + g_return_val_if_fail (stream_period != NULL, FALSE); + + if ((list = stream->cur_representation->BaseURLs) != NULL && + stream->repr_baseURL_idx < g_list_length (list) - 1) { + stream->repr_baseURL_idx++; + } else if ((list = stream->cur_adapt_set->BaseURLs) != NULL && + stream->adaptset_baseURL_idx < g_list_length (list) - 1) { + stream->adaptset_baseURL_idx++; + stream->repr_baseURL_idx = 0; + } else if ((list = stream_period->period->BaseURLs) != NULL && + stream->period_baseURL_idx < g_list_length (list) - 1) { + stream->period_baseURL_idx++; + stream->adaptset_baseURL_idx = 0; + stream->repr_baseURL_idx = 0; + } else if ((list = client->mpd_node->BaseURLs) != NULL && + stream->mpd_baseURL_idx < g_list_length (list) - 1) { + stream->mpd_baseURL_idx++; + stream->period_baseURL_idx = 0; + stream->adaptset_baseURL_idx = 0; + stream->repr_baseURL_idx = 0; + } else { + GST_WARNING ("Unable to change URI: No alternative baseURL available"); + return FALSE; + } + + stream->baseURL = gst_mpdparser_parse_baseURL (client); + + return TRUE; +} + +void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx) { g_return_if_fail (stream != NULL); @@ -3355,6 +3555,169 @@ gst_mpdparser_get_active_stream_by_index (GstMpdClient * client, return g_list_nth_data (client->active_streams, stream_idx); } +gint +gst_mpd_client_get_video_active_stream_id(GstMpdClient *client) { + guint idx; + g_return_val_if_fail (client != NULL, -1); + g_return_val_if_fail (client->active_streams != NULL, -1); + for (idx = 0; idx < gst_mpdparser_get_nb_active_stream(client); idx++) { + GstActiveStream *stream = gst_mpdparser_get_active_stream_by_index(client, idx); + if( strncmp_ext (gst_mpd_client_get_stream_mimeType (stream), "video") == 0 ) + return idx; + } + return -1; +} + +gboolean +gst_mpd_client_stream_seek (GstMpdClient * client, gint stream_idx, GstClockTime ts) +{ + guint segment_idx = 0; + GstActiveStream *stream; + GST_MPD_CLIENT_LOCK (client); + GST_DEBUG ("mpd client seeking to %"GST_TIME_FORMAT" on stream %d", GST_TIME_ARGS(ts), stream_idx); + stream = gst_mpdparser_get_active_stream_by_index (client, stream_idx); + g_return_val_if_fail (stream != NULL, FALSE); + + if ( GST_CLOCK_TIME_IS_VALID (gst_mpd_client_stream_find_segment (client, + stream_idx, ts, &segment_idx))) { + gst_mpd_client_set_segment_index(stream, segment_idx); + } + GST_MPD_CLIENT_UNLOCK (client); + return TRUE; +} + +static GDateTime * +_gst_date_time_to_g_date_time (GstDateTime * datetime) +{ + g_return_val_if_fail (datetime != NULL, NULL); + return g_date_time_new_utc ( gst_date_time_get_year (datetime), gst_date_time_get_month(datetime), + gst_date_time_get_day(datetime), gst_date_time_get_hour(datetime), + gst_date_time_get_minute(datetime),gst_date_time_get_second(datetime)); +} + +gboolean +gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time) +{ + GDateTime *start = + _gst_date_time_to_g_date_time (client->mpd_node->availabilityStartTime); + GTimeSpan ts_microseconds; + GstClockTime ts; + gboolean ret = TRUE; + gint i; + + g_return_val_if_fail (gst_mpd_client_is_live (client), 0); + + ts_microseconds = g_date_time_difference (time, start); + g_date_time_unref (start); + + ts = ts_microseconds * GST_USECOND; + for (i=0; i < g_list_length (client->active_streams); i++) { + ret = ret & gst_mpd_client_stream_seek (client, i, ts); + } + return ret; +} + +gint +gst_mpd_client_check_time_position (GstMpdClient * client, + GstActiveStream * stream, GstClockTime ts, gint64 * diff) +{ + GDateTime *now = g_date_time_new_now_utc (); + GDateTime *start = + _gst_date_time_to_g_date_time (client->mpd_node->availabilityStartTime); + GTimeSpan stream_now; + GTimeSpan ts_microseconds; + GstClockTime duration; + + g_return_val_if_fail (gst_mpd_client_is_live (client), 0); + + duration = gst_mpd_client_get_segment_duration (client, stream); + stream_now = g_date_time_difference (now, start); + g_date_time_unref (now); + g_date_time_unref (start); + + /* sum duration to check if the segment is fully ready */ + ts_microseconds = (ts + duration) / GST_USECOND; + + /* + * This functions checks if a given ts is in the 'available range' of + * a DASH presentation. This only makes sense for live streams, which + * are continuously adding new segments and removing old ones. + * + * Note: Both the client and the server should use UTC as a time reference. + * + * @ts is the time since the beginning of the stream and we need to find out + * if it is currently available. The server should be hosting segments + * + * * ---------------- ... --- * ----------- * ---- ... + * | + * | past(unavailable) | | available | future(unavailable yet) + * | + * * ---------------- ... --- * ----------- * ---- ... + * | | | + * availabilitStartTime | UTC now + * UTC now - timeShiftBufferDepth + * + * This function should return 0 if @ts is in the 'available' area, 1 for + * 'future' and '-1' for past and the corresponding distance to the + * 'available' area is set to @diff + * + * TODO untested with live presentations with multiple periods as no + * examples for it could be found/generated + */ + + if (ts_microseconds > stream_now) { + *diff = ts_microseconds - stream_now; + return 1; + } + if (GST_CLOCK_TIME_IS_VALID (client->mpd_node->timeShiftBufferDepth) + && ts_microseconds < + stream_now - client->mpd_node->timeShiftBufferDepth * GST_USECOND) { + *diff = ts_microseconds - stream_now; + return -1; + } + + *diff = 0; + return 0; +} + +/*Finds the segment with appropriate time*/ +GstClockTime +gst_mpd_client_stream_find_segment(GstMpdClient *client, guint stream_idx, + GstClockTime seek_pos, guint *seg_num) +{ + guint cur_segment_idx=0; + GstMediaSegment *chunk; + GList *list = NULL; + GstClockTime current_pos = 0; + GstActiveStream *stream = gst_mpdparser_get_active_stream_by_index (client, stream_idx); + g_return_val_if_fail (stream != NULL, GST_CLOCK_TIME_NONE); + if(stream->segments != NULL) { + for (list = g_list_first (stream->segments); list; + list = g_list_next (list)) { + chunk = list->data; + current_pos = chunk->start_time; + if (current_pos <= seek_pos + && seek_pos < current_pos + chunk->duration) { + break; + } + cur_segment_idx++; + } + if(list != NULL) { + *seg_num = cur_segment_idx; + return current_pos; + } else { + return GST_CLOCK_TIME_NONE; + } + } else { + GstClockTime duration; + duration = gst_mpd_client_get_segment_duration (client, stream); + if( !GST_CLOCK_TIME_IS_VALID (duration) ) + return FALSE; + *seg_num = seek_pos / duration; + return *seg_num * duration; + } +} + static const gchar * gst_mpdparser_mimetype_to_caps (const gchar * mimeType) { @@ -3396,6 +3759,52 @@ gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream) return stream->cur_adapt_set->bitstreamSwitching; } +gboolean +gst_mpd_client_get_max_video_dimensions (GstMpdClient *client, gint *max_width, gint *max_height) +{ + GList *period_it, *repr_it; + GstStreamPeriod *period; + GstAdaptationSetNode *adaptset; + GstRepresentationNode *repr; + + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (max_height != NULL, FALSE); + g_return_val_if_fail (max_width != NULL, FALSE); + + *max_width = 0; + *max_height = 0; + + period_it = client->periods; + while(period_it) { + period = period_it->data; + adaptset = gst_mpdparser_get_adapt_set_with_mimeType_and_idx ( + period->period->AdaptationSets, "video", 0); + if(adaptset == NULL) + continue; + repr_it = adaptset->Representations; + + if(adaptset->RepresentationBase->width > *max_width) + *max_width = adaptset->RepresentationBase->width; + if(adaptset->RepresentationBase->height > *max_height) + *max_height = adaptset->RepresentationBase->height; + + while(repr_it) { + repr = repr_it->data; + if(repr->RepresentationBase->width > *max_width) + *max_width = repr->RepresentationBase->width; + if(repr->RepresentationBase->height > *max_height) + *max_height = repr->RepresentationBase->height; + repr_it = repr_it->next; + } + + period_it = period_it->next; + } + if(*max_width == 0 && *max_height == 0) + return FALSE; + else + return TRUE; +} + guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream) { @@ -3431,6 +3840,23 @@ gst_mpd_client_get_video_stream_height (GstActiveStream * stream) } guint +gst_mpd_client_get_video_stream_bandwidth (GstActiveStream * stream) +{ + guint bandwidth; + + if (stream == NULL || stream->cur_adapt_set == NULL + || stream->cur_representation == NULL) + return 0; + + bandwidth = stream->cur_representation->RepresentationBase->bandwidth; + if (bandwidth == 0) { + bandwidth = stream->cur_adapt_set->RepresentationBase->bandwidth; + } + + return bandwidth; +} + +guint gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream) { const gchar *rate; diff --git a/wearable/dashdemux/src/gstmpdparser.h b/dashdemux/src/gstmpdparser.h similarity index 88% rename from wearable/dashdemux/src/gstmpdparser.h rename to dashdemux/src/gstmpdparser.h index b270a3e..3231d62 100755 --- a/wearable/dashdemux/src/gstmpdparser.h +++ b/dashdemux/src/gstmpdparser.h @@ -193,6 +193,7 @@ struct _GstRepresentationBaseType gchar *profiles; guint width; guint height; + guint bandwidth; GstRatio *sar; GstFrameRate *frameRate; gchar *audioSamplingRate; @@ -219,7 +220,7 @@ struct _GstSubRepresentationNode guint level; guint *dependencyLevel; /* UIntVectorType */ guint size; /* size of "dependencyLevel" array */ - guint bandwidth; + guint64 bandwidth; gchar **contentComponent; /* StringVectorType */ }; @@ -428,7 +429,11 @@ struct _GstActiveStream { GstStreamMimeType mimeType; /* video/audio/application */ - guint baseURL_idx; /* index of the baseURL used for last request */ + guint mpd_baseURL_idx; /* MPD baseURL index */ + guint period_baseURL_idx; /* Period baseURL index */ + guint adaptset_baseURL_idx; /* AdaptationSet baseURL index */ + guint repr_baseURL_idx; /* Representation baseURL index */ + gchar *baseURL; /* active baseURL used for last request */ guint max_bandwidth; /* max bandwidth allowed for this mimeType */ @@ -452,7 +457,7 @@ struct _GstMpdClient GList *active_streams; /* list of GstActiveStream */ guint stream_idx; /* currently active stream */ - guint update_failed_count; + guint download_failed_count; gchar *mpd_uri; /* manifest file URI */ GMutex *lock; }; @@ -469,40 +474,54 @@ gboolean gst_mpd_parse (GstMpdClient *client, const gchar *data, gint size); gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client); gboolean gst_mpd_client_setup_streaming (GstMpdClient *client, GstStreamMimeType mimeType, gchar* lang); gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation); -GstClockTime gst_mpd_client_get_current_position (GstMpdClient *client); +gboolean gst_mpd_client_get_stream_current_position (GstMpdClient * client, guint stream_idx, GstClockTime *ts); GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client); GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client); gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, gboolean *discontinuity, gchar **uri, GstClockTime *duration, GstClockTime *timestamp); +gboolean gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts); +gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts); gboolean gst_mpd_client_get_next_header (GstMpdClient *client, const gchar **uri, guint stream_idx); gboolean gst_mpd_client_is_live (GstMpdClient * client); /* Period selection */ gboolean gst_mpd_client_set_period_index (GstMpdClient *client, guint period_idx); guint gst_mpd_client_get_period_index (GstMpdClient *client); +const gchar* gst_mpd_client_get_period_id (GstMpdClient * client); +gboolean gst_mpd_client_set_period_id (GstMpdClient * client, const gchar * period_id); +gboolean gst_mpd_client_has_next_period (GstMpdClient * client); /* Representation selection */ -gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint max_bandwidth); +gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, guint64 max_bandwidth); /* URL management */ const gchar *gst_mpdparser_get_baseURL (GstMpdClient *client); -GstMediaSegment *gst_mpdparser_get_chunk_by_index (GstMpdClient *client, guint indexStream, guint indexChunk); +gboolean gst_mpdparser_get_chunk_by_index (GstMpdClient * client, guint indexStream, guint indexChunk, GstMediaSegment *segment); +gboolean gst_mpd_client_set_next_baseURL_for_stream (GstMpdClient * client); /* Active stream */ guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client); GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx); +gint gst_mpd_client_get_video_active_stream_id(GstMpdClient *client); +gboolean gst_mpd_client_stream_seek (GstMpdClient * client, gint stream_idx, GstClockTime ts); +gboolean gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time); +gint gst_mpd_client_check_time_position (GstMpdClient * client, GstActiveStream * stream, GstClockTime ts, gint64 * diff); +GstClockTime gst_mpd_client_stream_find_segment(GstMpdClient *client, guint stream_idx, GstClockTime seek_pos, guint *seg_num); /* AdaptationSet */ guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client); /* Segment */ void gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, guint segment_idx); +void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx); guint gst_mpd_client_get_segment_index (GstActiveStream * stream); /* Get audio/video stream parameters (mimeType, width, height, rate, number of channels) */ const gchar *gst_mpd_client_get_stream_mimeType (GstActiveStream * stream); const gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream); +gboolean gst_mpd_client_get_max_video_dimensions(GstMpdClient *client, gint *max_width, gint *max_height); guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream); guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream); +guint gst_mpd_client_get_video_stream_bandwidth (GstActiveStream * stream); guint gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream); guint gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream); diff --git a/wearable/dashdemux/src/gstplugin.c b/dashdemux/src/gstplugin.c similarity index 100% rename from wearable/dashdemux/src/gstplugin.c rename to dashdemux/src/gstplugin.c diff --git a/wearable/dashdemux/src/gsturidownloader.c b/dashdemux/src/gsturidownloader.c similarity index 94% rename from wearable/dashdemux/src/gsturidownloader.c rename to dashdemux/src/gsturidownloader.c index 81e693d..0f7375d 100755 --- a/wearable/dashdemux/src/gsturidownloader.c +++ b/dashdemux/src/gsturidownloader.c @@ -41,6 +41,7 @@ struct _GstUriDownloaderPrivate GstFragment *download; GMutex *lock; GCond *cond; + gboolean canceled; /* add setting UA,cookies */ gchar *user_agent; gchar **cookies; @@ -104,6 +105,13 @@ gst_uri_downloader_init (GstUriDownloader * downloader) /* add setting UA, cookies */ downloader->priv->user_agent = NULL; downloader->priv->cookies = NULL; + downloader->priv->canceled = FALSE; +} + +void +gst_uri_downloader_reset(GstUriDownloader *downloader) +{ + downloader->priv->canceled = FALSE; } static void @@ -168,19 +176,16 @@ gst_uri_downloader_sink_event (GstPad * pad, GstEvent * event) switch (event->type) { case GST_EVENT_EOS:{ - GST_OBJECT_LOCK (downloader); GST_DEBUG_OBJECT (downloader, "Got EOS on the fetcher pad"); + g_mutex_lock (downloader->priv->lock); if (downloader->priv->download != NULL) { /* signal we have fetched the URI */ downloader->priv->download->completed = TRUE; downloader->priv->download->download_stop_time = g_get_real_time (); - GST_OBJECT_UNLOCK (downloader); GST_DEBUG_OBJECT (downloader, "Signaling chain funtion"); g_cond_signal (downloader->priv->cond); - - } else { - GST_OBJECT_UNLOCK (downloader); } + g_mutex_unlock (downloader->priv->lock); break; } default: @@ -221,10 +226,9 @@ gst_uri_downloader_chain (GstPad * pad, GstBuffer * buf) * response but the source element will also post a warning or error message * in the bus, which is handled synchronously cancelling the download. */ - GST_OBJECT_LOCK (downloader); + g_mutex_lock (downloader->priv->lock); if (downloader->priv->download == NULL) { /* Download cancelled, quit */ - GST_OBJECT_UNLOCK (downloader); goto done; } @@ -233,10 +237,10 @@ gst_uri_downloader_chain (GstPad * pad, GstBuffer * buf) GST_BUFFER_SIZE (buf)); if (!gst_fragment_add_buffer (downloader->priv->download, buf)) GST_WARNING_OBJECT (downloader, "Could not add buffer to fragment"); - GST_OBJECT_UNLOCK (downloader); done: { + g_mutex_unlock (downloader->priv->lock); return GST_FLOW_OK; } } @@ -245,7 +249,6 @@ static void gst_uri_downloader_stop (GstUriDownloader * downloader) { GstPad *pad; - GST_DEBUG_OBJECT (downloader, "Stopping source element"); /* remove the bus' sync handler */ @@ -268,19 +271,20 @@ gst_uri_downloader_stop (GstUriDownloader * downloader) void gst_uri_downloader_cancel (GstUriDownloader * downloader) { - GST_OBJECT_LOCK (downloader); + g_mutex_lock (downloader->priv->lock); if (downloader->priv->download != NULL) { GST_DEBUG_OBJECT (downloader, "Cancelling download"); g_object_unref (downloader->priv->download); downloader->priv->download = NULL; - GST_OBJECT_UNLOCK (downloader); - GST_DEBUG_OBJECT (downloader, "Signaling chain funtion"); - g_cond_signal (downloader->priv->cond); } else { - GST_OBJECT_UNLOCK (downloader); GST_DEBUG_OBJECT (downloader, "Trying to cancell a download that was alredy cancelled"); } + + GST_DEBUG_OBJECT (downloader, "Signaling chain funtion"); + downloader->priv->canceled = TRUE; + g_cond_signal (downloader->priv->cond); + g_mutex_unlock (downloader->priv->lock); } static gboolean @@ -327,10 +331,19 @@ gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri) g_mutex_lock (downloader->priv->lock); + if(downloader->priv->canceled) { + GST_DEBUG_OBJECT (downloader, "Uridownloader was canceled."); + goto quit; + } + if (!gst_uri_downloader_set_uri (downloader, uri)) { goto quit; } + /* add setting UA,cookies */ + g_object_set (downloader->priv->urisrc, "cookies", downloader->priv->cookies, NULL); + g_object_set (downloader->priv->urisrc, "user-agent", downloader->priv->user_agent, NULL); + downloader->priv->download = gst_fragment_new (); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); @@ -340,10 +353,6 @@ gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri) goto quit; } -/* add setting UA,cookies */ - g_object_set (downloader->priv->urisrc, "cookies", downloader->priv->cookies, NULL); - g_object_set (downloader->priv->urisrc, "user-agent", downloader->priv->user_agent, NULL); - /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) @@ -356,10 +365,8 @@ gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri) g_object_get (downloader->priv->urisrc, "cookies", &cookies, NULL); gst_uri_downloader_set_cookies (downloader, cookies); - GST_OBJECT_LOCK (downloader); download = downloader->priv->download; downloader->priv->download = NULL; - GST_OBJECT_UNLOCK (downloader); if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); @@ -368,8 +375,8 @@ gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri) quit: { - gst_uri_downloader_stop (downloader); g_mutex_unlock (downloader->priv->lock); + gst_uri_downloader_stop (downloader); return download; } } diff --git a/wearable/dashdemux/src/gsturidownloader.h b/dashdemux/src/gsturidownloader.h similarity index 97% rename from wearable/dashdemux/src/gsturidownloader.h rename to dashdemux/src/gsturidownloader.h index 20a870c..b2b5f06 100755 --- a/wearable/dashdemux/src/gsturidownloader.h +++ b/dashdemux/src/gsturidownloader.h @@ -61,6 +61,6 @@ void gst_uri_downloader_cancel (GstUriDownloader *downloader); /* add setting UA,cookies */ void gst_uri_downloader_set_user_agent (GstUriDownloader * downloader, gchar * user_agent); void gst_uri_downloader_set_cookies (GstUriDownloader * downloader, gchar ** cookies); - +void gst_uri_downloader_reset(GstUriDownloader *downloader); G_END_DECLS #endif /* __GSTURIDOWNLOADER_H__ */ diff --git a/debian/changelog b/debian/changelog new file mode 100755 index 0000000..3a3a820 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,272 @@ +gst-plugins-ext0.10 (0.2.22-0) unstable; urgency=low + + * [encodebin] Add error log for element link failure + * Tag: gst-plugins-ext0.10_0.2.22-0 + + -- Jeongmo Yang Sat, 02 Feb 2013 14:07:59 +0900 + +gst-plugins-ext0.10 (0.2.21-0) unstable; urgency=low + + * [evasimagesink] enhance code for setting a new evas image object during playing + * Tag: gst-plugins-ext0.10_0.2.21-0 + + -- Sangchul Lee Tue, 15 Jan 2013 21:24:33 +0900 + +gst-plugins-ext0.10 (0.2.19-2) unstable; urgency=low + + * [evasimagesink] add defense code to avoid seg.fault + * Tag: gst-plugins-ext0.10_0.2.19-2 + + -- Sangchul Lee Mon, 07 Jan 2013 22:55:11 +0900 + +gst-plugins-ext0.10 (0.2.16-0) unstable; urgency=low + + * Fix prevent issue + * Tag: gst-plugins-ext0.10_0.2.16-0 + + -- Jeongmo Yang Sat, 22 Dec 2012 14:53:41 +0900 + +gst-plugins-ext0.10 (0.2.15-0) unstable; urgency=low + + * [evasimagesink] fix prevent defects + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.15-0 + + -- Sangchul Lee Sat, 22 Dec 2012 14:03:42 +0900 + +gst-plugins-ext0.10 (0.2.14-0) unstable; urgency=low + + * Solving Prevent issues. + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.14-0 + + -- Abhishek Bajaj Fri, 21 Dec 2012 15:30:27 +0530 + +gst-plugins-ext0.10 (0.2.12-0) unstable; urgency=low + + * drm_trusted was changed. + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.12-0 + + -- Haejeong Kim Thu, 06 Dec 2012 14:34:27 +0900 + +gst-plugins-ext0.10 (0.2.9-0) unstable; urgency=low + + * [evasimagesink] modify present_data_addr, not using vir_addr + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.9-0 + + -- Sangchul Lee Tue, 16 Oct 2012 18:37:08 +0900 + +gst-plugins-ext0.10 (0.2.8-1) unstable; urgency=low + + * add default smack manifest + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.8-1 + + -- Sangchul Lee Fri, 21 Sep 2012 11:27:42 +0900 + +gst-plugins-ext0.10 (0.2.5-0) unstable; urgency=low + + * [encodebin] Add new property to select video converting element + * Git: gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.5-0 + + -- Jeongmo Yang Thu, 13 Sep 2012 15:26:46 +0900 + +gst-plugins-ext0.10 (0.2.4-0) unstable; urgency=low + + * [avsysmemsink] change sink pad's capabilities to bgra8888 + * Git: framework/multimedia/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.4-0 + + -- Sangchul Lee Thu, 06 Sep 2012 22:23:15 +0900 + +gst-plugins-ext0.10 (0.2.3-0) unstable; urgency=low + + * [evasimagesink] fix code to show frame if evas image object does not support gl zerocopy + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.3-0 + + -- Sangchul Lee Mon, 09 Jul 2012 16:26:40 +0900 + +gst-plugins-ext0.10 (0.2.2-0) unstable; urgency=low + + * [evasimagesink] add evas_object_event_callback_del() for EVAS_CALLBACK_DEL and EVAS_CALLBACK_RESIZE event + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.2-0 + + -- Sangchul Lee Mon, 18 Jun 2012 14:19:04 +0900 + +gst-plugins-ext0.10 (0.2.1-0) unstable; urgency=low + + * [evasimagesink] 1.handling GST_EVENT_CUSTOM_DOWNSTREAM_OOB event to skip memory copy in ecore pipe callback 2.remove redundancy ecore_pipe_del() 3.add evas image object resize callback + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.1-0 + + -- Sangchul Lee Tue, 05 Jun 2012 12:03:39 +0900 + +gst-plugins-ext0.10 (0.2.0-1) unstable; urgency=low + + * Apply new drm + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.0-1 + + -- Seungbae Shin Wed, 23 May 2012 11:59:22 +0900 + +gst-plugins-ext0.10 (0.2.0-0) unstable; urgency=low + + * [AudioRoute] remove sound path in avsysaudiosink + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.2.0-0 + + -- Seungbae Shin Mon, 23 Apr 2012 14:10:06 +0900 + +gst-plugins-ext0.10 (0.1.10-1) unstable; urgency=low + + * Enable trickplay audio in case of rate > 0 + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.10-1 + + -- Dowan Kim Tue, 24 Apr 2012 14:44:26 +0900 + +gst-plugins-ext0.10 (0.1.10-0) unstable; urgency=low + + * [evasimagesink] 1. enhance code for multi-instance usage 2. apply MMTA for time analysis + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.10-0 + + -- Sangchul Lee Thu, 19 Apr 2012 19:35:13 +0900 + +gst-plugins-ext0.10 (0.1.9-0) unstable; urgency=low + + * [avsysmemsink] update caps format + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.9-0 + + -- Younghwan Ahn Mon, 02 Apr 2012 19:03:39 +0900 + +gst-plugins-ext0.10 (0.1.8-0) unstable; urgency=low + + * Audiotp plugin added + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.8-0 + + -- Santhoshi.KS Fri, 2 Mar 2012 18:52:26 +0900 + +gst-plugins-ext0.10 (0.1.7-0) unstable; urgency=low + + * [avsysaudiosink] remove memcpy when pcm write + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.7-0 + + -- Seungbae Shin Mon, 13 Feb 2012 13:24:37 +0900 + +gst-plugins-ext0.10 (0.1.6-0) unstable; urgency=low + + * [evasimagesink] 1. add visible property 2. add GST_DEBUG log 3. code cleanup + * [avsystem] revise a parameter of g_signal_emit() in gstavsysmemsink.c + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.6-0 + + -- Sangchul Lee Wed, 08 Feb 2012 14:34:10 +0900 + +gst-plugins-ext0.10 (0.1.5-1) unstable; urgency=low + + * Remove unused build dependency + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.5-1 + + -- Sangchul Lee Tue, 20 Dec 2011 16:26:58 +0900 + +gst-plugins-ext0.10 (0.1.5-0) unstable; urgency=low + + * Remove avsysvideosrc plugin, gettext related and unused files + * Change license from Apache-2.0 to LGPL + * Git: slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.5-0 + + -- Sangchul Lee Tue, 20 Dec 2011 14:41:14 +0900 + +gst-plugins-ext0.10 (0.1.4-2) unstable; urgency=low + + * Add missing files : gettext.h gst-i18n-lib.h for drmsrc + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.4-2 + + -- Sangchul Lee Wed, 07 Dec 2011 13:55:23 +0900 + +gst-plugins-ext0.10 (0.1.4-1) unstable; urgency=low + + * Replace boilerplate - APACHE v2.0 + * Delete unused files : gstavsysvideosink, encodetest, gstpreviewbin + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.4-1 + + -- Sangchul Lee Fri, 02 Dec 2011 14:43:21 +0900 + +gst-plugins-ext0.10 (0.1.4-0) unstable; urgency=low + + * [avsysaudiosrc] remove audio-route property + * [pdpushsrc] fix Makefile.am + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.4-0 + + -- Seungbae Shin Mon, 31 Oct 2011 18:15:01 +0900 + +gst-plugins-ext0.10 (0.1.3-1) unstable; urgency=low + + * [pdpushsrc] initial version + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.3-1 + + -- Younghwan Ahn Mon, 24 Oct 2011 12:51:49 +0900 + +gst-plugins-ext0.10 (0.1.3-0) unstable; urgency=low + + * 1. [avsysaudiosink] restore sound path according to current policy + * 2. [avsysaudiosink] remove unused function/variables + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.3-0 + + -- Seungbae Shin Thu, 20 Oct 2011 18:03:39 +0900 + +gst-plugins-ext0.10 (0.1.2-1) unstable; urgency=low + + * Fix bugs resulted from prevent test (delete unnecessary compare codes and add preventing memory leak codes) + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.2-1 + + -- Sangchul Lee Tue, 11 Oct 2011 15:50:08 +0900 + +gst-plugins-ext0.10 (0.1.2-0) unstable; urgency=low + + * [avsysvideosrc] Update code for metadata of samsung extension format + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.2-0 + + -- Jeongmo Yang Tue, 11 Oct 2011 15:39:10 +0900 + +gst-plugins-ext0.10 (0.1.1-2) unstable; urgency=low + + * [evasimagesink] Fix BS on U1 - add defensive code for gl extension error + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.1-2 + + -- Jeongmo Yang Thu, 06 Oct 2011 20:14:01 +0900 + +gst-plugins-ext0.10 (0.1.1-1) unstable; urgency=low + + * [avsysvideosrc] Correct thumbnail size when JPEG capture + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.1-1 + + -- Jeongmo Yang Mon, 26 Sep 2011 15:27:25 +0900 + +gst-plugins-ext0.10 (0.1.1-0) unstable; urgency=low + + * Initial Release. + * Git: slp-source.sec.samsung.net:slp/pkgs/g/gst-plugins-ext0.10 + * Tag: gst-plugins-ext0.10_0.1.1-0 + + -- Sangchul Lee Wed, 24 Aug 2011 09:58:05 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100755 index 0000000..e4ad9dc --- /dev/null +++ b/debian/control @@ -0,0 +1,18 @@ +Source: gst-plugins-ext0.10 +Section: libs +Priority: extra +Maintainer: JongHyuk Choi , Seungbae Shin , Younghwan Ahn , Jeongmo Yang , Sangchul Lee , Santhoshi KS +Build-Depends: debhelper (>= 5), libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev, libavsystem-dev, libmm-ta-dev, drm-client-dev, drm-trusted-dev, libecore-dev, libevas-dev, libmm-ta-dev +Standards-Version: 3.7.2 + +Package: gstreamer0.10-plugins-ext +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libgstreamer0.10-0, libgstreamer-plugins-base0.10-0, libavsystem-0, libmm-ta, drm-client-0, drm-trusted-0, libcamsrcjpegenc +Description: GStreamer extra plugins (common) + +Package: gstreamer0.10-plugins-ext-dbg +Section: debug +Architecture: armel +Depends: ${shlibs:Depends}, ${misc:Depends}, gstreamer0.10-plugins-ext (= ${Source-Version}) +Description: GStreamer extra plugins (all) (unstripped) diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..bd79a0c --- /dev/null +++ b/debian/copyright @@ -0,0 +1,16 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + +This library 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.1 of the License, or (at your option) +any later version. + +This library 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 library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + diff --git a/debian/gstreamer0.10-plugins-ext.install.in b/debian/gstreamer0.10-plugins-ext.install.in new file mode 100644 index 0000000..f93192c --- /dev/null +++ b/debian/gstreamer0.10-plugins-ext.install.in @@ -0,0 +1,9 @@ +@PREFIX@/lib/gstreamer-0.10/libgstavsyssink.so +@PREFIX@/lib/gstreamer-0.10/libgstencodebin.so +@PREFIX@/lib/gstreamer-0.10/libgsttoggle.so +@PREFIX@/lib/gstreamer-0.10/libgstavsysaudiosrc.so +@PREFIX@/lib/gstreamer-0.10/libgstevasimagesink.so +@PREFIX@/lib/gstreamer-0.10/libgstdrmsrc.so +@PREFIX@/lib/gstreamer-0.10/libgstpdpushsrc.so +@PREFIX@/lib/gstreamer-0.10/libgstaudiotp.so +@PREFIX@/lib/gstreamer-0.10/libgstaudioeq.so diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..49e5ea4 --- /dev/null +++ b/debian/rules @@ -0,0 +1,128 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_GNU_OS) + +CFLAGS += -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +MODULES= +# --disable-ext-evasimagesink + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed + +config.status: configure + dh_testdir + # Add here commands to configure the package. + ./autogen.sh + CFLAGS="$(CFLAGS) -DGST_EXT_TIME_ANALYSIS -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " LDFLAGS="$(LDFLAGS)" ./configure $(MODULES) $(OPTION) --prefix=$(PREFIX) + +build: build-stamp + +build-stamp: config.status + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/ncurses.sgml > ncurses.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean +ifneq "$(wildcard /usr/share/misc/config.sub)" "" + cp -f /usr/share/misc/config.sub config.sub +endif +ifneq "$(wildcard /usr/share/misc/config.guess)" "" + cp -f /usr/share/misc/config.guess config.guess +endif + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs -s + + # Add here commands to install the package into debian/ncurses. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install +#ifneq (, $(findstring arm, $(DEB_HOST_ARCH))) +# execstack -c $(EXECSTACK_FILES) +#endif + + +# 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 -s +# dh_installdocs +# dh_installexamples + dh_install -s --list-missing --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman + dh_link -s + dh_strip -s --dbg-package=gstreamer0.10-plugins-ext-dbg + dh_compress -s + dh_fixperms -s +# dh_perl + dh_makeshlibs -s + dh_installdeb -s + dh_shlibdeps -s + dh_gencontrol -s + dh_md5sums -s + dh_builddeb -s + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/wearable/depcomp b/depcomp similarity index 100% rename from wearable/depcomp rename to depcomp diff --git a/wearable/encodebin/Makefile.am b/drmsrc/Makefile.am old mode 100644 new mode 100755 similarity index 100% rename from wearable/encodebin/Makefile.am rename to drmsrc/Makefile.am diff --git a/mobile/drmsrc/src/Makefile.am b/drmsrc/src/Makefile.am similarity index 77% rename from mobile/drmsrc/src/Makefile.am rename to drmsrc/src/Makefile.am index 37eb3bb..cd3f88b 100755 --- a/mobile/drmsrc/src/Makefile.am +++ b/drmsrc/src/Makefile.am @@ -14,14 +14,14 @@ plugin_LTLIBRARIES = libgstdrmsrc.la ############################################################################## # sources used to compile this plug-in -libgstdrmsrc_la_SOURCES = gstdrmsrc.c +libgstdrmsrc_la_SOURCES = gstdrmsrc.c drm_util.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed -libgstdrmsrc_la_CFLAGS = $(GST_CFLAGS) $(MMTA_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -libgstdrmsrc_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(MMTA_LIBS) +libgstdrmsrc_la_CFLAGS = $(GST_CFLAGS) $(DRM_CLIENT_CFLAGS) $(DRM_TRUSTED_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +libgstdrmsrc_la_LIBADD = $(GST_LIBS) $(DRM_CLIENT_LIBS) $(DRM_TRUSTED_LIBS) $(GST_BASE_LIBS) libgstdrmsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # headers we need but don't want installed -noinst_HEADERS = gstdrmsrc.h +noinst_HEADERS = gstdrmsrc.h drm_util.h diff --git a/drmsrc/src/drm_util.c b/drmsrc/src/drm_util.c new file mode 100755 index 0000000..dcff886 --- /dev/null +++ b/drmsrc/src/drm_util.c @@ -0,0 +1,178 @@ +/* + * drm-util.c + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Seungbae Shin + * + * This library 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.1 of the License, or (at your option) + * any later version. + * + * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include +#include +#include "drm_util.h" + +gboolean drm_util_open (DRM_DECRYPT_HANDLE *phandle, char* file_path, int file_type) +{ + drm_trusted_result_e drm_trusted_result; + drm_trusted_open_decrypt_info_s open_decrypt_info; + drm_trusted_open_decrypt_resp_data_s open_decrypt_resp; + drm_trusted_set_consumption_state_info_s decrypt_state_data = { DRM_CONSUMPTION_STARTED }; + + if (phandle == NULL || file_path == NULL) { + GST_ERROR ("Invalid parameter, phandle=%p, file_path=%p", phandle, file_path); + return FALSE; + } + + /* Fill parameter structure for opening decrypt session */ + memset (&open_decrypt_info, 0, sizeof (drm_trusted_open_decrypt_info_s)); + memset (&open_decrypt_resp, 0, sizeof (drm_trusted_open_decrypt_resp_data_s)); + + strncpy (open_decrypt_info.filePath, file_path, sizeof (open_decrypt_info.filePath)-1); + open_decrypt_info.file_type = file_type; + open_decrypt_info.permission = DRM_TRUSTED_PERMISSION_TYPE_PLAY; + + /* Open decrypt session */ + drm_trusted_result = drm_trusted_open_decrypt_session(&open_decrypt_info, &open_decrypt_resp, phandle); + if (drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS || *phandle == NULL) { + GST_ERROR ("Error in drm_trusted_open_decrypt_session(), error=%x, *phandle=%p,", drm_trusted_result, *phandle); + return FALSE; + } + GST_DEBUG ("drm_trusted_open_decrypt_session () success!!, ret=%x, *phandle=%p", drm_trusted_result, *phandle); + + /* Set decryption state to STARTED */ + drm_trusted_result = drm_trusted_set_decrypt_state(*phandle, &decrypt_state_data); + if (drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_set_decrypt_state(), error=%x", drm_trusted_result); + drm_trusted_close_decrypt_session (phandle); + *phandle = NULL; + return FALSE; + } + GST_DEBUG ("drm_trusted_set_decrypt_state () success!!, ret=%x, *phandle=%p", drm_trusted_result, *phandle); + + return TRUE; +} + +gboolean drm_util_read (DRM_DECRYPT_HANDLE handle, unsigned char* buf, unsigned int buf_length, unsigned int *read_size) +{ + drm_trusted_result_e drm_trusted_result; + drm_trusted_payload_info_s payload_info; + drm_trusted_read_decrypt_resp_data_s decrypt_resp; + + if (handle == NULL || buf == NULL) { + GST_ERROR ("Invalid parameter, handle=%p, buf=%p", handle, buf); + return FALSE; + } + + GST_DEBUG ("Enter [%s] buf=%p, length=%d, read_size=%p", __func__, buf, buf_length, read_size); + + /* fill input/output data */ + memset (&payload_info, 0, sizeof (drm_trusted_payload_info_s)); + memset (&decrypt_resp, 0, sizeof (drm_trusted_read_decrypt_resp_data_s)); + + payload_info.payload_data = buf; + payload_info.payload_data_len = buf_length; + payload_info.payload_data_output = buf; + + drm_trusted_result = drm_trusted_read_decrypt_session (handle, &payload_info, &decrypt_resp); + if(drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_read_decrypt_session() [%x]", drm_trusted_result); + return FALSE; + } + + GST_DEBUG ("Leave [%s], drm_trusted_read_decrypt_session() success, requested=%d, read_size=%d", __func__, buf_length, decrypt_resp.read_size); + if (read_size) + *read_size = decrypt_resp.read_size; + + return TRUE; +} + +gboolean drm_util_seek (DRM_DECRYPT_HANDLE handle, int offset, int mode) +{ + drm_trusted_result_e drm_trusted_result; + drm_trusted_seek_decrypt_info_s seek_decrypt_info; + memset (&seek_decrypt_info, 0, sizeof(drm_trusted_seek_decrypt_info_s)); + + GST_DEBUG ("Enter [%s] offset=%d, mode=%d", __func__, offset, mode); + + seek_decrypt_info.offset = offset; + seek_decrypt_info.seek_mode = mode; + + drm_trusted_result = drm_trusted_seek_decrypt_session(handle, &seek_decrypt_info); + if (drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_seek_decrypt_session(), error=%x", drm_trusted_result); + return FALSE; + } + + GST_DEBUG ("Leave [%s], drm_trusted_seek_decrypt_session () success!!", __func__); + return TRUE; +} + +gboolean drm_util_tell (DRM_DECRYPT_HANDLE handle, unsigned int *offset) +{ + drm_trusted_result_e drm_trusted_result; + drm_trusted_tell_decrypt_resp_data_s tell_decrypt_resp_data; + + if (handle == NULL || offset == NULL) { + GST_ERROR ("Invalid parameter, handle=%p, offset=%p", handle, offset); + return FALSE; + } + + GST_DEBUG ("Enter [%s] offset=%p", __func__, offset); + + memset (&tell_decrypt_resp_data, 0, sizeof(drm_trusted_tell_decrypt_resp_data_s)); + + drm_trusted_result = drm_trusted_tell_decrypt_session(handle, &tell_decrypt_resp_data); + if (drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_tell_decrypt_session(), error=%x", drm_trusted_result); + return FALSE; + } + + if (offset) + *offset = tell_decrypt_resp_data.offset; + + GST_DEBUG ("Leave [%s], drm_trusted_tell_decrypt_session () success!!", __func__); + + return TRUE; +} + +gboolean drm_util_close (DRM_DECRYPT_HANDLE *phandle) +{ + drm_trusted_result_e drm_trusted_result; + drm_trusted_set_consumption_state_info_s decrypt_state_data = { DRM_CONSUMPTION_STOPPED }; + + if (phandle == NULL) { + GST_ERROR ("Invalid parameter, phandle=%p", phandle); + return FALSE; + } + + /* Set decryption state to STOPPED */ + drm_trusted_result = drm_trusted_set_decrypt_state(*phandle, &decrypt_state_data); + if (drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_set_decrypt_state(), error=%x", drm_trusted_result); + } else { + GST_DEBUG ("drm_trusted_set_decrypt_state () success!!"); + } + + /* Close decrypt session */ + drm_trusted_result = drm_trusted_close_decrypt_session(phandle); + if(drm_trusted_result != DRM_TRUSTED_RETURN_SUCCESS) { + GST_ERROR ("Error in drm_trusted_close_decrypt_session() error=%x", drm_trusted_result); + return FALSE; + } + GST_DEBUG ("drm_trusted_close_decrypt_session() success!!!"); + + return TRUE; +} diff --git a/drmsrc/src/drm_util.h b/drmsrc/src/drm_util.h new file mode 100755 index 0000000..2e7487d --- /dev/null +++ b/drmsrc/src/drm_util.h @@ -0,0 +1,37 @@ +/* + * drm_util.h + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Seungbae Shin + * + * This library 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.1 of the License, or (at your option) + * any later version. + * + * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __DRM_UTIL_H__ +#define __DRM_UTIL_H__ + +#include + +#include + +gboolean drm_util_open (DRM_DECRYPT_HANDLE *phandle, char* file_path, int file_type); +gboolean drm_util_read (DRM_DECRYPT_HANDLE handle, unsigned char* buf, unsigned int buf_length, unsigned int *read_size); +gboolean drm_util_seek (DRM_DECRYPT_HANDLE handle, int offset, int mode); +gboolean drm_util_tell (DRM_DECRYPT_HANDLE handle, unsigned int *offset); +gboolean drm_util_close (DRM_DECRYPT_HANDLE *phandle); + +#endif /* __DRM_UTIL_H__ */ diff --git a/drmsrc/src/gstdrmsrc.c b/drmsrc/src/gstdrmsrc.c new file mode 100755 index 0000000..74bf4d2 --- /dev/null +++ b/drmsrc/src/gstdrmsrc.c @@ -0,0 +1,1010 @@ +/* + * drmsrc + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi + * + * This library 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.1 of the License, or (at your option) + * any later version. + * + * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gstdrmsrc.h" + +#include "drm_util.h" +#include +#include + +#ifdef CONTROL_PAGECACHE +#include +#define DEFAULT_DO_FADVISE_THRESHOLD (100 * 1024 * 1024) /* 100 MB */ +#endif + +#define LOG_TRACE(message) //g_print("DRM_SRC: %s: %d: %s - %s \n", __FILE__, __LINE__, __FUNCTION__, message); + +#define GST_TAG_PLAYREADY "playready_file_path" + +static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,GST_STATIC_CAPS_ANY); + +#ifdef CONTROL_PAGECACHE +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) +#define DRMSRC_FADVISE_DONT(x_fd, x_offset, x_length) \ + do \ + { \ + if (posix_fadvise64(x_fd, x_offset, x_length, POSIX_FADV_DONTNEED) != 0) \ + { \ + GST_ERROR("Set posix_fadvise with POSIX_FADV_DONTNEED failed"); \ + } \ + }while (0); +#else +#define DRMSRC_FADVISE_DONT(x_fd, x_offset, x_length) \ + do \ + { \ + if (posix_fadvise(x_fd, x_offset, x_length, POSIX_FADV_DONTNEED) != 0) \ + { \ + GST_ERROR("Set posix_fadvise with POSIX_FADV_DONTNEED failed"); \ + } \ + }while (0); +#endif +#endif + +GST_DEBUG_CATEGORY_STATIC (gst_drm_src_debug); +#define GST_CAT_DEFAULT gst_drm_src_debug + +enum +{ + ARG_0, + ARG_LOCATION, + ARG_FD, + IS_DRM +}; +static void gst_drm_src_finalize (GObject * object); +static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static gboolean gst_drm_src_start (GstBaseSrc * basesrc); +static gboolean gst_drm_src_stop (GstBaseSrc * basesrc); +static gboolean gst_drm_src_is_seekable (GstBaseSrc * src); +static gboolean gst_drm_src_get_size (GstBaseSrc * src, guint64 * size); +static GstFlowReturn gst_drm_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buffer); +static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data); +static gboolean gst_drm_src_query (GstBaseSrc * src, GstQuery * query); +static GstStateChangeReturn gst_drm_src_change_state (GstElement * element, + GstStateChange transition); +/** + * This function does the following: + * 1. Initializes GstDrmSrc ( defines gst_drm_get_type) + * + * @param drmsrc_type [out] GType + * + * @return void + */ +static void _do_init (GType drmsrc_type) +{ + // 1. Initializes GstDrmSrc ( defines gst_drm_get_type) + static const GInterfaceInfo urihandler_info = { + gst_drm_src_uri_handler_init, + NULL, + NULL + }; + + g_type_add_interface_static (drmsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info); + GST_DEBUG_CATEGORY_INIT (gst_drm_src_debug, "drmsrc", 0, "drmsrc element"); +} +GST_BOILERPLATE_FULL (GstDrmSrc, gst_drm_src, GstBaseSrc, GST_TYPE_BASE_SRC, _do_init); +/** + * This function does the following: + * 1. Sets the class details + * 2. Adds the source pad template + * + * @param g_class [out] gpointer + * + * @return void + */ +static void gst_drm_src_base_init (gpointer g_class) +{ + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); + + /*Sets the class details */ + gst_element_class_set_details_simple (gstelement_class, + "DRM Source", + "Source/File", + "Read from arbitrary point in a standard/DRM file", + "Kishore Arepalli and Sadanand Dodawadakar "); + + /*Adds the source pad template */ + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate)); +} +/** + * This function does the following: + * 1. Installs the properties + * 2. Assigns the function pointers GObject class attributes + * + * @param klass [out] GstDrmSrcClass Structure + * + * @return void + */ +static void gst_drm_src_class_init (GstDrmSrcClass * klass) +{ + GObjectClass *gobject_class; + GstBaseSrcClass *gstbasesrc_class; + gobject_class = G_OBJECT_CLASS (klass); + gstbasesrc_class = GST_BASE_SRC_CLASS (klass); + GstElementClass *gstelement_class; + gstelement_class = (GstElementClass *) klass; + /* Assigns the function pointers GObject class attributes */ + gobject_class->set_property = gst_drm_src_set_property; + gobject_class->get_property = gst_drm_src_get_property; + + /* Installs the properties*/ + g_object_class_install_property (gobject_class, ARG_FD, + g_param_spec_int ("fd", "File-descriptor", + "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property (gobject_class, ARG_LOCATION, + g_param_spec_string ("location", "File Location", + "Location of the file to read", NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, IS_DRM, + g_param_spec_boolean ("is-drm", "whether selected file type is drm or not", + "true, false", FALSE, + G_PARAM_READABLE)); + + /*Assigns the function pointers GObject class attributes */ + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_drm_src_finalize); + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_drm_src_start); + gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_drm_src_stop); + gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_drm_src_is_seekable); + gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_drm_src_get_size); + gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_drm_src_create); + gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_drm_src_query); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_drm_src_change_state); + gst_tag_register (GST_TAG_PLAYREADY, GST_TAG_FLAG_META, + G_TYPE_STRING, + "PlayReady File Path", + "a tag that is specific to PlayReady File", + NULL); +} +/** + * This function does the following: + * 1. Initilizes the parameters of GstDrmSrc + * + * @param src [out] GstDrmSrc structure + * @param g_class [in] GstDrmSrcClass structure + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static void gst_drm_src_init (GstDrmSrc * src, GstDrmSrcClass * g_class) +{ + /* Initilizes the parameters of GstDrmSrc */ + src->filename = NULL; + src->fd = 0; + src->uri = NULL; + src->is_regular = FALSE; + src->is_oma = FALSE; + src->seekable = FALSE; + src->hfile = NULL; + src->event_posted = FALSE; + src->is_playready = FALSE; + src->is_drm = FALSE; + src->isopen = FALSE; +#ifdef CONTROL_PAGECACHE + src->accum = 0; +#endif +} +/** + * This function does the following: + * 1. deallocates the filename and uri + * 2. calls the parent class->finalize + * + * @param object [in] GObject Structure + * + * @return void + */ +static void gst_drm_src_finalize (GObject * object) +{ + GstDrmSrc *src; + + src = GST_DRM_SRC (object); + /*. deallocates the filename and uri */ + g_free (src->filename); + g_free (src->uri); + /* calls the parent class->finalize */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} +/** + * This function does the following: + * 1. Checks the state + * 2. Checks the filename + * 3. Sets the filename + * + * @param src [in] GstDrmSrc Structure + * @param location [in] location of the file + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static gboolean gst_drm_src_set_location (GstDrmSrc * src, const gchar * location) +{ + GstState state; + + GST_OBJECT_LOCK (src); + + /* Checks the state */ + state = GST_STATE (src); + if (state != GST_STATE_READY && state != GST_STATE_NULL) { + GST_DEBUG_OBJECT (src, "setting location in wrong state"); + GST_OBJECT_UNLOCK (src); + return FALSE; + } + GST_OBJECT_UNLOCK (src); + + g_free (src->filename); + g_free (src->uri); + + /* Checks the filename */ + if (location == NULL) { + src->filename = NULL; + src->uri = NULL; + } else { + /*. Sets the filename */ + src->filename = g_strdup (location); +#if 0 + /*This below API is changing the filename in case of punctuation marks in filename*/ + src->uri = gst_filename_to_uri (location, NULL); +#else + src->uri = g_strdup_printf ("%s://%s", "file", src->filename); + + drm_bool_type_e is_drm = DRM_FALSE; + if (drm_is_drm_file(src->filename, &is_drm) == DRM_RETURN_SUCCESS) { + if (is_drm == DRM_TRUE) { + src->is_drm = TRUE; + } + } + GST_DEBUG_OBJECT (src, "is drm : %d", src->is_drm); +#endif + GST_INFO_OBJECT(src, "filename : %s", src->filename); + GST_INFO_OBJECT(src, "uri : %s", src->uri); + } + g_object_notify (G_OBJECT (src), "location"); + gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri); + + return TRUE; +} +/** + * This function does the following: + * 1. Sets the location of the file. + * + * @param object [in] GObject Structure + * @param prop_id [in] id of the property + * @param value [in] property value + * @param pspec [in] GParamSpec Structure + * + * @return void + */ +static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstDrmSrc *src; + + g_return_if_fail (GST_IS_DRM_SRC (object)); + + src = GST_DRM_SRC (object); + + switch (prop_id) { + // 1. Sets the location of the file. + case ARG_LOCATION: + gst_drm_src_set_location (src, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} +/** + * This function does the following: + * 1. Provides the location of the file. + * 2. Provides the file descriptor. + * + * @param object [in] GObject Structure + * @param prop_id [in] id of the property + * @param value [out] property value + * @param pspec [in] GParamSpec Structure + * + * @return void + */ +static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value,GParamSpec * pspec) +{ + GstDrmSrc *src; + + g_return_if_fail (GST_IS_DRM_SRC (object)); + src = GST_DRM_SRC (object); + switch (prop_id) { + case ARG_LOCATION: + g_value_set_string (value, src->filename); + break; + case ARG_FD: + g_value_set_int (value, src->fd); + break; + case IS_DRM: + g_value_set_boolean(value, src->is_drm); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstStateChangeReturn +gst_drm_src_change_state (GstElement * element, GstStateChange transition) +{ + + GstDrmSrc *src = GST_DRM_SRC (element); + GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE; + gboolean ret = FALSE; + drm_file_type_e file_type = DRM_TYPE_UNDEFINED; + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY:{ + GST_INFO_OBJECT(src,"change state from NULL to ready"); + drm_result_e drm_result; + drm_result = drm_get_file_type (src->filename, &file_type); + if (file_type == DRM_TYPE_OMA_V1) { + /* Opens the DRM file if it is DRM */ + if (!src->isopen) { + GST_DEBUG_OBJECT (src, "trying to open drm util"); + if (drm_util_open (&src->hfile, src->filename, file_type) == FALSE) { + GST_ERROR_OBJECT (src, "failed to open drm util"); + return FALSE; + } + src->isopen=TRUE; + } + } + break; + } + case GST_STATE_CHANGE_READY_TO_PAUSED:{ + GST_INFO_OBJECT(src,"change state from ready to paused"); + drm_result_e drm_result; + drm_result = drm_get_file_type (src->filename, &file_type); + if (file_type == DRM_TYPE_OMA_V1){ + ret = drm_process_request(DRM_REQUEST_TYPE_CLIENT_CLEAN_UP, NULL, NULL); + if (DRM_RETURN_SUCCESS == ret) { + GST_INFO("Clean Up successful!!"); + } else { + GST_ERROR("Clean Up Failed!!, ret = 0x%x", ret); + } + ret = drm_trusted_handle_request(DRM_TRUSTED_REQ_TYPE_CLIENT_CLEAN_UP, NULL, NULL); + if (DRM_RETURN_SUCCESS == ret) { + GST_INFO("Clean Up successful!!"); + } else { + GST_ERROR("Clean Up Failed!!, ret = 0x%x", ret); + } + } + break; + } + case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{ + GST_INFO_OBJECT(src,"change state from paused to playing"); + break; + } + default: + break; + } + result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{ + GST_INFO_OBJECT(src,"change state from playing to paused"); + break; + } + case GST_STATE_CHANGE_PAUSED_TO_READY:{ + GST_INFO_OBJECT(src,"change state from paused to ready"); + if (src->hfile) { + if (src->isopen) + if (drm_util_close(&src->hfile)) + src->isopen=FALSE; + src->hfile = NULL; +#ifdef CONTROL_PAGECACHE + DRMSRC_FADVISE_DONT(src->hfile, 0, 0); + src->accum = 0; +#endif + } + break; + } + case GST_STATE_CHANGE_READY_TO_NULL:{ + GST_INFO_OBJECT(src,"change state from ready to null"); + break; + } + default: + break; + + } + return result; +} + + + + +/** + * This function does the following: + * 1. Seeks to the specified position for DRM file. + * 2. Allocates a buffer to push the data for DRM file. + * 3. Reads from the file and sets the related params for DRM file. + * + * @param i_pDrmSrc [in] GstDrmSrc Structure + * @param i_uiOffset [in] offset of the file to seek + * @param length [in] size of the data in bytes + * @param o_pBbuffer [out] GstBuffer to hold the contents + * + * @return GstFlowReturn Returns GST_FLOW_OK on success and ERROR on failure + */ +static GstFlowReturn gst_drm_src_create_read_drm_file (GstDrmSrc* src, guint64 i_uiOffset, guint length, GstBuffer ** o_pBbuffer) +{ + GstBuffer *buf = NULL; + unsigned int readSize; + + /* Seeks to the specified position for DRM file. */ + if (G_UNLIKELY (src->read_position != i_uiOffset)) { + if (drm_util_seek (src->hfile, i_uiOffset, DRM_SEEK_SET) == FALSE) + goto FAILED; + + src->read_position = i_uiOffset; + } + + /* Allocates a buffer to push the data for DRM file. */ + buf = gst_buffer_new_and_alloc (length); + if(buf == NULL) { + LOG_TRACE("Exit on error"); + return GST_FLOW_ERROR; + } + + /*. Reads from the file and sets the related params for DRM file. */ + if (drm_util_read (src->hfile, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf), &readSize) == FALSE) + goto FAILED; + + if(readSize <= 0) { + LOG_TRACE("Exit on error"); + return GST_FLOW_ERROR; + } + + #if 0 // Drm service can give lesser size block than requested thing. + if (G_UNLIKELY ((guint) readSize < length && i_pDrmSrc->seekable)) { + GST_ELEMENT_ERROR (i_pDrmSrc, RESOURCE, READ, (NULL),("unexpected end of file.")); + gst_buffer_unref (buf); + return GST_FLOW_ERROR; + } + #endif + + if (G_UNLIKELY (readSize == 0 && length > 0)) { + GST_DEBUG ("non-regular file hits EOS"); + gst_buffer_unref (buf); + return GST_FLOW_UNEXPECTED; + } + +#ifdef CONTROL_PAGECACHE + src->accum += readSize; + if (src->accum >= DEFAULT_DO_FADVISE_THRESHOLD) { + DRMSRC_FADVISE_DONT(src->hfile, 0, 0); + src->accum = 0; + } +#endif + + length = readSize; + GST_BUFFER_SIZE (buf) = length; + GST_BUFFER_OFFSET (buf) = i_uiOffset; + GST_BUFFER_OFFSET_END (buf) = i_uiOffset + length; + *o_pBbuffer = buf; + src->read_position += length; + + return GST_FLOW_OK; + +FAILED: +{ + GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); + return GST_FLOW_ERROR; +} +} +/** + * This function does the following: + * 1. Seeks to the specified position. + * 2. Allocates a buffer to push the data + * 3. Reads from the file and sets the related params + * + * @param src [in] GstDrmSrc Structure + * @param offset [in] offset of the file to seek + * @param length [in] size of the data in bytes + * @param buffer [out] GstBuffer to hold the contents + * + * @return GstFlowReturn Returns GST_FLOW_OK on success and ERROR on failure + */ +static GstFlowReturn gst_drm_src_create_read (GstDrmSrc * src, guint64 offset, guint length, GstBuffer ** buffer) +{ + int ret; + GstBuffer *buf; + + /* Seeks to the specified position. */ + if (G_UNLIKELY (src->read_position != offset)) { + off_t res; + res = lseek (src->fd, offset, SEEK_SET); + if (G_UNLIKELY (res < 0 || res != offset)) { + GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); + return GST_FLOW_ERROR; + } + src->read_position = offset; + } + + /* Allocates a buffer to push the data */ + buf = gst_buffer_new_and_alloc (length); + if (NULL == buf) { + GST_ERROR_OBJECT (src, "failed to allocate memory.."); + GST_ELEMENT_ERROR (src, RESOURCE, NO_SPACE_LEFT, (NULL), ("failed to allocate memory")); + return GST_FLOW_ERROR; + } + + GST_LOG_OBJECT (src, "Reading %d bytes", length); + + /* Reads from the file and sets the related params */ + ret = read (src->fd, GST_BUFFER_DATA (buf), length); + if (G_UNLIKELY (ret < 0)) { + GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); + gst_buffer_unref (buf); + return GST_FLOW_ERROR; + } + + if (G_UNLIKELY ((guint) ret < length && src->seekable)) { + GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),("unexpected end of file.")); + gst_buffer_unref (buf); + return GST_FLOW_ERROR; + } + + if (G_UNLIKELY (ret == 0 && length > 0)) { + GST_DEBUG ("non-regular file hits EOS"); + gst_buffer_unref (buf); + return GST_FLOW_UNEXPECTED; + } + +#ifdef CONTROL_PAGECACHE + src->accum += ret; + if (src->accum >= DEFAULT_DO_FADVISE_THRESHOLD) { + DRMSRC_FADVISE_DONT(src->fd, 0, 0); + src->accum = 0; + } + //DRMSRC_FADVISE_DONT(src->fd, offset, ret); +#endif + + length = ret; + GST_BUFFER_SIZE (buf) = length; + GST_BUFFER_OFFSET (buf) = offset; + GST_BUFFER_OFFSET_END (buf) = offset + length; + *buffer = buf; + src->read_position += length; + + return GST_FLOW_OK; +} +/** + * This function does the following: + * 1. Calls DRM file read chain method for drm files. + * 2. Calls normal file read chain method for standard files. + * + * @param basesrc [in] BaseSrc Structure + * @param size [out] Size of the file + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static GstFlowReturn gst_drm_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) +{ + GstDrmSrc *src = GST_DRM_SRC (basesrc); + + if (src->is_playready && src->event_posted == FALSE) { + GstTagList *tags = NULL; + GST_DEBUG_OBJECT (src, "posting playready tags"); + tags = gst_tag_list_new_full (GST_TAG_PLAYREADY, src->filename, NULL); + if (tags) { + GstPad* src_pad = gst_element_get_static_pad (src, "src"); + if (src_pad) { + if(!gst_pad_push_event (src_pad, gst_event_new_tag (tags))) { + GST_ERROR_OBJECT (src, "failed to push tags.."); + gst_object_unref (src_pad); + return GST_FLOW_ERROR; + } + GST_DEBUG_OBJECT (src, "posting tags returns [%d]", src->event_posted); + src->event_posted = TRUE; + gst_object_unref (src_pad); + } + } + } + + if(src->is_oma == TRUE) /* Calls DRM file read chain method for drm files. */ + return gst_drm_src_create_read_drm_file (src, offset, length, buffer); + else /* Calls normal file read chain method for standard files. */ + return gst_drm_src_create_read (src, offset, length, buffer); +} + +static gboolean +gst_drm_src_query (GstBaseSrc * basesrc, GstQuery * query) +{ + gboolean ret = FALSE; + GstDrmSrc *src = GST_DRM_SRC (basesrc); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_URI: + gst_query_set_uri (query, src->uri); + ret = TRUE; + break; + case GST_QUERY_CUSTOM: + { + GstStructure *s; + guint64 size = 0; + GValue v = { 0, { { 0 } } }; + g_value_init(&v, G_TYPE_UINT64); + + s = gst_query_get_structure (query); + if (gst_structure_has_name (s, "dynamic-size")) { + if (gst_drm_src_get_size (basesrc, &size)){ + /* succedded. take size */ + g_value_set_uint64 (&v, size); + gst_structure_set_value(s, "size", &v); + ret = TRUE; + } + } + break; + } + default: + ret = FALSE; + break; + } + + if (!ret) + ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); + + return ret; +} + +/** + * + * @param basesrc [in] BaseSrc Structure + * + * @return gboolean Returns TRUE if the file is seekable and FALSE if the file is not seekable + */ +static gboolean gst_drm_src_is_seekable (GstBaseSrc * basesrc) +{ + GstDrmSrc *src = GST_DRM_SRC (basesrc); + return src->seekable; +} +/** + * This function does the following: + * 1. Gets the filesize for drm file by using seek oprations + * 2. Gets the file size for standard file by using statistics + * + * @param basesrc [in] BaseSrc Structure + * @param size [in] Size of the file + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static gboolean gst_drm_src_get_size (GstBaseSrc * basesrc, guint64 * size) +{ + struct stat stat_results; + GstDrmSrc *src = GST_DRM_SRC (basesrc); + unsigned int offset; + + /* Gets the filesize for drm file by using seek oprations */ + if(src->is_oma==TRUE) { + drm_util_seek (src->hfile, 0, DRM_SEEK_END); + if (drm_util_tell(src->hfile, &offset) == TRUE) { + /* FIXME : drm doesn't support 64 */ + *size = offset; + } + drm_util_seek (src->hfile, 0, DRM_SEEK_SET); + src->read_position = 0; + return TRUE; + } + + if (!src->seekable) { + GST_DEBUG_OBJECT (src, "non-seekable"); + return FALSE; + } + + /* Gets the file size for standard file by using statistics */ + if (fstat (src->fd, &stat_results) < 0) + return FALSE; + + *size = stat_results.st_size; + GST_DEBUG_OBJECT (src, "size : %"G_GUINT64_FORMAT, *size); + return TRUE; +} +/** + * This function does the following: + * 1. Checks the filename + * 2. Opens the file and check statistics of the file + * 3. Checks whether DRM file or not. + * 4. Checks the DRM file type (supports only for OMA) if it is DRM + * 5. Opens the DRM file if it is DRM + * 6. Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flag. + * 7. Checks the seeking for standard files + * + * @param basesrc [in] BaseSrc Structure + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static gboolean gst_drm_src_start (GstBaseSrc * basesrc) +{ + GstDrmSrc *src = GST_DRM_SRC (basesrc); + struct stat stat_results; + drm_result_e drm_result; + drm_file_type_e file_type; + off_t ret; + + /* Checks the filename */ + if (src->filename == NULL || src->filename[0] == '\0') { + GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,("No file name specified for reading."), (NULL)); + return FALSE; + } + + /* Opens the file and check statistics of the file */ + GST_INFO_OBJECT (src, "opening file %s", src->filename); + src->fd = open (src->filename, O_RDONLY | O_BINARY); + if (src->fd < 0) { + if(errno == ENOENT) { + GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),("No such file \"%s\"", src->filename)); + return FALSE; + } + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not open file \"%s\" for reading.", src->filename), GST_ERROR_SYSTEM); + return FALSE; + } + + if (fstat (src->fd, &stat_results) < 0) { + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"%s\".", src->filename), (NULL)); + close (src->fd); + return FALSE; + } + + if (S_ISDIR (stat_results.st_mode)) { + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("\"%s\" is a directory.", src->filename), (NULL)); + close (src->fd); + return FALSE; + } + + if (S_ISSOCK (stat_results.st_mode)) { + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is a socket.", src->filename), (NULL)); + close (src->fd); + return FALSE; + } + + src->read_position = 0; + + + /* Checks whether DRM file or not.*/ + drm_result = drm_get_file_type (src->filename, &file_type); + if (drm_result != DRM_RETURN_SUCCESS) { + GST_ERROR_OBJECT (src,"Error in drm_get_file_type(), error=%d", drm_result); + return FALSE; + } + GST_DEBUG_OBJECT (src, "file_path = [%s], file_type = [%d]", src->filename, file_type); + +#if 0 + if (DRM_TYPE_UNDEFINED != file_type) { + drm_bool_type_e is_drm = DRM_FALSE; + if (drm_is_drm_file(src->filename, &is_drm) == DRM_RETURN_SUCCESS) { + if (is_drm == DRM_TRUE) { + src->is_drm = TRUE; + } + } + GST_DEBUG_OBJECT (src, "is drm = [%d]", src->is_drm); + } +#endif + + /* We handles as DRM file if it is drm with OMA type */ + if (file_type == DRM_TYPE_OMA_V1) { /* FIMXE: what about DRM_TYPE_OMA_V2 */ + // Gets the DRM_FILE_HANDLE and sets the drm, seekable and regular flags. + drm_util_seek (src->hfile, 0, DRM_SEEK_END); + drm_util_seek (src->hfile, 0, DRM_SEEK_SET); + + src->seekable = TRUE; + src->is_regular = TRUE; + src->is_oma = TRUE; + + LOG_TRACE("Exit"); + return TRUE; + } + + if (file_type == DRM_TYPE_PLAYREADY || file_type == DRM_TYPE_PLAYREADY_ENVELOPE) { /* FIXME: what is envelope?? */ + src->is_playready = TRUE; + src->event_posted = FALSE; + } + + /* Checks the seeking for standard files */ + if (S_ISREG (stat_results.st_mode)) + src->is_regular = TRUE; + + ret = lseek (src->fd, 0, SEEK_END); + if (ret < 0) { + GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek failed: %s", g_strerror (errno)); + src->seekable = FALSE; + } else { + src->seekable = TRUE; + } + + lseek (src->fd, 0, SEEK_SET); + src->seekable = src->seekable && src->is_regular; + + + return TRUE; +} +/** + * This function does the following: + * 1. Closes the file desciptor and resets the flags + * + * @param basesrc [in] BaseSrc Structure + * + * @return gboolean Returns TRUE on success and FALSE on ERROR + */ +static gboolean gst_drm_src_stop (GstBaseSrc * basesrc) +{ + GstDrmSrc *src = GST_DRM_SRC (basesrc); + // 1. Closes the file desciptor and resets the flags + if(src->fd > 0) { +#ifdef CONTROL_PAGECACHE + DRMSRC_FADVISE_DONT(src->fd, 0, 0); + src->accum = 0; +#endif + close (src->fd); + } + + src->fd = 0; + src->is_regular = FALSE; + src->event_posted = FALSE; + src->is_playready = FALSE; + + return TRUE; +} +/** + * + * @param void + * + * @return GstURIType Returns GST_URI_SRC + */ + +static GstURIType gst_drm_src_uri_get_type (void) +{ + return GST_URI_SRC; +} + +/** + * This function does the following: + * 1. Defines the list of protocols + * + * @param void + * + * @return gchar ** Returns the protocol list + */ + +static gchar ** gst_drm_src_uri_get_protocols (void) +{ + static gchar *protocols[] = { "file", NULL }; + return protocols; +} +/** + * + * @param handler [in] GstURIHandler structure + * + * @return gchar* Returns the uri + */ +static const gchar * gst_drm_src_uri_get_uri (GstURIHandler *handler) +{ + GstDrmSrc *src = GST_DRM_SRC (handler); + return src->uri; +} +/** + * This function does the following: + * 1. Checks the protocol + * 2. Checks the whether it is absolute or not + * 3 sets the location + * + * @param handler [in] GstURIHandler structure + * @param uri [in] uri string + * + * @return gboolean Returns TRUE on success and FALSE on Error + */ +static gboolean gst_drm_src_uri_set_uri (GstURIHandler *handler, const gchar * uri) +{ + gchar *location, *hostname = NULL; + gboolean ret = FALSE; + GstDrmSrc *src = GST_DRM_SRC (handler); + GError *error = NULL; + + if (strcmp (uri, "file://") == 0) { + /* Special case for "file://" as this is used by some applications + * to test with gst_element_make_from_uri if there's an element + * that supports the URI protocol. */ + gst_drm_src_set_location (src, NULL); + return TRUE; + } + + location = g_filename_from_uri (uri, &hostname, &error); + + if (!location || error) { + if (error) { + GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc: %s", uri, + error->message); + g_error_free (error); + } else { + GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc", uri); + } + goto beach; + } + + if ((hostname) && (strcmp (hostname, "localhost"))) { + /* Only 'localhost' is permitted */ + GST_WARNING_OBJECT (src, "Invalid hostname '%s' for filesrc", hostname); + goto beach; + } + + ret = gst_drm_src_set_location (src, location); + +beach: + if (location) + g_free (location); + if (hostname) + g_free (hostname); + + return ret; +} + + +/** + * This function does the following: + * 1. Assignes the function pointer for URI related stuff + * + * @param g_iface [in] an interface to URI handler + * @param iface_data [in] a gpointer + * + * @return void + */ +static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + /* Assigning the function pointer for URI related stuff */ + iface->get_type = gst_drm_src_uri_get_type; + iface->get_protocols = gst_drm_src_uri_get_protocols; + iface->get_uri = gst_drm_src_uri_get_uri; + iface->set_uri = gst_drm_src_uri_set_uri; +} +/** + * This function does the following: + * 1. Registers an element as drmsrc + * + * @param i_pPlugin [in] a plug-in structure + * + * @return gboolean TRUE on SUCCESS and FALSE on Error + */ +static gboolean plugin_init(GstPlugin* i_pPlugin) +{ + return gst_element_register(i_pPlugin, "drmsrc", GST_RANK_NONE, GST_TYPE_DRM_SRC); +} +/** + * This function does the following: + * 1. plugin defination + * + */ +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "drmsrc", + "Plugin to read data from standad/DRM File", + plugin_init, + VERSION, + "LGPL", + "Samsung Electronics Co", + "http://www.samsung.com/") + diff --git a/mobile/drmsrc/src/gstdrmsrc.h b/drmsrc/src/gstdrmsrc.h similarity index 71% rename from mobile/drmsrc/src/gstdrmsrc.h rename to drmsrc/src/gstdrmsrc.h index e47802e..3390b5c 100755 --- a/mobile/drmsrc/src/gstdrmsrc.h +++ b/drmsrc/src/gstdrmsrc.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -48,30 +49,6 @@ #define O_BINARY (0) #endif -#define ENABLE_PROFILING_INFO -#ifdef ENABLE_PROFILING_INFO -#define PROFILE_FUNC_BEGIN\ - char *newname; \ - newname=__FUNCTION__; \ - gst_ta_accum_item_begin(newname,FALSE,__FILE__,__LINE__); - -#define PROFILE_FUNC_END \ - gst_ta_accum_item_end(newname,FALSE,__FILE__,__LINE__); - -#define PROFILE_BLOCK_BEGIN(name) gst_ta_accum_item_begin(name,FALSE,__FILE__,__LINE__); -#define PROFILE_BLOCK_END(name) gst_ta_accum_item_end(name,FALSE,__FILE__,__LINE__); -#define PROFILE_INIT gst_ta_init(); -#define PROFILE_SHOW_RESULT gst_ta_accum_show_result(0);//MMTA_SHOW_FILE); -#define PROFILE_CLEAR_DATA gst_ta_release(); -#else -#define PROFILE_FUNC_BEGIN -#define PROFILE_FUNC_END -#define PROFILE_BLOCK_BEGIN(name) -#define PROFILE_BLOCK_END(name) -#define PROFILE_INIT -#define PROFILE_SHOW_RESULT -#define PROFILE_CLEAR_DATA -#endif G_BEGIN_DECLS #define GST_TYPE_DRM_SRC (gst_drm_src_get_type()) @@ -90,8 +67,17 @@ struct _GstDrmSrc gchar *uri; gint fd; guint64 read_position; - gboolean seekable; + gboolean seekable; gboolean is_regular; + gboolean is_drm; // flag indicating drm file + DRM_DECRYPT_HANDLE hfile; + gboolean is_playready; + gboolean is_oma; + gboolean event_posted; + gboolean isopen; +#ifdef CONTROL_PAGECACHE + guint64 accum; +#endif }; struct _GstDrmSrcClass diff --git a/wearable/dashdemux/Makefile.am b/encodebin/Makefile.am old mode 100755 new mode 100644 similarity index 100% rename from wearable/dashdemux/Makefile.am rename to encodebin/Makefile.am diff --git a/wearable/encodebin/src/Makefile.am b/encodebin/src/Makefile.am similarity index 100% rename from wearable/encodebin/src/Makefile.am rename to encodebin/src/Makefile.am diff --git a/wearable/encodebin/src/gstencodebin.c b/encodebin/src/gstencodebin.c similarity index 99% rename from wearable/encodebin/src/gstencodebin.c rename to encodebin/src/gstencodebin.c index 610a9de..59954d9 100644 --- a/wearable/encodebin/src/gstencodebin.c +++ b/encodebin/src/gstencodebin.c @@ -647,7 +647,7 @@ gst_encode_bin_get_property (GObject * object, //elements pointer case PROP_VIDEO_ENC: if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) { - encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode"); + encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, NULL); if(encodebin->video_encode != NULL) gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); } @@ -1639,7 +1639,7 @@ gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement { switch(type) { case ENCODEBIN_ELEMENT_VENC: - encodebin->video_encode = gst_element_factory_make (name, "video_encode"); + encodebin->video_encode = gst_element_factory_make (name, NULL); if(encodebin->video_encode != NULL) { gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); g_free(encodebin->venc_name); @@ -2713,7 +2713,7 @@ gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data) #endif if(encodebin->video_encode == NULL) { - encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode"); + encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, NULL); gst_bin_add (GST_BIN (element), encodebin->video_encode); } diff --git a/wearable/encodebin/src/gstencodebin.h b/encodebin/src/gstencodebin.h similarity index 100% rename from wearable/encodebin/src/gstencodebin.h rename to encodebin/src/gstencodebin.h diff --git a/wearable/audiotp/Makefile.am b/evasimagesink/Makefile.am old mode 100755 new mode 100644 similarity index 100% rename from wearable/audiotp/Makefile.am rename to evasimagesink/Makefile.am diff --git a/wearable/evasimagesink/src/Makefile.am b/evasimagesink/src/Makefile.am similarity index 93% rename from wearable/evasimagesink/src/Makefile.am rename to evasimagesink/src/Makefile.am index 8521916..8a88d14 100644 --- a/wearable/evasimagesink/src/Makefile.am +++ b/evasimagesink/src/Makefile.am @@ -17,8 +17,8 @@ plugin_LTLIBRARIES = libgstevasimagesink.la libgstevasimagesink_la_SOURCES = gstevasimagesink.c gstevasimagesink.h # compiler and linker flags used to compile this plugin, set in configure.ac -libgstevasimagesink_la_CFLAGS = $(GST_CFLAGS) $(GST_VIDEO_CFLAGS) $(EFL_CFLAGS) $(MMTA_CFLAGS) -libgstevasimagesink_la_LIBADD = $(GST_LIBS) $(GST_VIDEO_LIBS) $(EFL_LIBS) $(MMTA_LIBS) +libgstevasimagesink_la_CFLAGS = $(GST_CFLAGS) $(GST_VIDEO_CFLAGS) $(EFL_CFLAGS) $(NATIVE_BUFFER_CFLAGS) $(TBM_CFLAGS) +libgstevasimagesink_la_LIBADD = $(GST_LIBS) $(GST_VIDEO_LIBS) $(EFL_LIBS) $(NATIVE_BUFFER_LIBS) $(TBM_LIBS) libgstevasimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstevasimagesink_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/evasimagesink/src/gstevasimagesink.c b/evasimagesink/src/gstevasimagesink.c new file mode 100755 index 0000000..d9706a4 --- /dev/null +++ b/evasimagesink/src/gstevasimagesink.c @@ -0,0 +1,1984 @@ +/* + * evasimagesink + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Sangchul Lee + * + * This library 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.1 of the License, or (at your option) + * any later version. + * + * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * SECTION:element-evasimagesink + * Gstreamer Evas Video Sink - draw video on the given Evas Image Object + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "gstevasimagesink.h" + +#define CAP_WIDTH "width" +#define CAP_HEIGHT "height" + +GST_DEBUG_CATEGORY_STATIC (gst_evas_image_sink_debug); +#define GST_CAT_DEFAULT gst_evas_image_sink_debug + +/* Enumerations */ +enum +{ + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_EVAS_OBJECT, + PROP_EVAS_OBJECT_SHOW, +#ifdef USE_NATIVE_BUFFER + PROP_ROTATE_ANGLE, + PROP_DISPLAY_GEOMETRY_METHOD, + PROP_ENABLE_FLUSH_BUFFER, + PROP_FLIP +#endif +}; + +enum +{ + UPDATE_FALSE, + UPDATE_TRUE +}; + +#define COLOR_DEPTH 4 +#define GL_X11_ENGINE "gl_x11" +#define DO_RENDER_FROM_FIMC 1 +#define SIZE_FOR_UPDATE_VISIBILITY sizeof(gchar) +#ifdef USE_NATIVE_BUFFER +#define MAX_ECOREPIPE_BUFFER_CNT 4 +#define DEBUGLOG_DEFAULT_COUNT 8 +#define SIZE_FOR_NATIVE_INDEX sizeof(gint) + +/* max channel count *********************************************************/ +#define SCMN_IMGB_MAX_PLANE (4) + +/* image buffer definition *************************************************** + + +------------------------------------------+ --- + | | ^ + | a[], p[] | | + | +---------------------------+ --- | | + | | | ^ | | + | |<---------- w[] ---------->| | | | + | | | | | | + | | | | + | | | h[] | e[] + | | | | + | | | | | | + | | | | | | + | | | v | | + | +---------------------------+ --- | | + | | v + +------------------------------------------+ --- + + |<----------------- s[] ------------------>| +*/ + +typedef struct +{ + /* width of each image plane */ + int w[SCMN_IMGB_MAX_PLANE]; + /* height of each image plane */ + int h[SCMN_IMGB_MAX_PLANE]; + /* stride of each image plane */ + int s[SCMN_IMGB_MAX_PLANE]; + /* elevation of each image plane */ + int e[SCMN_IMGB_MAX_PLANE]; + /* user space address of each image plane */ + void *a[SCMN_IMGB_MAX_PLANE]; + /* physical address of each image plane, if needs */ + void *p[SCMN_IMGB_MAX_PLANE]; + /* color space type of image */ + int cs; + /* left postion, if needs */ + int x; + /* top position, if needs */ + int y; + /* to align memory */ + int __dummy2; + /* arbitrary data */ + int data[16]; + /* dma buf fd */ + int fd[SCMN_IMGB_MAX_PLANE]; + /* buffer share method */ + int buf_share_method; + /* Y plane size in case of ST12 */ + int y_size; + /* UV plane size in case of ST12 */ + int uv_size; + /* Tizen buffer object */ + void *bo[SCMN_IMGB_MAX_PLANE]; + /* JPEG data */ + void *jpeg_data; + /* JPEG size */ + int jpeg_size; + /* TZ memory buffer */ + int tz_enable; +} SCMN_IMGB; +#endif + +#define EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \ +do \ +{ \ + if (x_evas_image_object) { \ + GST_LOG("object callback add"); \ + evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event, x_usr_data); \ + evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, x_usr_data); \ + } \ +}while(0) + +#define EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \ +do \ +{ \ + if (x_evas_image_object) { \ + GST_LOG("object callback del"); \ + evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event); \ + evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event); \ + } \ +}while(0) + +#ifdef USE_NATIVE_BUFFER +#define EVASIMAGESINK_SET_EVAS_EVENT_CALLBACK( x_evas, x_usr_data ) \ +do \ +{ \ + if (x_evas) { \ + GST_DEBUG("callback add... evas_callback_render_pre.. evas : %p esink : %p", x_evas, x_usr_data); \ + evas_event_callback_add (x_evas, EVAS_CALLBACK_RENDER_PRE, evas_callback_render_pre, x_usr_data); \ + } \ +}while(0) + +#define EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK( x_evas ) \ +do \ +{ \ + if (x_evas) { \ + GST_DEBUG("callback del... evas_callback_render_pre"); \ + evas_event_callback_del (x_evas, EVAS_CALLBACK_RENDER_PRE, evas_callback_render_pre); \ + } \ +}while(0) +#endif + +GMutex *instance_lock; +guint instance_lock_count; + +static inline gboolean +is_evas_image_object (Evas_Object *obj) +{ + const char *type; + if (!obj) { + return FALSE; + } + type = evas_object_type_get (obj); + if (!type) { + return FALSE; + } + if (strcmp (type, "image") == 0) { + return TRUE; + } + return FALSE; +} + +#ifdef USE_NATIVE_BUFFER +gint +gst_evas_image_sink_ref_count (GstBuffer * buf) +{ + return GST_OBJECT_REFCOUNT_VALUE(GST_BUFFER_CAST(buf)); +} +#endif + +/* the capabilities of the inputs. + * + * BGRx format + */ +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, +#ifdef USE_FIMCC + GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)); +#endif +#ifdef USE_NATIVE_BUFFER + GST_STATIC_CAPS(GST_VIDEO_CAPS_YUV ("I420") ";" + GST_VIDEO_CAPS_YUV ("NV12") ";" + GST_VIDEO_CAPS_YUV ("SN12")) +); +#endif +GST_BOILERPLATE (GstEvasImageSink, gst_evas_image_sink, GstVideoSink, GST_TYPE_VIDEO_SINK); + +static void gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static gboolean gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps); +static GstFlowReturn gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf); +static gboolean gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event); +static GstStateChangeReturn gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition); +static void evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info); +static void evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info); +#ifdef USE_NATIVE_BUFFER +static void evas_callback_render_pre (void *data, Evas *e, void *event_info); +static GstFlowReturn gst_esink_epipe_reset(GstEvasImageSink *esink); +static gboolean gst_esink_make_flush_buffer(GstEvasImageSink *esink); +static void _release_flush_buffer(GstEvasImageSink *esink); +static void gst_evas_image_sink_update_geometry (GstEvasImageSink *esink, GstVideoRectangle *result); +static void gst_evas_image_sink_apply_geometry (GstEvasImageSink *esink); +#endif +static void +gst_evas_image_sink_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + gst_element_class_set_details_simple (element_class, + "EvasImageSink", + "VideoSink", + "Video sink element for evas image object", + "Samsung Electronics "); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); +} + +static void +gst_evas_image_sink_class_init (GstEvasImageSinkClass *klass) +{ + GObjectClass *gobject_class; + GstBaseSinkClass *gstbasesink_class; + GstVideoSinkClass *gstvideosink_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstbasesink_class = GST_BASE_SINK_CLASS (klass); + gstvideosink_class = GST_VIDEO_SINK_CLASS (klass); + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_evas_image_sink_set_property; + gobject_class->get_property = gst_evas_image_sink_get_property; + + g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT, + g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT_SHOW, + g_param_spec_boolean ("visible", "Show Evas Object", "When disabled, evas object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#ifdef USE_NATIVE_BUFFER + g_object_class_install_property(gobject_class, PROP_ROTATE_ANGLE, + g_param_spec_int("rotate", "Rotate angle", "Rotate angle of display output", DEGREE_0, DEGREE_NUM, DEGREE_0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(gobject_class, PROP_DISPLAY_GEOMETRY_METHOD, + g_param_spec_int("display-geometry-method", "Display geometry method", + "Geometrical method for display", DISP_GEO_METHOD_LETTER_BOX, DISP_GEO_METHOD_NUM, DISP_GEO_METHOD_LETTER_BOX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ENABLE_FLUSH_BUFFER, + g_param_spec_boolean("enable-flush-buffer", "Enable flush buffer mechanism", + "Enable flush buffer mechanism when state change(PAUSED_TO_READY)", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(gobject_class, PROP_FLIP, + g_param_spec_int("flip", "Display flip", + "Flip for display", FLIP_NONE, FLIP_NUM, FLIP_NONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif + gstvideosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evas_image_sink_show_frame); + gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evas_image_sink_set_caps); + gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evas_image_sink_event); + gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_evas_image_sink_change_state); +} + +static void +gst_evas_image_sink_fini (gpointer data, GObject *obj) +{ + GST_DEBUG ("[ENTER]"); + + GstEvasImageSink *esink = GST_EVASIMAGESINK (obj); + if (!esink) { + return; + } +#ifdef USE_FIMCC + if (esink->oldbuf) { + gst_buffer_unref (esink->oldbuf); + } +#endif + + if (esink->eo) { +#ifdef USE_NATIVE_BUFFER + EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK (evas_object_evas_get(esink->eo)); + GST_DEBUG("unset EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK esink : %p, esink->eo : %x", esink, esink->eo); +#endif + EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); + GST_DEBUG("unset EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK esink : %p, esink->eo : %x", esink, esink->eo); + evas_object_image_data_set(esink->eo, NULL); + } +#ifdef USE_NATIVE_BUFFER + if (esink->display_buffer_lock) { + g_mutex_free (esink->display_buffer_lock); + esink->display_buffer_lock = NULL; + } + if (esink->flow_lock) { + g_mutex_free (esink->flow_lock); + esink->flow_lock = NULL; + } + if(esink->n_provider) + native_buffer_provider_destroy(esink->n_provider); + esink->eo = NULL; + esink->epipe = NULL; +#endif + g_mutex_lock (instance_lock); + instance_lock_count--; + g_mutex_unlock (instance_lock); + if (instance_lock_count == 0) { + g_mutex_free (instance_lock); + instance_lock = NULL; + } + + GST_DEBUG ("[LEAVE]"); +} + +#ifdef USE_NATIVE_BUFFER +static void +gst_evas_image_sink_reset (GstEvasImageSink *esink) +{ + int i = 0; + tbm_bo_handle bo_handle; + + GST_DEBUG("gst_evas_image_sink_reset start"); + + g_mutex_lock(esink->display_buffer_lock); + + for(i=0; idisplaying_buffer[i].n_buffer) + { + native_buffer_destroy(esink->displaying_buffer[i].n_buffer); + esink->displaying_buffer[i].n_buffer = NULL; + } + if(esink->displaying_buffer[i].buffer) + { + if(esink->displaying_buffer[i].ref_count) + { + if(esink->displaying_buffer[i].bo) { + bo_handle = tbm_bo_map(esink->displaying_buffer[i].bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE); + if (!bo_handle.ptr) { + GST_WARNING("failed to map bo [%p]", esink->displaying_buffer[i].bo); + } + else + tbm_bo_unmap(esink->displaying_buffer[i].bo); + } + else + GST_WARNING("there is no bo information. so skip to map bo"); + + GST_WARNING("[reset] unreffing gst %p", esink->displaying_buffer[i].buffer); + + while(esink->displaying_buffer[i].ref_count) + { + GST_WARNING("index[%d]'s buffer ref count=%d",i,gst_evas_image_sink_ref_count (esink->displaying_buffer[i].buffer)); + esink->displaying_buffer[i].ref_count--; + gst_buffer_unref(esink->displaying_buffer[i].buffer); + } + } + esink->displaying_buffer[i].buffer = NULL; + } + if(esink->displaying_buffer[i].bo) + esink->displaying_buffer[i].bo = NULL; + } + esink->prev_buf = NULL; + esink->prev_index = -1; + esink->cur_index = -1; + + esink->eo_size.x = esink->eo_size.y = + esink->eo_size.w = esink->eo_size.h = 0; + esink->use_ratio = FALSE; + esink->sent_buffer_cnt = 0; + + g_mutex_unlock(esink->display_buffer_lock); +} +#endif + +#ifdef USE_FIMCC +static void +evas_image_sink_cb_pipe (void *data, void *buffer, unsigned int nbyte) +#endif +#ifdef USE_NATIVE_BUFFER +static void +evas_image_sink_cb_pipe (void *data, int *buffer_index, unsigned int nbyte) +#endif +{ + GstEvasImageSink *esink = data; +#ifdef USE_FIMCC + GstBuffer *buf; + void *img_data; +#endif + GST_DEBUG ("[ENTER]"); + if (!esink || !esink->eo) { + GST_WARNING ("esink : %p, or eo is NULL returning", esink); + return; + } + GST_LOG("esink : %p, esink->eo : %x", esink, esink->eo); + if (nbyte == SIZE_FOR_UPDATE_VISIBILITY) { + if(!esink->object_show) { + evas_object_hide(esink->eo); + GST_INFO ("object hide.."); + } else { + evas_object_show(esink->eo); + GST_INFO ("object show.."); + } + GST_DEBUG ("[LEAVE]"); + return; + } +#ifdef USE_FIMCC + if (!buffer || nbyte != sizeof (GstBuffer *)) { + GST_WARNING ("buffer %p, nbyte : %d, sizeof(GstBuffer *) : %d", buffer, nbyte, sizeof (GstBuffer *)); + return; + } +#endif +#ifdef USE_NATIVE_BUFFER + int index = 0; + index = *buffer_index; + if ((index<0 || index>=NATIVE_BUFFER_NUM) || nbyte != SIZE_FOR_NATIVE_INDEX) { + GST_WARNING ("index : %d, nbyte : %d", index, nbyte); + return; + } +#endif + if (GST_STATE(esink) < GST_STATE_PAUSED) { + GST_WARNING ("WRONG-STATE(%d) for rendering, skip this frame", GST_STATE(esink)); + return; + } + +#ifdef USE_FIMCC + memcpy (&buf, buffer, sizeof (GstBuffer *)); + if (!buf) { + GST_ERROR ("There is no buffer"); + return; + } + if (esink->present_data_addr == -1) { + /* if present_data_addr is -1, we don't use this member variable */ + } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { + GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); + return; + } +#endif +#ifdef USE_NATIVE_BUFFER + g_mutex_lock(esink->display_buffer_lock); + if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12) { + if (!esink->displaying_buffer[index].n_buffer) { + GST_ERROR("the index's nbuffer was already NULL, so return"); + g_mutex_unlock(esink->display_buffer_lock); + return; + } + GST_LOG("received (bo %p, gst %p) index num : %d", esink->displaying_buffer[index].bo, esink->displaying_buffer[index].buffer, index); + } else if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_I420) { + GST_LOG("received (bo %p) index num : %d", esink->displaying_buffer[index].bo, index); + } + + Evas_Native_Surface surf; + surf.type = EVAS_NATIVE_SURFACE_TIZEN; + surf.version = EVAS_NATIVE_SURFACE_VERSION; + surf.data.tizen.buffer = esink->displaying_buffer[index].n_buffer; + surf.data.tizen.rot = esink->rotate_angle; + surf.data.tizen.flip = esink->flip; + + GST_LOG("received (bo %p, gst %p) index num : %d", esink->displaying_buffer[index].bo, esink->displaying_buffer[index].buffer, index); + + GstVideoRectangle result = {0}; + + evas_object_geometry_get(esink->eo, &esink->eo_size.x, &esink->eo_size.y, &esink->eo_size.w, &esink->eo_size.h); + if (!esink->eo_size.w || !esink->eo_size.h) { + GST_ERROR ("there is no information for evas object size"); + g_mutex_unlock(esink->display_buffer_lock); + return; + } + gst_evas_image_sink_update_geometry(esink, &result); + if(!result.w || !result.h) + { + GST_ERROR("no information about geometry (%d, %d)", result.w, result.h); + g_mutex_unlock(esink->display_buffer_lock); + return; + } + + if(esink->use_ratio) + { + surf.data.tizen.ratio = (float) esink->w / esink->h; + GST_LOG("set ratio for letter mode"); + } + evas_object_size_hint_align_set(esink->eo, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(esink->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) { + evas_object_image_size_set(esink->eo, esink->w, esink->h); + esink->is_evas_object_size_set = TRUE; + } + evas_object_image_native_surface_set(esink->eo, &surf); + GST_DEBUG("native surface set finish"); + + if(result.x || result.y) + GST_LOG("coordinate x, y (%d, %d) for locating video to center", result.x, result.y); + evas_object_image_fill_set(esink->eo, result.x, result.y, result.w, result.h); + + evas_object_image_pixels_dirty_set(esink->eo, EINA_TRUE); + GST_DEBUG_OBJECT (esink, "GEO_METHOD : src(%dx%d), dst(%dx%d), dst_x(%d), dst_y(%d), rotate(%d), flip(%d)", + esink->w, esink->h, esink->eo_size.w, esink->eo_size.h, esink->eo_size.x, esink->eo_size.y, esink->rotate_angle, esink->flip); + + /* unref previous buffer */ + if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12) { + if(esink->prev_buf && esink->displaying_buffer[esink->prev_index].ref_count) + { + GST_DEBUG("before index %d's ref_count =%d, gst_buf %p",esink->prev_index,esink->displaying_buffer[esink->prev_index].ref_count, esink->prev_buf); + esink->displaying_buffer[esink->prev_index].ref_count--; + GST_DEBUG("after index %d's ref_count =%d, gst_buf %p",esink->prev_index,esink->displaying_buffer[esink->prev_index].ref_count, esink->prev_buf); + /* Print debug log for 8 frame */ + if(esink->debuglog_cnt_ecoreCbPipe > 0) + { + GST_WARNING("(%d) ecore_cb_pipe unref index[%d] .. gst_buf %p", DEBUGLOG_DEFAULT_COUNT-(esink->debuglog_cnt_ecoreCbPipe), esink->prev_index, esink->prev_buf); + esink->debuglog_cnt_ecoreCbPipe--; + } + if (esink->sent_buffer_cnt == MAX_ECOREPIPE_BUFFER_CNT) + GST_WARNING("sent buffer cnt 4->3 so skip will be stop"); + + esink->sent_buffer_cnt--; + GST_DEBUG("prev gst_buffer %p's unref Start!!", esink->prev_buf); + gst_buffer_unref(esink->prev_buf); + GST_DEBUG("prev gst_buffer %p's unref End!!", esink->prev_buf); + } else { + GST_DEBUG("ref_count=%d unref prev gst_buffer %p", esink->displaying_buffer[esink->prev_index].ref_count,esink->prev_buf); + } + + GST_DEBUG("Current gst_buf %p and index=%d is overwrited to Prev gst_buf %p & index %d", + esink->displaying_buffer[index].buffer, index, esink->prev_buf, esink->prev_index ); + esink->prev_buf = esink->displaying_buffer[index].buffer; + esink->prev_index = index; + }else if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_I420) { + /* Print debug log for 8 frame */ + if(esink->debuglog_cnt_ecoreCbPipe > 0) + { + GST_WARNING("(%d) ecore_cb_pipe set native surface [%d] n_buffer[%p]", + DEBUGLOG_DEFAULT_COUNT-(esink->debuglog_cnt_ecoreCbPipe), index, esink->displaying_buffer[index].n_buffer); + esink->debuglog_cnt_ecoreCbPipe--; + } + if (esink->sent_buffer_cnt == MAX_ECOREPIPE_BUFFER_CNT) + GST_WARNING("sent buffer cnt 4->3 so skip will be stop"); + + esink->sent_buffer_cnt--; + } +#endif +#ifdef USE_FIMCC + if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) { + evas_object_image_size_set (esink->eo, esink->w, esink->h); + GST_DEBUG("evas_object_image_size_set(), width(%d),height(%d)", esink->w, esink->h); + esink->is_evas_object_size_set = TRUE; + } + if (esink->gl_zerocopy) { + img_data = evas_object_image_data_get (esink->eo, EINA_TRUE); + if (!img_data || !GST_BUFFER_DATA(buf)) { + GST_WARNING ("Cannot get image data from evas object or cannot get gstbuffer data"); + evas_object_image_data_set(esink->eo, img_data); + } else { + GST_DEBUG ("img_data(%x), GST_BUFFER_DATA(buf):%x, esink->w(%d),esink->h(%d), esink->eo(%x)",img_data,GST_BUFFER_DATA(buf),esink->w,esink->h,esink->eo); + memcpy (img_data, GST_BUFFER_DATA (buf), esink->w * esink->h * COLOR_DEPTH); + evas_object_image_pixels_dirty_set (esink->eo, 1); + evas_object_image_data_set(esink->eo, img_data); + } + gst_buffer_unref (buf); + } else { + GST_DEBUG ("GST_BUFFER_DATA(buf):%x, esink->eo(%x)",GST_BUFFER_DATA(buf),esink->eo); + evas_object_image_data_set (esink->eo, GST_BUFFER_DATA (buf)); + evas_object_image_pixels_dirty_set (esink->eo, 1); + if (esink->oldbuf) { + gst_buffer_unref(esink->oldbuf); + } + esink->oldbuf = buf; + } +#endif +#ifdef USE_NATIVE_BUFFER + g_mutex_unlock(esink->display_buffer_lock); +#endif + GST_DEBUG ("[LEAVE]"); +} +#ifdef USE_NATIVE_BUFFER +static void +gst_evas_image_sink_update_geometry (GstEvasImageSink *esink, GstVideoRectangle *result) +{ + if (!esink || !esink->eo) { + GST_WARNING("there is no esink"); + return; + } + + result->x = 0; + result->y = 0; + + switch (esink->display_geometry_method) + { + case DISP_GEO_METHOD_LETTER_BOX: // 0 + /* set black padding for letter box mode */ + GST_DEBUG("letter box mode"); + esink->use_ratio = TRUE; + result->w = esink->eo_size.w; + result->h = esink->eo_size.h; + break; + case DISP_GEO_METHOD_ORIGIN_SIZE: // 1 + GST_DEBUG("origin size mode"); + esink->use_ratio = FALSE; + /* set coordinate for each case */ + result->x = (esink->eo_size.w-esink->w) / 2; + result->y = (esink->eo_size.h-esink->h) / 2; + result->w = esink->w; + result->h = esink->h; + break; + case DISP_GEO_METHOD_FULL_SCREEN: // 2 + GST_DEBUG("full screen mode"); + esink->use_ratio = FALSE; + result->w = esink->eo_size.w; + result->h = esink->eo_size.h; + break; + case DISP_GEO_METHOD_CROPPED_FULL_SCREEN: // 3 + GST_DEBUG("cropped full screen mode"); + esink->use_ratio = FALSE; + /* compare evas object's ratio with video's */ + if((esink->eo_size.w/esink->eo_size.h) > (esink->w/esink->h)) + { + result->w = esink->eo_size.w; + result->h = esink->eo_size.w * esink->h / esink->w; + result->y = -(result->h-esink->eo_size.h) / 2; + } + else + { + result->w = esink->eo_size.h * esink->w / esink->h; + result->h = esink->eo_size.h; + result->x = -(result->w-esink->eo_size.w) / 2; + } + break; + case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX: // 4 + GST_DEBUG("origin size or letter box mode"); + /* if video size is smaller than evas object's, it will be set to origin size mode */ + if((esink->eo_size.w > esink->w) && (esink->eo_size.h > esink->h)) + { + GST_DEBUG("origin size mode"); + esink->use_ratio = FALSE; + /* set coordinate for each case */ + result->x = (esink->eo_size.w-esink->w) / 2; + result->y = (esink->eo_size.h-esink->h) / 2; + result->w = esink->w; + result->h = esink->h; + } + else + { + GST_DEBUG("letter box mode"); + esink->use_ratio = TRUE; + result->w = esink->eo_size.w; + result->h = esink->eo_size.h; + } + break; + default: + GST_WARNING("unsupported mode."); + break; + } + GST_DEBUG("geometry result [%d, %d, %d, %d]", result->x, result->y, result->w, result->h); +} +static void +gst_evas_image_sink_apply_geometry (GstEvasImageSink *esink) +{ + if (!esink || !esink->eo) { + GST_WARNING("there is no esink"); + return; + } + + Evas_Native_Surface *surf = evas_object_image_native_surface_get(esink->eo); + GstVideoRectangle result = {0}; + + if(surf) + { + GST_DEBUG("native surface exists"); + surf->data.tizen.rot = esink->rotate_angle; + surf->data.tizen.flip = esink->flip; + evas_object_image_native_surface_set(esink->eo, surf); + + gst_evas_image_sink_update_geometry(esink, &result); + + if(esink->use_ratio) + { + surf->data.tizen.ratio = (float) esink->w / esink->h; + GST_LOG("set ratio for letter mode"); + } + + if(result.x || result.y) + GST_LOG("coordinate x, y (%d, %d) for locating video to center", result.x, result.y); + + evas_object_image_fill_set(esink->eo, result.x, result.y, result.w, result.h); + } + else + GST_WARNING("there is no surf"); +} +#endif + +static void +gst_evas_image_sink_init (GstEvasImageSink *esink, GstEvasImageSinkClass *gclass) +{ + GST_DEBUG ("[ENTER]"); + + esink->eo = NULL; + esink->epipe = NULL; + esink->object_show = FALSE; + esink->update_visibility = UPDATE_FALSE; + esink->is_evas_object_size_set = FALSE; +#ifdef USE_FIMCC + esink->gl_zerocopy = FALSE; + esink->present_data_addr = -1; +#endif +#ifdef USE_NATIVE_BUFFER + esink->display_buffer_lock = g_mutex_new (); + esink->flow_lock = g_mutex_new (); + esink->n_provider = native_buffer_provider_create (NATIVE_BUFFER_PROVIDER_CORE); + int i = 0; + for (i=0; idisplaying_buffer[i].n_buffer = NULL; + esink->displaying_buffer[i].buffer = NULL; + esink->displaying_buffer[i].bo = NULL; + esink->displaying_buffer[i].ref_count = 0; + } + esink->prev_buf = NULL; + esink->prev_index = -1; + esink->cur_index = -1; + esink->enable_flush_buffer = TRUE; + esink->need_flush = FALSE; + esink->display_geometry_method = DISP_GEO_METHOD_LETTER_BOX; + esink->flip = FLIP_NONE; + esink->eo_size.x = esink->eo_size.y = + esink->eo_size.w = esink->eo_size.h = 0; + esink->use_ratio = FALSE; + esink->sent_buffer_cnt = 0; + esink->debuglog_cnt_showFrame = DEBUGLOG_DEFAULT_COUNT; + esink->debuglog_cnt_ecoreCbPipe = DEBUGLOG_DEFAULT_COUNT; + + esink->src_buf_idx = 0; + esink->is_buffer_allocated = FALSE; +#endif + if(!instance_lock) { + instance_lock = g_mutex_new(); + } + g_mutex_lock (instance_lock); + instance_lock_count++; + g_mutex_unlock (instance_lock); + + g_object_weak_ref (G_OBJECT (esink), gst_evas_image_sink_fini, NULL); + + GST_DEBUG ("[LEAVE]"); +} + +static void +evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + GST_DEBUG ("[ENTER]"); + + GstEvasImageSink *esink = data; + if (!esink) { + return; + } + +#ifdef USE_FIMCC + if (esink->oldbuf) { + gst_buffer_unref (esink->oldbuf); + esink->oldbuf = NULL; + } +#endif + if (esink->eo) { +#ifdef USE_NATIVE_BUFFER + EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK (evas_object_evas_get(esink->eo)); + GST_DEBUG("unset EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK esink : %p, esink->eo : %x", esink, esink->eo); +#endif + EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); + GST_DEBUG("unset EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK esink : %p, esink->eo : %x", esink, esink->eo); + + evas_object_image_data_set(esink->eo, NULL); + esink->eo = NULL; + } + + GST_DEBUG ("[LEAVE]"); +} + +static void +evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + int x, y, w, h; + x = y = w = h = 0; + + GST_DEBUG ("[ENTER]"); + + GstEvasImageSink *esink = data; + if (!esink || !esink->eo) { + return; + } + + evas_object_geometry_get(esink->eo, &x, &y, &w, &h); + if (!w || !h) { + GST_WARNING ("evas object size (w:%d,h:%d) was not set", w, h); + } else { +#ifdef USE_NATIVE_BUFFER + esink->eo_size.x = x; + esink->eo_size.y = y; + esink->eo_size.w = w; + esink->eo_size.h = h; + GST_WARNING ("resize (x:%d, y:%d, w:%d, h:%d)", x, y, w, h); + gst_evas_image_sink_apply_geometry(esink); +#endif +#ifdef USE_FIMCC + evas_object_image_fill_set(esink->eo, 0, 0, w, h); + GST_DEBUG ("evas object fill set (w:%d,h:%d)", w, h); +#endif + } + + GST_DEBUG ("[LEAVE]"); +} +#ifdef USE_NATIVE_BUFFER +static void +evas_callback_render_pre (void *data, Evas *e, void *event_info) +{ + GstEvasImageSink *esink = data; + if (!esink || !esink->eo) { + GST_WARNING("there is no esink info.... esink : %p, or eo is NULL returning", esink); + return; + } + if(esink->need_flush && esink->flush_buffer) + { + g_mutex_lock(esink->display_buffer_lock); + Evas_Native_Surface surf; + GstVideoRectangle result = {0}; + + evas_object_geometry_get(esink->eo, &esink->eo_size.x, &esink->eo_size.y, &esink->eo_size.w, &esink->eo_size.h); + if (!esink->eo_size.w || !esink->eo_size.h) { + GST_ERROR ("there is no information for evas object size"); + return; + } + gst_evas_image_sink_update_geometry(esink, &result); + if(!result.w || !result.h) + { + GST_ERROR("no information about geometry (%d, %d)", result.w, result.h); + return; + } + + if(esink->use_ratio) + { + surf.data.tizen.ratio = (float) esink->w / esink->h; + GST_LOG("set ratio for letter mode"); + } + evas_object_size_hint_align_set(esink->eo, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(esink->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) { + evas_object_image_size_set(esink->eo, esink->w, esink->h); + esink->is_evas_object_size_set = TRUE; + } + + if(result.x || result.y) + GST_LOG("coordinate x, y (%d, %d) for locating video to center", result.x, result.y); + + evas_object_image_fill_set(esink->eo, result.x, result.y, result.w, result.h); + + surf.type = EVAS_NATIVE_SURFACE_TIZEN; + surf.version = EVAS_NATIVE_SURFACE_VERSION; + surf.data.tizen.buffer = esink->flush_buffer->n_buffer; + surf.data.tizen.rot = esink->rotate_angle; + surf.data.tizen.flip = esink->flip; + GST_DEBUG("use esink->flush buffer->n_buffer (%p), rotate(%d), flip(%d)", + esink->flush_buffer->n_buffer, esink->rotate_angle, esink->flip); + evas_object_image_native_surface_set(esink->eo, &surf); + g_mutex_unlock(esink->display_buffer_lock); + esink->need_flush = FALSE; + } + evas_object_image_pixels_dirty_set (esink->eo, EINA_TRUE); + GST_LOG("dirty set finish"); +} + +static gboolean +gst_evas_image_sink_release_source_buffer(GstEvasImageSink *esink) +{ + int i = 0; + tbm_bo_handle bo_handle; + g_mutex_lock(esink->display_buffer_lock); + + for(i = 0; i < NATIVE_BUFFER_NUM; i++) { + GST_WARNING("[reset] reset gst %p", esink->displaying_buffer[i].buffer); + esink->displaying_buffer[i].bo = NULL; + esink->displaying_buffer[i].n_buffer = NULL; + esink->displaying_buffer[i].ref_count = 0; + } + + for(i = 0; i < SOURCE_BUFFER_NUM; i++) { + if(esink->src_buffer_info[i].bo) { + tbm_bo_unmap(esink->src_buffer_info[i].bo); + esink->src_buffer_info[i].bo = NULL; + } + + if (esink->src_buffer_info[i].n_buffer) { + native_buffer_destroy(esink->src_buffer_info[i].n_buffer); + esink->src_buffer_info[i].n_buffer = NULL; + } + } + + if(esink->n_provider) { + native_buffer_provider_destroy(esink->n_provider); + esink->n_provider = NULL; + } + esink->is_buffer_allocated = FALSE; + esink->src_buf_idx = 0; + esink->prev_buf = NULL; + esink->prev_index = -1; + esink->cur_index = -1; + + esink->eo_size.x = esink->eo_size.y = + esink->eo_size.w = esink->eo_size.h = 0; + esink->use_ratio = FALSE; + esink->sent_buffer_cnt = 0; + + g_mutex_unlock(esink->display_buffer_lock); + + return TRUE; +} + +static gboolean +gst_evas_image_sink_allocate_source_buffer(GstEvasImageSink *esink) +{ + int size = 0; + int idx = 0; + tbm_bo bo; + tbm_bo_handle vaddr; + GstFlowReturn ret=GST_FLOW_OK; + + if (esink == NULL) { + GST_ERROR("handle is NULL"); + return FALSE; + } + + /* create native buffer provider for making native buffer */ + if(esink->n_provider) { + GST_INFO("Native buffer provider already exists. Skipping creating one."); + } else { + esink->n_provider = native_buffer_provider_create (NATIVE_BUFFER_PROVIDER_CORE); + if(!esink->n_provider) { + GST_ERROR("n_provider is NULL!!"); + goto ALLOC_FAILED; + } + } + + for(idx=0; idx < SOURCE_BUFFER_NUM; idx++) { + if(!esink->src_buffer_info[idx].n_buffer) { + /* create native buffer */ + esink->src_buffer_info[idx].n_buffer = native_buffer_create(esink->n_provider, esink->w, esink->h, 0, esink->native_buffer_format, + NATIVE_BUFFER_USAGE_CPU|NATIVE_BUFFER_USAGE_3D_TEXTURE); + } + if(!esink->src_buffer_info[idx].n_buffer) + { + GST_ERROR("n_buffer is NULL!!"); + goto ALLOC_FAILED; + } + + /* get bo and size */ + bo = native_buffer_get_bo(esink->src_buffer_info[idx].n_buffer); + size = tbm_bo_size(bo); + if(!bo || !size) + { + GST_ERROR("bo(%p), size(%d)", bo, size); + goto ALLOC_FAILED; + } + esink->src_buffer_info[idx].bo = bo; + + vaddr = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE); + if (!vaddr.ptr) { + GST_WARNING_OBJECT(esink, "get vaddr failed pointer = %p", vaddr.ptr); + tbm_bo_unmap(bo); + goto ALLOC_FAILED; + } else { + memset (vaddr.ptr, 0x0, size); + GST_LOG_OBJECT (esink, "tbm_bo_map(VADDR) finished, bo(%p), vaddr(%p)", bo, vaddr.ptr); + } + + esink->src_buffer_info[idx].usr_addr = vaddr.ptr; + + GST_WARNING_OBJECT(esink, "src buffer index:%d , native buffer : %p", idx, esink->src_buffer_info[idx].n_buffer); + } + + return TRUE; + +ALLOC_FAILED: + gst_evas_image_sink_release_source_buffer(esink); + return FALSE; +} +#endif + +static int +evas_image_sink_get_size_from_caps (GstCaps *caps, int *w, int *h) +{ + gboolean r; + int width, height; + GstStructure *s; + + if (!caps || !w || !h) { + return -1; + } + s = gst_caps_get_structure (caps, 0); + if (!s) { + return -1; + } + + r = gst_structure_get_int (s, CAP_WIDTH, &width); + if (r == FALSE) { + GST_DEBUG("fail to get width from caps"); + return -1; + } + + r = gst_structure_get_int (s, CAP_HEIGHT, &height); + if (r == FALSE) { + GST_DEBUG("fail to get height from caps"); + return -1; + } + + *w = width; + *h = height; + GST_DEBUG ("size w(%d), h(%d)", width, height); + + return 0; +} +#ifdef USE_FIMCC +static gboolean +is_zerocopy_supported (Evas *e) +{ + Eina_List *engines, *l; + int cur_id; + int id; + char *name; + + if (!e) { + return FALSE; + } + + engines = evas_render_method_list (); + if (!engines) { + return FALSE; + } + + cur_id = evas_output_method_get (e); + + EINA_LIST_FOREACH (engines, l, name) { + id = evas_render_method_lookup (name); + if (name && id == cur_id) { + if (!strcmp (name, GL_X11_ENGINE)) { + return TRUE; + } + break; + } + } + return FALSE; +} + +static int +evas_image_sink_event_parse_data (GstEvasImageSink *esink, GstEvent *event) +{ + const GstStructure *st; + guint st_data_addr = 0; + gint st_data_width = 0; + gint st_data_height = 0; + + g_return_val_if_fail (event != NULL, FALSE); + g_return_val_if_fail (esink != NULL, FALSE); + + if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM_OOB) { + GST_WARNING ("it's not a custom downstream oob event"); + return -1; + } + st = gst_event_get_structure (event); + if (st == NULL || !gst_structure_has_name (st, "GstStructureForCustomEvent")) { + GST_WARNING ("structure in a given event is not proper"); + return -1; + } + if (!gst_structure_get_uint (st, "data-addr", &st_data_addr)) { + GST_WARNING ("parsing data-addr failed"); + return -1; + } + esink->present_data_addr = st_data_addr; + + return 0; +} +#endif +static gboolean +gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event) +{ +#ifdef USE_FIMCC + GstEvasImageSink *esink = GST_EVASIMAGESINK (sink); + GstMessage *msg; + gchar *str; +#endif + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + GST_DEBUG ("GST_EVENT_FLUSH_START"); + break; + case GST_EVENT_FLUSH_STOP: + GST_DEBUG ("GST_EVENT_FLUSH_STOP"); + break; + case GST_EVENT_EOS: + GST_DEBUG ("GST_EVENT_EOS"); + break; +#ifdef USE_FIMCC + case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: + if(!evas_image_sink_event_parse_data(esink, event)) { + GST_DEBUG ("GST_EVENT_CUSTOM_DOWNSTREAM_OOB, present_data_addr:%x",esink->present_data_addr); + } else { + GST_ERROR ("evas_image_sink_event_parse_data() failed"); + } + break; +#endif + default: + break; + } + if (GST_BASE_SINK_CLASS (parent_class)->event) { + return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); + } else { + return TRUE; + } +} + +static GstStateChangeReturn +gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition) +{ + GstStateChangeReturn ret_state = GST_STATE_CHANGE_SUCCESS; + GstEvasImageSink *esink = NULL; + GstFlowReturn ret=GST_FLOW_OK; + esink = GST_EVASIMAGESINK(element); + + if(!esink) { + GST_ERROR("can not get evasimagesink from element"); + return GST_STATE_CHANGE_FAILURE; + } + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + GST_WARNING ("*** STATE_CHANGE_NULL_TO_READY ***"); +#ifdef USE_NATIVE_BUFFER + g_mutex_lock (esink->flow_lock); + if (!is_evas_image_object (esink->eo)) { + GST_ERROR_OBJECT (esink, "There is no evas image object.."); + g_mutex_unlock (esink->flow_lock); + return GST_STATE_CHANGE_FAILURE; + } + g_mutex_unlock (esink->flow_lock); +#endif + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + GST_WARNING ("*** STATE_CHANGE_READY_TO_PAUSED ***"); + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: +#ifdef USE_NATIVE_BUFFER + /* Print debug log for 8 frame */ + esink->debuglog_cnt_showFrame = DEBUGLOG_DEFAULT_COUNT; + esink->debuglog_cnt_ecoreCbPipe = DEBUGLOG_DEFAULT_COUNT; +#endif + GST_WARNING ("*** STATE_CHANGE_PAUSED_TO_PLAYING ***"); + break; + default: + break; + } + + ret_state = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_WARNING ("*** STATE_CHANGE_PLAYING_TO_PAUSED ***"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_WARNING ("*** STATE_CHANGE_PAUSED_TO_READY ***"); +#ifdef USE_NATIVE_BUFFER + Eina_Bool r; + /* flush buffer, we will copy last buffer to keep image data and reset buffer list */ + GST_WARNING("esink->enable_flush_buffer : %d", esink->enable_flush_buffer); + if(esink->enable_flush_buffer && esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12) + { + if (gst_esink_make_flush_buffer(esink) == FALSE) { + ret = gst_esink_epipe_reset(esink); + if(ret) { + GST_ERROR_OBJECT(esink, "evas epipe reset ret=%d, need to check",ret); + return GST_STATE_CHANGE_FAILURE; + } + gst_evas_image_sink_reset(esink); + } + } + else { + ret = gst_esink_epipe_reset(esink); + if(ret) { + GST_ERROR_OBJECT(esink, "evas epipe reset ret=%d, need to check",ret); + return GST_STATE_CHANGE_FAILURE; + } + if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12) { + gst_evas_image_sink_reset(esink); + } else if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_I420) { + gst_evas_image_sink_release_source_buffer(esink); + } + } +#endif + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_WARNING ("*** STATE_CHANGE_READY_TO_NULL ***"); +#ifdef USE_NATIVE_BUFFER + if(esink->flush_buffer) + _release_flush_buffer(esink); + EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK (evas_object_evas_get(esink->eo)); +#endif + EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); + if (esink->epipe) { + GST_DEBUG("ecore-pipe will delete"); + ecore_pipe_del (esink->epipe); + esink->epipe = NULL; + } + break; + default: + break; + } + + return ret_state; +} + +static void +gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstEvasImageSink *esink = GST_EVASIMAGESINK (object); + Evas_Object *eo; + + g_mutex_lock (instance_lock); + + switch (prop_id) { + case PROP_EVAS_OBJECT: + eo = g_value_get_pointer (value); + if (is_evas_image_object (eo)) { + if (eo != esink->eo) { + Eina_Bool r; +#ifdef USE_NATIVE_BUFFER + EVASIMAGESINK_UNSET_EVAS_EVENT_CALLBACK (evas_object_evas_get(esink->eo)); +#endif + /* delete evas object callbacks registrated on a previous evas image object */ + EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); + esink->eo = eo; + /* add evas object callbacks on a new evas image object */ + EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo, esink); +#ifdef USE_NATIVE_BUFFER + GST_WARNING("register render callback [esink : %p, esink->eo : %x]", esink, esink->eo); + EVASIMAGESINK_SET_EVAS_EVENT_CALLBACK (evas_object_evas_get(esink->eo), esink); + evas_object_geometry_get(esink->eo, &esink->eo_size.x, &esink->eo_size.y, &esink->eo_size.w, &esink->eo_size.h); + GST_WARNING ("evas object size (x:%d, y:%d, w:%d, h:%d)", esink->eo_size.x, esink->eo_size.y, esink->eo_size.w, esink->eo_size.h); +#endif +#ifdef USE_FIMCC + esink->gl_zerocopy = is_zerocopy_supported (evas_object_evas_get (eo)); + if (esink->gl_zerocopy) { + evas_object_image_content_hint_set (esink->eo, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); + GST_DEBUG("Enable gl zerocopy"); + } +#endif + GST_DEBUG("Evas Image Object(%x) is set", esink->eo); + esink->is_evas_object_size_set = FALSE; + esink->object_show = TRUE; + esink->update_visibility = UPDATE_TRUE; + if (esink->epipe) { + r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); + if (r == EINA_FALSE) { + GST_WARNING ("Failed to ecore_pipe_write() for updating visibility\n"); + } + } + } + } else { + GST_ERROR ("Cannot set evas-object property: value is not an evas image object"); + } + break; + + case PROP_EVAS_OBJECT_SHOW: + { + Eina_Bool r; + esink->object_show = g_value_get_boolean (value); + if( !is_evas_image_object(esink->eo) ) { + GST_WARNING ("Cannot apply visible(show-object) property: cannot get an evas object\n"); + break; + } + esink->update_visibility = UPDATE_TRUE; + GST_LOG("esink->update_visibility : %d", esink->update_visibility); + if (esink->epipe) { + r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); + if (r == EINA_FALSE) { + GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n"); + } + } + break; + } +#ifdef USE_NATIVE_BUFFER + case PROP_ROTATE_ANGLE: + { + int rotate = 0; + rotate = g_value_get_int (value); + switch(rotate) + { + case DEGREE_0: + esink->rotate_angle = 0; + break; + case DEGREE_90: + esink->rotate_angle = 90; + break; + case DEGREE_180: + esink->rotate_angle = 180; + break; + case DEGREE_270: + esink->rotate_angle = 270; + break; + default: + break; + } + GST_INFO("update rotate_angle : %d", esink->rotate_angle); + break; + } + case PROP_DISPLAY_GEOMETRY_METHOD: + { + Eina_Bool r; + guint geometry = g_value_get_int (value); + if (esink->display_geometry_method != geometry) { + esink->display_geometry_method = geometry; + GST_INFO_OBJECT (esink, "Overlay geometry method update, display_geometry_method(%d)", esink->display_geometry_method); + } + + g_mutex_lock(esink->display_buffer_lock); + + if(esink->cur_index!=-1 && esink->epipe) + { + GST_WARNING("apply property esink->cur_index =%d",esink->cur_index); + esink->displaying_buffer[esink->cur_index].ref_count++; + gst_buffer_ref(esink->displaying_buffer[esink->cur_index].buffer); + esink->sent_buffer_cnt++; + r = ecore_pipe_write (esink->epipe, &esink->cur_index, SIZE_FOR_NATIVE_INDEX); + + if (r == EINA_FALSE) { + GST_WARNING("ecore_pipe_write fail"); + esink->displaying_buffer[esink->cur_index].ref_count--; + gst_buffer_unref(esink->displaying_buffer[esink->cur_index].buffer); + esink->sent_buffer_cnt--; + } + } + g_mutex_unlock(esink->display_buffer_lock); + break; + } + case PROP_ENABLE_FLUSH_BUFFER: + esink->enable_flush_buffer = g_value_get_boolean(value); + break; + case PROP_FLIP: + { + esink->flip = g_value_get_int(value); + GST_INFO("update flip : %d", esink->flip); + break; + } +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + + g_mutex_unlock (instance_lock); +} + +static void +gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstEvasImageSink *esink = GST_EVASIMAGESINK (object); + + switch (prop_id) { + case PROP_EVAS_OBJECT: + g_value_set_pointer (value, esink->eo); + break; + case PROP_EVAS_OBJECT_SHOW: + g_value_set_boolean (value, esink->object_show); + break; +#ifdef USE_NATIVE_BUFFER + case PROP_ROTATE_ANGLE: + g_value_set_int (value, esink->rotate_angle); + break; + case PROP_DISPLAY_GEOMETRY_METHOD: + g_value_set_int (value, esink->display_geometry_method); + break; + case PROP_ENABLE_FLUSH_BUFFER: + g_value_set_boolean(value, esink->enable_flush_buffer); + break; + case PROP_FLIP: + g_value_set_int(value, esink->flip); + break; +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps) +{ + int r; + int w, h; + GstEvasImageSink *esink = GST_EVASIMAGESINK (base_sink); + GstStructure *structure = NULL; + guint32 format = 0; + + esink->is_evas_object_size_set = FALSE; + r = evas_image_sink_get_size_from_caps (caps, &w, &h); + if (!r) { + esink->w = w; + esink->h = h; + GST_DEBUG ("set size w(%d), h(%d)", w, h); + } + + structure = gst_caps_get_structure (caps, 0); + if (!structure) { + return FALSE; + } + + if (!gst_structure_get_fourcc (structure, "format", &format)) { + GST_DEBUG ("format(dst) is not set...it may be rgb series"); + } + + GST_DEBUG_OBJECT(esink, "source color format is %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (format)); + +#ifdef USE_NATIVE_BUFFER + if (format == GST_MAKE_FOURCC('S','N','1','2') || format == GST_MAKE_FOURCC('N','V','1','2') ) { + esink->native_buffer_format = NATIVE_BUFFER_FORMAT_NV12; + } else if (format == GST_MAKE_FOURCC('I','4','2','0')){ + esink->native_buffer_format = NATIVE_BUFFER_FORMAT_I420; + } else { + GST_ERROR("cannot parse fourcc format from caps."); + return FALSE; + } +#endif + + return TRUE; +} + +static GstFlowReturn +gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf) +{ + GstEvasImageSink *esink = GST_EVASIMAGESINK (video_sink); + Eina_Bool r; + + GST_LOG("[ENTER] show frame"); +#ifdef USE_NATIVE_BUFFER + if (!gst_evas_image_sink_ref_count (buf)) + { + GST_WARNING("ref count is 0.. skip show frame"); + return GST_FLOW_OK; + } +#endif + g_mutex_lock (instance_lock); +#ifdef USE_FIMCC + if (esink->present_data_addr == -1) { + /* if present_data_addr is -1, we don't use this member variable */ + } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { + GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); + g_mutex_unlock (instance_lock); + return GST_FLOW_OK; + } +#endif + if (!esink->epipe) { + esink->epipe = ecore_pipe_add ((Ecore_Pipe_Cb)evas_image_sink_cb_pipe, esink); + if (!esink->epipe) { + GST_ERROR ("ecore-pipe create failed"); + g_mutex_unlock (instance_lock); + return GST_FLOW_ERROR; + } + GST_DEBUG("ecore-pipe create success"); + } +#ifdef USE_NATIVE_BUFFER + int i = 0; + int index = -1; + SCMN_IMGB *scmn_imgb = NULL; + gboolean exist_bo = FALSE; + + GST_LOG ("BUF: gst_buf= %p ts= %" GST_TIME_FORMAT " size= %lu, mallocdata= %p", + buf, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_SIZE (buf), GST_BUFFER_MALLOCDATA(buf)); + + if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12) { + /* get received buffer informations */ + scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf); + if (!scmn_imgb) { + GST_WARNING("scmn_imgb is NULL. Skip..." ); + g_mutex_unlock (instance_lock); + return GST_FLOW_OK; + } + if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_TIZEN_BUFFER) + { + /* check whether bo is new or not */ + for(i=0; idisplaying_buffer[i].bo==scmn_imgb->bo[0]) + { + GST_DEBUG("it is already saved bo %p (index num : %d)", esink->displaying_buffer[i].bo, i); + index = i; + exist_bo = TRUE; + break; + } + else + exist_bo = FALSE; + } + /* keep bo */ + if(!exist_bo) + { + /* find empty buffer space for indexing */ + for(i=0; idisplaying_buffer[i].bo) + { + index = i; + break; + } + } + if(index!=-1) + { + /* keep informations */ + esink->displaying_buffer[index].buffer = buf; + esink->displaying_buffer[index].bo = scmn_imgb->bo[0]; + GST_WARNING("TBM bo %p / gst_buf %p", esink->displaying_buffer[index].bo, esink->displaying_buffer[index].buffer); + + /* create new native buffer */ + if(!esink->n_provider) + { + GST_WARNING("native buffer provide don't exist... create it"); + esink->n_provider = native_buffer_provider_create (NATIVE_BUFFER_PROVIDER_CORE); + } + esink->displaying_buffer[index].n_buffer = native_buffer_create_for_tbm(esink->n_provider, esink->displaying_buffer[index].bo, esink->w, esink->h, 0, + NATIVE_BUFFER_FORMAT_NV12); + if(!esink->displaying_buffer[index].n_buffer) + { + GST_WARNING("there is no native buffer.. bo : %p, gst_buf : %p", esink->displaying_buffer[index].bo, esink->displaying_buffer[index].buffer); + g_mutex_unlock (instance_lock); + return GST_FLOW_OK; + } + + GST_WARNING("create native buffer : %p", esink->displaying_buffer[index].n_buffer); + } + } + /* because it has same bo, use existing native buffer */ + else + { + if(index!=-1) + { + esink->displaying_buffer[index].buffer = buf; + GST_DEBUG("existing native buffer %p.. bo %p, gst_buf %p", esink->displaying_buffer[index].n_buffer, esink->displaying_buffer[index].bo, esink->displaying_buffer[index].buffer); + exist_bo = FALSE; + } + } + + /* if it couldn't find proper index */ + if(index == -1) + GST_WARNING("all spaces are using!!!"); + else + GST_DEBUG("selected buffer index %d", index); + + } + else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FLUSH_BUFFER) + { + /* flush buffer, we will copy last buffer to keep image data and reset buffer list */ + GST_WARNING_OBJECT(esink, "FLUSH_BUFFER: gst_buf= %p ts= %" GST_TIME_FORMAT " size= %lu, mallocdata= %p", + buf, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_SIZE (buf), GST_BUFFER_MALLOCDATA(buf)); + gst_buffer_ref (buf); + if (gst_esink_make_flush_buffer(esink)) + GST_WARNING("made flush buffer"); + gst_buffer_unref (buf); + } + else + { + GST_ERROR("it is not TBM buffer.. %d", scmn_imgb->buf_share_method); + } + } else if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_I420) { + static int skip_count_i420=0; + if(esink->sent_buffer_cnt >= MAX_ECOREPIPE_BUFFER_CNT) { + if(!(skip_count_i420++%20)) { + GST_WARNING("[%d]EA buffer was already sent to ecore pipe, and %d frame skipped", esink->sent_buffer_cnt,skip_count_i420); + } + g_mutex_unlock (instance_lock); + return GST_FLOW_OK; + } + + if(!esink->is_buffer_allocated) { + /* Allocate TBM buffer for non-zero copy case */ + if(!gst_evas_image_sink_allocate_source_buffer(esink)) { + GST_ERROR_OBJECT(esink, "Buffer allocation failed"); + g_mutex_unlock (instance_lock); + return GST_FLOW_ERROR; + } + esink->is_buffer_allocated = TRUE; + } + + skip_count_i420 = 0; //for skip log in I420 + + /* check whether bo is new or not */ + for(i=0; idisplaying_buffer[i].bo == esink->src_buffer_info[esink->src_buf_idx].bo) { + GST_DEBUG_OBJECT(esink, "it is already saved bo %p (index num : %d)", esink->displaying_buffer[i].bo, i); + index = i; + exist_bo = TRUE; + break; + } + else + exist_bo = FALSE; + } + + /* keep bo */ + if(!exist_bo) { + /* find empty buffer space for indexing */ + for(i=0; idisplaying_buffer[i].bo) { + index = i; + break; + } + } + + if(index!=-1) { + /* keep informations */ + esink->displaying_buffer[index].bo = esink->src_buffer_info[esink->src_buf_idx].bo; + esink->displaying_buffer[index].n_buffer = esink->src_buffer_info[esink->src_buf_idx].n_buffer; + + GST_DEBUG_OBJECT(esink, "gst_buf %p, TBM bo %p.. gst_buf vaddr %p .. src data size(%lu)", + buf, esink->displaying_buffer[index].bo, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); + + memcpy(esink->src_buffer_info[esink->src_buf_idx].usr_addr, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); + } + } else { + /* because it has same bo, use existing native buffer */ + if(index!=-1) { + memcpy(esink->src_buffer_info[esink->src_buf_idx].usr_addr, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf)); + + GST_DEBUG_OBJECT(esink, "existing native buffer %p.. gst_buf %p, bo %p, gst_buf vaddr %p", + esink->displaying_buffer[index].n_buffer, buf, esink->displaying_buffer[index].bo, GST_BUFFER_DATA(buf)); + exist_bo = FALSE; + } + } + + /* if it couldn't find proper index */ + if(index == -1) + GST_WARNING_OBJECT(esink, "all spaces are being used!!!"); + else + GST_DEBUG_OBJECT(esink, "selected buffer index %d", index); + + } else { + GST_ERROR_OBJECT(esink, "unsupported color format"); + g_mutex_unlock (instance_lock); + return GST_FLOW_ERROR; + } +#endif + if (esink->object_show && index != -1) { +#ifdef USE_FIMCC + gst_buffer_ref (buf); + r = ecore_pipe_write (esink->epipe, &buf, sizeof (GstBuffer *)); + if (r == EINA_FALSE) { + //add error handling + GST_WARNING("ecore_pipe_write fail"); + } +#endif +#ifdef USE_NATIVE_BUFFER + int old_curidx=esink->cur_index ; + static int skip_count=0; + g_mutex_lock(esink->display_buffer_lock); + + if(esink->native_buffer_format == NATIVE_BUFFER_FORMAT_NV12 && scmn_imgb->buf_share_method != BUF_SHARE_METHOD_FLUSH_BUFFER) { + if (esink->sent_buffer_cnt < MAX_ECOREPIPE_BUFFER_CNT) { + GST_LOG("[show_frame] before refcount : %d .. gst_buf : %p", gst_evas_image_sink_ref_count (buf), buf); + gst_buffer_ref (buf); + esink->displaying_buffer[index].ref_count++; + esink->cur_index = index; + GST_LOG("index %d set refcount increase as %d", index,esink->displaying_buffer[index].ref_count); + GST_LOG("[show_frame] after refcount : %d .. gst_buf : %p", gst_evas_image_sink_ref_count (buf), buf); + + /* Print debug log for 8 frame */ + if(esink->debuglog_cnt_showFrame > 0) + { + GST_WARNING("(%d) ecore_pipe_write index[%d] gst_buf : %p", DEBUGLOG_DEFAULT_COUNT-(esink->debuglog_cnt_showFrame), + esink->cur_index, esink->displaying_buffer[esink->cur_index].buffer); + esink->debuglog_cnt_showFrame--; + } + + esink->sent_buffer_cnt++; + skip_count =0 ; + + r = ecore_pipe_write (esink->epipe, &esink->cur_index , SIZE_FOR_NATIVE_INDEX); + + if (r == EINA_FALSE) { + GST_LOG("[show_frame] before refcount : %d .. gst_buf : %p", gst_evas_image_sink_ref_count (buf), buf); + esink->cur_index = old_curidx; + if(esink->displaying_buffer[index].ref_count) + { + esink->displaying_buffer[index].ref_count--; + esink->sent_buffer_cnt--; + gst_buffer_unref(buf); + GST_ERROR("finish unreffing"); + } + } + } else { + /* If buffer count which is sent to ecore pipe, is upper 3, Print Error log */ + if(!(skip_count++%20)) { + GST_WARNING("[%d]EA buffer was already sent to ecore pipe, and %d frame skipped", esink->sent_buffer_cnt,skip_count); + } + } + } else if (esink->native_buffer_format == NATIVE_BUFFER_FORMAT_I420) { + esink->cur_index = index; + GST_LOG("index %d", index); + GST_LOG("[show_frame] gst_buf vaddr %p", esink->src_buffer_info[esink->src_buf_idx].usr_addr); + + /* Print debug log for 8 frame */ + if(esink->debuglog_cnt_showFrame > 0) + { + GST_WARNING("(%d) ecore_pipe_write : index[%d], bo[%p], n_buffer[%p], gst_buf[%p], gst_buf vaddr [%p]", DEBUGLOG_DEFAULT_COUNT-(esink->debuglog_cnt_showFrame), + esink->cur_index, esink->displaying_buffer[index].bo, esink->displaying_buffer[index].n_buffer, buf, esink->src_buffer_info[esink->src_buf_idx].usr_addr); + esink->debuglog_cnt_showFrame--; + } + + esink->sent_buffer_cnt++; + + esink->src_buf_idx++; + r = ecore_pipe_write (esink->epipe, &esink->cur_index , SIZE_FOR_NATIVE_INDEX); + + if (r == EINA_FALSE) { + esink->cur_index = old_curidx; + esink->sent_buffer_cnt--; + esink->src_buf_idx--; + GST_ERROR("ecore_pipe_write is failed. index[%d], bo[%p], n_buffer[%p], gst_buf vaddr [%p]", + index, esink->displaying_buffer[index].bo, esink->displaying_buffer[index].n_buffer, esink->src_buffer_info[esink->src_buf_idx].usr_addr); + } + esink->src_buf_idx = esink->src_buf_idx % SOURCE_BUFFER_NUM; + } + + g_mutex_unlock(esink->display_buffer_lock); +#endif + GST_DEBUG ("ecore_pipe_write() was called with gst_buf= %p.. gst_buf Vaddr=%p, mallocdata= %p", buf, GST_BUFFER_DATA(buf), GST_BUFFER_MALLOCDATA(buf)); + } else { + GST_WARNING ("skip ecore_pipe_write(). becuase of esink->object_show(%d) index(%d)", esink->object_show, index); + } + g_mutex_unlock (instance_lock); + GST_DEBUG ("Leave"); + return GST_FLOW_OK; +} +#ifdef USE_NATIVE_BUFFER + +static GstFlowReturn +gst_esink_epipe_reset(GstEvasImageSink *esink) +{ + if (esink == NULL) { + GST_ERROR("handle is NULL"); + return GST_FLOW_ERROR; + } + + if (esink->epipe) { + GST_DEBUG("ecore-pipe will delete"); + ecore_pipe_del (esink->epipe); + esink->epipe = NULL; + } + + if (!esink->epipe) { + esink->epipe = ecore_pipe_add ((Ecore_Pipe_Cb)evas_image_sink_cb_pipe, esink); + if (!esink->epipe) { + GST_ERROR ("ecore-pipe create failed"); + return GST_FLOW_ERROR; + } + GST_DEBUG("ecore-pipe create success"); + } + + return GST_FLOW_OK; +} + + +static gboolean gst_esink_make_flush_buffer(GstEvasImageSink *esink) +{ + GstEvasImageFlushBuffer *flush_buffer = NULL; + GstEvasImageDisplayingBuffer *display_buffer = NULL; + int size = 0; + tbm_bo bo; + tbm_bo_handle vaddr_src; + tbm_bo_handle vaddr_dst; + GstFlowReturn ret=GST_FLOW_OK; + int src_size = 0; + + if (esink == NULL) { + GST_ERROR("handle is NULL"); + return FALSE; + } + + if (esink->cur_index == -1) { + GST_WARNING_OBJECT(esink, "there is no remained buffer"); + return FALSE; + } + + if(esink->flush_buffer) + _release_flush_buffer(esink); + + /* malloc buffer */ + flush_buffer = (GstEvasImageFlushBuffer *)malloc(sizeof(GstEvasImageFlushBuffer)); + if (flush_buffer == NULL) { + GST_ERROR_OBJECT(esink, "GstEvasImageFlushBuffer alloc failed"); + return FALSE; + } + + memset(flush_buffer, 0x0, sizeof(GstEvasImageFlushBuffer)); + + display_buffer = &(esink->displaying_buffer[esink->cur_index]); + GST_WARNING_OBJECT(esink, "cur_index [%d]", + esink->cur_index); + if(!display_buffer || !display_buffer->bo) + { + GST_WARNING("display_buffer(%p) or bo (%p) is NULL!!", display_buffer, display_buffer->bo); + goto FLUSH_BUFFER_FAILED; + } + + /* create native buffer provider for making native buffer */ + flush_buffer->n_provider = native_buffer_provider_create (NATIVE_BUFFER_PROVIDER_CORE); + + if(!flush_buffer->n_provider) + { + GST_ERROR("n_provider is NULL!!"); + goto FLUSH_BUFFER_FAILED; + } + + /* create native buffer */ + flush_buffer->n_buffer = native_buffer_create(flush_buffer->n_provider, esink->w, esink->h, 0, NATIVE_BUFFER_FORMAT_NV12, + NATIVE_BUFFER_USAGE_CPU|NATIVE_BUFFER_USAGE_3D_TEXTURE); + if(!flush_buffer->n_buffer) + { + GST_ERROR("n_buffer is NULL!!"); + goto FLUSH_BUFFER_FAILED; + } + + /* get bo and size */ + bo = native_buffer_get_bo(flush_buffer->n_buffer); + size = tbm_bo_size(bo); + if(!bo || !size) + { + GST_ERROR("bo(%p), size(%d)", bo, size); + goto FLUSH_BUFFER_FAILED; + } + flush_buffer->bo = bo; + + src_size = display_buffer->buffer->size; + + vaddr_src = tbm_bo_map(display_buffer->bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE); + vaddr_dst = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE); + if (!vaddr_src.ptr || !vaddr_dst.ptr) { + GST_WARNING_OBJECT(esink, "get vaddr failed src %p, dst %p", vaddr_src.ptr, vaddr_dst.ptr); + if (vaddr_src.ptr) { + tbm_bo_unmap(display_buffer->bo); + } + if (vaddr_dst.ptr) { + tbm_bo_unmap(bo); + } + goto FLUSH_BUFFER_FAILED; + } else { + memset (vaddr_dst.ptr, 0x0, size); + GST_WARNING_OBJECT (esink, "tbm_bo_map(VADDR) finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr); + } + + /* copy buffer */ + memcpy(vaddr_dst.ptr, vaddr_src.ptr, src_size); + + tbm_bo_unmap(display_buffer->bo); + tbm_bo_unmap(bo); + + GST_WARNING_OBJECT(esink, "copy done.. native buffer : %p src_size : %d", flush_buffer->n_buffer, src_size); + + esink->flush_buffer = flush_buffer; + + /* initialize buffer list */ + if (esink->object_show) + esink->need_flush = TRUE; + + ret = gst_esink_epipe_reset(esink); + if(ret) { + GST_ERROR_OBJECT(esink, "evas epipe reset ret=%d, need to check",ret); + return FALSE; + } else { + GST_ERROR_OBJECT(esink, "evas epipe reset success"); + } + + gst_evas_image_sink_reset(esink); + + + return TRUE; + +FLUSH_BUFFER_FAILED: + if (flush_buffer) { + if(flush_buffer->n_buffer) + { + native_buffer_destroy(flush_buffer->n_buffer); + flush_buffer->n_buffer = NULL; + } + if(flush_buffer->n_provider) + { + native_buffer_provider_destroy(flush_buffer->n_provider); + } + free(flush_buffer); + flush_buffer = NULL; + } + return FALSE; +} + + static void _release_flush_buffer(GstEvasImageSink *esink) +{ + if (esink == NULL || + esink->flush_buffer == NULL) { + GST_WARNING("handle is NULL"); + return; + } + + GST_WARNING_OBJECT(esink, "release FLUSH BUFFER start"); + if (esink->flush_buffer->bo) { + esink->flush_buffer->bo = NULL; + } + if(esink->flush_buffer->n_buffer) { + native_buffer_destroy(esink->flush_buffer->n_buffer); + esink->flush_buffer->n_buffer = NULL; + } + if(esink->flush_buffer->n_provider) { + native_buffer_provider_destroy(esink->flush_buffer->n_provider); + } + + GST_WARNING_OBJECT(esink, "release FLUSH BUFFER done"); + + free(esink->flush_buffer); + esink->flush_buffer = NULL; + + return; +} + +#endif +static gboolean +evas_image_sink_init (GstPlugin *evasimagesink) +{ + GST_DEBUG_CATEGORY_INIT (gst_evas_image_sink_debug, "evasimagesink", 0, "Evas image object based videosink"); + + return gst_element_register (evasimagesink, "evasimagesink", GST_RANK_NONE, GST_TYPE_EVASIMAGESINK); +} + +#ifndef PACKAGE +#define PACKAGE "gstevasimagesink-plugin-package" +#endif + +GST_PLUGIN_DEFINE ( + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "evasimagesink", + "Evas image object based videosink", + evas_image_sink_init, + VERSION, + "LGPL", + "Samsung Electronics Co", + "http://www.samsung.com/" +) diff --git a/evasimagesink/src/gstevasimagesink.h b/evasimagesink/src/gstevasimagesink.h new file mode 100755 index 0000000..54ee4bd --- /dev/null +++ b/evasimagesink/src/gstevasimagesink.h @@ -0,0 +1,173 @@ +/* + * evasimagesink + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Sangchul Lee + * + * This library 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.1 of the License, or (at your option) + * any later version. + * + * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __GST_EVASIMAGESINK_H__ +#define __GST_EVASIMAGESINK_H__ + +//#define USE_NATIVE_BUFFER +#define USE_FIMCC + +#include +#include +#include +#include +#ifdef USE_NATIVE_BUFFER +#include +#include +#endif +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_EVASIMAGESINK \ + (gst_evas_image_sink_get_type()) +#define GST_EVASIMAGESINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EVASIMAGESINK,GstEvasImageSink)) +#define GST_EVASIMAGESINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EVASIMAGESINK,GstEvasImageSinkClass)) +#define GST_IS_EVASIMAGESINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EVASIMAGESINK)) +#define GST_IS_EVASIMAGESINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EVASIMAGESINK)) + +typedef struct _GstEvasImageSink GstEvasImageSink; +typedef struct _GstEvasImageSinkClass GstEvasImageSinkClass; +#ifdef USE_NATIVE_BUFFER +typedef struct _GstEvasImageDisplayingBuffer GstEvasImageDisplayingBuffer; +typedef struct _GstEvasImageFlushBuffer GstEvasImageFlushBuffer; +typedef enum { + BUF_SHARE_METHOD_NONE = -1, + BUF_SHARE_METHOD_PADDR = 0, + BUF_SHARE_METHOD_FD, + BUF_SHARE_METHOD_TIZEN_BUFFER, + BUF_SHARE_METHOD_FLUSH_BUFFER +} buf_share_method_t; + +enum { + DEGREE_0 = 0, + DEGREE_90, + DEGREE_180, + DEGREE_270, + DEGREE_NUM, +}; + +enum { + DISP_GEO_METHOD_LETTER_BOX = 0, + DISP_GEO_METHOD_ORIGIN_SIZE, + DISP_GEO_METHOD_FULL_SCREEN, + DISP_GEO_METHOD_CROPPED_FULL_SCREEN, + DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX, + DISP_GEO_METHOD_CUSTOM_DST_ROI, + DISP_GEO_METHOD_NUM, +}; + +enum { + FLIP_NONE = 0, + FLIP_HORIZONTAL, + FLIP_VERTICAL, + FLIP_BOTH, + FLIP_NUM +}; + +struct buffer_info { + uint64_t usr_addr; + uint64_t size; + void *bo; + native_buffer_t *n_buffer; + native_buffer_provider_t *n_provider; +}; + +/* _GstEvasDisplayingBuffer + * + * buffer : manage ref count by got index through comparison + * bo : compare with buffer from codec for getting index + * n_buffer : compare with buffer from evas for getting index + * ref_count : decide whether it unref buffer or not in gst_evas_image_sink_fini/reset + */ +struct _GstEvasImageDisplayingBuffer { + GstBuffer *buffer; + void *bo; + native_buffer_t *n_buffer; + int ref_count; +}; + +struct _GstEvasImageFlushBuffer { + void *bo; + native_buffer_t *n_buffer; + native_buffer_provider_t *n_provider; +}; +#define NATIVE_BUFFER_NUM 20 +#define SOURCE_BUFFER_NUM 8 +#endif +struct _GstEvasImageSink +{ + GstVideoSink element; + + Evas_Object *eo; + Ecore_Pipe *epipe; + Evas_Coord w; + Evas_Coord h; + gboolean object_show; + gchar update_visibility; + gboolean gl_zerocopy; + + GstBuffer *oldbuf; + + gboolean is_evas_object_size_set; + guint present_data_addr; +#ifdef USE_NATIVE_BUFFER + GMutex *display_buffer_lock; + GMutex *flow_lock; + GstEvasImageDisplayingBuffer displaying_buffer[NATIVE_BUFFER_NUM]; + GstVideoRectangle eo_size; + gboolean use_ratio; + guint rotate_angle; + guint display_geometry_method; + guint flip; + native_buffer_provider_t *n_provider; + GstBuffer *prev_buf; + gint prev_index; + gint cur_index; + gboolean need_flush; + gboolean enable_flush_buffer; + GstEvasImageFlushBuffer *flush_buffer; + gint sent_buffer_cnt; + gint debuglog_cnt_showFrame; + gint debuglog_cnt_ecoreCbPipe; + + native_buffer_format_t native_buffer_format; + struct buffer_info src_buffer_info[NATIVE_BUFFER_NUM]; + guint src_buf_idx; + gboolean is_buffer_allocated; +#endif +}; + +struct _GstEvasImageSinkClass +{ + GstVideoSinkClass parent_class; +}; + +GType gst_evas_image_sink_get_type (void); + +G_END_DECLS + +#endif /* __GST_EVASIMAGESINK_H__ */ diff --git a/mobile/evaspixmapsink/Makefile.am b/evaspixmapsink/Makefile.am similarity index 79% rename from mobile/evaspixmapsink/Makefile.am rename to evaspixmapsink/Makefile.am index f05ccbd..4caa9d5 100644 --- a/mobile/evaspixmapsink/Makefile.am +++ b/evaspixmapsink/Makefile.am @@ -1,14 +1,13 @@ plugin_LTLIBRARIES = libgstevaspixmapsink.la libgstevaspixmapsink_la_SOURCES = evaspixmapsink.c -libgstevaspixmapsink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(EFL_CFLAGS) $(MMTA_CFLAGS) \ - $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XDAMAGE_CFLAGS) $(XV_CFLAGS) $(TBM_CFLAGS) +libgstevaspixmapsink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(EFL_CFLAGS) \ + $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XDAMAGE_CFLAGS) $(XV_CFLAGS) $(TBM_CFLAGS) $(DRM_CFLAGS) $(DRM_DEVEL_CFLAGS) libgstevaspixmapsink_la_LIBADD = \ $(GST_LIBS) -lgstvideo-$(GST_MAJORMINOR) -lgstinterfaces-$(GST_MAJORMINOR) \ $(X_LIBS) $(XVIDEO_LIBS) $(XSHM_LIBS) $(LIBM) \ $(EFL_LIBS) \ - $(MMTA_LIBS) \ - $(XFIXES_LIBS) $(DRI2PROTO_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XDAMAGE_LIBS) $(XV_LIBS) $(TBM_LIBS) + $(XFIXES_LIBS) $(DRI2PROTO_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XDAMAGE_LIBS) $(XV_LIBS) $(TBM_LIBS) $(DRM_LIBS) $(DRM_DEVEL_LIBS) libgstevaspixmapsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstxvimagesink_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/mobile/evaspixmapsink/evaspixmapsink.c b/evaspixmapsink/evaspixmapsink.c old mode 100644 new mode 100755 similarity index 89% rename from mobile/evaspixmapsink/evaspixmapsink.c rename to evaspixmapsink/evaspixmapsink.c index 8d62714..3bfd235 --- a/mobile/evaspixmapsink/evaspixmapsink.c +++ b/evaspixmapsink/evaspixmapsink.c @@ -161,6 +161,30 @@ enum { #define SIZE_FOR_UPDATE_VISIBILITY sizeof(gchar) #define EPIPE_REQUEST_LIMIT 20 +#ifdef DUMP_IMG +int util_write_rawdata (const char *file, const void *data, unsigned int size); +typedef struct _BufferInfo +{ + Display *dpy; + Pixmap pixmap; + int width; + int height; + + /* Dri2 */ + int drm_fd; + tbm_bufmgr bufmgr; + void *virtual; + DRI2Buffer *dri2_buffers; + tbm_bo bo; +} BufferInfo; + +static BufferInfo *g_bufinfo[NUM_OF_PIXMAP]; +void * gst_evaspixmapsink_get_buffer (Display *dpy, Pixmap pixmap, int width, int height, int i); +void gst_evaspixmapsink_free_buffer (int i); +static Bool gst_evaspixmapsink_init_dri2 (BufferInfo *bufinfo); +int g_cnt; +#endif + /* macro ******************************************************/ #define EVASPIXMAPSINK_SET_PIXMAP_ID_TO_GEM_INFO( x_evaspixmapsink, x_pixmap_id ) \ do \ @@ -362,6 +386,10 @@ static GstVideoSinkClass *parent_class = NULL; #define GST_IS_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVASPIXMAP_BUFFER)) #define GST_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVASPIXMAP_BUFFER, GstEvasPixmapBuffer)) +static int log_warn_count = 0; + +Display *g_my_disp; + static int get_millis_time() { struct timespec tp; @@ -372,20 +400,29 @@ static int get_millis_time() static void ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) { + if (!data ) { + GST_WARNING ("data is NULL.."); + return; + } + GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink*)data; GST_DEBUG_OBJECT (evaspixmapsink,"[START] Evas_Object(0x%x)", evaspixmapsink->eo); - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink - ecore thread cb : TOTAL", FALSE); int i = 0; guint idx = 0; GstXPixmap *xpixmap = NULL; - if (!data ) { - GST_WARNING_OBJECT (evaspixmapsink,"data is NULL.."); - return; - } + g_mutex_lock (evaspixmapsink->flow_lock); + evaspixmapsink->epipe_request_count--; if (!evaspixmapsink->eo) { GST_WARNING_OBJECT (evaspixmapsink,"evas object is NULL.."); + g_mutex_unlock (evaspixmapsink->flow_lock); + return; + } + + if (!evaspixmapsink->xcontext) { + GST_WARNING_OBJECT (evaspixmapsink,"xcontext is NULL.."); + g_mutex_unlock (evaspixmapsink->flow_lock); return; } @@ -402,6 +439,7 @@ ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) GST_INFO_OBJECT (evaspixmapsink, "object show"); } } + g_mutex_unlock (evaspixmapsink->flow_lock); return; } @@ -415,10 +453,11 @@ ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) surf.type = EVAS_NATIVE_SURFACE_X11; surf.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); surf.data.x11.pixmap = evaspixmapsink->xpixmap[idx]->pixmap; - __ta__("evaspixmapsink - ecore thread cb : _native_surface_set(LINK)", evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); ); + evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); evaspixmapsink->do_link = FALSE; } else { GST_WARNING_OBJECT (evaspixmapsink,"pixmap is NULL.."); + g_mutex_unlock (evaspixmapsink->flow_lock); return; } for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { @@ -482,7 +521,7 @@ ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) if (evaspixmapsink->eo) { evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); } - __ta__("evaspixmapsink - ecore thread cb : _native_surface_set", evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); ); + evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); GST_LOG_OBJECT (evaspixmapsink,"update, native_surface_set of xpixmap[%d]",idx); if (evaspixmapsink->last_updated_idx == -1) { xpixmap->damaged_time = 0; @@ -498,11 +537,8 @@ ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) evaspixmapsink->last_updated_idx = idx; } - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evas_object_image update", FALSE); - evas_object_image_pixels_dirty_set (evaspixmapsink->eo, 1); evas_object_image_fill_set(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h); evas_object_image_data_update_add(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h); - MMTA_ACUM_ITEM_END("evaspixmapsink evas_object_image update", FALSE); //GST_LOG_OBJECT (evaspixmapsink,"request to update : pixmap idx(%d), ref(%d)", idx, xpixmap->ref); } else { GST_ERROR_OBJECT (evaspixmapsink,"pixmap is NULL.."); @@ -510,9 +546,8 @@ ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); } - MMTA_ACUM_ITEM_END("evaspixmapsink - ecore thread cb : TOTAL", FALSE); - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); + g_mutex_unlock (evaspixmapsink->flow_lock); } static inline gboolean @@ -578,12 +613,24 @@ evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_i evaspixmapsink->gem_info[i].ref_pixmap = 0; } } + + /** + * Pixmap is reallocated. + * But native surface has old pixmap. + * In this case, evas can rendering with old pixmap. + * That makes broken image in the window. + * So I just unset evas native surface. + */ + if (evaspixmapsink->eo) { + evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); + evas_object_image_data_set(evaspixmapsink->eo, NULL); + } #ifdef COMPARE_RATIO } #endif } - if (GST_STATE(evaspixmapsink) == GST_STATE_PAUSED) { + if (GST_STATE(evaspixmapsink) >= GST_STATE_PAUSED) { gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf); } @@ -632,11 +679,203 @@ gst_evaspixmapsink_handle_xerror (Display * display, XErrorEvent * xevent) char error_msg[1024]; XGetErrorText (display, xevent->error_code, error_msg, 1024); - GST_ERROR ("evaspixmapsink triggered an XError. error(%s), display(%p), xevent->request_code(%d)", error_msg, display, xevent->request_code); - error_caught = TRUE; + if (display != g_my_disp) { + GST_WARNING ("evaspixmapsink triggered an XError. but display(%p) is not ours(%p), just skip it. error(%s), xevent->request_code(%d)", display, g_my_disp, error_msg, xevent->request_code); + } else { + GST_ERROR ("evaspixmapsink triggered an XError. error(%s), display(%p), xevent->request_code(%d)", error_msg, display, xevent->request_code); + error_caught = TRUE; + } return 0; } +#ifdef DUMP_IMG +int util_write_rawdata(const char *file, const void *data, unsigned int size) +{ + FILE *fp; + + fp = fopen(file, "wb"); + if (fp == NULL) + { + GST_WARNING("fopen fail... size : %d", size); + return -1; + } + fwrite((char*)data, sizeof(char), size, fp); + fclose(fp); + + return 0; +} + +void * +gst_evaspixmapsink_get_buffer (Display *dpy, Pixmap pixmap, int width, int height, int i) +{ + if (g_bufinfo[i]!=NULL) + { + GST_ERROR("g_bufinfo!=NULL %p", g_bufinfo[i]); + exit (-1); + } + + g_bufinfo[i] = calloc (1, sizeof (BufferInfo)); + + g_bufinfo[i]->dpy = dpy; + g_bufinfo[i]->pixmap = pixmap; + g_bufinfo[i]->width = width; + g_bufinfo[i]->height = height; + + if (!gst_evaspixmapsink_init_dri2 (g_bufinfo[i])) + { + free (g_bufinfo[i]); + g_bufinfo[i] = NULL; + return NULL; + } + + if (g_bufinfo[i]->virtual == NULL) + { + GST_ERROR("g_bufinfo->virtual == NULL"); + exit (-1); + } + + return g_bufinfo[i]->virtual; +} + +void +gst_evaspixmapsink_free_buffer (int i) +{ + if (g_bufinfo[i] == NULL) + { + GST_ERROR("g_bufinfo == NULL"); + exit (-1); + } + + if (g_bufinfo[i]==NULL) + { + GST_ERROR("g_bufinfo==NULL"); + exit (-1); + } + + if (g_bufinfo[i]) + { + if (g_bufinfo[i]->bo) + tbm_bo_unref(g_bufinfo[i]->bo); + if (g_bufinfo[i]->dri2_buffers) + free(g_bufinfo[i]->dri2_buffers); + if (g_bufinfo[i]->bufmgr) + tbm_bufmgr_deinit (g_bufinfo[i]->bufmgr); + if (g_bufinfo[i]->drm_fd >= 0) + close (g_bufinfo[i]->drm_fd); + } + + XSync (g_bufinfo[i]->dpy, 0); + free (g_bufinfo[i]); + g_bufinfo[i] = NULL; +} + +static Bool gst_evaspixmapsink_init_dri2 (BufferInfo *bufinfo) +{ + int screen; + int dri2_base = 0; + int dri2_err_base = 0; + int dri2Major, dri2Minor; + char *driverName = NULL, *deviceName = NULL; + unsigned int attachments[1]; + int dri2_count, dri2_out_count; + int dri2_width, dri2_height; + drm_magic_t magic; + tbm_bo_handle bo_handle; + screen = DefaultScreen(bufinfo->dpy); + if (!DRI2QueryExtension (bufinfo->dpy, &dri2_base, &dri2_err_base)) + { + GST_ERROR ("no DRI2 extension. !!\n"); + goto fail_init_dri2; + } + if (!DRI2QueryVersion (bufinfo->dpy, &dri2Major, &dri2Minor)) + { + GST_ERROR ("fail : DRI2QueryVersion !!\n"); + goto fail_init_dri2; + } + if (!DRI2Connect (bufinfo->dpy, RootWindow(bufinfo->dpy, screen), &driverName, &deviceName)) + { + GST_ERROR ("fail : DRI2Connect !!\n"); + goto fail_init_dri2; + } /* drm_fd */ + bufinfo->drm_fd = open (deviceName, O_RDWR); + if (bufinfo->drm_fd < 0) + { + GST_ERROR ("fail : open drm device (%s)\n", deviceName); + goto fail_init_dri2; + } + /* get the drm magic */ + drmGetMagic(bufinfo->drm_fd, &magic); + if (!DRI2Authenticate(bufinfo->dpy, RootWindow(bufinfo->dpy, screen), magic)) + { + GST_ERROR ("fail : DRI2Authenticate (%d)\n", magic); + goto fail_init_dri2; + } + /* bufmgr */ + bufinfo->bufmgr = tbm_bufmgr_init (bufinfo->drm_fd); + if (!bufinfo->bufmgr) + { + GST_ERROR ("fail : init buffer manager \n"); + goto fail_init_dri2; + } + DRI2CreateDrawable (bufinfo->dpy, bufinfo->pixmap); + attachments[0] = DRI2BufferFrontLeft; + dri2_count = 1; + bufinfo->dri2_buffers = DRI2GetBuffers (bufinfo->dpy, bufinfo->pixmap, &dri2_width, &dri2_height, + attachments, dri2_count, &dri2_out_count); + if (!bufinfo->dri2_buffers) + { + GST_ERROR ("fail : get buffers\n"); + goto fail_init_dri2; + } + if (!bufinfo->dri2_buffers[0].name) + { + GST_ERROR ("fail : a handle of the dri2 buffer is null \n "); + goto fail_init_dri2; + } + bufinfo->bo = tbm_bo_import (bufinfo->bufmgr, bufinfo->dri2_buffers[0].name); + if (!bufinfo->bo) + { + GST_ERROR ("fail : import bo (key:%d)\n", bufinfo->dri2_buffers[0].name); + goto fail_init_dri2; + } + /* virtual */ + bo_handle = tbm_bo_map(bufinfo->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE); + if(!bo_handle.ptr) + { + GST_ERROR ("fail : tbm_bo_map"); + goto fail_init_dri2; + } + tbm_bo_unmap (bufinfo->bo); + + bufinfo->virtual = (void *)bo_handle.ptr; + if (!bufinfo->virtual) + { + GST_ERROR ("fail : map \n"); + goto fail_init_dri2; + } + + free (driverName); + free (deviceName); + + return True; + + fail_init_dri2: + if (driverName) + free (driverName); + if (deviceName) + free (deviceName); + if (bufinfo->bo) + tbm_bo_unref(bufinfo->bo); + if (bufinfo->dri2_buffers) + free(bufinfo->dri2_buffers); + if (bufinfo->bufmgr) + tbm_bufmgr_deinit (bufinfo->bufmgr); + if (bufinfo->drm_fd >= 0) + close (bufinfo->drm_fd); + return False; +} +#endif + #ifdef HAVE_XSHM /* This function checks that it is actually really possible to create an image using XShm */ @@ -1123,8 +1362,7 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe int ret = 0; int idx = 0; GstXPixmap *xpixmap = NULL; - - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evaspixmap_buffer_put()", FALSE); + int i = 0; /* We take the flow_lock. If expose is in there we don't want to run concurrently from the data flow thread */ @@ -1133,7 +1371,7 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe if (G_UNLIKELY (evaspixmapsink->xpixmap[idx] == NULL)) { GST_WARNING_OBJECT (evaspixmapsink, "xpixmap is NULL. Skip buffer_put." ); g_mutex_unlock(evaspixmapsink->flow_lock); - return FALSE; + return TRUE; } if (evaspixmapsink->visible == FALSE) { GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. Skip buffer_put." ); @@ -1314,16 +1552,16 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe break; } + g_mutex_lock (evaspixmapsink->x_lock); + /* set display rotation */ if (atom_rotation == None) { atom_rotation = XInternAtom(evaspixmapsink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_ROTATION", False); } - ret = XvSetPortAttribute(evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_rotation, rotate); if (ret != Success) { GST_ERROR_OBJECT( evaspixmapsink, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],rotate[%d]", ret, evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_rotation, rotate ); - return FALSE; } /* set display flip */ @@ -1366,6 +1604,8 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe ret, evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_vflip, set_vflip); } + g_mutex_unlock (evaspixmapsink->x_lock); + } else { result.x = result.y = 0; result.w = evaspixmapsink->xpixmap[idx]->width; @@ -1373,6 +1613,19 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe GST_INFO_OBJECT (evaspixmapsink, "USE ORIGIN SIZE, no geometry method, no rotation/flip" ); } + if((evaspixmapsink->result_prev.w != 0 && evaspixmapsink->result_prev.h != 0) + && (evaspixmapsink->src_prev.w==src_origin.w && evaspixmapsink->src_prev.h==src_origin.h) + && (evaspixmapsink->result_prev.w!=result.w || evaspixmapsink->result_prev.h!=result.h)) + { + GST_WARNING("It will execute XFillRectangle..... evaspixmapsink->result_prev.w : %d, evaspixmapsink->result_prev.h: %d, result.w : %d, result.h : %d", + evaspixmapsink->result_prev.w, evaspixmapsink->result_prev.h, result.w, result.h); + for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { + XFillRectangle (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, evaspixmapsink->xpixmap[i]->gc, + 0, 0, evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); + GST_LOG_OBJECT (evaspixmapsink,"fill black to xpixmap[%d] with size(w:%d,h:%d)", evaspixmapsink->xpixmap[i]->pixmap, + evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); + } + } g_mutex_lock (evaspixmapsink->x_lock); /* We scale to the pixmap's geometry */ @@ -1429,13 +1682,18 @@ gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffe GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." ); } } + + evaspixmapsink->src_prev.w = src_origin.w; + evaspixmapsink->src_prev.h = src_origin.h; + + evaspixmapsink->result_prev.w = result.w; + evaspixmapsink->result_prev.h = result.h; + XSync (evaspixmapsink->xcontext->disp, FALSE); g_mutex_unlock (evaspixmapsink->x_lock); g_mutex_unlock (evaspixmapsink->flow_lock); - MMTA_ACUM_ITEM_END("evaspixmapsink evaspixmap_buffer_put()", FALSE); - return TRUE; } @@ -2190,6 +2448,13 @@ gst_evaspixmapsink_event_thread (GstEvasPixmapSink * evaspixmapsink) int i = 0; Display *disp = NULL; +#ifdef DUMP_IMG + int ret = 0; + char file_name[128]; + char *dump_data; +#endif + + GST_OBJECT_LOCK (evaspixmapsink); if (evaspixmapsink->xcontext && evaspixmapsink->xcontext->disp) { @@ -2223,19 +2488,55 @@ gst_evaspixmapsink_event_thread (GstEvasPixmapSink * evaspixmapsink) xpixmap->damaged_time = (gint)get_millis_time(); } g_mutex_unlock(evaspixmapsink->pixmap_ref_lock); - GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : got a damage event for pixmap(%d), refcount(%d), damaged_time(%d)", - xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time); + if (GST_STATE(evaspixmapsink) < GST_STATE_PLAYING || log_warn_count < 20) { + GST_WARNING_OBJECT (evaspixmapsink,"event_handler : got a damage event for pixmap(%d), refcount(%d), damaged_time(%d)", + xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time); + } else { + GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : got a damage event for pixmap(%d), refcount(%d), damaged_time(%d)", + xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time); + } if (evaspixmapsink->epipe_request_count > EPIPE_REQUEST_LIMIT) { GST_WARNING_OBJECT (evaspixmapsink,"event_handler : epipe_request_count(%d), skip ecore_pipe_write()", evaspixmapsink->epipe_request_count); } else { - __ta__("evaspixmapsink ecore_pipe_write", ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink));); + ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink)); evaspixmapsink->epipe_request_count++; - GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write() for pixmap(%d)", xpixmap->pixmap); + if (GST_STATE(evaspixmapsink) < GST_STATE_PLAYING || log_warn_count < 20 ) { + GST_WARNING_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write() for pixmap(%d)", xpixmap->pixmap); + log_warn_count++; + } else { + GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write() for pixmap(%d)", xpixmap->pixmap); + } } g_mutex_lock (evaspixmapsink->x_lock); XDamageSubtract (evaspixmapsink->xcontext->disp, evaspixmapsink->damage[i], None, None ); g_mutex_unlock (evaspixmapsink->x_lock); +#ifdef DUMP_IMG + int dump_w = evaspixmapsink->w + (32 - (evaspixmapsink->w%32)); // for multiples of 32 + if(g_cnt<100) + { + evaspixmapsink->pixmap_addr[i] = gst_evaspixmapsink_get_buffer(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, dump_w, evaspixmapsink->h, i); + GST_ERROR(" pixmap[%d] addr %p (w : %d, h : %d)", g_cnt, i, evaspixmapsink->pixmap_addr[i], dump_w, evaspixmapsink->h); + sprintf(file_name, "/opt/usr/media/DUMP_%2.2d.dump", g_cnt); + + dump_data = g_malloc(dump_w * evaspixmapsink->h * 4); + memcpy (dump_data, evaspixmapsink->pixmap_addr[i], dump_w * evaspixmapsink->h * 4); + + ret = util_write_rawdata(file_name, dump_data, dump_w * evaspixmapsink->h * 4); + if (ret) { + GST_ERROR_OBJECT (evaspixmapsink, "util_write_rawdata() failed"); + } + else + g_cnt++; + g_free(dump_data); + + if (g_bufinfo[i]) { + gst_evaspixmapsink_free_buffer (i); + g_bufinfo[i] = NULL; + } + evaspixmapsink->pixmap_addr[i] = NULL; + } +#endif if (evaspixmapsink->buf_shared_type == BUF_SHARE_METHOD_FD) { if (GST_STATE(evaspixmapsink) == GST_STATE_PLAYING) { drm_fini_close_gem_handle(evaspixmapsink, xpixmap->pixmap); @@ -2368,20 +2669,20 @@ gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink) g_mutex_lock (evaspixmapsink->x_lock); xcontext->disp = XOpenDisplay (evaspixmapsink->display_name); - if (!xcontext->disp) { g_mutex_unlock (evaspixmapsink->x_lock); g_free (xcontext); GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Could not initialise Xv output"), ("Could not open display")); return NULL; } + GST_WARNING_OBJECT (evaspixmapsink,"Display(0x%x) is opened", xcontext->disp); + g_my_disp = xcontext->disp; xcontext->screen = DefaultScreenOfDisplay (xcontext->disp); xcontext->screen_num = DefaultScreen (xcontext->disp); xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num); xcontext->root = DefaultRootWindow (xcontext->disp); xcontext->white = XWhitePixel (xcontext->disp, xcontext->screen_num); - xcontext->black = XBlackPixel (xcontext->disp, xcontext->screen_num); xcontext->depth = DefaultDepthOfScreen (xcontext->screen); xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num); @@ -2402,6 +2703,7 @@ gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink) g_free (xcontext); GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS, ("Could not initialise Xv output"), ("Could not get pixel formats")); + g_my_disp = NULL; return NULL; } @@ -2436,6 +2738,7 @@ gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink) g_free (xcontext->par); g_free (xcontext); /* GST_ELEMENT_ERROR is thrown by gst_evaspixmapsink_get_xv_support */ + g_my_disp = NULL; return NULL; } #ifdef HAVE_XSHM @@ -2575,6 +2878,7 @@ gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink) XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0); XCloseDisplay (xcontext->disp); + g_my_disp = NULL; g_mutex_unlock (evaspixmapsink->x_lock); @@ -2662,6 +2966,17 @@ gst_evaspixmapsink_setcaps (GstBaseSink *bsink, GstCaps *caps) evaspixmapsink->aligned_width = video_width; evaspixmapsink->aligned_height = video_height; + /* get combine prop of hevc */ + if(gst_structure_get_int (structure, "yuvcombine", &(evaspixmapsink->need_combine_data))) + { + GST_INFO_OBJECT(evaspixmapsink, "need combine data : %d", evaspixmapsink->need_combine_data); + } + else + { + /*Not need to combine data, just directly copy*/ + evaspixmapsink->need_combine_data = 0; + } + /* get enable-last-buffer */ g_object_get(G_OBJECT(evaspixmapsink), "enable-last-buffer", &enable_last_buffer, NULL); GST_INFO_OBJECT (evaspixmapsink,"current enable-last-buffer : %d", enable_last_buffer); @@ -2675,8 +2990,11 @@ gst_evaspixmapsink_setcaps (GstBaseSink *bsink, GstCaps *caps) evaspixmapsink->fps_n = gst_value_get_fraction_numerator (fps); evaspixmapsink->fps_d = gst_value_get_fraction_denominator (fps); - evaspixmapsink->video_width = video_width; - evaspixmapsink->video_height = video_height; + if (evaspixmapsink->video_width != video_width || evaspixmapsink->video_height != video_height) { + evaspixmapsink->src_prev.w = evaspixmapsink->video_width = video_width; + evaspixmapsink->src_prev.h = evaspixmapsink->video_height = video_height; + evaspixmapsink->need_to_fill_black = TRUE; + } im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps); if (im_format == -1) { @@ -2858,7 +3176,9 @@ gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition) /* call XSynchronize with the current value of synchronous */ GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE"); + g_mutex_lock (evaspixmapsink->x_lock); XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous); + g_mutex_unlock (evaspixmapsink->x_lock); gst_evaspixmapsink_update_colorbalance (evaspixmapsink); g_mutex_unlock (evaspixmapsink->flow_lock); @@ -2881,6 +3201,7 @@ gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PLAYING_TO_PAUSED"); + log_warn_count = 0; break; case GST_STATE_CHANGE_PAUSED_TO_READY: @@ -2897,7 +3218,9 @@ gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition) case GST_STATE_CHANGE_READY_TO_NULL: GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_NULL"); + g_mutex_lock (evaspixmapsink->flow_lock); gst_evaspixmapsink_reset(evaspixmapsink); + g_mutex_unlock (evaspixmapsink->flow_lock); /* close drm */ drm_fini(evaspixmapsink); break; @@ -2929,6 +3252,58 @@ gst_evaspixmapsink_get_times (GstBaseSink *bsink, GstBuffer *buf, GstClockTime * } } +static void +gst_evaspixmapsink_combine_i420_scmn_data(GstEvasPixmapSink *evaspixmapsink, GstBuffer *buf) +{ + unsigned int outsize = 0; + unsigned char *temp_outbuf = evaspixmapsink->evas_pixmap_buf->xvimage->data; + int cnt = 0, j = 0; + unsigned char *temp_imgb; + SCMN_IMGB *imgb = NULL; + int stride, w, h, i; + + GST_DEBUG("Begin"); + + imgb = (SCMN_IMGB *)GST_BUFFER_DATA(buf); + if(imgb == NULL || imgb->a[0] == NULL) + { + return; + } + + stride = GST_ROUND_UP_4 (imgb->w[0]); + h = imgb->h[0]; + w = imgb->w[0]; + /*Y plane copy */ + for (i = 0; i < h; i++) + { + memcpy (temp_outbuf + i * stride, imgb->a[0] + i * imgb->s[0], w); + } + + temp_outbuf += GST_ROUND_UP_4 (imgb->w[0]) * GST_ROUND_UP_2 (imgb->h[0]); + + stride = GST_ROUND_UP_4 (GST_ROUND_UP_2 (imgb->w[0]) / 2); + h = GST_ROUND_UP_2 (imgb->h[0]) / 2; + w = GST_ROUND_UP_2 (imgb->w[0]) / 2; + /* Cb plane copy */ + for (i = 0; i < h; i++) + { + memcpy (temp_outbuf + i * stride, imgb->a[1] + i * imgb->s[1], w); + } + + temp_outbuf += GST_ROUND_UP_4 (GST_ROUND_UP_2 (imgb->w[0]) / 2) * (GST_ROUND_UP_2 (imgb->h[0]) / 2); + /* Same stride, height, width as above */ + /* Cr plane copy */ + for (i = 0; i < h; i++) + { + memcpy (temp_outbuf + i * stride, imgb->a[2] + i * imgb->s[2], w); + } + + outsize = imgb->w[0] * imgb->h[0]* 3 >> 1; + evaspixmapsink->evas_pixmap_buf->size = MIN(outsize, evaspixmapsink->evas_pixmap_buf->size); + + GST_DEBUG("End"); +} + static GstFlowReturn gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) { @@ -2937,13 +3312,15 @@ gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) SCMN_IMGB *scmn_imgb = NULL; gint format = 0; - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); - evaspixmapsink = GST_EVASPIXMAPSINK (vsink); + if (GST_STATE(evaspixmapsink) < GST_STATE_PLAYING || log_warn_count < 20) { + GST_WARNING_OBJECT (evaspixmapsink, "enter >>>" ); + } + if( evaspixmapsink->stop_video ) { GST_INFO_OBJECT (evaspixmapsink, "Stop video is TRUE. so skip show frame..." ); - return GST_FLOW_OK; + goto skip_frame; } if (!evaspixmapsink->evas_pixmap_buf) { @@ -2961,13 +3338,13 @@ gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf); if(scmn_imgb == NULL) { GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." ); - return GST_FLOW_OK; + goto skip_frame; } /* skip buffer if aligned size is smaller than size of caps */ if (scmn_imgb->s[0] < evaspixmapsink->video_width || scmn_imgb->e[0] < evaspixmapsink->video_height) { GST_WARNING_OBJECT (evaspixmapsink,"invalid size[caps:%dx%d,aligned:%dx%d]. Skip this buffer...", evaspixmapsink->video_width, evaspixmapsink->video_height, scmn_imgb->s[0], scmn_imgb->e[0]); - return GST_FLOW_OK; + goto skip_frame; } evaspixmapsink->aligned_width = scmn_imgb->s[0]; evaspixmapsink->aligned_height = scmn_imgb->e[0]; @@ -3010,7 +3387,7 @@ gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf); if (scmn_imgb == NULL) { GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." ); - return GST_FLOW_OK; + goto skip_frame; } if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_PADDR) { @@ -3051,17 +3428,17 @@ gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) } } else { GST_WARNING_OBJECT (evaspixmapsink, "Not supported, buf_share_method(%d)", scmn_imgb->buf_share_method); - return GST_FLOW_OK; + goto skip_frame; } if (!img_data->YBuf) { GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." ); - return GST_FLOW_OK; + goto skip_frame; } GST_LOG_OBJECT(evaspixmapsink, "YBuf[%d], CbBuf[%d], CrBuf[%d]", img_data->YBuf, img_data->CbBuf, img_data->CrBuf ); } else { GST_WARNING_OBJECT (evaspixmapsink, "xvimage->data is NULL. skip buffer put..." ); - return GST_FLOW_OK; + goto skip_frame; } break; } @@ -3071,17 +3448,26 @@ gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_NONE; } GST_DEBUG_OBJECT (evaspixmapsink,"Normal format activated. fourcc = %d", evaspixmapsink->evas_pixmap_buf->im_format); - __ta__("evaspixmapsink memcpy in _show_frame", memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, GST_BUFFER_DATA (buf), - MIN (GST_BUFFER_SIZE (buf), evaspixmapsink->evas_pixmap_buf->size));); + if(evaspixmapsink->need_combine_data == 1) + { + gst_evaspixmapsink_combine_i420_scmn_data(evaspixmapsink, buf); + } + else + { + memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, + GST_BUFFER_DATA (buf), + MIN (GST_BUFFER_SIZE (buf), evaspixmapsink->evas_pixmap_buf->size)); + } break; } } - if (!gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf)) { - MMTA_ACUM_ITEM_END("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); - return GST_FLOW_OK; - } + gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf); - MMTA_ACUM_ITEM_END("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); +skip_frame: + + if (GST_STATE(evaspixmapsink) < GST_STATE_PLAYING || log_warn_count < 20) { + GST_WARNING_OBJECT (evaspixmapsink, "leave <<<" ); + } return GST_FLOW_OK; @@ -3432,6 +3818,14 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) unsigned int xw = 0; unsigned int xh = 0; int i = 0; + XGCValues gc_values_black; + gc_values_black.foreground = 0xff000000; +#ifdef DUMP_IMG + int ret = 0; + char file_name[128]; + char *dump_data; + int dump_w = 0; +#endif GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); @@ -3447,6 +3841,7 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink); if (!evaspixmapsink->xcontext) { GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext.."); + g_mutex_unlock (evaspixmapsink->flow_lock); return FALSE; } } @@ -3461,12 +3856,42 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) if (evaspixmapsink->xpixmap[i]->width == evas_object_width && evaspixmapsink->xpixmap[i]->height == evas_object_height) { GST_WARNING_OBJECT (evaspixmapsink,"pixmap was already created(w:%d, h:%d), skip it..", evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - XSetForeground (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->gc, evaspixmapsink->xcontext->black); - XFillRectangle (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, evaspixmapsink->xpixmap[i]->gc, - 0, 0, evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); - GST_LOG_OBJECT (evaspixmapsink,"fill black to xpixmap[%d] with size(w:%d,h:%d)", evaspixmapsink->xpixmap[i]->pixmap, - evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); + if (evaspixmapsink->need_to_fill_black) { + for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { + g_mutex_lock (evaspixmapsink->x_lock); + XFillRectangle (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, evaspixmapsink->xpixmap[i]->gc, + 0, 0, evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); + GST_LOG_OBJECT (evaspixmapsink,"fill black to xpixmap[%d] with size(w:%d,h:%d)", evaspixmapsink->xpixmap[i]->pixmap, + evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); +#ifdef DUMP_IMG + dump_w = evaspixmapsink->xpixmap[i]->width + (32 - (evaspixmapsink->xpixmap[i]->width%32)); // for multiples of 32 + if(g_cnt<100) + { + evaspixmapsink->pixmap_addr[i] = gst_evaspixmapsink_get_buffer(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, dump_w, evaspixmapsink->xpixmap[i]->height, i); + GST_ERROR(" pixmap[%d] addr %p (w : %d, h : %d)", g_cnt, i, evaspixmapsink->pixmap_addr[i], dump_w, evaspixmapsink->xpixmap[i]->height); + sprintf(file_name, "/opt/usr/media/DUMP_%2.2d.dump", g_cnt); + + dump_data = g_malloc(dump_w * evaspixmapsink->xpixmap[i]->height * 4); + memcpy (dump_data, evaspixmapsink->pixmap_addr[i], dump_w * evaspixmapsink->xpixmap[i]->height * 4); + + ret = util_write_rawdata(file_name, dump_data, dump_w * evaspixmapsink->xpixmap[i]->height * 4); + if (ret) { + GST_ERROR_OBJECT (evaspixmapsink, "util_write_rawdata() failed"); + } + else + g_cnt++; + g_free(dump_data); + + if (g_bufinfo[i]) { + gst_evaspixmapsink_free_buffer (i); + g_bufinfo[i] = NULL; + } + evaspixmapsink->pixmap_addr[i] = NULL; + } +#endif + g_mutex_unlock (evaspixmapsink->x_lock); + } + evaspixmapsink->need_to_fill_black = FALSE; } goto SKIP_LINK; } @@ -3537,6 +3962,7 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) } goto GO_OUT_OF_FUNC; } + evaspixmapsink->need_to_fill_black = FALSE; GST_INFO_OBJECT (evaspixmapsink,"creation pixmap_id[%d]:%d success", i, pixmap_id[i]); GST_DEBUG_OBJECT (evaspixmapsink,"evas_object_width(%d),evas_object_height(%d),pixmap:%d,depth:%d", evas_object_width,evas_object_height,pixmap_id[i],DefaultDepth(dpy, DefaultScreen(dpy))); @@ -3547,12 +3973,25 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) if (evaspixmapsink->xpixmap[i]->pixmap && pixmap_id[i] != evaspixmapsink->xpixmap[i]->pixmap) { g_mutex_unlock (evaspixmapsink->x_lock); g_mutex_lock (evaspixmapsink->pixmap_ref_lock); + /* If we reset another pixmap, do below */ + if (evaspixmapsink->xpixmap[i]->prev_pixmap) { + GST_LOG_OBJECT (evaspixmapsink,"Free pixmap(%d), gc(%x), destroy previous damage(%d)", + evaspixmapsink->xpixmap[i]->prev_pixmap, evaspixmapsink->xpixmap[i]->prev_gc, evaspixmapsink->prev_damage[i]); + g_mutex_lock (evaspixmapsink->x_lock); + XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->prev_pixmap); + XFreeGC (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->prev_gc); + XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->prev_damage[i]); + XSync(evaspixmapsink->xcontext->disp, FALSE); + g_mutex_unlock (evaspixmapsink->x_lock); + evaspixmapsink->prev_damage[i] = NULL; + } evaspixmapsink->xpixmap[i]->prev_pixmap = evaspixmapsink->xpixmap[i]->pixmap; evaspixmapsink->xpixmap[i]->prev_gc = evaspixmapsink->xpixmap[i]->gc; evaspixmapsink->xpixmap[i]->pixmap = 0; evaspixmapsink->xpixmap[i]->ref = 0; evaspixmapsink->xpixmap[i]->damaged_time = 0; + g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); g_mutex_lock (evaspixmapsink->x_lock); } @@ -3561,7 +4000,7 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { /* Set pixmap id and create GC */ evaspixmapsink->xpixmap[i]->pixmap = pixmap_id[i]; - evaspixmapsink->xpixmap[i]->gc = XCreateGC(dpy, evaspixmapsink->xpixmap[i]->pixmap, 0,0); + evaspixmapsink->xpixmap[i]->gc = XCreateGC(dpy, evaspixmapsink->xpixmap[i]->pixmap, GCForeground, &gc_values_black); evaspixmapsink->xpixmap[i]->width = xw; evaspixmapsink->xpixmap[i]->height = xh; @@ -3575,11 +4014,37 @@ gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) i, evaspixmapsink->xpixmap[i]->pixmap, evaspixmapsink->xpixmap[i]->gc, i, evaspixmapsink->damage[i]); /* Fill blackcolor for the new pixmap */ - XSetForeground (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->gc, evaspixmapsink->xcontext->black); XFillRectangle (evaspixmapsink->xcontext->disp, pixmap_id[i], evaspixmapsink->xpixmap[i]->gc, 0, 0, evaspixmapsink->w, evaspixmapsink->h); GST_LOG_OBJECT (evaspixmapsink,"fill black to xpixmap[%d] with size(w:%d,h:%d)", pixmap_id[i], evaspixmapsink->w, evaspixmapsink->h); + +#ifdef DUMP_IMG + dump_w = evaspixmapsink->w + (32 - (evaspixmapsink->w%32)); // for multiples of 32 + if(g_cnt<100) + { + evaspixmapsink->pixmap_addr[i] = gst_evaspixmapsink_get_buffer(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->pixmap, dump_w, evaspixmapsink->h, i); + GST_ERROR(" pixmap[%d] addr %p (w : %d, h : %d)", g_cnt, i, evaspixmapsink->pixmap_addr[i], dump_w, evaspixmapsink->h); + sprintf(file_name, "/opt/usr/media/DUMP_%2.2d.dump", g_cnt); + + dump_data = g_malloc(dump_w * evaspixmapsink->h * 4); + memcpy (dump_data, evaspixmapsink->pixmap_addr[i], dump_w * evaspixmapsink->h * 4); + + ret = util_write_rawdata(file_name, dump_data, dump_w * evaspixmapsink->h * 4); + if (ret) { + GST_ERROR_OBJECT (evaspixmapsink, "util_write_rawdata() failed"); + } + else + g_cnt++; + g_free(dump_data); + + if (g_bufinfo[i]) { + gst_evaspixmapsink_free_buffer (i); + g_bufinfo[i] = NULL; + } + evaspixmapsink->pixmap_addr[i] = NULL; + } +#endif } XSync(dpy, FALSE); @@ -3649,7 +4114,9 @@ gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *v case PROP_SYNCHRONOUS: evaspixmapsink->synchronous = g_value_get_boolean (value); if (evaspixmapsink->xcontext) { + g_mutex_lock (evaspixmapsink->x_lock); XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous); + g_mutex_unlock (evaspixmapsink->x_lock); GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE"); } break; @@ -3799,7 +4266,7 @@ gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *v break; case PROP_VISIBLE: { - Eina_Bool r; + Eina_Bool r = EINA_FALSE; gboolean visible = g_value_get_boolean (value); GST_INFO_OBJECT (evaspixmapsink,"evaspixmapsink->visible(%d), new value of visible(%d)", evaspixmapsink->visible, visible); if (evaspixmapsink->visible != visible) { @@ -3814,11 +4281,12 @@ gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *v } } else { r = ecore_pipe_write (evaspixmapsink->epipe, &evaspixmapsink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); + if (r == EINA_FALSE) { + GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n"); + } evaspixmapsink->epipe_request_count++; } - if (r == EINA_FALSE) { - GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n"); - } + if (!visible) { int i = 0; g_mutex_lock( evaspixmapsink->flow_lock ); @@ -3985,7 +4453,9 @@ gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink) for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { if(evaspixmapsink->damage[i]) { + g_mutex_lock (evaspixmapsink->x_lock); XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage[i]); + g_mutex_unlock (evaspixmapsink->x_lock); evaspixmapsink->damage[i] = NULL; } } @@ -3997,15 +4467,28 @@ gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink) } for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { +#ifdef DUMP_IMG + if (g_bufinfo[i]) { + gst_evaspixmapsink_free_buffer (i); + g_bufinfo[i] = NULL; + } + evaspixmapsink->pixmap_addr[i] = NULL; +#endif gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap[i]); gst_evaspixmapsink_xpixmap_destroy (evaspixmapsink, evaspixmapsink->xpixmap[i]); evaspixmapsink->xpixmap[i] = NULL; } if (evaspixmapsink->eo) { evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); + evas_object_image_data_set(evaspixmapsink->eo, NULL); evaspixmapsink->eo = NULL; } + if (evaspixmapsink->epipe) { + ecore_pipe_del (evaspixmapsink->epipe); + evaspixmapsink->epipe = NULL; + } + evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = evaspixmapsink->render_rect.w = evaspixmapsink->render_rect.h = 0; evaspixmapsink->have_render_rect = FALSE; @@ -4047,17 +4530,11 @@ gst_evaspixmapsink_finalize (GObject *object) g_mutex_free (evaspixmapsink->pixmap_ref_lock); evaspixmapsink->pixmap_ref_lock = NULL; } - if (evaspixmapsink->epipe) { - ecore_pipe_del (evaspixmapsink->epipe); - evaspixmapsink->epipe = NULL; - } GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); G_OBJECT_CLASS (parent_class)->finalize (object); - MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_FILE); - MMTA_RELEASE(); } static void @@ -4074,6 +4551,10 @@ gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink) for (i = 0; i < NUM_OF_PIXMAP; i++) { evaspixmapsink->xpixmap[i] = NULL; evaspixmapsink->damage[i] = 0; +#ifdef DUMP_IMG + g_bufinfo[i] = NULL; + evaspixmapsink->pixmap_addr[i] = NULL; +#endif } evaspixmapsink->evas_pixmap_buf = NULL; @@ -4086,6 +4567,7 @@ gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink) evaspixmapsink->fps_d = 0; evaspixmapsink->video_width = 0; evaspixmapsink->video_height = 0; + evaspixmapsink->need_to_fill_black = FALSE; evaspixmapsink->x_lock = g_mutex_new (); evaspixmapsink->flow_lock = g_mutex_new (); @@ -4128,7 +4610,12 @@ gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink) evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_NONE; - MMTA_INIT(); + memset(&evaspixmapsink->src_prev, 0, sizeof (GstVideoRectangle)); + memset(&evaspixmapsink->result_prev, 0, sizeof (GstVideoRectangle)); + +#ifdef DUMP_IMG + g_cnt = 0; +#endif GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); } diff --git a/mobile/evaspixmapsink/evaspixmapsink.h b/evaspixmapsink/evaspixmapsink.h old mode 100644 new mode 100755 similarity index 97% rename from mobile/evaspixmapsink/evaspixmapsink.h rename to evaspixmapsink/evaspixmapsink.h index 9bbacca..25d8495 --- a/mobile/evaspixmapsink/evaspixmapsink.h +++ b/evaspixmapsink/evaspixmapsink.h @@ -25,7 +25,6 @@ #define __GST_EVASPIXMAPSINK_H__ #include -#include #ifdef HAVE_XSHM #include @@ -57,6 +56,8 @@ #include #include +//#define DUMP_IMG + #define MAX_PLANE_NUM 3 #define MAX_BUFFER_NUM 20 #define MAX_GEM_BUFFER_NUM (MAX_PLANE_NUM * MAX_BUFFER_NUM) @@ -141,7 +142,7 @@ struct _GstXContext { Window root; - gulong white, black; + gulong white; gint depth; gint bpp; @@ -284,6 +285,7 @@ struct _GstEvasPixmapSink { /* size of incoming video, used as the size for XvImage */ guint video_width, video_height; + gboolean need_to_fill_black; /* display sizes, used for clipping the image */ gint disp_x, disp_y; @@ -323,7 +325,7 @@ struct _GstEvasPixmapSink { gboolean visible; gint last_updated_idx; gchar update_visibility; - guint epipe_request_count; + gint epipe_request_count; /* pixmap */ gboolean do_link; @@ -340,6 +342,16 @@ struct _GstEvasPixmapSink { gint drm_fd; gem_info_t gem_info[MAX_GEM_BUFFER_NUM]; + + /* if needed combine planes data */ + gint need_combine_data; + + GstVideoRectangle src_prev; + GstVideoRectangle result_prev; + +#ifdef DUMP_IMG + void *pixmap_addr[NUM_OF_PIXMAP]; +#endif }; /* max plane count *********************************************************/ diff --git a/wearable/evaspixmapsink/xv_types.h b/evaspixmapsink/xv_types.h similarity index 100% rename from wearable/evaspixmapsink/xv_types.h rename to evaspixmapsink/xv_types.h diff --git a/wearable/gst-autogen.sh b/gst-autogen.sh similarity index 100% rename from wearable/gst-autogen.sh rename to gst-autogen.sh diff --git a/wearable/gst-plugins-ext0.10.manifest b/gst-plugins-ext0.10.manifest similarity index 100% rename from wearable/gst-plugins-ext0.10.manifest rename to gst-plugins-ext0.10.manifest diff --git a/wearable/audioeq/Makefile.am b/hlsdemux2/Makefile.am similarity index 100% rename from wearable/audioeq/Makefile.am rename to hlsdemux2/Makefile.am diff --git a/hlsdemux2/predefined_frame/blackframe_QVGA.264 b/hlsdemux2/predefined_frame/blackframe_QVGA.264 new file mode 100755 index 0000000..03e3d8a Binary files /dev/null and b/hlsdemux2/predefined_frame/blackframe_QVGA.264 differ diff --git a/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.264 b/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.264 new file mode 100755 index 0000000..068599c Binary files /dev/null and b/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.264 differ diff --git a/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.jpg b/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.jpg new file mode 100755 index 0000000..55d43b4 Binary files /dev/null and b/hlsdemux2/predefined_frame/sec_audio_fixed_qvga.jpg differ diff --git a/hlsdemux2/src/Makefile.am b/hlsdemux2/src/Makefile.am new file mode 100755 index 0000000..88525c3 --- /dev/null +++ b/hlsdemux2/src/Makefile.am @@ -0,0 +1,31 @@ + +plugin_LTLIBRARIES = libgsthlsdemux2.la + +libgsthlsdemux2_la_SOURCES = \ + m3u8.c \ + gsthlsdemux2.c + +libgsthlsdemux2_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(SOUP_CFLAGS) $(GST_APP_CFLAGS) $(CRYPTO_CFLAGS) +libgsthlsdemux2_la_LIBADD = -lgsttag-@GST_MAJORMINOR@ \ + $(GST_LIBS) $(GST_BASE_LIBS) $(SOUP_LIBS) $(GST_APP_LIBS) -lgstapp-0.10 $(CRYPTO_LIBS) +libgsthlsdemux2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -no-undefined +libgsthlsdemux2_la_LIBTOOLFLAGS = --tag=disable-static + +# headers we need but don't want installed +noinst_HEADERS = \ + gsthlsdemux2.h \ + m3u8.h + +Android.mk: Makefile.am $(BUILT_SOURCES) + androgenizer \ + -:PROJECT libgsthls -:SHARED libgsthls \ + -:TAGS eng debug \ + -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ + -:SOURCES $(libgsthls_la_SOURCES) \ + -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsthls_la_CFLAGS) \ + -:LDFLAGS $(libgsthls_la_LDFLAGS) \ + $(libgsthls_la_LIBADD) \ + -ldl \ + -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ + LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ + > $@ diff --git a/hlsdemux2/src/gsthlsdemux2.c b/hlsdemux2/src/gsthlsdemux2.c new file mode 100755 index 0000000..5ef6c0e --- /dev/null +++ b/hlsdemux2/src/gsthlsdemux2.c @@ -0,0 +1,5443 @@ +/* + * hlsdemux2 + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , Naveen Cherukuri + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include +#include +#include +#include +#include +#include +#include + +#include "gsthlsdemux2.h" + +enum +{ + PROP_0, + PROP_BITRATE_SWITCH_TOLERANCE, + PROP_FORCE_LOWER_BITRATE, + PROP_BLOCKSIZE, + PROP_LAST +}; + +#define HLS_VIDEO_CAPS \ + GST_STATIC_CAPS (\ + "video/mpeg, " \ + "mpegversion = (int) { 1, 2, 4 }, " \ + "systemstream = (boolean) FALSE; " \ + "video/x-h264,stream-format=(string)byte-stream," \ + "alignment=(string)nal;" \ + "video/x-dirac;" \ + "video/x-wmv," \ + "wmvversion = (int) 3, " \ + "format = (fourcc) WVC1" \ + ) + +#define HLS_AUDIO_CAPS \ + GST_STATIC_CAPS ( \ + "audio/mpeg, " \ + "mpegversion = (int) { 1, 4 };" \ + "audio/x-lpcm, " \ + "width = (int) { 16, 20, 24 }, " \ + "rate = (int) { 48000, 96000 }, " \ + "channels = (int) [ 1, 8 ], " \ + "dynamic_range = (int) [ 0, 255 ], " \ + "emphasis = (boolean) { FALSE, TRUE }, " \ + "mute = (boolean) { FALSE, TRUE }; " \ + "audio/x-ac3; audio/x-eac3;" \ + "audio/x-dts;" \ + "audio/x-private-ts-lpcm;" \ + "application/x-id3" \ + ) + +/* Can also use the subpicture pads for text subtitles? */ +#define HLS_SUBPICTURE_CAPS \ + GST_STATIC_CAPS ("subpicture/x-pgs; video/x-dvd-subpicture") + +static GstStaticPadTemplate hlsdemux2_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-hls")); + +static GstStaticPadTemplate hlsdemux2_videosrc_template = +GST_STATIC_PAD_TEMPLATE ("video", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + HLS_VIDEO_CAPS); + +static GstStaticPadTemplate hlsdemux2_audiosrc_template = +GST_STATIC_PAD_TEMPLATE ("audio", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + HLS_AUDIO_CAPS); + +static GstStaticPadTemplate hlsdemux2_subpicture_template = +GST_STATIC_PAD_TEMPLATE ("subpicture", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + HLS_SUBPICTURE_CAPS); + +static GstStaticPadTemplate hlsdemux2_private_template = +GST_STATIC_PAD_TEMPLATE ("private", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); + +GST_DEBUG_CATEGORY_STATIC (gst_hlsdemux2_debug); +#define GST_CAT_DEFAULT gst_hlsdemux2_debug + +GST_DEBUG_CATEGORY (hlsdemux2_m3u8_debug); + +static const float update_interval_factor[] = { 1, 0.5, 1.5, 3 }; + +#define HLS_DEFAULT_FRAME_DURATION (0.04 * GST_SECOND) // 40ms +#define DEFAULT_BLOCKSIZE (8 * 1024) // 8 kbytes +#define DEFAULT_FAST_SWITCH_BUFFER_SIZE 0.7 // factor +static void _do_init (GType type) +{ + GST_DEBUG_CATEGORY_INIT (gst_hlsdemux2_debug, "hlsdemux2", 0, "hlsdemux2 element"); + GST_DEBUG_CATEGORY_INIT (hlsdemux2_m3u8_debug, "hlsdemux2m3u8", 0, "m3u8 parser"); +} + +GST_BOILERPLATE_FULL (GstHLSDemux2, gst_hlsdemux2, GstElement, GST_TYPE_ELEMENT, _do_init); + +#define DEFAULT_BITRATE_SWITCH_TOLERANCE 0.4 +#define DEFAULT_FAILED_COUNT 3 +#define DEFAULT_TARGET_DURATION 10 +#define DEFAULT_NUM_FRAGMENTS_CACHE 3 +#define DEFAULT_TOTAL_CACHE_DURATION (DEFAULT_NUM_FRAGMENTS_CACHE * DEFAULT_TARGET_DURATION * GST_SECOND) + +#define PREDEFINED_VIDEO_FRAME_LOCATION "/usr/etc/sec_audio_fixed_qvga.264" +//#define PREDEFINED_VIDEO_FRAME_LOCATION "/usr/etc/blackframe_QVGA.264" +#define PREDEFINED_IMAGE_FRAME_LOCATION "/usr/etc/sec_audio_fixed_qvga.jpg" + +#define HLSDEMUX2_SOUP_FAILED_CNT 10 +#define DEFAULT_FORCE_LOWER_BITRATE FALSE +#define FORCE_LOW_BITRATE_AFTER_CNT 4 +#define HLSDEMUX2_HTTP_TIMEOUT 30 //30sec + +enum { + HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE = 0, + HLSDEMUX2_HTTP_ERROR_RECOVERABLE = 1, +}; + +typedef struct _HLSDemux2_HTTP_error HLSDemux2_HTTP_error; + +typedef gboolean (*HLS_HTTP_error_handle_function) (GstHLSDemux2 *demux, gchar *element_name); + +struct _HLSDemux2_HTTP_error { + guint HTTP_error_code; + const gchar *error_phrase; + guint error_type; + HLS_HTTP_error_handle_function handle_error; +}; + +struct _GstHLSDemux2PvtStream +{ + void *parent; + GstPad *sinkpad; + GstElement *sink; + gulong sink_eprobe; + gulong sink_bprobe; + HLSDEMUX2_STREAM_TYPE type; + GValue codec_type; + GstBuffer *id3_buffer; + GstBuffer *image_buffer; + GstBuffer *video_buffer; + gboolean got_img_buffer; + GstElement *convert_pipe; + GCond *img_load_cond; + GMutex *img_load_lock; + GCond *convert_cond; + GMutex *convert_lock; +}; + +struct _GstHLSDemux2Stream +{ + void *parent; + GstPad *pad; + GQueue *queue; + GMutex *queue_lock; + GCond *queue_full; + GCond *queue_empty; + gint64 percent; + HLSDEMUX2_STREAM_TYPE type; + gboolean is_linked; + gboolean eos; + gboolean apply_disc; + gint64 cached_duration; + GThread *dummy_data_thread; /* for pushing dummy video data */ + GstClockTime base_ts; /* base ts start */ + GstClockTime fts; /* first valid timestamp in a fragment */ + GstClockTime lts; /* last valid timestamp in a fragment */ + /* expected first timestamp in next fragment : usefule for handling fragments discontinuities*/ + GstClockTime nts; + GstClockTime prev_nts; /* stores last nts for handling .aac files */ + gboolean valid_fts_rcvd; + GstClockTime cdisc; /* current disc time */ + GstClockTime frame_duration; + guint64 total_stream_time; + GstClockTime total_disc; + GQueue *downloader_queue; + gboolean need_newsegment; + GstEvent *newsegment; +}; + +/* GStreamer virtual functions */ +static void gst_hlsdemux2_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_hlsdemux2_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static gboolean gst_hlsdemux2_sink_event (GstPad * pad, GstEvent * event); +static GstStateChangeReturn gst_hlsdemux2_change_state (GstElement * element, GstStateChange transition); +static void gst_hlsdemux2_dispose (GObject * obj); +static GstFlowReturn gst_hlsdemux2_chain (GstPad * pad, GstBuffer * buf); +static gboolean gst_hlsdemux2_handle_src_event (GstPad * pad, GstEvent * event); + +/* init & de-init functions */ +static void gst_hlsdemux2_private_init (GstHLSDemux2 *demux); +static void gst_hlsdemux2_private_deinit (GstHLSDemux2 *demux); +static void gst_hlsdemux2_playlist_downloader_init (GstHLSDemux2 *demux); +static void gst_hlsdemux2_playlist_downloader_deinit (GstHLSDemux2 *demux); +static void gst_hlsdemux2_key_downloader_init (GstHLSDemux2 *demux); +static void gst_hlsdemux2_key_downloader_deinit (GstHLSDemux2 *demux); +static void gst_hlsdemux2_fragment_downloader_init (GstHLSDemux2 *demux); +static void gst_hlsdemux2_fragment_downloader_deinit (GstHLSDemux2 *demux); + +/* helper functions */ +static void gst_hlsdemux2_stop (GstHLSDemux2 * demux); +static gboolean gst_hlsdemux2_set_location (GstHLSDemux2 * demux, const gchar * uri); +static gchar *gst_hlsdemux2_src_buf_to_utf8_playlist (GstBuffer * buf); +static void gst_hlsdemux2_new_pad_added (GstElement *element, GstPad *pad, gpointer data); +static void gst_hlsdemux2_get_cookies(GstHLSDemux2 *demux); +static void gst_hlsdemux2_get_user_agent(GstHLSDemux2 *demux); +static gboolean gst_hlsdemux2_update_playlist (GstHLSDemux2 * demux, gboolean update, gboolean *is_error); +static gboolean gst_hlsdemux2_schedule (GstHLSDemux2 * demux); +static void gst_hlsdemux2_calculate_pushed_duration (GstHLSDemux2 *demux, GstHLSDemux2Stream *stream, + GstBuffer *inbuf); + +/* stream specific functions */ +static void gst_hlsdemux2_stream_init (GstHLSDemux2 *demux, GstHLSDemux2Stream *stream, + HLSDEMUX2_STREAM_TYPE stream_type, gchar *name, GstCaps *src_caps); +static void gst_hlsdemux2_stream_deinit (GstHLSDemux2Stream *stream, gpointer data); +static void gst_hlsdemux2_stop_stream (GstHLSDemux2 *demux); +static HLSDemux2SinkBin *gst_hlsdemux2_create_stream (GstHLSDemux2 *demux, gchar *name, GstCaps *caps); + +/* task functions */ +static void gst_hlsdemux2_push_loop (GstHLSDemux2Stream *stream); +static void gst_hlsdemux2_fragment_download_loop (GstHLSDemux2 * demux); + +/* playlist download related functions */ +static void gst_hlsdemux2_on_playlist_buffer (GstElement * appsink, void* data); +static GstBusSyncReply gst_hlsdemux2_playlist_download_bus_sync_cb (GstBus * bus, GstMessage *msg, gpointer data); + +/* key file download related functions */ +static gboolean gst_hlsdemux2_key_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data); +static void gst_hlsdemux2_on_key_buffer (GstElement *appsink, void *data); + +/* fragment download related functions */ +static gboolean gst_hlsdemux2_fragment_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data); +static void gst_hlsdemux2_downloader_new_buffer (GstElement *appsink, void *user_data); +static void gst_hlsdemux2_downloader_eos (GstElement * appsink, void* user_data); + +/* probe functions */ +static gboolean gst_hlsdemux2_sink_event_handler (GstPad * pad, GstEvent * event, gpointer data); +static gboolean gst_hlsdemux2_change_playlist (GstHLSDemux2 * demux, guint max_bitrate, gboolean *is_switched); +static gboolean gst_hlsdemux2_download_monitor_thread (GstHLSDemux2 *demux); +static void gst_hlsdemux2_push_eos (GstHLSDemux2 *demux); +static void gst_hlsdemux2_apply_disc (GstHLSDemux2 * demux); +static gboolean gst_hlsdemux2_queue_buffer_handler (GstPad * pad, GstBuffer *buffer, gpointer data); +static gboolean hlsdemux2_HTTP_not_found(GstHLSDemux2 *demux, gchar *element_name); +static gboolean hlsdemux2_HTTP_time_out (GstHLSDemux2 *demux, gchar *element_name); +static gboolean hlsdemux2_HTTP_repeat_request (GstHLSDemux2 *demux, gchar *element_name); +static void gst_hlsdemux2_handle_private_pad (GstHLSDemux2 *demux, GstPad *srcpad); +static void gst_hlsdemux2_private_sink_on_new_buffer (GstElement *appsink, void *user_data); +static void gst_hlsdemux2_private_sink_on_eos (GstElement * appsink, void* user_data); +static gboolean gst_hlsdemux2_imagebuf_pipe_bus_cb (GstBus *bus, GstMessage *msg, gpointer data); +static gboolean gst_hlsdemux2_set_video_buffer (GstPad * srcpad, GstBuffer * buffer, gpointer user_data); +static gboolean gst_hlsdemux2_done_video_buffer (GstPad * srcpad, GstEvent * event, gpointer user_data); +static gboolean gst_hlsdemux2_check_fast_switch (GstHLSDemux2 *demux); + +static const HLSDemux2_HTTP_error http_errors[] = { + + /* transport errors by libsoup */ + { 1, "Cancelled", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 2, "Cannot resolve hostname", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 3, "Cannot resolve proxy hostname", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 4, "Cannot connect to destination", HLSDEMUX2_HTTP_ERROR_RECOVERABLE, hlsdemux2_HTTP_repeat_request }, + { 5, "Cannot connect to proxy", HLSDEMUX2_HTTP_ERROR_RECOVERABLE, hlsdemux2_HTTP_repeat_request }, + { 6, "SSL handshake failed", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 7, "Connection terminated unexpectedly", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 8, "Message Corrupt", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 9, "Too many redirects", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + + /* Client error */ + { 400, "Bad Request", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 401, "Unauthorized", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 402, "Payment Required", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 403, "Forbidden", HLSDEMUX2_HTTP_ERROR_RECOVERABLE, hlsdemux2_HTTP_repeat_request }, // TODO: Currently taking it as recoverable for testing + { 404, "Not Found", HLSDEMUX2_HTTP_ERROR_RECOVERABLE, hlsdemux2_HTTP_not_found }, + { 405, "Method Not Allowed", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 406, "Not Acceptable", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 407, "Proxy Authentication Required", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 408, "Request Timeout", HLSDEMUX2_HTTP_ERROR_RECOVERABLE, hlsdemux2_HTTP_time_out }, + { 409, "Conflict", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 410, "Gone", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 411, "Length Required", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 412, "Precondition Failed", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 413, "Request Entity Too Large", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 414, "Request-URI Too Long", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 415, "Unsupported Media Type", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 416, "Requested Range Not Satisfiable", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 417, "Expectation Failed", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 418, "Unprocessable Entity", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 419, "Locked", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 420, "Failed Dependency", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + + /* Server error */ + { 500, "Internal Server Error", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 501, "Not Implemented", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 502, "Bad Gateway", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 503, "Service Unavailable", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, // TODO: need to make as recoverable with timout value + { 504, "Gateway Timeout", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 505, "HTTP Version Not Supported", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 506, "Insufficient Storage", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, + { 507, "Not Extended", HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE, NULL }, +}; + + +static void +gst_hlsdemux2_base_init (gpointer g_class) +{ + GstElementClass *element_class= GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&hlsdemux2_videosrc_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&hlsdemux2_audiosrc_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&hlsdemux2_subpicture_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&hlsdemux2_sink_template)); + + gst_element_class_set_details_simple (element_class, + "HLS Demuxer2", + "Demuxer/URIList", + "HTTP Live Streaming (HLS) demuxer", + "Naveen Cherukuri"); +} + +static void +gst_hlsdemux2_class_init (GstHLSDemux2Class * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_hlsdemux2_set_property; + gobject_class->get_property = gst_hlsdemux2_get_property; + gobject_class->dispose = gst_hlsdemux2_dispose; + + g_object_class_install_property (gobject_class, PROP_BITRATE_SWITCH_TOLERANCE, + g_param_spec_float ("bitrate-switch-tolerance", + "Bitrate switch tolerance", + "Tolerance with respect of the fragment duration to switch to " + "a different bitrate if the client is too slow/fast.", + 0, 1, DEFAULT_BITRATE_SWITCH_TOLERANCE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_FORCE_LOWER_BITRATE, + g_param_spec_boolean ("force-low-bitrate", + "forcing lower variant", "forcing lower variant after every few fragments [for debugging purpose only]", + DEFAULT_FORCE_LOWER_BITRATE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_BLOCKSIZE, + g_param_spec_ulong ("blocksize", "Block size", + "Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG, + DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_hlsdemux2_change_state); +} + +static void +gst_hlsdemux2_init (GstHLSDemux2 * demux, GstHLSDemux2Class * klass) +{ + /* sink pad */ + demux->sinkpad = gst_pad_new_from_static_template (&hlsdemux2_sink_template, "sink"); + gst_pad_set_chain_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hlsdemux2_chain)); + gst_pad_set_event_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_hlsdemux2_sink_event)); + gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); + + gst_hlsdemux2_private_init (demux); + + /* fragment downloader init */ + gst_hlsdemux2_fragment_downloader_init (demux); + + /* playlist downloader init */ + gst_hlsdemux2_playlist_downloader_init (demux); + + /* key downloader init */ + gst_hlsdemux2_key_downloader_init (demux); + +} + +static void +gst_hlsdemux2_dispose (GObject * obj) +{ + GstHLSDemux2 *demux = GST_HLSDEMUX2 (obj); + + GST_INFO_OBJECT (demux,"entering"); + + gst_hlsdemux2_stop (demux); + + gst_hlsdemux2_private_deinit (demux); + + gst_hlsdemux2_fragment_downloader_deinit (demux); + + gst_hlsdemux2_playlist_downloader_deinit (demux); + + gst_hlsdemux2_key_downloader_deinit (demux); + + GST_INFO_OBJECT (demux,"leaving"); + + G_OBJECT_CLASS (parent_class)->dispose (obj); +} + +static void +gst_hlsdemux2_private_init (GstHLSDemux2 *demux) +{ + demux->is_live = TRUE; + demux->bitrate_switch_tol = DEFAULT_BITRATE_SWITCH_TOLERANCE; + demux->percent = 100; + demux->active_stream_cnt = 0; + demux->download_task = NULL; + demux->pl_update_lock = g_mutex_new (); + demux->pl_update_cond = g_cond_new (); + demux->cancelled = FALSE; + demux->total_cache_duration = DEFAULT_TOTAL_CACHE_DURATION; + demux->target_duration = DEFAULT_TARGET_DURATION; + demux->keyCookie = NULL; + demux->playlistCookie = NULL; + demux->fragCookie = NULL; + demux->lastCookie = NULL; + demux->keyDomain = NULL; + demux->playlistDomain = NULL; + demux->fragDomain = NULL; + demux->lastDomain = NULL; + demux->user_agent = NULL; + demux->buffering_lock = g_mutex_new (); + demux->soup_request_fail_cnt = HLSDEMUX2_SOUP_FAILED_CNT; + demux->force_lower_bitrate = DEFAULT_FORCE_LOWER_BITRATE; + demux->cfrag_dur = 0; + demux->error_posted = FALSE; + demux->playlist_uri = NULL; + demux->frag_uri = NULL; + demux->key_uri = NULL; + demux->blocksize = DEFAULT_BLOCKSIZE; + demux->flushing = FALSE; + demux->ns_start = 0; + demux->cur_audio_fts = GST_CLOCK_TIME_NONE; + demux->is_buffering = TRUE; + demux->buffering_posting_thread = NULL; + demux->post_msg_lock = g_mutex_new (); + demux->post_msg_start = g_cond_new (); + demux->post_msg_exit = g_cond_new (); + demux->stream_config = HLSDEMUX2_SINGLE_VARIANT; + demux->has_image_buffer = FALSE; + demux->prev_image_buffer = NULL; + demux->prev_video_buffer = NULL; + demux->private_stream = NULL; +} + +static void +gst_hlsdemux2_private_deinit (GstHLSDemux2 *demux) +{ + demux->end_of_playlist = FALSE; + + if (demux->pl_update_lock) { + g_mutex_free (demux->pl_update_lock); + demux->pl_update_lock = NULL; + } + + if (demux->pl_update_cond) { + g_cond_free (demux->pl_update_cond); + demux->pl_update_cond = NULL; + } + + if (demux->buffering_lock) { + g_mutex_free (demux->buffering_lock); + demux->buffering_lock = NULL; + } + + if (demux->user_agent) { + g_free (demux->user_agent); + demux->user_agent = NULL; + } + + if (demux->playlist) { + gst_buffer_unref (demux->playlist); + demux->playlist = NULL; + } + + if (demux->fragCookie) { + g_strfreev (demux->fragCookie); + demux->fragCookie = NULL; + } + + if (demux->keyCookie) { + g_strfreev (demux->keyCookie); + demux->keyCookie = NULL; + } + + if (demux->lastCookie) { + g_strfreev (demux->lastCookie); + demux->lastCookie = NULL; + } + + if (demux->playlistCookie) { + g_strfreev (demux->playlistCookie); + demux->playlistCookie = NULL; + } + + if (demux->fragDomain) { + g_free (demux->fragDomain); + demux->fragDomain = NULL; + } + + if (demux->keyDomain) { + g_free (demux->keyDomain); + demux->keyDomain = NULL; + } + + if (demux->lastDomain) { + g_free (demux->lastDomain); + demux->lastDomain = NULL; + } + + if (demux->playlistDomain) { + g_free (demux->playlistDomain); + demux->playlistDomain = NULL; + } + + if (demux->playlist_uri) { + g_free (demux->playlist_uri); + demux->playlist_uri = NULL; + } + + if (demux->key_uri) { + g_free (demux->key_uri); + demux->key_uri = NULL; + } + + if (demux->frag_uri) { + g_free (demux->frag_uri); + demux->frag_uri = NULL; + } + + if (demux->prev_image_buffer) { + gst_buffer_unref (demux->prev_image_buffer); + demux->prev_image_buffer = NULL; + } + + if (demux->prev_video_buffer) { + gst_buffer_unref (demux->prev_video_buffer); + demux->prev_video_buffer = NULL; + } + + if (demux->private_stream) { + g_free (demux->private_stream); + demux->private_stream = NULL; + } + + if (demux->client) { + gst_m3u8_client_free (demux->client); + demux->client = NULL; + } +} + +static void +gst_hlsdemux2_fragment_downloader_init (GstHLSDemux2 *demux) +{ + demux->fdownloader = g_new0 (HLSDemux2FragDownloader, 1); + demux->fdownloader->pipe = NULL; + demux->fdownloader->urisrc = NULL; + demux->fdownloader->queue = NULL; + demux->fdownloader->typefind = NULL; + demux->fdownloader->demuxer = NULL; + demux->fdownloader->sinkbins = NULL; + demux->fdownloader->lock = g_mutex_new (); + demux->fdownloader->cond = g_cond_new (); + demux->fdownloader->is_encrypted = FALSE; + demux->fdownloader->content_size = 0; + demux->fdownloader->get_next_frag = FALSE; + demux->fdownloader->applied_fast_switch = FALSE; + demux->fdownloader->remaining_data = NULL; + demux->fdownloader->remaining_size = 0; + demux->fdownloader->first_buffer = TRUE; + demux->fdownloader->cur_stream_cnt = 0; + demux->fdownloader->force_timestamps = FALSE; + demux->fdownloader->error_rcvd = FALSE; + demux->fdownloader->find_mediaseq = FALSE; + demux->fdownloader->seeked_pos = 0; + demux->fdownloader->cur_running_dur = 0; + demux->fdownloader->download_rate = -1; + demux->fdownloader->download_start_ts = 0; + demux->fdownloader->download_stop_ts = 0; + demux->fdownloader->src_downloaded_size = 0; + demux->fdownloader->queue_downloaded_size = 0; + demux->fdownloader->ndownloaded = 0; + demux->fdownloader->chunk_downloaded_size = 0; + demux->fdownloader->chunk_start_ts = 0; + demux->fdownloader->avg_chunk_drates = g_array_new(FALSE, TRUE, sizeof(guint64)); + demux->fdownloader->avg_frag_drates = g_array_new(FALSE, TRUE, sizeof(guint64)); +} + +static void +gst_hlsdemux2_fragment_downloader_deinit (GstHLSDemux2 *demux) +{ + if (!demux->fdownloader) + return; + + /* free fragment downloader structure */ + if (demux->fdownloader->lock) { + g_mutex_free (demux->fdownloader->lock); + demux->fdownloader->lock = NULL; + } + + if (demux->fdownloader->cond) { + g_cond_free (demux->fdownloader->cond); + demux->fdownloader->cond = NULL; + } + + if (demux->fdownloader->remaining_data) { + g_free (demux->fdownloader->remaining_data); + demux->fdownloader->remaining_data = NULL; + } + + if (demux->fdownloader->avg_chunk_drates) { + g_array_free(demux->fdownloader->avg_chunk_drates, TRUE); + demux->fdownloader->avg_chunk_drates = NULL; + } + + if (demux->fdownloader->avg_frag_drates) { + g_array_free(demux->fdownloader->avg_frag_drates, TRUE); + demux->fdownloader->avg_frag_drates = NULL; + } + + g_free (demux->fdownloader); + demux->fdownloader = NULL; +} + +static void +gst_hlsdemux2_playlist_downloader_init (GstHLSDemux2 *demux) +{ + demux->pldownloader = g_new0 (HLSDemux2PLDownloader, 1); + demux->pldownloader->pipe = NULL; + demux->pldownloader->bus = NULL; + demux->pldownloader->urisrc = NULL; + demux->pldownloader->sink = NULL; + demux->pldownloader->lock = g_mutex_new (); + demux->pldownloader->cond = g_cond_new (); + demux->pldownloader->playlist = NULL; + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; +} + +static void +gst_hlsdemux2_playlist_downloader_deinit (GstHLSDemux2 *demux) +{ + if (!demux->pldownloader) + return; + + /* free playlist downloader structure */ + if (demux->pldownloader->lock) { + g_mutex_free (demux->pldownloader->lock); + demux->pldownloader->lock = NULL; + } + + if (demux->pldownloader->cond) { + g_cond_free (demux->pldownloader->cond); + demux->pldownloader->cond = NULL; + } + + if (demux->pldownloader->playlist){ + gst_buffer_unref (demux->pldownloader->playlist); + demux->pldownloader->playlist = NULL; + } + + g_free (demux->pldownloader); + demux->pldownloader = NULL; +} + +static void +gst_hlsdemux2_key_downloader_init (GstHLSDemux2 *demux) +{ + demux->kdownloader = g_new0 (HLSDemux2KeyDownloader, 1); + demux->kdownloader->pipe = NULL; + demux->kdownloader->bus = NULL; + demux->kdownloader->urisrc = NULL; + demux->kdownloader->sink = NULL; + demux->kdownloader->lock = g_mutex_new (); + demux->kdownloader->cond = g_cond_new (); + demux->kdownloader->key = NULL; + demux->kdownloader->prev_key_uri = NULL; +} + +static void +gst_hlsdemux2_key_downloader_deinit (GstHLSDemux2 *demux) +{ + /* free key file downloader structure */ + if (!demux->kdownloader) + return; + + if (demux->kdownloader->lock) { + g_mutex_free (demux->kdownloader->lock); + demux->kdownloader->lock = NULL; + } + + if (demux->kdownloader->cond) { + g_cond_free (demux->kdownloader->cond); + demux->kdownloader->cond = NULL; + } + + if (demux->kdownloader->key){ + gst_buffer_unref (demux->kdownloader->key); + demux->kdownloader->key = NULL; + } + + if (demux->kdownloader->prev_key_uri) { + g_free (demux->kdownloader->prev_key_uri); + demux->kdownloader->prev_key_uri = NULL; + } + + g_free (demux->kdownloader); + demux->kdownloader = NULL; +} + +static void +gst_hlsdemux2_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstHLSDemux2 *demux = GST_HLSDEMUX2 (object); + + switch (prop_id) { + case PROP_BITRATE_SWITCH_TOLERANCE: + demux->bitrate_switch_tol = g_value_get_float (value); + break; + case PROP_FORCE_LOWER_BITRATE: + demux->force_lower_bitrate = g_value_get_boolean (value); + break; + case PROP_BLOCKSIZE: + demux->blocksize = g_value_get_ulong (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_hlsdemux2_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstHLSDemux2 *demux = GST_HLSDEMUX2 (object); + + switch (prop_id) { + case PROP_BITRATE_SWITCH_TOLERANCE: + g_value_set_float (value, demux->bitrate_switch_tol); + break; + case PROP_FORCE_LOWER_BITRATE: + g_value_set_boolean (value, demux->force_lower_bitrate); + break; + case PROP_BLOCKSIZE: + g_value_set_ulong (value, demux->blocksize); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_hlsdemux2_sink_event (GstPad * pad, GstEvent * event) +{ + GstHLSDemux2 *demux = GST_HLSDEMUX2 (gst_pad_get_parent (pad)); + GstQuery *query = NULL; + gboolean ret = FALSE; + gchar *uri = NULL; + + GST_LOG_OBJECT (demux, "Received event '%s' on sink pad...", GST_EVENT_TYPE_NAME (event)); + + switch (event->type) { + case GST_EVENT_EOS: { + gchar *playlist = NULL; + GError *err = NULL; + + if (demux->playlist == NULL) { + GST_ERROR_OBJECT (demux, "Received EOS without a playlist."); + goto error; + } + + GST_INFO_OBJECT (demux, "Got EOS on the sink pad: playlist file fetched"); + + query = gst_query_new_uri (); + + /* query the location from upstream element for absolute path */ + ret = gst_pad_peer_query (demux->sinkpad, query); + if (ret) { + gst_query_parse_uri (query, &uri); + gst_hlsdemux2_set_location (demux, uri); + g_free (uri); + } else { + GST_ERROR_OBJECT (demux, "failed to query URI from upstream"); + goto error; + } + gst_query_unref (query); + query = NULL; + + /* get cookies from upstream httpsrc */ + gst_hlsdemux2_get_cookies (demux); + + /* get user-agent from upstream httpsrc */ + gst_hlsdemux2_get_user_agent (demux); + + playlist = gst_hlsdemux2_src_buf_to_utf8_playlist (demux->playlist); + demux->playlist = NULL; + + if (playlist == NULL) { + GST_ERROR_OBJECT (demux, "Error validating first playlist."); + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), (NULL)); + goto error; + } + + if (!gst_m3u8_client_update (demux->client, playlist)) { + /* In most cases, this will happen if we set a wrong url in the + * source element and we have received the 404 HTML response instead of + * the playlist */ + GST_ERROR_OBJECT (demux, "failed to parse playlist..."); + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), (NULL)); + goto error; + } + + /* Loop to download the fragments & updates playlist */ + g_static_rec_mutex_init (&demux->download_lock); + demux->download_task = gst_task_create ((GstTaskFunction) gst_hlsdemux2_fragment_download_loop, demux); + if (NULL == demux->download_task) { + GST_ERROR_OBJECT (demux, "failed to create download task..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to fragment download task"), (NULL)); + goto error; + } + gst_task_set_lock (demux->download_task, &demux->download_lock); + gst_task_start (demux->download_task); + + /* create thread to send dummy data */ + demux->buffering_posting_thread = g_thread_create ( + (GThreadFunc) gst_hlsdemux2_download_monitor_thread, demux, TRUE, &err); + + /* Swallow EOS, we'll push our own */ + gst_event_unref (event); + gst_object_unref (demux); + return TRUE; + } + case GST_EVENT_NEWSEGMENT: + /* Swallow newsegments, we'll push our own */ + gst_event_unref (event); + gst_object_unref (demux); + return TRUE; + default: + gst_object_unref (demux); + break; + } + + return gst_pad_event_default (pad, event); + +error: + gst_hlsdemux2_stop (demux); + gst_event_unref (event); + gst_object_unref (demux); + + if (query) + gst_query_unref (query); + + GST_LOG_OBJECT (demux,"Returning from sink event..."); + return FALSE; +} + +static GstStateChangeReturn + gst_hlsdemux2_change_state (GstElement * element, GstStateChange transition) + { + GstStateChangeReturn ret; + GstHLSDemux2 *demux = GST_HLSDEMUX2 (element); + gboolean bret = FALSE; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + GST_INFO_OBJECT (demux,"PAUSED->PLAYING"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT (demux,"PAUSED->READY before parent"); + gst_hlsdemux2_stop (demux); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_INFO_OBJECT (demux,"PLAYING->PAUSED"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT (demux,"PAUSED->READY after parent"); + if (demux->download_task) { + bret = gst_task_join (demux->download_task); + GST_DEBUG_OBJECT (demux,"Joining download task : %d", bret); + } + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_INFO_OBJECT (demux,"READY->NULL"); + break; + default: + break; + } + return ret; + } + + + +static GstFlowReturn +gst_hlsdemux2_chain (GstPad * pad, GstBuffer * buf) +{ + GstHLSDemux2 *demux = GST_HLSDEMUX2 (gst_pad_get_parent (pad)); + + if (demux->playlist == NULL) + demux->playlist = buf; + else + demux->playlist = gst_buffer_join (demux->playlist, buf); + gst_object_unref (demux); + + return GST_FLOW_OK; +} + +static gboolean +gst_hlsdemux2_handle_src_event (GstPad * pad, GstEvent * event) +{ + GstHLSDemux2 *hlsdemux2 = NULL; + GstHLSDemux2Stream *stream = NULL; + + stream = (GstHLSDemux2Stream *) (gst_pad_get_element_private (pad)); + hlsdemux2 = stream->parent; + + switch (event->type) { + case GST_EVENT_SEEK: { + gdouble rate; + GstFormat format; + GstSeekFlags flags; + GstSeekType start_type, stop_type; + gint64 start, stop; + gint idx = 0; + + if (gst_m3u8_client_is_live (hlsdemux2->client)) { + GST_WARNING_OBJECT (stream->pad, "SEEK is NOT Supported in LIVE"); + return FALSE; + } + + GST_INFO_OBJECT (stream->pad, "received SEEK event.."); + + gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, + &stop_type, &stop); + + if (format != GST_FORMAT_TIME) { + GST_WARNING_OBJECT (stream->pad, "received seek with unsupported format"); + return FALSE; + } + + // TODO: Validate requested SEEK time is within the duration or not + + hlsdemux2->end_of_playlist = FALSE; // resent end of playlist + + GST_DEBUG_OBJECT (stream->pad, "SEEK event with rate: %f start: %" GST_TIME_FORMAT + " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start), + GST_TIME_ARGS (stop)); + + if (!(flags & GST_SEEK_FLAG_FLUSH)) { + GST_WARNING_OBJECT (stream->pad, "non-flush seek is not supported yet"); + return FALSE; + } + + hlsdemux2->flushing = TRUE; + + /* signal queue full condition to come out */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream) { + cur_stream->eos = FALSE; // resent stream EOS + if (cur_stream->queue) { + GST_INFO_OBJECT (cur_stream->pad, "signalling stream queue"); + g_cond_signal (cur_stream->queue_full); /* to signal downloader eos blocking */ + g_cond_signal (cur_stream->queue_empty); /* incase push_loop blocked on condition */ + } + } + } + + /* send FLUSH_START event to all source pads */ + if (flags & GST_SEEK_FLAG_FLUSH) { + + GST_INFO_OBJECT (hlsdemux2, "sending flush start on all the stream pads"); + + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream && GST_PAD_TASK(cur_stream->pad)) { + gboolean bret = FALSE; + bret = gst_pad_push_event (cur_stream->pad, gst_event_new_flush_start ()); + GST_DEBUG_OBJECT (cur_stream->pad, "flush_start returned = %d", bret); + } + } + } + + /* wait till all stream pad's task paused */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream && GST_PAD_TASK(cur_stream->pad)) { + GST_INFO_OBJECT (cur_stream->pad, "trying acquire stream lock"); + GST_PAD_STREAM_LOCK (cur_stream->pad); + GST_INFO_OBJECT (cur_stream->pad, "acquired stream lock"); + GST_PAD_STREAM_UNLOCK (cur_stream->pad); + } + } + + /* pause fragment download loop */ + g_mutex_lock (hlsdemux2->kdownloader->lock); + GST_INFO_OBJECT (stream->pad, "Signalling key downloader condition"); + g_cond_signal (hlsdemux2->kdownloader->cond); + g_mutex_unlock (hlsdemux2->kdownloader->lock); + + g_mutex_lock (hlsdemux2->fdownloader->lock); + GST_INFO_OBJECT (stream->pad, "Signalling fragment downloader condition"); + g_cond_signal (hlsdemux2->fdownloader->cond); + g_mutex_unlock (hlsdemux2->fdownloader->lock); + + g_mutex_lock (hlsdemux2->pldownloader->lock); + GST_INFO_OBJECT (stream->pad, "Signalling playlist downloader condition"); + g_cond_signal (hlsdemux2->pldownloader->cond); + g_mutex_unlock (hlsdemux2->pldownloader->lock); + + GST_INFO_OBJECT (stream->pad, "waiting for download task to pause..."); + g_static_rec_mutex_lock (&hlsdemux2->download_lock); + g_static_rec_mutex_unlock (&hlsdemux2->download_lock); + + GST_INFO_OBJECT (hlsdemux2, "Download task paused"); + + /* clear internal stream queues */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream && cur_stream->queue) { + while (!g_queue_is_empty (cur_stream->queue)) { + gpointer data = NULL; + data = g_queue_pop_head (cur_stream->queue); + gst_object_unref (data); + } + g_queue_clear (cur_stream->queue); + cur_stream->cached_duration = 0; + stream->percent = 0; + + while (!g_queue_is_empty (cur_stream->downloader_queue)) { + gpointer data = NULL; + data = g_queue_pop_head (cur_stream->downloader_queue); + gst_object_unref (data); + } + g_queue_clear (cur_stream->downloader_queue); + } + } + +#if 0 /* useful when we want to switch to lowest variant on seek for faster buffering */ + if (gst_m3u8_client_has_variant_playlist (hlsdemux2->client)) { + /* intentionally sending zero download rate, to move to least possible variant */ + gst_hlsdemux2_change_playlist (hlsdemux2, 0, NULL); + } +#endif + + /* send FLUSH_STOP event to all source pads */ + if (flags & GST_SEEK_FLAG_FLUSH) { + + GST_INFO_OBJECT (hlsdemux2, "sending flush stop"); + + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream && GST_PAD_TASK(cur_stream->pad)) { + gboolean bret = FALSE; + bret = gst_pad_push_event (cur_stream->pad, gst_event_new_flush_stop ()); + GST_DEBUG_OBJECT (cur_stream->pad, "flush_stop returned = %d", bret); + } + } + } + + hlsdemux2->flushing = FALSE; + hlsdemux2->fdownloader->find_mediaseq = TRUE; + hlsdemux2->fdownloader->seeked_pos = start; + + /* start all streams loop tasks & fragment download task */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = hlsdemux2->streams[idx]; + + if (cur_stream && GST_PAD_TASK(cur_stream->pad)) { + GST_INFO_OBJECT (cur_stream->pad, "Starting push task"); + cur_stream->need_newsegment = TRUE; + cur_stream->nts = GST_CLOCK_TIME_NONE; /*useful for audio-only seeking */ + cur_stream->cdisc = 0; + cur_stream->fts = GST_CLOCK_TIME_NONE; + cur_stream->valid_fts_rcvd = FALSE; + cur_stream->total_stream_time = 0; + + if (!gst_pad_start_task (cur_stream->pad, (GstTaskFunction) gst_hlsdemux2_push_loop, cur_stream)) { + GST_ERROR_OBJECT (hlsdemux2, "failed to start stream task..."); + GST_ELEMENT_ERROR (hlsdemux2, RESOURCE, FAILED, ("failed to create stream push loop"), (NULL)); + goto error; + } + } + } + + gst_hlsdemux2_apply_disc (hlsdemux2); + + GST_INFO_OBJECT (hlsdemux2, "Starting Download task.."); + + gst_task_start (hlsdemux2->download_task); + + GST_INFO_OBJECT (hlsdemux2, "Successfully configured SEEK..."); + gst_event_unref (event); + return TRUE; + } + default: + break; + } + + return gst_pad_event_default (pad, event); + +error: + GST_ERROR_OBJECT (hlsdemux2, "seeking failed..."); + gst_event_unref (event); + return FALSE; +} + +static gboolean +gst_hlsdemux2_src_query (GstPad *pad, GstQuery * query) +{ + GstHLSDemux2 *hlsdemux2 = NULL; + gboolean ret = FALSE; + GstHLSDemux2Stream *stream = NULL; + + if (query == NULL) + return FALSE; + + stream = (GstHLSDemux2Stream *) (gst_pad_get_element_private (pad)); + hlsdemux2 = stream->parent; + + switch (query->type) { + case GST_QUERY_DURATION:{ + GstClockTime duration = -1; + GstFormat fmt; + + gst_query_parse_duration (query, &fmt, NULL); + if (fmt == GST_FORMAT_TIME) { + duration = gst_m3u8_client_get_duration (hlsdemux2->client); + if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) { + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + ret = TRUE; + } + } + GST_LOG_OBJECT (hlsdemux2, "GST_QUERY_DURATION returns %s with duration %" + GST_TIME_FORMAT, ret ? "TRUE" : "FALSE", GST_TIME_ARGS (duration)); + break; + } + case GST_QUERY_URI: + if (hlsdemux2->client) { + /* FIXME: Do we answer with the variant playlist, with the current + * playlist or the the uri of the least downlowaded fragment? */ + gst_query_set_uri (query, gst_m3u8_client_get_uri (hlsdemux2->client)); + ret = TRUE; + } + break; + case GST_QUERY_SEEKING:{ + GstFormat fmt; + gint64 stop = -1; + + gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); + GST_INFO_OBJECT (hlsdemux2, "Received GST_QUERY_SEEKING with format %d", + fmt); + if (fmt == GST_FORMAT_TIME) { + GstClockTime duration; + + duration = gst_m3u8_client_get_duration (hlsdemux2->client); + if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) + stop = duration; + + gst_query_set_seeking (query, fmt, + !gst_m3u8_client_is_live (hlsdemux2->client), 0, stop); + ret = TRUE; + GST_INFO_OBJECT (hlsdemux2, "GST_QUERY_SEEKING returning with stop : %" + GST_TIME_FORMAT, GST_TIME_ARGS (stop)); + } + break; + } + default: + /* Don't fordward queries upstream because of the special nature of this + * "demuxer", which relies on the upstream element only to be fed with the + * first playlist */ + break; + } + + return ret; +} + +static gchar * +gst_hlsdemux2_uri_get_domain ( GstHLSDemux2 *demux, gchar * uri) +{ + gchar *pointer = uri; + gchar *domain = NULL; + guint flag = 0; + guint counter=0; + + domain = g_malloc0(strlen (uri)); + if (!domain) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + return NULL; + } + + while(*pointer != '\0') { + switch(*pointer) { + case '.': + flag = 1; + break; + case '/': + if(flag==1) + flag = 2; + break; + } + if(flag==1) { + domain[counter]=*pointer; + counter++; + } else if(flag == 2) { + domain[counter]='\0'; + break; + } + pointer++; + } + + GST_DEBUG_OBJECT (demux, "uri = %s and domain = %s", uri, domain); + return domain; +} + +static void +gst_hlsdemux2_get_cookies(GstHLSDemux2 *demux) +{ + GstQuery *cquery; + GstStructure *structure; + gboolean bret = FALSE; + + structure = gst_structure_new ("HTTPCookies", + "cookies", G_TYPE_STRING, NULL, NULL); + + cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure); + + bret = gst_pad_peer_query (demux->sinkpad, cquery); + if (bret) { + const GstStructure *s; + const GValue *value; + + s = gst_query_get_structure (cquery); + value = gst_structure_get_value (s, "cookies"); + demux->playlistCookie = g_strdupv (g_value_get_boxed (value)); + + GST_INFO_OBJECT (demux, "Received playlist cookies from upstream element : %s", demux->playlistCookie ? *(demux->playlistCookie) : NULL); + if(demux->playlistCookie){ + demux->lastCookie = g_strdupv(demux->playlistCookie); + } + } else { + GST_WARNING_OBJECT (demux, "Failed to get cookies"); + } + + gst_query_unref (cquery); +} + +static void +gst_hlsdemux2_get_user_agent(GstHLSDemux2 *demux) +{ + GstQuery *cquery; + GstStructure *structure; + gboolean bret = FALSE; + + structure = gst_structure_new ("HTTPUserAgent", + "user-agent", G_TYPE_STRING, NULL, NULL); + + cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure); + + bret = gst_pad_peer_query (demux->sinkpad, cquery); + if (bret) { + const GstStructure *s; + const GValue *value; + + GST_INFO_OBJECT (demux, "Received user-agent from upstream element..."); + + s = gst_query_get_structure (cquery); + value = gst_structure_get_value (s, "user-agent"); + demux->user_agent = g_strdup (g_value_get_string (value)); + + GST_INFO_OBJECT (demux,"User agent received from query : %s", demux->user_agent); + } else { + GST_WARNING_OBJECT (demux, "Failed to get user-agent"); + } + + gst_query_unref (cquery); +} + +static gboolean +gst_hlsdemux2_create_playlist_download (GstHLSDemux2 *demux, const gchar *playlist_uri) +{ + if (!gst_uri_is_valid (playlist_uri)) { + GST_ERROR_OBJECT (demux, "invalid uri : %s...", playlist_uri == NULL ? "NULL" : playlist_uri); + return FALSE; + } + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (demux,"returning from download playlist due to cancel or flushing.."); + return FALSE; + } + + /* create playlist downloader pipeline */ + demux->pldownloader->pipe = gst_pipeline_new ("playlist-downloader"); + if (!demux->pldownloader->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + return FALSE; + } + + demux->pldownloader->bus = gst_pipeline_get_bus (GST_PIPELINE (demux->pldownloader->pipe)); + gst_bus_set_sync_handler(demux->pldownloader->bus, gst_hlsdemux2_playlist_download_bus_sync_cb, demux); + + gst_object_unref (demux->pldownloader->bus); + + GST_INFO_OBJECT (demux, "Creating source element for the URI : %s", playlist_uri); + + /* creating source element */ + demux->pldownloader->urisrc = gst_element_make_from_uri (GST_URI_SRC, playlist_uri, "playlisturisrc"); + if (!demux->pldownloader->urisrc) { + GST_ERROR_OBJECT (demux, "failed to create urisrc"); + return FALSE; + } + g_object_set (G_OBJECT (demux->pldownloader->urisrc), "timeout", HLSDEMUX2_HTTP_TIMEOUT, NULL); + g_object_set (G_OBJECT (demux->pldownloader->urisrc), "user-agent", demux->user_agent, NULL); + g_object_set (G_OBJECT (demux->pldownloader->urisrc), "ahs-streaming", TRUE, NULL); + + demux->playlistDomain = gst_hlsdemux2_uri_get_domain(demux, playlist_uri); + if(!g_strcmp0(demux->playlistDomain, demux->lastDomain) && demux->lastCookie) { + g_strfreev (demux->playlistCookie); + demux->playlistCookie = g_strdupv (demux->lastCookie); + } + + if (demux->playlistCookie) { + GST_DEBUG_OBJECT (demux, "Setting cookies before PLAYLIST download, before PLAYING: %s", *(demux->playlistCookie)); + /* setting cookies */ + g_object_set (demux->pldownloader->urisrc, "cookies", demux->playlistCookie, NULL); + } + + /* create sink element */ + demux->pldownloader->sink = gst_element_factory_make ("appsink", "playlistsink"); + if (!demux->pldownloader->sink) { + GST_ERROR_OBJECT (demux, "failed to create playlist sink element"); + return FALSE; + } + g_object_set (G_OBJECT (demux->pldownloader->sink), "sync", FALSE, "emit-signals", TRUE, NULL); + g_signal_connect (demux->pldownloader->sink, "new-buffer", G_CALLBACK (gst_hlsdemux2_on_playlist_buffer), demux); + + gst_bin_add_many (GST_BIN (demux->pldownloader->pipe), demux->pldownloader->urisrc, demux->pldownloader->sink, NULL); + + if (!gst_element_link_many (demux->pldownloader->urisrc, demux->pldownloader->sink, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link src & demux elements..."); + return FALSE; + } + + return TRUE; +} + +static void +gst_hlsdemux2_destroy_playlist_download (GstHLSDemux2 * demux) +{ + if (demux->pldownloader->pipe) { + GST_DEBUG_OBJECT (demux, "Shutting down playlist download pipeline"); + gst_element_set_state (demux->pldownloader->pipe, GST_STATE_NULL); + gst_element_get_state (demux->pldownloader->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_object_unref (demux->pldownloader->pipe); + demux->pldownloader->pipe = NULL; + } +} + +static gboolean +gst_hlsdemux2_download_playlist (GstHLSDemux2 *demux, const gchar * uri) +{ + GstStateChangeReturn ret; + + if (demux->playlist_uri) { + g_free (demux->playlist_uri); + } + demux->playlist_uri = g_strdup (uri); + + demux->pldownloader->download_start_ts = gst_util_get_timestamp(); + + if (!gst_hlsdemux2_create_playlist_download (demux, uri)) { + GST_ERROR_OBJECT (demux, "failed to create playlist download pipeline"); + return FALSE; + } + + ret = gst_element_set_state (demux->pldownloader->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (demux, "set_state failed..."); + return FALSE; + } + + /* schedule the next update of playlist */ + if (demux->is_live) + gst_hlsdemux2_schedule (demux); + + /* wait until: + * - the download succeed (EOS) + * - the download failed (Error message on the fetcher bus) + * - the download was canceled + */ + GST_LOG_OBJECT (demux, "Waiting to fetch the URI"); + g_cond_wait (demux->pldownloader->cond, demux->pldownloader->lock); + GST_LOG_OBJECT (demux, "Recived signal to shutdown..."); + + if (demux->playlistCookie) + g_strfreev (demux->playlistCookie); + + g_object_get (demux->pldownloader->urisrc, "cookies", &demux->playlistCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after PLAYLIST download : %s", demux->playlistCookie ? *(demux->playlistCookie) : NULL); + + if(demux->playlistCookie){ + g_strfreev(demux->lastCookie); + g_free(demux->lastDomain); + demux->lastCookie = g_strdupv(demux->playlistCookie); + demux->lastDomain = g_strdup(demux->playlistDomain); + } + + gst_hlsdemux2_destroy_playlist_download (demux); + + if (demux->cancelled || demux->flushing) + return FALSE; + + return TRUE; +} + + +static gboolean +gst_hlsdemux2_update_playlist (GstHLSDemux2 * demux, gboolean update, gboolean *is_error) +{ + gchar *playlist = NULL; + gboolean updated = FALSE; + const gchar *playlist_uri = gst_m3u8_client_get_current_uri (demux->client); + + *is_error = FALSE; + + if (!gst_m3u8_client_is_playlist_download_needed (demux->client)) { + GST_INFO_OBJECT (demux, "Playlist download is not needed..."); + return TRUE; + } + + g_mutex_lock (demux->pldownloader->lock); + +try_again: + + if (!gst_hlsdemux2_download_playlist (demux, playlist_uri)) { + GST_ERROR_OBJECT (demux, "failed to create playlist download"); + goto error; + } + + if ((demux->pldownloader->playlist == NULL) || (GST_BUFFER_DATA(demux->pldownloader->playlist) == NULL)) { + // TODO: don't exact reason, why eos is coming from soup without data... + GST_ERROR_OBJECT (demux, "Received playlist eos, without playlist data -> TRY AGAIN"); + goto try_again; + } + + /* reset the count */ + demux->soup_request_fail_cnt = HLSDEMUX2_SOUP_FAILED_CNT; + + playlist = gst_hlsdemux2_src_buf_to_utf8_playlist (demux->pldownloader->playlist); + if (!playlist) { + GST_ERROR_OBJECT(demux, "failed to create playlist"); + goto error; + } + demux->pldownloader->playlist = NULL; + + updated = gst_m3u8_client_update (demux->client, playlist); + g_mutex_unlock (demux->pldownloader->lock); + + return updated; + +error: + if (demux->flushing) + *is_error = TRUE; + g_mutex_unlock (demux->pldownloader->lock); + return FALSE; +} + +static gboolean +gst_hlsdemux2_create_key_download (GstHLSDemux2 *demux, const gchar *key_uri) +{ + if (!gst_uri_is_valid (key_uri)) { + GST_ERROR_OBJECT (demux, "invalid uri : %s...", key_uri == NULL ? "NULL" : key_uri); + return FALSE; + } + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (demux,"returning from download key due to cancel or flushing.."); + return FALSE; + } + + demux->kdownloader->pipe = gst_pipeline_new ("keydownloader"); + if (!demux->kdownloader->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + return FALSE; + } + + demux->kdownloader->bus = gst_pipeline_get_bus (GST_PIPELINE (demux->kdownloader->pipe)); + gst_bus_add_watch (demux->kdownloader->bus, (GstBusFunc)gst_hlsdemux2_key_download_bus_cb, demux); + gst_object_unref (demux->kdownloader->bus); + + GST_INFO_OBJECT (demux, "Creating source element for the URI : %s", key_uri); + + demux->kdownloader->urisrc = gst_element_make_from_uri (GST_URI_SRC, key_uri, "keyurisrc"); + if (!demux->kdownloader->urisrc) { + GST_ERROR_OBJECT (demux, "failed to create urisrc"); + return FALSE; + } + + g_object_set (G_OBJECT (demux->kdownloader->urisrc), "timeout", HLSDEMUX2_HTTP_TIMEOUT, NULL); + g_object_set (G_OBJECT (demux->kdownloader->urisrc), "user-agent", demux->user_agent, NULL); + g_object_set (G_OBJECT (demux->kdownloader->urisrc), "ahs-streaming", TRUE, NULL); + + demux->keyDomain = gst_hlsdemux2_uri_get_domain(demux, key_uri); + if(!g_strcmp0(demux->keyDomain, demux->lastDomain) && demux->lastCookie) { + g_strfreev(demux->keyCookie); + demux->keyCookie = g_strdupv(demux->lastCookie); + } + + if (demux->keyCookie) { + GST_DEBUG_OBJECT (demux, "Setting cookies before KEY download goto PLAYING : %s", *(demux->keyCookie)); + g_object_set (demux->kdownloader->urisrc, "cookies", demux->keyCookie, NULL); + } + + demux->kdownloader->sink = gst_element_factory_make ("appsink", "keyfilesink"); + if (!demux->kdownloader->sink) { + GST_ERROR_OBJECT (demux, "failed to create playlist sink element"); + return FALSE; + } + g_object_set (G_OBJECT (demux->kdownloader->sink), "sync", FALSE, "emit-signals", TRUE, NULL); + g_signal_connect (demux->kdownloader->sink, "new-buffer", G_CALLBACK (gst_hlsdemux2_on_key_buffer), demux); + + gst_bin_add_many (GST_BIN (demux->kdownloader->pipe), demux->kdownloader->urisrc, demux->kdownloader->sink, NULL); + + if (!gst_element_link_many (demux->kdownloader->urisrc, demux->kdownloader->sink, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link src & demux elements..."); + return FALSE; + } + + return TRUE; +} + +static void +gst_hlsdemux2_destroy_key_download (GstHLSDemux2 * demux) +{ + if (demux->kdownloader->pipe) { + GST_DEBUG_OBJECT (demux, "Shutting down key download pipeline"); + gst_element_set_state (demux->kdownloader->pipe, GST_STATE_NULL); + gst_element_get_state (demux->kdownloader->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_object_unref (demux->kdownloader->pipe); + demux->kdownloader->pipe = NULL; + } +} + +static gboolean +gst_hlsdemux2_download_key (GstHLSDemux2 *demux, const gchar * uri) +{ + GstStateChangeReturn ret; + + if (demux->key_uri) { + g_free (demux->key_uri); + } + demux->key_uri = g_strdup (uri); + + g_mutex_lock (demux->kdownloader->lock); + + if (!gst_hlsdemux2_create_key_download (demux, uri)) { + GST_ERROR_OBJECT (demux, "failed to create key download pipeline"); + return FALSE; + } + + ret = gst_element_set_state (demux->kdownloader->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (demux, "set_state failed..."); + return FALSE; + } + + /* wait until: + * - the download succeed (EOS) + * - the download failed (Error message on the fetcher bus) + * - the download was canceled + */ + GST_DEBUG_OBJECT (demux, "Waiting to fetch the key URI"); + g_cond_wait (demux->kdownloader->cond, demux->kdownloader->lock); + GST_DEBUG_OBJECT (demux, "Recived signal to shutdown key downloader..."); + g_mutex_unlock (demux->kdownloader->lock); + + if (demux->keyCookie) { + g_object_get (demux->kdownloader->urisrc, "cookies", &demux->keyCookie, NULL); + } + + GST_DEBUG_OBJECT (demux, "Got cookies after KEY download : %s", demux->keyCookie ? *(demux->keyCookie) : NULL); + + if(demux->keyCookie){ + g_strfreev(demux->lastCookie); + g_free(demux->lastDomain); + demux->lastCookie = g_strdupv(demux->keyCookie); + demux->lastDomain = g_strdup(demux->keyDomain); + } + + gst_hlsdemux2_destroy_key_download (demux); + + if (demux->cancelled || demux->flushing) + return FALSE; + + return TRUE; +} + +static void +gst_hlsdemux2_have_type_cb (GstElement * typefind, guint probability, + GstCaps * caps, GstHLSDemux2 * demux) +{ + GstStructure *structure = NULL; + + structure = gst_caps_get_structure (caps, 0); + + GST_DEBUG_OBJECT (demux, "typefind found caps %" GST_PTR_FORMAT, caps); + + if (gst_structure_has_name (structure, "video/mpegts")) { + /* found ts fragment */ + demux->fdownloader->demuxer = gst_element_factory_make ("mpegtsdemux", "tsdemux"); + if (!demux->fdownloader->demuxer) { + GST_ERROR_OBJECT (demux, "failed to create mpegtsdemux element"); + GST_ELEMENT_ERROR (demux, CORE, MISSING_PLUGIN, ("failed to create mpegtsdemuxer element"), (NULL)); + return; + } + g_signal_connect (demux->fdownloader->demuxer, "pad-added", G_CALLBACK (gst_hlsdemux2_new_pad_added), demux); + + gst_bin_add (GST_BIN (demux->fdownloader->pipe), demux->fdownloader->demuxer); + + /* set queue element to PLAYING state */ + gst_element_set_state (demux->fdownloader->demuxer, GST_STATE_PLAYING); + + if (!gst_element_link (demux->fdownloader->typefind, demux->fdownloader->demuxer)) { + GST_ERROR_OBJECT (demux, "failed to link src and demux elements..."); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("failed to link typefind & demuxer"), (NULL)); + return; + } + } else if (gst_structure_has_name (structure, "application/x-id3")) { + /* found ts fragment */ + demux->fdownloader->demuxer = gst_element_factory_make ("id3demux", "id3demuxer"); + if (!demux->fdownloader->demuxer) { + GST_ERROR_OBJECT (demux, "failed to create mpegtsdemux element"); + GST_ELEMENT_ERROR (demux, CORE, MISSING_PLUGIN, ("failed to create id3demuxer element"), (NULL)); + return; + } + g_signal_connect (demux->fdownloader->demuxer, "pad-added", G_CALLBACK (gst_hlsdemux2_new_pad_added), demux); + + gst_bin_add (GST_BIN (demux->fdownloader->pipe), demux->fdownloader->demuxer); + + /* set queue element to PLAYING state */ + gst_element_set_state (demux->fdownloader->demuxer, GST_STATE_PLAYING); + + if (!gst_element_link_many (demux->fdownloader->typefind, demux->fdownloader->demuxer, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link src and demux elements..."); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("failed to link typefind & demuxer"), (NULL)); + return; + } + + /* as the fragment does not contain in container format, force the timestamps based on fragment duration */ + demux->fdownloader->force_timestamps = TRUE; + } +} + +static gboolean +gst_hlsdemux2_download_monitor_thread (GstHLSDemux2 *demux) +{ + GTimeVal post_msg_update = {0, }; + + g_mutex_lock (demux->post_msg_lock); + GST_INFO_OBJECT (demux, "waiting for streaming to start to post message..."); + g_cond_wait (demux->post_msg_start, demux->post_msg_lock); + GST_INFO_OBJECT (demux, "Start posting messages..."); + g_mutex_unlock (demux->post_msg_lock); + + while (TRUE) { + gboolean do_post = FALSE; + guint64 percent = 0; + guint idx = 0; + guint64 total_percent = 0; + gboolean bret = FALSE; + + if (demux->cancelled) { + GST_WARNING_OBJECT (demux, "returning msg posting thread..."); + return TRUE; + } + + /* schedule the next update using the target duration field of the + * playlist */ + post_msg_update.tv_sec = 0; + post_msg_update.tv_usec = 0; + + g_get_current_time (&post_msg_update); + g_time_val_add (&post_msg_update, 200000); // posts buffering msg after every 0.5 sec + + /* verify fast switch from here */ + g_mutex_lock (demux->fdownloader->lock); + if (demux->fdownloader->ndownloaded + && !demux->fdownloader->applied_fast_switch && demux->fdownloader->download_start_ts) { + gst_hlsdemux2_check_fast_switch (demux); + } + g_mutex_unlock (demux->fdownloader->lock); + + /* calculate avg percent of streams' percentages */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *stream = demux->streams[idx]; + if (stream ) { + guint64 stream_percent = 0; + + stream_percent = ((stream->cached_duration * 100) / (demux->total_cache_duration / DEFAULT_NUM_FRAGMENTS_CACHE)); + GST_DEBUG_OBJECT (stream->pad, "stream percent = %"G_GUINT64_FORMAT, stream_percent); + total_percent += stream_percent; + } + } + percent = total_percent / demux->active_stream_cnt; + + if (demux->is_buffering) { + do_post = TRUE; + if (percent >= 100) + demux->is_buffering = FALSE; + } else { + if (percent < 10) { + /* if buffering drops below 10% lets start posting msgs */ + demux->is_buffering = TRUE; + do_post = TRUE; + } + } + + if (do_post) { + GstMessage *message; + + if (percent > 100) { + //GST_LOG_OBJECT (demux, " exceeded percent = %d", (gint) percent); + percent = 100; + } + + if (demux->end_of_playlist) { + GST_INFO_OBJECT (demux, "end of the playlist reached... always post 100%"); + percent = 100; + } + + if (percent != demux->percent) { + g_mutex_lock (demux->buffering_lock); + demux->percent = percent; + g_mutex_unlock (demux->buffering_lock); + + GST_LOG_OBJECT (demux, "buffering %d percent", (gint) percent); + + /* posting buffering to internal bus, which will take average & post to main bus */ + message = gst_message_new_buffering (GST_OBJECT_CAST (demux), (gint) demux->percent); + if (!gst_element_post_message (GST_ELEMENT_CAST (demux), message)) { + GST_WARNING_OBJECT (demux, "failed to post buffering msg..."); + } + } + } + + g_mutex_lock (demux->post_msg_lock); + /* block until the next scheduled update or the exit signal */ + bret = g_cond_timed_wait (demux->post_msg_exit, demux->post_msg_lock, &post_msg_update); + g_mutex_unlock (demux->post_msg_lock); + + if (bret) { + GST_WARNING_OBJECT (demux, "signalled to exit posting msgs..."); + break; + } + } + + return TRUE; +} + +static gboolean +gst_hlsdemux2_fragurisrc_event_handler (GstPad * pad, GstEvent *event, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { + GTimeVal time = {0, }; + + GST_INFO_OBJECT (demux, "received EOS from fragment downloader's httpsrc"); + + if (demux->fdownloader->error_rcvd) { + GST_WARNING_OBJECT (demux, "received EOS event after ERROR.. discard this"); + demux->fdownloader->src_downloaded_size = 0; + demux->fdownloader->download_stop_ts = demux->fdownloader->download_start_ts = 0; + return FALSE; + } + + /* download rate calculation : note down stop time*/ + g_get_current_time (&time); + demux->fdownloader->download_stop_ts = gst_util_get_timestamp(); + + GST_INFO_OBJECT (demux, "download stop_ts = %"G_GUINT64_FORMAT, demux->fdownloader->download_stop_ts); + GST_INFO_OBJECT (demux, "time taken to download current fragment = %"G_GUINT64_FORMAT, demux->fdownloader->download_stop_ts - demux->fdownloader->download_start_ts); + GST_INFO_OBJECT (demux, "fragment downloaded size = %"G_GUINT64_FORMAT" and content_size = %"G_GUINT64_FORMAT, + demux->fdownloader->src_downloaded_size, demux->fdownloader->content_size); + + if (demux->fdownloader->src_downloaded_size && (demux->fdownloader->src_downloaded_size == demux->fdownloader->content_size)) { + guint64 download_rate = 0; + guint i = 0; + guint64 dsum = 0; + + /* calculate current fragment download rate */ + download_rate = (demux->fdownloader->src_downloaded_size * 8 * GST_SECOND) / + (demux->fdownloader->download_stop_ts - demux->fdownloader->download_start_ts); + + if (demux->fdownloader->avg_frag_drates->len == HLSDEMUX2_MAX_N_PAST_FRAG_DOWNLOADRATES) { + /* removing starting element */ + g_array_remove_index (demux->fdownloader->avg_frag_drates, 0); + GST_DEBUG_OBJECT (demux, "removing index from download rates"); + } + g_array_append_val (demux->fdownloader->avg_frag_drates, download_rate); + + for (i = 0 ; i < demux->fdownloader->avg_frag_drates->len; i++) { + dsum += g_array_index (demux->fdownloader->avg_frag_drates, guint64, i); + } + + demux->fdownloader->download_rate = dsum / demux->fdownloader->avg_frag_drates->len; + + GST_INFO_OBJECT (demux, " >>>> DOWNLOAD RATE = %"G_GUINT64_FORMAT, demux->fdownloader->download_rate); + } else { + GST_WARNING_OBJECT (demux, "something wrong better not to calculate download rate with this and discard EOS..."); + demux->fdownloader->src_downloaded_size = 0; + demux->fdownloader->download_stop_ts = demux->fdownloader->download_start_ts = 0; + return FALSE; + } + + demux->fdownloader->src_downloaded_size = 0; + demux->fdownloader->download_stop_ts = demux->fdownloader->download_start_ts = 0; + } + + return TRUE; +} + +static gboolean +gst_hlsdemux2_check_fast_switch (GstHLSDemux2 *demux) +{ + GstClockTime elapsed_time = 0; + guint i = 0; + guint64 download_rate = 0; + + elapsed_time = gst_util_get_timestamp(); + + if (gst_m3u8_client_has_variant_playlist (demux->client) && + ((elapsed_time - demux->fdownloader->download_start_ts) > + (HLSDEMUX2_FAST_CHECK_WARNING_TIME_FACTOR * demux->target_duration))) { + guint64 drate_sum = 0; + GList *previous_variant, *current_variant; + gint old_bandwidth, new_bandwidth; + + GST_INFO_OBJECT (demux, "Doing fast switch using array len %d...", demux->fdownloader->avg_chunk_drates->len); + + for (i = 0 ; i < demux->fdownloader->avg_chunk_drates->len; i++) { + drate_sum += g_array_index (demux->fdownloader->avg_chunk_drates, guint64, i); + } + + /* 0.9 factor is for compensating for connection time*/ + download_rate = (drate_sum * 0.9) / demux->fdownloader->avg_chunk_drates->len; + + GST_INFO_OBJECT (demux, "average chunk download rate = %"G_GUINT64_FORMAT, download_rate); + + if ((elapsed_time - demux->fdownloader->download_start_ts) > + (HLSDEMUX2_FAST_CHECK_CRITICAL_TIME_FACTOR * demux->target_duration)) { + GST_WARNING_OBJECT (demux, "Reached FAST_SWITCH critical point...do fast_switch"); + goto fast_switch; + } + + previous_variant = demux->client->main->current_variant; + current_variant = gst_m3u8_client_get_playlist_for_bitrate (demux->client, download_rate); + + old_bandwidth = GST_M3U8 (previous_variant->data)->bandwidth; + new_bandwidth = GST_M3U8 (current_variant->data)->bandwidth; + + GST_INFO_OBJECT (demux, "variant's bandwidth got using average chunk download rate is %d", new_bandwidth); + + /* Don't do anything else if the playlist is the same */ + if (new_bandwidth == old_bandwidth) { + GST_WARNING_OBJECT (demux, "Either BW is recovering or NO LOWER variant available than current, DON'T DO FAST_SWITCH..."); + return TRUE; + } + + GST_WARNING_OBJECT (demux, "Going to do fast_switch due to BW problem..."); + goto fast_switch; + } + + return TRUE; + +fast_switch: + + demux->fdownloader->download_rate = download_rate; + + /* flush previous fragment downloads history */ + for (i = 3; i ; --i) { + g_array_remove_index (demux->fdownloader->avg_frag_drates, i - 1); + } + + GST_INFO_OBJECT (demux, "in fast download rate : len %d...", demux->fdownloader->avg_frag_drates->len); + g_array_append_val (demux->fdownloader->avg_frag_drates, demux->fdownloader->download_rate); + + GST_INFO_OBJECT (demux, " >>>> DOWNLOAD RATE in fast switch = %"G_GUINT64_FORMAT, demux->fdownloader->download_rate); + + demux->fdownloader->applied_fast_switch = TRUE; + + /* close current fragment */ + g_cond_signal (demux->fdownloader->cond); + + return FALSE; + +} + +static gboolean +gst_hlsdemux2_fragurisrc_buffer_handler (GstPad * pad, GstBuffer *buffer, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GstClockTime elapsed_ts = 0; + guint64 chunk_drate = 0; + + /* if block_switch already enabled no need to cross check. IMP check*/ + if (demux->fdownloader->applied_fast_switch) { + GST_WARNING_OBJECT (demux, "already applied fast_switch.. drop current buffer"); + return FALSE; + } + + demux->fdownloader->src_downloaded_size += GST_BUFFER_SIZE(buffer); + + if (demux->fdownloader->first_buffer) { + /* get the content size for doing last buffer decryption & for vaidating complete download happend or not */ + GST_INFO_OBJECT (demux, "just received first buffer..."); + g_object_get (demux->fdownloader->urisrc, "content-size", &demux->fdownloader->content_size, NULL); + GST_INFO_OBJECT (demux, "content size = %"G_GUINT64_FORMAT, demux->fdownloader->content_size); + demux->fdownloader->first_buffer = FALSE; + demux->fdownloader->chunk_start_ts = gst_util_get_timestamp(); + demux->fdownloader->chunk_downloaded_size = 0; + } + + + demux->fdownloader->chunk_downloaded_size += GST_BUFFER_SIZE(buffer); + elapsed_ts = gst_util_get_timestamp(); + + if ((elapsed_ts - demux->fdownloader->chunk_start_ts) > HLSDEMUX2_CHUNK_TIME_DURATION) { + GST_DEBUG_OBJECT (demux, "chunk downloaded time = %"GST_TIME_FORMAT, + GST_TIME_ARGS(elapsed_ts - demux->fdownloader->chunk_start_ts)); + + chunk_drate = (demux->fdownloader->chunk_downloaded_size * 8 * GST_SECOND) / (elapsed_ts - demux->fdownloader->chunk_start_ts); + demux->fdownloader->chunk_start_ts = elapsed_ts; + demux->fdownloader->chunk_downloaded_size = 0; + + GST_DEBUG_OBJECT(demux, "CHUNK DOWNLOAD RATE = %"G_GUINT64_FORMAT, chunk_drate); + + if (demux->fdownloader->avg_chunk_drates->len == HLSDEMUX2_NUM_CHUNK_DOWNLOADS_FAST_SWITCH) { + /* removing starting element */ + g_array_remove_index (demux->fdownloader->avg_chunk_drates, 0); + } + g_array_append_val (demux->fdownloader->avg_chunk_drates, chunk_drate); + } + + GST_LOG_OBJECT (demux, "fragment downloaded size at urisrc = %"G_GUINT64_FORMAT, demux->fdownloader->src_downloaded_size); + + return TRUE; +} + +static gboolean +gst_hlsdemux2_queue_buffer_handler (GstPad *pad, GstBuffer *buffer, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + unsigned char *encry_data = NULL; + unsigned char *outdata = NULL; + unsigned char *remained_data = NULL; + unsigned char* total_data = NULL; + + demux->fdownloader->queue_downloaded_size += GST_BUFFER_SIZE(buffer); + + GST_DEBUG_OBJECT (demux, "total downloaded size = %"G_GUINT64_FORMAT, demux->fdownloader->queue_downloaded_size); + + if (demux->fdownloader->is_encrypted) { + guint encry_data_size = 0; + unsigned char *indata = GST_BUFFER_DATA (buffer); + guint insize = GST_BUFFER_SIZE (buffer); + gint out_len = 0; + + if (demux->fdownloader->remaining_data && demux->fdownloader->remaining_size) { + GST_LOG_OBJECT (demux, "remain size = %d..", demux->fdownloader->remaining_size); + + encry_data = (unsigned char *) malloc (insize + demux->fdownloader->remaining_size); + if (!encry_data) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + goto error; + } + + /* copy remaining data in previous iteration */ + memcpy (encry_data, demux->fdownloader->remaining_data, demux->fdownloader->remaining_size); + /* copy input encrypted data of current iteration */ + memcpy (encry_data + demux->fdownloader->remaining_size, indata, insize); + + encry_data_size = insize + demux->fdownloader->remaining_size; + + free (demux->fdownloader->remaining_data); + demux->fdownloader->remaining_data = NULL; + demux->fdownloader->remaining_size = 0; + } else { + encry_data_size = insize; + encry_data = indata; + } + + demux->fdownloader->remaining_size = encry_data_size % GST_HLS_DEMUX_AES_BLOCK_SIZE; + + if (demux->fdownloader->remaining_size) { + GST_LOG_OBJECT (demux, "Remining in current iteration = %d\n", demux->fdownloader->remaining_size); + demux->fdownloader->remaining_data = (gchar *) malloc (demux->fdownloader->remaining_size); + if ( demux->fdownloader->remaining_data == NULL) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + goto error; + } + + /* copy remained portion to buffer */ + memcpy (demux->fdownloader->remaining_data, + encry_data + encry_data_size - demux->fdownloader->remaining_size, + demux->fdownloader->remaining_size); + } + + out_len = encry_data_size - demux->fdownloader->remaining_size + GST_HLS_DEMUX_AES_BLOCK_SIZE; + outdata = (unsigned char *) malloc (out_len); + if (!outdata) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + goto error; + } + + if (!gst_m3u8_client_decrypt_update (demux->client, outdata, &out_len, + encry_data, encry_data_size - demux->fdownloader->remaining_size)) { + GST_ERROR_OBJECT (demux, "failed to decrypt...\n"); + GST_ELEMENT_ERROR (demux, STREAM, FAILED, ("failed to decrypt"), (NULL)); + goto error; + } + + if (encry_data != indata) { + g_free (encry_data); + encry_data = NULL; + } + + g_free (GST_BUFFER_MALLOCDATA(buffer)); + + /* decrypt the final buffer */ + if (demux->fdownloader->queue_downloaded_size == demux->fdownloader->content_size) { + gint remained_size = 0; + gint total_len = 0; + + GST_LOG_OBJECT (demux, "remained data = %p & remained size = %d", demux->fdownloader->remaining_data, demux->fdownloader->remaining_size); + + remained_data = (unsigned char *) malloc (GST_HLS_DEMUX_AES_BLOCK_SIZE); + if (!remained_data) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + goto error; + } + gst_m3u8_client_decrypt_final (demux->client, remained_data, &remained_size); + GST_LOG_OBJECT (demux,"remained size = %d\n", remained_size); + + if (remained_size) { + total_len = out_len + remained_size; + + total_data = (unsigned char *) malloc (total_len); + if (!total_data) { + GST_ERROR_OBJECT (demux, "failed to allocate memory...\n"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + goto error; + } + + memcpy (total_data, outdata, out_len); + memcpy (total_data+out_len, remained_data, remained_size); + + GST_BUFFER_MALLOCDATA(buffer) = GST_BUFFER_DATA(buffer) = total_data; + GST_BUFFER_SIZE(buffer) = total_len; + g_free (remained_data); + g_free (outdata); + } else { + GST_BUFFER_MALLOCDATA(buffer) = GST_BUFFER_DATA(buffer) = outdata; + GST_BUFFER_SIZE(buffer) = out_len; + g_free (remained_data); + } + + if (!gst_m3u8_client_decrypt_deinit (demux->client)) { + GST_WARNING_OBJECT (demux, "decryption cleanup failed..."); + } + } else { + GST_BUFFER_MALLOCDATA(buffer) = GST_BUFFER_DATA(buffer) = outdata; + GST_BUFFER_SIZE(buffer) = out_len; + } + } + + return TRUE; + +error: + if (encry_data) + free (encry_data); + + if (outdata) + free (outdata); + + if (remained_data) + free (remained_data); + + return FALSE; +} + +static gboolean +gst_hlsdemux2_create_fragment_download (GstHLSDemux2 * demux, const gchar * uri) +{ + GstBus *bus = NULL; + GstPad *srcpad = NULL; + + if (!gst_uri_is_valid (uri)) { + GST_ERROR_OBJECT (demux, "invalid uri : %s...", uri == NULL ? "NULL" : uri); + return FALSE; + } + + /* re-initialize fragment variables */ + demux->fdownloader->first_buffer = TRUE; + demux->fdownloader->cur_stream_cnt = 0; + demux->fdownloader->error_rcvd = FALSE; + + demux->fdownloader->pipe = gst_pipeline_new ("frag-fdownloader"); + if (!demux->fdownloader->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + return FALSE; + } + + bus = gst_pipeline_get_bus (GST_PIPELINE (demux->fdownloader->pipe)); + gst_bus_add_watch (bus, (GstBusFunc)gst_hlsdemux2_fragment_download_bus_cb, demux); + gst_object_unref (bus); + + GST_INFO_OBJECT (demux, "Creating source element for the URI : %s", uri); + + demux->fdownloader->urisrc = gst_element_make_from_uri (GST_URI_SRC, uri, "fragurisrc"); + if (!demux->fdownloader->urisrc) { + GST_ERROR_OBJECT (demux, "failed to create urisrc"); + return FALSE; + } + + g_object_set (G_OBJECT (demux->fdownloader->urisrc), "timeout", HLSDEMUX2_HTTP_TIMEOUT, NULL); + g_object_set (G_OBJECT (demux->fdownloader->urisrc), "user-agent", demux->user_agent, NULL); + g_object_set (G_OBJECT (demux->fdownloader->urisrc), "ahs-streaming", TRUE, NULL); + g_object_set (G_OBJECT (demux->fdownloader->urisrc), "blocksize", DEFAULT_BLOCKSIZE, NULL); + + demux->fragDomain = gst_hlsdemux2_uri_get_domain(demux, uri); + if(!g_strcmp0 (demux->fragDomain, demux->lastDomain) && demux->lastCookie) { + g_strfreev(demux->fragCookie); + demux->fragCookie = g_strdupv (demux->lastCookie); + } + + if (demux->fragCookie) { + GST_DEBUG_OBJECT (demux, "Setting cookies before FRAG download goto PLAYING: %s", *(demux->fragCookie)); + g_object_set (demux->fdownloader->urisrc, "cookies", demux->fragCookie, NULL); + } + + srcpad = gst_element_get_static_pad (demux->fdownloader->urisrc, "src"); + if (!srcpad) { + GST_ERROR_OBJECT (demux, "failed to get source pad from urisrc..."); + return FALSE; + } + + gst_pad_add_event_probe (srcpad, G_CALLBACK (gst_hlsdemux2_fragurisrc_event_handler), demux); + gst_pad_add_buffer_probe (srcpad, G_CALLBACK (gst_hlsdemux2_fragurisrc_buffer_handler), demux); + + gst_object_unref (srcpad); + + demux->fdownloader->queue = gst_element_factory_make ("queue2", "frag_queue"); + if (!demux->fdownloader->queue) { + GST_ERROR_OBJECT (demux, "failed to create queue2"); + return FALSE; + } + + g_object_set (G_OBJECT (demux->fdownloader->queue), + "max-size-buffers", 0, + "max-size-bytes", 0, + "max-size-time", 0 * GST_SECOND, NULL); + + srcpad = gst_element_get_static_pad (demux->fdownloader->queue, "src"); + if (!srcpad) { + GST_ERROR_OBJECT (demux, "failed to get source pad from fragment queue..."); + return FALSE; + } + + gst_pad_add_buffer_probe (srcpad, G_CALLBACK (gst_hlsdemux2_queue_buffer_handler), demux); + + demux->fdownloader->typefind = gst_element_factory_make ("typefind", "typefinder"); + if (!demux->fdownloader->typefind) { + GST_ERROR_OBJECT (demux, "failed to create typefind element"); + gst_object_unref (srcpad); + return FALSE; + } + + gst_bin_add_many (GST_BIN (demux->fdownloader->pipe), + demux->fdownloader->urisrc, demux->fdownloader->queue, demux->fdownloader->typefind, NULL); + + if (!gst_element_link_many (demux->fdownloader->urisrc, + demux->fdownloader->queue, demux->fdownloader->typefind, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link src, queue & typefind elements..."); + gst_object_unref (srcpad); + return FALSE; + } + + /* typefind callback to determine file type */ + g_signal_connect (demux->fdownloader->typefind, "have-type", G_CALLBACK (gst_hlsdemux2_have_type_cb), demux); + + gst_object_unref (srcpad); + + return TRUE; +} + +static void +gst_hlsdemux2_destroy_fragment_download (GstHLSDemux2 * demux) +{ + if (demux->fdownloader->pipe) { + GST_DEBUG_OBJECT (demux, "completely closing fragment downloader pipeline"); + gst_element_set_state (demux->fdownloader->pipe, GST_STATE_NULL); + gst_element_get_state (demux->fdownloader->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + GST_DEBUG_OBJECT (demux, "completely closed fragment downloader pipeline"); + gst_object_unref (demux->fdownloader->pipe); + demux->has_image_buffer = FALSE; + demux->fdownloader->pipe = NULL; + demux->fdownloader->cur_stream_cnt = 0; + g_list_free (demux->fdownloader->sinkbins); // all sink elements will be unreffed when pipeline is unreffed + demux->fdownloader->sinkbins = 0; + } +} + +static gboolean +gst_hlsdemux2_download_fragment (GstHLSDemux2 *demux, const gchar * uri) +{ + GstStateChangeReturn ret; + + g_mutex_lock (demux->fdownloader->lock); + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (demux,"returning from download fragment due to cancel or flushing.."); + g_mutex_unlock (demux->fdownloader->lock); + return FALSE; + } + + if (demux->frag_uri) { + g_free (demux->frag_uri); + } + demux->frag_uri = g_strdup (uri); + + demux->fdownloader->get_next_frag = FALSE; + + if (!gst_hlsdemux2_create_fragment_download (demux, uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + g_mutex_unlock (demux->fdownloader->lock); + return FALSE; + } + + /* download rate calculation : note down start time*/ + demux->fdownloader->download_start_ts = gst_util_get_timestamp(); + GST_INFO_OBJECT (demux, "download start_ts = %"G_GUINT64_FORMAT, demux->fdownloader->download_start_ts); + + ret = gst_element_set_state (demux->fdownloader->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (demux, "set_state failed..."); + g_mutex_unlock (demux->fdownloader->lock); + return FALSE; + } + gst_element_get_state (demux->fdownloader->pipe, NULL, NULL, -1); + + /* wait until: + * - the download succeed (EOS) + * - the download failed (Error message on the fetcher bus) + * - the download was canceled + */ + GST_DEBUG_OBJECT (demux, "Waiting to fetch the URI"); + g_cond_wait (demux->fdownloader->cond, demux->fdownloader->lock); + GST_INFO_OBJECT (demux, "Recived signal to shutdown..."); + + if (demux->fragCookie) + g_strfreev (demux->fragCookie); + + g_object_get (demux->fdownloader->urisrc, "cookies", &demux->fragCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after FRAG download : %s", demux->fragCookie ? *(demux->fragCookie) : NULL); + + if (demux->fdownloader->applied_fast_switch) { + if (demux->fdownloader->src_downloaded_size == demux->fdownloader->content_size) { + /* to handle case, when both fast_switch & bus_callback signalled at same moment */ + GST_WARNING_OBJECT (demux, "ignoring fast_switch as fragment download is completed..."); + demux->fdownloader->applied_fast_switch = FALSE; + } else { + GST_WARNING_OBJECT (demux, "decrement the media sequence by one, due to fast_switch"); + gst_m3u8_client_decrement_sequence (demux->client); + } + } + + if (demux->cancelled || demux->flushing || + demux->fdownloader->get_next_frag || demux->fdownloader->applied_fast_switch) { + GstBuffer *buf = NULL; + guint idx = 0; + + /* clear stream queues if we already downloaded some data */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *stream = demux->streams[idx]; + if (stream ) { + while (!g_queue_is_empty (stream->downloader_queue)) { + buf = g_queue_pop_head (stream->downloader_queue); + gst_buffer_unref (buf); + } + GST_LOG_OBJECT (stream->pad, "cleared stream download queue..."); + g_queue_clear (stream->downloader_queue); + } + } + } + + if(demux->fragCookie){ + g_strfreev(demux->lastCookie); + g_free(demux->lastDomain); + demux->lastCookie = g_strdupv(demux->fragCookie); + demux->lastDomain = g_strdup(demux->fragDomain); + } + + if(demux->active_stream_cnt == 1 && !demux->private_stream) { + gchar *image_header = NULL; + GValue codec_type = G_VALUE_INIT; + GValue image_data = G_VALUE_INIT; + GstMessage * tag_message = NULL; + struct stat stat_results; + gint iread = 0; + GstBuffer *image_buffer = NULL; + GstTagList * tag_list = gst_tag_list_new(); + int dummy_fp = -1; + + GST_INFO_OBJECT (demux, "Going to show fixed image"); + dummy_fp = open (PREDEFINED_IMAGE_FRAME_LOCATION, O_RDONLY); + if (dummy_fp < 0) { + GST_WARNING_OBJECT (demux, "failed to open fixed image file : %s...", PREDEFINED_IMAGE_FRAME_LOCATION); + goto skip_posting_image; + } + + GST_LOG_OBJECT (demux, "opened fixed image file %s successfully...", PREDEFINED_IMAGE_FRAME_LOCATION); + + if (fstat (dummy_fp, &stat_results) < 0) { + GST_WARNING_OBJECT (demux, "failed to get stats of a file..."); + close (dummy_fp); + goto skip_posting_image; + } + + GST_LOG_OBJECT (demux, "size of the dummy file = %d", stat_results.st_size); + + image_buffer = gst_buffer_new_and_alloc (stat_results.st_size); + if (!image_buffer) { + GST_ERROR_OBJECT (demux, "failed to allocate memory..."); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + close (dummy_fp); + goto error; + } + + iread = read (dummy_fp, GST_BUFFER_DATA (image_buffer), stat_results.st_size); + + GST_LOG_OBJECT (demux, "read size = %d successfully", iread); + + close (dummy_fp); + + /* check whether it is same as previous image */ + if (demux->prev_image_buffer && + (GST_BUFFER_SIZE(demux->prev_image_buffer) == GST_BUFFER_SIZE(image_buffer))) { + if (!memcmp (GST_BUFFER_DATA(demux->prev_image_buffer), GST_BUFFER_DATA(image_buffer), GST_BUFFER_SIZE(image_buffer))) { + GST_INFO_OBJECT (demux, "current & previous embedded images are same..no need to post image again"); + gst_buffer_unref (image_buffer); + goto skip_posting_image; + } + } + + if (demux->prev_image_buffer) { + gst_buffer_unref (demux->prev_image_buffer); + } + demux->prev_image_buffer = gst_buffer_copy(image_buffer); + + g_value_init (&codec_type, G_TYPE_STRING); + g_value_init (&image_data, GST_TYPE_BUFFER); + gst_value_set_buffer(&image_data, image_buffer); + + image_header = g_strndup((gchar *) image_buffer->data, 8); + + if((image_header[0] == 0xFF) && (image_header[1] == 0xD8)) { + GST_INFO_OBJECT(demux, "Found JPEG image header"); + g_value_set_static_string (&codec_type, "image/jpeg"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } else if (!g_strcmp0(image_header, "\211PNG\015\012\032\012")) { + GST_INFO_OBJECT(demux, "Found PNG image header"); + g_value_set_static_string (&codec_type, "image/png"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } else { + g_value_set_static_string (&codec_type, "image/unknown"); + GST_INFO_OBJECT(demux, "Unknown image header"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } + + gst_tag_list_add_value (tag_list, GST_TAG_MERGE_APPEND, GST_TAG_IMAGE, &image_data); + + GST_INFO_OBJECT(demux, "Set value : %s", g_value_get_string (&codec_type)); + g_value_unset(&codec_type); + + tag_message = gst_message_new_tag (GST_OBJECT_CAST (demux), tag_list); + if(!gst_element_post_message (GST_ELEMENT_CAST (demux), tag_message)) { + GST_ERROR_OBJECT (demux, "failed to post fixed image tag"); + } + + GST_INFO_OBJECT (demux, "successfully posted image tag..."); + gst_buffer_unref (image_buffer); + g_free (image_header); + } + +skip_posting_image: + + gst_hlsdemux2_destroy_fragment_download (demux); + + if (demux->fdownloader->remaining_data) { + free (demux->fdownloader->remaining_data); + demux->fdownloader->remaining_data = NULL; + } + + demux->fdownloader->remaining_size = 0; + demux->fdownloader->src_downloaded_size = 0; + demux->fdownloader->queue_downloaded_size = 0; + demux->fdownloader->download_stop_ts = demux->fdownloader->download_start_ts = 0; + demux->fdownloader->applied_fast_switch = FALSE; + demux->fdownloader->content_size = 0; + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (demux, "returning false due to flushing/cancelled"); + goto error; + } else if (demux->fdownloader->get_next_frag || demux->fdownloader->applied_fast_switch) { + GST_INFO_OBJECT (demux, "Requesting next fragment due to error or same sequence number from different variant"); + goto exit; + } + + demux->fdownloader->ndownloaded++; + + GST_INFO_OBJECT (demux, "number of fragments downloaded = %d", demux->fdownloader->ndownloaded); + + /* reset the count */ + demux->soup_request_fail_cnt = HLSDEMUX2_SOUP_FAILED_CNT; + +exit: + if (demux->private_stream) { + g_free (demux->private_stream); + demux->private_stream = NULL; + } + g_mutex_unlock (demux->fdownloader->lock); + + return TRUE; + +error: + if (demux->private_stream) { + g_free (demux->private_stream); + demux->private_stream = NULL; + } + g_mutex_unlock (demux->fdownloader->lock); + + return FALSE; +} + +static gboolean +gst_hlsdemux2_change_playlist (GstHLSDemux2 * demux, guint max_bitrate, gboolean *is_switched) +{ + GList *previous_variant, *current_variant; + gint old_bandwidth, new_bandwidth; + + previous_variant = demux->client->main->current_variant; + current_variant = gst_m3u8_client_get_playlist_for_bitrate (demux->client, max_bitrate); + + old_bandwidth = GST_M3U8 (previous_variant->data)->bandwidth; + new_bandwidth = GST_M3U8 (current_variant->data)->bandwidth; + + /* Don't do anything else if the playlist is the same */ + if (new_bandwidth == old_bandwidth) { + if (is_switched) + *is_switched = FALSE; + return TRUE; + } + + GST_M3U8_CLIENT_LOCK (demux->client); + demux->client->main->current_variant = current_variant; + GST_M3U8_CLIENT_UNLOCK (demux->client); + + gst_m3u8_client_set_current (demux->client, current_variant->data); + + GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching" + " to bitrate %dbps", old_bandwidth, max_bitrate, new_bandwidth); + + gst_hlsdemux2_apply_disc(demux); + + if (is_switched) + *is_switched = TRUE; + + return TRUE; +} + +static gboolean +gst_hlsdemux2_get_next_fragment (GstHLSDemux2 * demux, gboolean *is_error) +{ + const gchar *next_fragment_uri = NULL;; + gchar *next_fragment_key_uri = NULL; + gchar *iv = NULL; + GstClockTime duration; + GstClockTime timestamp; + gboolean discont = FALSE; + gboolean bret = TRUE; + GstClockTime lookup_time = 0; + guint i = 0; + GstHLSDemux2Stream *stream = NULL; + + if (!demux->is_live) { + for (i = 0; i< HLSDEMUX2_STREAM_NUM; i++) { + stream = demux->streams[i]; + if (stream) { + lookup_time = stream->lts + stream->frame_duration + (0.5 * GST_SECOND); + GST_INFO_OBJECT (stream->pad, "Lookup time = %"GST_TIME_FORMAT, GST_TIME_ARGS(lookup_time)); + stream->frame_duration = 0; + if (stream->type == HLSDEMUX2_STREAM_AUDIO) + break; + } + } + } + + if (!gst_m3u8_client_get_next_fragment (demux->client, lookup_time, + &discont, &next_fragment_uri, &duration, ×tamp, &next_fragment_key_uri, &iv)) { + + GST_INFO_OBJECT (demux, "This playlist doesn't contain more fragments"); + + if (demux->is_live && (demux->client->update_failed_count < DEFAULT_FAILED_COUNT)) { + GST_WARNING_OBJECT (demux, "Could not get next fragment, try again after updating playlist..."); + *is_error = FALSE; + return FALSE; + } else { + goto end_of_list; + } + } + + demux->cfrag_dur = duration; + demux->fdownloader->cur_running_dur += duration; + + GST_LOG_OBJECT (demux, "current running duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->fdownloader->cur_running_dur)); + + GST_DEBUG_OBJECT (demux, "Fetching next fragment = %s & key uri = %s", next_fragment_uri, next_fragment_key_uri); + + /* when hls requests next fragment due to some error like NOT_FOUND, then also we need to set apply disc */ + if (discont || demux->fdownloader->get_next_frag) + gst_hlsdemux2_apply_disc (demux); + + if (next_fragment_key_uri) { + /* download key data & initialize decryption with key data & IV */ + GST_INFO_OBJECT (demux, "Fetching next fragment key %s", next_fragment_key_uri); + + if (demux->kdownloader->prev_key_uri) { + if (strcmp (demux->kdownloader->prev_key_uri, next_fragment_key_uri)) { + /* if previous & current key uris are different, download new one */ + if (demux->kdownloader->key) { + gst_buffer_unref (demux->kdownloader->key); + demux->kdownloader->key = NULL; + } + + if (demux->kdownloader->prev_key_uri) + g_free (demux->kdownloader->prev_key_uri); + + demux->kdownloader->prev_key_uri = g_strdup(next_fragment_key_uri); + + /* download the key data as there is a change */ + if (!gst_hlsdemux2_download_key (demux, next_fragment_key_uri)) { + GST_ERROR_OBJECT (demux, "failed to download key..."); + goto error; + } + } else { + GST_INFO_OBJECT (demux, "already having the key...no need to download again"); + } + } else { + if (demux->kdownloader->key) { + gst_buffer_unref (demux->kdownloader->key); + demux->kdownloader->key = NULL; + } + + demux->kdownloader->prev_key_uri = g_strdup(next_fragment_key_uri); + + if (!gst_hlsdemux2_download_key (demux, next_fragment_key_uri)) { + GST_ERROR_OBJECT (demux, "failed to download key..."); + goto error; + } + /* reset the count */ + demux->soup_request_fail_cnt = HLSDEMUX2_SOUP_FAILED_CNT; + } + + if (!demux->kdownloader->key || !GST_BUFFER_DATA (demux->kdownloader->key)) { + GST_ERROR_OBJECT (demux, "eos received without key content..."); + goto error; + } + + if (!gst_m3u8_client_decrypt_init (demux->client, GST_BUFFER_DATA (demux->kdownloader->key), iv)) { + GST_ERROR_OBJECT (demux, "failed to initialize AES decryption..."); + goto error; + } + + demux->fdownloader->is_encrypted = TRUE; + } + + if (!gst_hlsdemux2_download_fragment (demux, next_fragment_uri)) { + GST_ERROR_OBJECT (demux, "failed to download fragment..."); + goto error; + } + +exit: + if (next_fragment_uri) + g_free ((gpointer)next_fragment_uri); + if (next_fragment_key_uri) + g_free ((gpointer)next_fragment_key_uri); + if (iv) + g_free ((gpointer)iv); + + return bret; + +error: + if (!demux->flushing) + *is_error = TRUE; + bret = FALSE; + goto exit; + + end_of_list: + GST_INFO_OBJECT (demux, "Reached end of playlist, sending EOS"); + + gst_hlsdemux2_push_eos (demux); + + demux->end_of_playlist = TRUE; + bret = FALSE; + goto exit; +} + + +static gboolean +gst_hlsdemux2_switch_playlist (GstHLSDemux2 * demux, gboolean *is_switched) +{ + GST_M3U8_CLIENT_LOCK (demux->client); + if (!demux->client->main->lists) { + /* not a variant to switch */ + GST_M3U8_CLIENT_UNLOCK (demux->client); + GST_INFO_OBJECT (demux, "not a variant to switch..."); + return TRUE; + } + GST_M3U8_CLIENT_UNLOCK (demux->client); + + if (demux->force_lower_bitrate && (demux->fdownloader->ndownloaded % FORCE_LOW_BITRATE_AFTER_CNT == 0)) { + demux->fdownloader->download_rate = 0; // Using some temp lowest value + GST_WARNING_OBJECT (demux, "resetting to lowest one bitrate = %"G_GUINT64_FORMAT, demux->fdownloader->download_rate); + } + + return gst_hlsdemux2_change_playlist (demux, demux->fdownloader->download_rate, is_switched); +} + +static void +gst_hlsdemux2_apply_disc (GstHLSDemux2 * demux) +{ + int i = 0; + GstHLSDemux2Stream *stream = NULL; + + for (i = 0; i< HLSDEMUX2_STREAM_NUM; i++) { + stream = demux->streams[i]; + + if (stream) { + stream->apply_disc = TRUE; + GST_INFO_OBJECT (stream->pad, "apply discontinuity..."); + } + } +} + +static void +gst_hlsdemux2_fragment_download_loop (GstHLSDemux2 * demux) +{ + gboolean is_error = FALSE; + gboolean bret = FALSE; + GTimeVal tmp_update = {0, }; + GTimeVal current; + guint64 current_time = 0; + guint64 nextupdate_time = 0; + + /* if variant playlist, get current subplaylist first */ + if (gst_m3u8_client_has_variant_playlist(demux->client)) { + gboolean is_error = FALSE; + + if (!gst_hlsdemux2_update_playlist (demux, FALSE, &is_error)) { + GST_ERROR_OBJECT (demux, "failed to update playlist. uri : %s", gst_m3u8_client_get_current_uri(demux->client)); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not update the playlist"), (NULL)); + goto exit; + } + } else if (demux->is_live) { + /* single variant live.. so schedule for starting */ + if (demux->is_live) + gst_hlsdemux2_schedule (demux); + } + + if (demux->fdownloader->find_mediaseq) { + GList *walk; + GstClockTime current_pos, target_pos; + gint current_sequence; + GstM3U8MediaFile *file; + guint i = 0; + GstHLSDemux2Stream *stream = NULL; + + GST_M3U8_CLIENT_LOCK (demux->client); + file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data); + current_sequence = file->sequence; + current_pos = 0 ; + target_pos = demux->fdownloader->seeked_pos; + for (walk = demux->client->current->files; walk; walk = walk->next) { + file = walk->data; + + current_sequence = file->sequence; + if (current_pos <= target_pos && + target_pos < current_pos + file->duration) { + break; + } + current_pos += file->duration; + } + GST_M3U8_CLIENT_UNLOCK (demux->client); + + if (walk == NULL) { + GST_WARNING_OBJECT (demux, "Could not find seeked fragment"); + } + GST_M3U8_CLIENT_LOCK (demux->client); + GST_INFO_OBJECT (demux, "seeking to sequence %d", current_sequence); + demux->client->sequence = current_sequence; + GST_M3U8_CLIENT_UNLOCK (demux->client); + demux->ns_start = demux->fdownloader->cur_running_dur = current_pos; // NON-accurate seek + + for (i = 0; i< HLSDEMUX2_STREAM_NUM; i++) { + stream = demux->streams[i]; +#ifdef LATEST_AV_SYNC + if (stream) { + stream->lts = stream->total_stream_time = current_pos; + GST_INFO_OBJECT (stream->pad, "Changed stream->lts to %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->lts)); + } +#else + if (stream && stream->type == HLSDEMUX2_STREAM_AUDIO) { + stream->lts = current_pos; + } +#endif + } + + demux->fdownloader->find_mediaseq = FALSE; + } + + demux->target_duration = gst_m3u8_client_get_target_duration(demux->client); + demux->total_cache_duration = DEFAULT_NUM_FRAGMENTS_CACHE * demux->target_duration; + demux->is_live = gst_m3u8_client_is_live(demux->client); + + GST_INFO_OBJECT (demux, "Total cache duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(demux->total_cache_duration)); + + while (TRUE) { + + if (demux->cancelled) + goto exit; + + /* get the next fragement */ + bret = gst_hlsdemux2_get_next_fragment (demux, &is_error); + + if (!bret) { + if (is_error) { + GST_ERROR_OBJECT (demux, "error in getting next fragment"); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("could not download fragment"), (NULL)); + goto exit; + } else { + if (!demux->end_of_playlist) { + if (demux->flushing) { + GST_WARNING_OBJECT (demux, "SEEK is in progress.. pause the task"); + goto exit; + } else if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) { + GST_WARNING_OBJECT (demux, "Could not update fragment & playlist update failed count = %d", + demux->client->update_failed_count); + } else { + GST_ERROR_OBJECT (demux, "Could not get next fragment.."); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not get next fragment..."), (NULL)); + goto exit; + } + } else { + GST_INFO_OBJECT (demux, "end of fragment download, doing pause"); + goto exit; + } + } + } else { + /* reset the update failed count */ + demux->client->update_failed_count = 0; + } + + if (demux->cancelled) + goto exit; + + if (demux->is_live) { + /* get the current time */ + current.tv_sec = current.tv_usec = 0; + g_get_current_time (¤t); + + current_time = (current.tv_sec * 1000000)+ current.tv_usec; + nextupdate_time = (demux->next_update.tv_sec * 1000000)+ demux->next_update.tv_usec; + } + + if (demux->is_live && ((current_time > nextupdate_time) || !bret)) { + gboolean is_switched = FALSE; + + /* try to switch to another bitrate if needed */ + // TODO: take care of return value + gst_hlsdemux2_switch_playlist (demux, &is_switched); + + g_mutex_lock (demux->pl_update_lock); + + /* block until the next scheduled update or the exit signal */ + bret = g_cond_timed_wait (demux->pl_update_cond, demux->pl_update_lock, &demux->next_update); + + g_mutex_unlock (demux->pl_update_lock); + + GST_DEBUG_OBJECT (demux, "playlist update wait is completed. reason : %s", bret ? "Received signal" : "time-out"); + + tmp_update.tv_sec = 0; + tmp_update.tv_usec = 0; + + g_get_current_time (&tmp_update); + + if (bret) { + GST_DEBUG_OBJECT (demux, "Sombody signalled manifest waiting... going to exit and diff = %ld", + ((demux->next_update.tv_sec * 1000000)+ demux->next_update.tv_usec) - ((tmp_update.tv_sec * 1000000)+ tmp_update.tv_usec)); + goto exit; + } else if (demux->cancelled) { + GST_WARNING_OBJECT (demux, "closing is in progress..exit now"); + goto exit; + } + + if (!gst_hlsdemux2_update_playlist (demux, FALSE, &is_error)) { + if (is_error) { + GST_ERROR_OBJECT (demux, "failed to update playlist..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to update playlist"), (NULL)); + goto exit; + } else { + if (demux->flushing) { + GST_WARNING_OBJECT (demux, "SEEK is in progress.. pause the task"); + goto exit; + } else if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) { + GST_WARNING_OBJECT (demux, "Could not update playlist & playlist update failed count = %d", + demux->client->update_failed_count); + continue; + } else { + GST_ERROR_OBJECT (demux, "Could not update playlist.."); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not update playlist..."), (NULL)); + goto exit; + } + } + } + + } else { + gboolean is_switched = FALSE; + + /* try to switch to another bitrate if needed */ + // TODO: take care of return value + + /* when in recovery mode, do not obey download rates */ + if (demux->pldownloader->recovery_mode == HLSDEMUX2_NO_RECOVERY) + gst_hlsdemux2_switch_playlist (demux, &is_switched); + + if (is_switched) { + if (!gst_hlsdemux2_update_playlist (demux, FALSE, &is_error)) { + if (is_error) { + GST_ERROR_OBJECT (demux, "failed to update playlist..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to update playlist"), (NULL)); + goto exit; + } else { + if (demux->flushing) { + GST_WARNING_OBJECT (demux, "SEEK is in progress.. pause the task"); + goto exit; + } else if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) { + GST_WARNING_OBJECT (demux, "Could not update playlist & playlist update failed count = %d", + demux->client->update_failed_count); + continue; + } else { + GST_ERROR_OBJECT (demux, "Could not update playlist.."); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not update playlist..."), (NULL)); + goto exit; + } + } + } + } else if (demux->is_live) { + GstClockTime current_time = gst_util_get_timestamp(); + + if ((current_time - demux->pldownloader->download_start_ts) < + (PLAYLIST_REFRESH_TIMEOUT - (HLSDEMUX2_FAST_CHECK_CRITICAL_TIME_FACTOR * demux->target_duration) - HLSDEMUX2_OVERHEAD)) { + GST_INFO_OBJECT (demux, "Eligible to download next fragment w/o playlist update : " + "elapsed time since last playlist request = %"GST_TIME_FORMAT" and max_time_limit = %"GST_TIME_FORMAT, + GST_TIME_ARGS(current_time - demux->pldownloader->download_start_ts), + GST_TIME_ARGS(PLAYLIST_REFRESH_TIMEOUT - (HLSDEMUX2_FAST_CHECK_CRITICAL_TIME_FACTOR * demux->target_duration) - HLSDEMUX2_OVERHEAD)); + } else { + + GST_INFO_OBJECT (demux, "NOT Eligible to download next fragment w/o playlist update : " + "elapsed time since previous request = %"GST_TIME_FORMAT" and max_time_limit = %"GST_TIME_FORMAT, + GST_TIME_ARGS(current_time - demux->pldownloader->download_start_ts), + GST_TIME_ARGS(PLAYLIST_REFRESH_TIMEOUT - (HLSDEMUX2_FAST_CHECK_CRITICAL_TIME_FACTOR * demux->target_duration) - HLSDEMUX2_OVERHEAD)); + + /* we are not eligible to download, next fragment.. So wait till next playlist update */ + g_mutex_lock (demux->pl_update_lock); + /* block until the next scheduled update or the exit signal */ + bret = g_cond_timed_wait (demux->pl_update_cond, demux->pl_update_lock, &demux->next_update); + g_mutex_unlock (demux->pl_update_lock); + + GST_DEBUG_OBJECT (demux, "playlist update wait is completed. reason : %s", bret ? "Received signal" : "time-out"); + + tmp_update.tv_sec = 0; + tmp_update.tv_usec = 0; + + g_get_current_time (&tmp_update); + + if (bret) { + GST_DEBUG_OBJECT (demux, "Sombody signalled manifest waiting... going to exit and diff = %ld", + ((demux->next_update.tv_sec * 1000000)+ demux->next_update.tv_usec) - ((tmp_update.tv_sec * 1000000)+ tmp_update.tv_usec)); + goto exit; + } else if (demux->cancelled) { + GST_WARNING_OBJECT (demux, "closing is in progress..exit now"); + goto exit; + } + + if (!gst_hlsdemux2_update_playlist (demux, FALSE, &is_error)) { + if (is_error) { + GST_ERROR_OBJECT (demux, "failed to update playlist..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to update playlist"), (NULL)); + goto exit; + } else { + if (demux->flushing) { + GST_WARNING_OBJECT (demux, "SEEK is in progress.. pause the task"); + goto exit; + } else if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) { + GST_WARNING_OBJECT (demux, "Could not update playlist & playlist update failed count = %d", + demux->client->update_failed_count); + continue; + } else { + GST_ERROR_OBJECT (demux, "Could not update playlist.."); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not update playlist..."), (NULL)); + goto exit; + } + } + } + } + } + } + } + +exit: + GST_WARNING_OBJECT (demux, "Going to PAUSE download task from self"); + gst_task_pause (demux->download_task); + return; +} + +static void +gst_hlsdemux2_calculate_popped_duration (GstHLSDemux2 *demux, GstHLSDemux2Stream *stream, + GstBuffer *outbuf) +{ + gpointer data = NULL; + gint i = g_queue_get_length (stream->queue); + + /* get the buffer with valid timestamp from tail of the queue */ + while (i > 1) { + data = g_queue_peek_nth (stream->queue, (i - 1)); + if (data == NULL) { + return; + } + + if (GST_IS_BUFFER ((GstBuffer *)data)) { + if (GST_BUFFER_TIMESTAMP_IS_VALID(data)) { + /* found valid timestamp & stop searching */ + GST_LOG_OBJECT (stream->pad, "data found buffer with valid ts = %"GST_TIME_FORMAT " len = %d & i = %d", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(data)), g_queue_get_length (stream->queue), i); + break; + } + } + i--; + } + + if (data == NULL) { + return; + } + + if (GST_BUFFER_TIMESTAMP (outbuf) <= GST_BUFFER_TIMESTAMP ((GstBuffer *)data)) { + stream->cached_duration = GST_BUFFER_TIMESTAMP ((GstBuffer *)data) - GST_BUFFER_TIMESTAMP (outbuf); + GST_DEBUG_OBJECT (stream->pad, "cache duration in popping : %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->cached_duration)); + } else { + GST_ERROR_OBJECT (stream->pad, "Wrong order.. not calculating"); + } + + return; +} + +static void +gst_hlsdemux2_push_loop (GstHLSDemux2Stream *stream) +{ + GstHLSDemux2 *demux = stream->parent; + GstFlowReturn fret = GST_FLOW_OK; + gpointer data = NULL; + + // TODO: need to take care of EOS handling.... + + if (demux->cancelled || demux->flushing) + goto error; + + g_mutex_lock (stream->queue_lock); + + if (g_queue_is_empty (stream->queue)) { + GST_LOG_OBJECT (stream->pad,"queue is empty wait till, some buffers are available..."); + g_cond_wait (stream->queue_empty, stream->queue_lock); + GST_LOG_OBJECT (stream->pad,"Received queue empty signal..."); + } + + if (demux->cancelled || demux->flushing) { + GST_ERROR_OBJECT (stream->pad, "Shutting down push loop"); + g_mutex_unlock (stream->queue_lock); + goto error; + } + + if (g_queue_is_empty (stream->queue)) { + GST_ERROR_OBJECT (stream->pad, "Queue empty undesired...."); + g_mutex_unlock (stream->queue_lock); + goto error; + } + + data = g_queue_pop_head (stream->queue); + if (!data) { + GST_ERROR_OBJECT (stream->pad, "Received null data..."); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Unhandled GstObjectType"), (NULL)); + g_mutex_unlock (stream->queue_lock); + goto error; + } + + /* Calculate duration only when + * 1. popped obj is a buffer and + * 2. buffer has valid ts and + * 3. queue length > 1 + */ + + if (GST_IS_BUFFER(data) && + GST_BUFFER_TIMESTAMP_IS_VALID(data) ) { + + /* calculate buffering duration */ + gst_hlsdemux2_calculate_popped_duration (demux, stream, data); + + if (stream->cached_duration < 0) { + GST_WARNING_OBJECT (stream->pad, "Wrong cached duration in push_loop...\n"); + stream->cached_duration = 0; + } + } + + g_mutex_unlock (stream->queue_lock); + + if (GST_IS_EVENT(data)) { + GstEvent *event = (GstEvent *)data; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NEWSEGMENT: { + GstFormat format; + gboolean update; + gdouble rate, arate; + gint64 start, stop, pos; + gst_event_parse_new_segment_full(event, &update, &rate, &arate, &format, &start, &stop, &pos); + GST_INFO_OBJECT (stream->pad, "Pushing newsegment to downstream : rate = %0.3f, start = %"GST_TIME_FORMAT + ", stop = %"GST_TIME_FORMAT, rate, GST_TIME_ARGS(start), GST_TIME_ARGS(stop)); + } + break; + case GST_EVENT_EOS: + GST_INFO_OBJECT (stream->pad, "going to push eos event to downstream"); + stream->eos = TRUE; + break; + default: + GST_ERROR_OBJECT (stream->pad, "not handled event...still pushing event"); + break; + } + if (!gst_pad_push_event (stream->pad, event)) { + GST_ERROR_OBJECT (demux, "failed to push newsegment event"); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("failed to push '%s' event", GST_EVENT_TYPE_NAME(event)), (NULL)); + goto error; + } + + GST_INFO_OBJECT (stream->pad, "Pushed '%s' event...", GST_EVENT_TYPE_NAME(event)); + + if (stream->eos) { + //gst_element_post_message (GST_ELEMENT_CAST (stream->sink), gst_message_new_eos (GST_OBJECT_CAST(stream->sink))); + GST_INFO_OBJECT (stream->pad, "Pausing the task"); + goto error; + } + } else if (GST_IS_BUFFER(data)) { + GstCaps *temp_caps = NULL; + g_cond_signal (stream->queue_full); + + GST_DEBUG_OBJECT (stream->pad, "Pushing buffer : size = %d, ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_BUFFER_SIZE(data), GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(data)), GST_TIME_ARGS(GST_BUFFER_DURATION(data))); + + temp_caps = gst_buffer_get_caps((GstBuffer *)data); + temp_caps = gst_caps_make_writable (temp_caps); + gst_caps_set_simple (temp_caps,"hls_streaming", G_TYPE_BOOLEAN, TRUE, NULL); + gst_buffer_set_caps((GstBuffer *)data, temp_caps); + gst_caps_unref(temp_caps); + + /* push data to downstream*/ + fret = gst_pad_push (stream->pad, data); + if (fret != GST_FLOW_OK) { + GST_ERROR_OBJECT (stream->pad, "failed to push data, reason : %s", gst_flow_get_name (fret)); + goto error; + } + } else { + GST_ERROR_OBJECT (stream->pad, "unhandled object type..still pushing"); + //GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Unhandled GstObjectType"), (NULL)); + //return; + gst_object_unref (data); + } + + if (demux->cancelled || demux->flushing) { + goto error; + } + + return; + +error: + { + GST_WARNING_OBJECT (stream->pad, "Pausing the push task..."); + + if (fret < GST_FLOW_UNEXPECTED) { + GST_ERROR_OBJECT (stream->pad, "Crtical error in push loop...."); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("failed to push. reason - %s", gst_flow_get_name (fret)), (NULL)); + } + + gst_pad_pause_task (stream->pad); + return; + } +} + +// TODO: need to review change_playlist API + +static gboolean +gst_hlsdemux2_schedule (GstHLSDemux2 * demux) +{ + gfloat update_factor; + gint count; + GstClockTime last_frag_duration; + + /* As defined in §6.3.4. Reloading the Playlist file: + * "If the client reloads a Playlist file and finds that it has not + * changed then it MUST wait for a period of time before retrying. The + * minimum delay is a multiple of the target duration. This multiple is + * 0.5 for the first attempt, 1.5 for the second, and 3.0 thereafter." + */ + count = demux->client->update_failed_count; + if (count < 3) + update_factor = update_interval_factor[count]; + else + update_factor = update_interval_factor[3]; + + /* schedule the next update using the target duration field of the + * playlist */ + demux->next_update.tv_sec = 0; + demux->next_update.tv_usec = 0; + + last_frag_duration = gst_m3u8_client_get_last_fragment_duration (demux->client); + + GST_DEBUG_OBJECT (demux, "last fragment duration = %"GST_TIME_FORMAT" and next update = %"GST_TIME_FORMAT, + GST_TIME_ARGS(last_frag_duration), GST_TIME_ARGS(GST_TIME_AS_USECONDS(last_frag_duration) * 1000)); + + g_get_current_time (&demux->next_update); + + //g_time_val_add (&demux->next_update, last_frag_duration / GST_SECOND * G_USEC_PER_SEC * update_factor); + g_time_val_add (&demux->next_update, GST_TIME_AS_USECONDS(last_frag_duration)* update_factor); + + return TRUE; +} + +static void +gst_hlsdemux2_new_pad_added (GstElement *element, GstPad *srcpad, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GstPad *sinkpad = NULL; + GstCaps *caps = NULL; + HLSDemux2SinkBin *sinkbin = NULL; + gchar *demuxer_name = NULL; + gchar *src_pad_name = NULL; + + GST_INFO_OBJECT (demux, "received the src_pad '%s' from mpeg2ts demuxer...", GST_PAD_NAME(srcpad)); + + if (strstr (GST_PAD_NAME(srcpad), "private")) { + /* handle private image TAG */ + gst_hlsdemux2_handle_private_pad (demux, srcpad); + return; + } + + caps = GST_PAD_CAPS (srcpad); + demuxer_name = GST_ELEMENT_NAME (element); + + sinkbin = gst_hlsdemux2_create_stream (demux, demuxer_name, caps); + if (!sinkbin) { + return; + } + + sinkpad = gst_element_get_pad(GST_ELEMENT(sinkbin->sinkbin), "sink"); + if (!sinkpad) { + GST_ERROR_OBJECT (demux, "failed to get sinkpad from element - %s", GST_PAD_NAME(sinkbin->sinkbin)); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("could not get sink pad"), (NULL)); + return; + } + + /* link demuxer srcpad & sink element's sink pad */ + if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) { + GST_ERROR_OBJECT (demux, "failed to link pad '%s' & sink's sink pad", GST_PAD_NAME(srcpad)); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("Could not link pads.."), (NULL)); + gst_object_unref(sinkpad); + return; + } + + if (sinkbin->parser) { + GST_INFO_OBJECT (demux, "linking parser"); + if (!gst_element_link_many (sinkbin->queue, sinkbin->parser, sinkbin->sink, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link sink bin elements"); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("Could not link pads.."), (NULL)); + gst_object_unref(sinkpad); + return; + } + } else { + if (!gst_element_link_many (sinkbin->queue, sinkbin->sink, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link sink bin elements"); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("Could not link pads.."), (NULL)); + gst_object_unref(sinkpad); + return; + } + } + demux->fdownloader->cur_stream_cnt++; + + src_pad_name = gst_pad_get_name(srcpad); + GST_INFO_OBJECT (demux, "succesfully linked pad (%s) with stream pad and current stream cnt = %d", + src_pad_name, demux->fdownloader->cur_stream_cnt); + g_free(src_pad_name); + src_pad_name = NULL; + + gst_element_set_state (GST_ELEMENT(sinkbin->sinkbin), GST_STATE_PLAYING); + + gst_object_unref (sinkpad); +} + +static gboolean +gst_hlsdemux2_check_stream_type_exist (GstHLSDemux2 *demux, HLSDEMUX2_STREAM_TYPE stream_type) +{ + int i = 0; + GstHLSDemux2Stream *stream = NULL; + + for (i = 0; i< HLSDEMUX2_STREAM_NUM; i++) { + stream = demux->streams[i]; + + if (stream && (stream->type == stream_type)) { + GST_INFO_OBJECT (demux, "stream type '%d' is already present", stream_type); + return TRUE; + } + } + + GST_INFO_OBJECT (demux, "received new stream type [%d]", stream_type); + + return FALSE; +} + +static HLSDemux2SinkBin * +gst_hlsdemux2_create_stream (GstHLSDemux2 *demux, gchar *demuxer_name, GstCaps *caps) +{ + GstHLSDemux2Stream *stream = NULL; + GstPad *sinkpad = NULL; + GstPad *linkpad = NULL; + HLSDEMUX2_STREAM_TYPE stream_type; + gchar *element_name = NULL; + gboolean stream_exist = FALSE; + gulong sink_probe; + HLSDemux2SinkBin *bin = NULL; + GstStructure *structure = NULL; + gchar *mime = NULL; + gchar *stream_name = NULL; + + stream = g_new0 (GstHLSDemux2Stream, 1); + + structure = gst_caps_get_structure (caps, 0); + + mime = gst_structure_get_name (structure); + + if (strstr (mime, "video")) { + stream_type = HLSDEMUX2_STREAM_VIDEO; + GST_DEBUG_OBJECT (demux, "Its a Multi-variant, Audio only stream.."); + demux->stream_config = HLSDEMUX2_MULTI_VARIANT; + stream_name = g_strdup ("video"); + } else if (strstr (mime, "audio")) { + stream_type = HLSDEMUX2_STREAM_AUDIO; + stream_name = g_strdup ("audio"); + } else if (strstr (mime, "subpicture")) { + stream_type = HLSDEMUX2_STREAM_TEXT; + stream_name = g_strdup ("subpicture"); + } else if (strstr (mime, "private")) { + stream_type = HLSDEMUX2_STREAM_PRIVATE; + stream_name = g_strdup ("private"); + } else { + GST_ELEMENT_ERROR (demux, CORE, PAD, ("Received unknown named pad"), (NULL)); + goto error; + } + + stream_exist = gst_hlsdemux2_check_stream_type_exist (demux, stream_type); + + if (!stream_exist) { + stream = g_new0 (GstHLSDemux2Stream, 1); + gst_hlsdemux2_stream_init (demux, stream, stream_type, stream_name, caps); + + if (!stream->is_linked) { + goto error; + } + } else { + int i = 0; + + for (i = 0; i< HLSDEMUX2_STREAM_NUM; i++) { + stream = demux->streams[i]; + if (stream && (stream->type == stream_type)) { + GST_INFO_OBJECT (demux, "found the stream - '%d'", stream->type); + break; + } + } + } + + if (!stream) + goto error; + + bin = g_new0 (HLSDemux2SinkBin, 1); + + element_name = g_strdup_printf("%s-%s", stream_name, "bin"); + bin->sinkbin = GST_BIN(gst_bin_new (element_name)); + if (!bin->sinkbin) { + GST_ERROR_OBJECT (demux, "failed to create sink bin - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("failed to create bin - %s", element_name), (NULL)); + goto error; + } + g_free (element_name); + element_name = NULL; + + /* create queue element */ + element_name = g_strdup_printf("%s-%s", stream_name, "queue"); + bin->queue = gst_element_factory_make ("queue", element_name); + if (!bin->queue) { + GST_ERROR_OBJECT (demux, "failed to create queue element - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("failed to create element - %s", element_name), (NULL)); + goto error; + } + g_free (element_name); + element_name = NULL; + + if ((stream->type == HLSDEMUX2_STREAM_AUDIO) && + g_strstr_len(demuxer_name, strlen(demuxer_name), "id3")) { + /* create parser element */ + + GST_INFO_OBJECT (stream->pad, "demuxer is id3demuxer, so create audio parser..."); + + element_name = g_strdup_printf("%s-%s", stream_name, "parse"); + bin->parser = gst_element_factory_make ("aacparse", element_name); + if (!bin->parser) { + GST_ERROR_OBJECT (demux, "failed to create parser element - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("failed to create element - %s", element_name), (NULL)); + goto error; + } + g_free (element_name); + element_name = NULL; + gst_bin_add (GST_BIN (bin->sinkbin), bin->parser); + } + + /* create sink element */ + element_name = g_strdup_printf("%s-%s", stream_name, "sink"); + bin->sink = gst_element_factory_make ("appsink", element_name); + if (!bin->sink) { + GST_ERROR_OBJECT (demux, "failed to create sink element - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("failed to create element - %s", element_name), (NULL)); + goto error; + } + + g_object_set (G_OBJECT (bin->sink), "sync", FALSE, "emit-signals", TRUE, NULL); + g_signal_connect (bin->sink, "new-buffer", G_CALLBACK (gst_hlsdemux2_downloader_new_buffer), stream); + g_signal_connect (bin->sink, "eos", G_CALLBACK (gst_hlsdemux2_downloader_eos), stream); + + gst_bin_add_many (GST_BIN (bin->sinkbin), bin->queue, bin->sink, NULL); + + gst_bin_add (GST_BIN (demux->fdownloader->pipe), GST_ELEMENT(bin->sinkbin)); + + /* set queue element to PLAYING state */ + gst_element_set_state (GST_ELEMENT(bin->sinkbin), GST_STATE_READY); + + sinkpad = gst_element_get_pad(bin->sink, "sink"); + if (!sinkpad) { + GST_ERROR_OBJECT (demux, "failed to get sinkpad from element - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("Count not get sink pad"), (NULL)); + goto error; + } + g_free (element_name); + element_name = NULL; + + /* adding probe to get new segment events */ + sink_probe = gst_pad_add_event_probe (sinkpad, + G_CALLBACK (gst_hlsdemux2_sink_event_handler), stream); + + if (!stream_exist) { + /* add stream to stream_type list */ + demux->streams[stream_type] = stream; + demux->active_stream_cnt++; + GST_INFO_OBJECT (demux, "number of active streams = %d", demux->active_stream_cnt); + } + + linkpad = gst_element_get_pad(bin->queue, "sink"); + if (!linkpad) { + element_name = gst_element_get_name (bin->queue); + GST_ERROR_OBJECT (demux, "failed to get sinkpad from element - %s", element_name); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("could not get sink pad"), (NULL)); + goto error; + } + + gst_pad_set_active(linkpad,TRUE); + + gst_element_add_pad (GST_ELEMENT(bin->sinkbin), gst_ghost_pad_new ("sink", linkpad)); + + GST_INFO_OBJECT (stream->pad, "successfully created stream..."); + + demux->fdownloader->sinkbins = g_list_append (demux->fdownloader->sinkbins, bin); + + g_cond_signal (demux->post_msg_start); + + g_free (stream_name); + + return bin; + +error: + g_free (stream); + if (element_name) + g_free (element_name); + + if (stream_name) + g_free (stream_name); + + return NULL; +} + +static gboolean +gst_hlsdemux2_private_image_to_vid(gpointer user_data,GstBuffer *image_buffer) +{ + GstHLSDemux2PvtStream *pvt_stream = (GstHLSDemux2PvtStream *) user_data; + GstHLSDemux2 *demux = (GstHLSDemux2 *) pvt_stream->parent; + GstPad *pad, *srcpad; + GstElement *appsrc, *appsink, *dec, *videorate, *capsfilter, *enc; + GstCaps *scale_caps, *image_caps; + GstBus * bus; + GstFlowReturn fret = GST_FLOW_OK; + + gchar *image_header = g_strndup((gchar *) image_buffer->data, 8); + if(!((image_header[0] == 0xFF) && (image_header[1] == 0xD8))) { + GST_WARNING_OBJECT(demux, "Not a valid JPEG image header : %d %d",image_header[0],image_header[1]); + goto error; + } + + GST_DEBUG_OBJECT(demux, "IMAGE DATA [%d,%d]",pvt_stream->image_buffer->data[0],pvt_stream->image_buffer->data[1]); + + GST_INFO_OBJECT (demux, "Creating jpeg->h264 conversion pipeline"); + + pvt_stream->convert_pipe = gst_pipeline_new ("jpegdec-pipe"); + if (!pvt_stream->convert_pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + goto error; + } + + bus = gst_pipeline_get_bus (GST_PIPELINE (pvt_stream->convert_pipe)); + gst_bus_add_watch (bus, (GstBusFunc)gst_hlsdemux2_imagebuf_pipe_bus_cb, user_data); + gst_object_unref (bus); + + appsrc = gst_element_factory_make ("appsrc", "imgbuf-src"); + if (!appsrc) { + GST_ERROR_OBJECT (demux, "failed to create appSrc element"); + goto error; + } + + appsink = gst_element_factory_make ("appsink", "imgbuf-sink"); + if (!appsink) { + GST_ERROR_OBJECT (demux, "failed to create appSink element"); + goto error; + } + + dec = gst_element_factory_make ("jpegdec", "jpeg-decoder"); + if (!dec) { + GST_ERROR_OBJECT (demux, "failed to create jpeg-decoder element"); + goto error; + } + + videorate = gst_element_factory_make ("videorate", "video-rate"); + if (!videorate) { + GST_ERROR_OBJECT (demux, "failed to create ffmpeg-converter element"); + goto error; + } + + capsfilter = gst_element_factory_make ("capsfilter", "caps-filter"); + if (!capsfilter) { + GST_ERROR_OBJECT (demux, "failed to create caps-filter element"); + goto error; + } + + scale_caps = gst_caps_new_simple ("video/x-raw-yuv", + "width" , G_TYPE_INT, 480, + "height", G_TYPE_INT, 270, + "framerate",GST_TYPE_FRACTION,30,1, + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC('I','4','2','0'), + NULL); + g_object_set (capsfilter, "caps", scale_caps, NULL); + + enc = gst_element_factory_make ("savsenc_h264", "h264-encoder"); + if (!enc) { + GST_ERROR_OBJECT (demux, "failed to create h264-encoder element"); + goto error; + } + + image_caps = gst_caps_new_simple ("image/jpeg", + "framerate", GST_TYPE_FRACTION, 30, 1, + "width", G_TYPE_INT, 480, + "height", G_TYPE_INT, 270, + NULL); + gst_buffer_set_caps (image_buffer, image_caps); + + gst_bin_add_many (GST_BIN (pvt_stream->convert_pipe), appsrc, dec, videorate, capsfilter, enc, appsink, NULL); + if (!gst_element_link_many ( appsrc, dec, videorate, capsfilter, enc, appsink, NULL)) { + GST_ERROR_OBJECT (demux, "failed to link elements..."); + goto error; + } + + pad = gst_element_get_static_pad(appsink,"sink"); + gst_pad_add_buffer_probe (pad,G_CALLBACK (gst_hlsdemux2_set_video_buffer), user_data); + gst_pad_add_event_probe (pad,G_CALLBACK (gst_hlsdemux2_done_video_buffer), user_data); + gst_element_set_state (pvt_stream->convert_pipe, GST_STATE_PLAYING); + + fret = gst_app_src_push_buffer ((GstAppSrc *)appsrc, pvt_stream->image_buffer); + if(fret != GST_FLOW_OK){ + GST_ERROR_OBJECT (demux, "Push Failed; Error: %s[%d]", gst_flow_get_name(fret),fret); + goto error; + } + + fret = gst_app_src_end_of_stream ((GstAppSrc *)appsrc); + if(fret != GST_FLOW_OK){ + GST_ERROR_OBJECT (demux, "Push EOS Failed; Error: %s[%d]", gst_flow_get_name(fret),fret); + goto error; + } + g_free(image_header); + image_header = NULL; + return TRUE; + + error: + GST_ERROR_OBJECT (demux, "ERROR ERROR ERROR: tut tut tut "); + g_free(image_header); + image_header = NULL; + return FALSE; +} + +static gboolean +gst_hlsdemux2_push_dummy_data (GstHLSDemux2Stream *stream) +{ + GstHLSDemux2 *demux = stream->parent; + struct stat stat_results; + GstBuffer *buf = NULL; + gint iread = 0; + gint64 percent = 0; + GstCaps *caps = NULL; + GstBuffer *pushbuf = NULL; + GstClockTime stop = GST_CLOCK_TIME_NONE; + GstClockTime next_ts = GST_CLOCK_TIME_NONE; + gboolean first_frame = TRUE; + gint n = 0; + gboolean convert_success = TRUE; + GstHLSDemux2Stream *cur_stream = NULL; + int dummy_fp = -1; + GstClockTime cdisc = 0; + + GST_INFO_OBJECT (demux, "START dummy video data thread"); + + /* Read dummy frame */ + if(demux->has_image_buffer) { + GstHLSDemux2PvtStream *pvt_stream = demux->private_stream; + + g_mutex_lock (pvt_stream->img_load_lock); + if(pvt_stream->got_img_buffer == FALSE) + g_cond_wait(pvt_stream->img_load_cond, pvt_stream->img_load_lock); + g_mutex_unlock (pvt_stream->img_load_lock); + + GST_LOG_OBJECT (demux, "prev_image_buffer = %p and image_buffer = %p", + demux->prev_image_buffer, pvt_stream->image_buffer); + + /* check whether it is same as previous image */ + if (demux->prev_video_buffer && demux->prev_image_buffer && + (GST_BUFFER_SIZE(demux->prev_image_buffer) == GST_BUFFER_SIZE(pvt_stream->image_buffer))) { + if (!memcmp (GST_BUFFER_DATA(demux->prev_image_buffer), GST_BUFFER_DATA(pvt_stream->image_buffer), + GST_BUFFER_SIZE(pvt_stream->image_buffer))) { + GST_INFO_OBJECT (demux, "current & previous embedded images are same..no need to prepare video buffer"); + gst_buffer_unref(pvt_stream->image_buffer); + pvt_stream->image_buffer = NULL; + buf = gst_buffer_copy(demux->prev_video_buffer); + goto start_push; + } + } + + if (demux->prev_image_buffer) { + gst_buffer_unref (demux->prev_image_buffer); + } + demux->prev_image_buffer = gst_buffer_copy(pvt_stream->image_buffer); + + g_mutex_lock (pvt_stream->convert_lock); + convert_success = gst_hlsdemux2_private_image_to_vid(pvt_stream, pvt_stream->image_buffer); + if(convert_success) + g_cond_wait(pvt_stream->convert_cond, pvt_stream->convert_lock); + g_mutex_unlock (pvt_stream->convert_lock); + + if(pvt_stream->convert_pipe){ + pvt_stream->convert_pipe = NULL; + gst_object_unref(pvt_stream->convert_pipe); + } + + if (demux->prev_video_buffer) { + gst_buffer_unref (demux->prev_video_buffer); + demux->prev_video_buffer = NULL; + } + + if(convert_success){ + buf = pvt_stream->video_buffer; + pvt_stream->video_buffer = NULL; + demux->prev_video_buffer = gst_buffer_copy(buf); + GST_DEBUG_OBJECT (demux, "Set Image from buffer - success [%d,%d]", buf->data[0], buf->data[1]); + GST_INFO_OBJECT (demux, "Going to show embedded image"); + } + } + + //load black frame if error occured while creating video buffer. + if(demux->has_image_buffer == FALSE || convert_success == FALSE) + { + GST_INFO_OBJECT (demux, "Going to show fixed image"); + dummy_fp = open (PREDEFINED_VIDEO_FRAME_LOCATION, O_RDONLY); + if (dummy_fp < 0) { + GST_ERROR_OBJECT (stream->pad, "failed to open dummy data file : %s...", PREDEFINED_VIDEO_FRAME_LOCATION); + GST_ELEMENT_ERROR (demux, RESOURCE, OPEN_READ, ("Failed open file '%s' for reading. reason : %s",PREDEFINED_VIDEO_FRAME_LOCATION ,g_strerror(errno)), (NULL)); + goto quit; + } + + GST_LOG_OBJECT (stream->pad, "opened dummy video file %s succefully...", PREDEFINED_VIDEO_FRAME_LOCATION); + + if (fstat (dummy_fp, &stat_results) < 0) { + GST_ERROR_OBJECT (stream->pad, "failed to get stats of a file..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("Failed get stats. reason : %s", g_strerror(errno)), (NULL)); + close (dummy_fp); + goto quit; + } + + GST_LOG_OBJECT (stream->pad, "size of the dummy file = %d\n", stat_results.st_size); + + buf = gst_buffer_new_and_alloc (stat_results.st_size); + if (!buf) { + GST_ERROR_OBJECT (stream->pad, "failed to allocate memory..."); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + close (dummy_fp); + goto quit; + } + + iread = read (dummy_fp, GST_BUFFER_DATA (buf), stat_results.st_size); + + close (dummy_fp); + } + +start_push: + + for (n = 0; n < HLSDEMUX2_STREAM_NUM; n++) { + cur_stream = demux->streams[n]; + + if (cur_stream && (stream != cur_stream)) { + cdisc = cur_stream->cdisc; + } + } + + stream->nts = stop = stream->fts + demux->cfrag_dur; + stream->total_disc += cdisc; + stream->cdisc = cdisc; + next_ts = stream->fts; + + GST_INFO_OBJECT (stream->pad, "Dummy video start_ts = %"GST_TIME_FORMAT" and stop_ts = %"GST_TIME_FORMAT, + GST_TIME_ARGS(stream->fts), GST_TIME_ARGS(stop)); + + /* set caps on buffer */ + caps = gst_caps_new_simple ("video/x-h264", + "stream-format", G_TYPE_STRING, "byte-stream", + "alignment", G_TYPE_STRING, "nal", + NULL); + + gst_buffer_set_caps (buf, caps); + + if (stream->need_newsegment) { + GST_INFO_OBJECT (stream->pad, "need to send new segment event based on audio"); + g_queue_push_tail (stream->queue, (demux->streams[HLSDEMUX2_STREAM_AUDIO])->newsegment); + stream->need_newsegment = FALSE; + } + + while (TRUE) { + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (stream->pad, "Stopping dummy push task..."); + goto quit; + } + + g_mutex_lock (stream->queue_lock); + + pushbuf = gst_buffer_copy (buf); + gst_buffer_set_caps (pushbuf, caps); + GST_BUFFER_TIMESTAMP (pushbuf) = stream->lts = next_ts; + GST_BUFFER_DURATION (pushbuf) = GST_CLOCK_TIME_NONE; + + if (first_frame) { + GST_BUFFER_FLAG_SET (pushbuf, GST_BUFFER_FLAG_DISCONT); + first_frame = FALSE; + } + + GST_LOG_OBJECT (stream->pad, "Pushing dummy buffer : ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (pushbuf))); + + /* calculate cached duration */ + gst_hlsdemux2_calculate_pushed_duration (demux, stream, pushbuf); + + if (stream->cached_duration >= 0) { + + percent = (stream->cached_duration * 100) / demux->total_cache_duration; + GST_LOG_OBJECT (stream->pad, "percent done = %"G_GINT64_FORMAT, percent); + + if (percent > 100) { + guint64 overall_percent = 0; + + g_mutex_lock (demux->buffering_lock); + overall_percent = demux->percent; + g_mutex_unlock (demux->buffering_lock); + + if (overall_percent < 100) { /* otherwise, may cause blocking while buffering*/ + GST_DEBUG_OBJECT (stream->pad, "@@@@@@@@@@@ queue should not go to wait now @@@@@@@@"); + } else { + /* update buffering & wait if space is not available */ + GST_DEBUG_OBJECT (stream->pad, "Reached more than 100 percent, queue full & wait till free"); + g_cond_wait(stream->queue_full, stream->queue_lock); + GST_DEBUG_OBJECT (stream->pad,"Received signal to add more data..."); + } + } + } + + g_cond_signal (stream->queue_empty); + + g_mutex_unlock (stream->queue_lock); + + /* calculate next timestamp */ + next_ts += HLS_DEFAULT_FRAME_DURATION; + + if (next_ts > stop) { + GST_DEBUG_OBJECT (stream->pad, "Reached Endof the fragment ....\n\n"); + break; + } + } + + if (demux->end_of_playlist) { + /* end of playlist, push EOS to queue */ + GST_INFO_OBJECT (stream->pad, "pushing EOS event to stream's queue"); + g_queue_push_tail (stream->queue, gst_event_new_eos ()); + } + +#ifdef LATEST_AV_SYNC + if (demux->is_live) { + stream->total_stream_time += (stream->lts - stream->fts); + } else { + stream->total_stream_time += (stream->lts - stream->fts + HLS_DEFAULT_FRAME_DURATION); + stream->total_stream_time = stream->nts; + } +#else + stream->total_stream_time += (stream->lts - stream->fts); +#endif + + GST_DEBUG_OBJECT (stream->pad, "---------------- TS VALUES ----------------"); + GST_DEBUG_OBJECT (stream->pad, "valid start ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->fts)); + GST_DEBUG_OBJECT (stream->pad, "valid end ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->lts)); + GST_DEBUG_OBJECT (stream->pad, "fragment duration received = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->lts - stream->fts)); + GST_DEBUG_OBJECT (stream->pad, "total stream time = %"GST_TIME_FORMAT,GST_TIME_ARGS(stream->total_stream_time)); + GST_DEBUG_OBJECT (stream->pad, "total disc time = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->total_disc)); + GST_DEBUG_OBJECT (stream->pad, "next expected start ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->nts)); + GST_DEBUG_OBJECT (stream->pad, "---------------- DUMP VALUES END----------------"); + + stream->apply_disc = FALSE; + stream->fts = GST_CLOCK_TIME_NONE; + stream->valid_fts_rcvd = FALSE; + stream->prev_nts = stream->nts; + +quit: + { + GST_INFO_OBJECT (stream->pad, "Stopping dummy data thread..."); + gst_buffer_unref (buf); + stream->dummy_data_thread = NULL; + return TRUE; + } + +} + +static gboolean +gst_hlsdemux2_sink_event_handler (GstPad * pad, GstEvent * event, gpointer data) +{ + GstHLSDemux2Stream *stream = (GstHLSDemux2Stream *)data; + GstHLSDemux2 *demux = stream->parent; + + if ((GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) && stream->need_newsegment) { + GstEvent *newsegment = NULL; + GstFormat format; + gboolean update; + gdouble rate, arate; + gint64 start, stop, pos; + + newsegment = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, demux->ns_start, -1, demux->ns_start); + + GST_INFO_OBJECT (stream->pad, "Received NEWSEGMENT event..."); + + g_mutex_lock (stream->queue_lock); + + gst_event_parse_new_segment_full(event, &update, &rate, &arate, &format, &start, &stop, &pos); + + if (!GST_CLOCK_TIME_IS_VALID(stream->base_ts)) { + GST_INFO_OBJECT (stream->pad, "storing stream's base timestamp = %"GST_TIME_FORMAT, GST_TIME_ARGS(start)); + stream->base_ts = start; + } + + g_queue_push_tail (stream->queue, newsegment); + + GST_INFO_OBJECT (stream->pad, "Pushed new segment event with start = %"GST_TIME_FORMAT" to queue..", + GST_TIME_ARGS(demux->ns_start)); + + g_mutex_unlock (stream->queue_lock); + + stream->need_newsegment = FALSE; + stream->prev_nts = demux->ns_start; + + if (stream->newsegment) + gst_event_unref (stream->newsegment); + + stream->newsegment = gst_event_copy (newsegment); + } + return TRUE; +} + +static gboolean +hlsdemux2_HTTP_repeat_request (GstHLSDemux2 *demux, gchar *element_name) +{ + if (g_strrstr(element_name, "fragurisrc")) { + guint idx = 0; + GstBuffer *buf = NULL; + + /* clear stream queues if we already downloaded some data */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *stream = demux->streams[idx]; + if (stream ) { + while (!g_queue_is_empty (stream->downloader_queue)) { + buf = g_queue_pop_head (stream->downloader_queue); + gst_buffer_unref (buf); + } + GST_LOG_OBJECT (stream->pad, "cleared stream download queue..."); + g_queue_clear (stream->downloader_queue); + } + } + + /* request the same fragment again */ + if (demux->fragCookie) + g_strfreev (demux->fragCookie); + + g_object_get (demux->fdownloader->urisrc, "cookies", &demux->fragCookie, NULL); + GST_DEBUG_OBJECT (demux, "Got cookies after FRAGMENT download : %s", demux->fragCookie ? *(demux->fragCookie) : NULL); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download fragment AGAIN: %s", demux->frag_uri); + + gst_hlsdemux2_destroy_fragment_download (demux); + + if (!gst_hlsdemux2_create_fragment_download (demux, demux->frag_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + /* download rate calculation : note down start time*/ + demux->fdownloader->download_start_ts = gst_util_get_timestamp(); + + gst_element_set_state (demux->fdownloader->pipe, GST_STATE_PLAYING); + + return TRUE; + } else if (g_strrstr(element_name, "playlisturisrc")) { + + if (demux->playlistCookie) + g_strfreev (demux->playlistCookie); + + g_object_get (demux->pldownloader->urisrc, "cookies", &demux->playlistCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after PLAYLIST download : %s", demux->playlistCookie ? *(demux->playlistCookie) : NULL); + + gst_hlsdemux2_destroy_playlist_download (demux); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download playlist AGAIN: %s", demux->playlist_uri); + if (!gst_hlsdemux2_create_playlist_download (demux, demux->playlist_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + gst_element_set_state (demux->pldownloader->pipe, GST_STATE_PLAYING); + return TRUE; + } else if (g_strrstr(element_name, "keyurisrc")) { + + if (demux->keyCookie) + g_strfreev (demux->keyCookie); + + g_object_get (demux->kdownloader->urisrc, "cookies", &demux->keyCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after KEY download : %s", demux->keyCookie ? *(demux->keyCookie) : NULL); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download key AGAIN: %s", demux->key_uri); + + gst_hlsdemux2_destroy_key_download (demux); + + if (!gst_hlsdemux2_create_key_download (demux, demux->key_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + gst_element_set_state (demux->kdownloader->pipe, GST_STATE_PLAYING); + return TRUE; + } + + return FALSE; +} + + +static gboolean +hlsdemux2_HTTP_time_out (GstHLSDemux2 *demux, gchar *element_name) +{ + if (g_strrstr(element_name, "fragurisrc")) { + /* as it is because of timeout, there is no point in requesting the same fragment again, so request next one */ + GST_INFO_OBJECT (demux, "signalling fragment downloader to get next fragment..."); + demux->fdownloader->get_next_frag = TRUE; + g_cond_signal (demux->fdownloader->cond); + return TRUE; + } else if (g_strrstr(element_name, "playlisturisrc")) { + + if (demux->playlistCookie) + g_strfreev (demux->playlistCookie); + + g_object_get (demux->pldownloader->urisrc, "cookies", &demux->playlistCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after PLAYLIST download : %s", demux->playlistCookie ? *(demux->playlistCookie) : NULL); + + gst_hlsdemux2_destroy_playlist_download (demux); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download playlist AGAIN: %s", demux->playlist_uri); + if (!gst_hlsdemux2_create_playlist_download (demux, demux->playlist_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + gst_element_set_state (demux->pldownloader->pipe, GST_STATE_PLAYING); + return TRUE; + } else if (g_strrstr(element_name, "keyurisrc")) { + + if (demux->keyCookie) + g_strfreev (demux->keyCookie); + + g_object_get (demux->kdownloader->urisrc, "cookies", &demux->keyCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after KEY download : %s", demux->keyCookie ? *(demux->keyCookie) : NULL); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download key AGAIN: %s", demux->key_uri); + + gst_hlsdemux2_destroy_key_download (demux); + + if (!gst_hlsdemux2_create_key_download (demux, demux->key_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + gst_element_set_state (demux->kdownloader->pipe, GST_STATE_PLAYING); + return TRUE; + } + + return FALSE; +} + +static gboolean +hlsdemux2_HTTP_not_found(GstHLSDemux2 *demux, gchar *element_name) +{ + if (g_strrstr(element_name, "fragurisrc")) { + if (demux->is_live) { + /* request next fragment url */ + GST_INFO_OBJECT (demux, "signalling fragment downloader to get next fragment..."); + demux->fdownloader->get_next_frag = TRUE; + g_cond_signal (demux->fdownloader->cond); + return TRUE; + } else { + +#if 0 // In future enable + GList *next_variant = NULL; + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_NO_RECOVERY) + demux->pldownloader->recovery_mode = HLSDEMUX2_DOWNWARD_RECOVERY; + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_DOWNWARD_RECOVERY) { + /* get next available lower variant */ + next_variant = gst_m3u8_client_get_next_lower_bw_playlist (demux->client); + if (!next_variant) { + GST_WARNING_OBJECT (demux, "no next lower variants.. Go Upward"); + demux->pldownloader->recovery_mode = HLSDEMUX2_UPWARD_RECOVERY; + } + } + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_UPWARD_RECOVERY) { + /* get next available lower variant */ + next_variant = gst_m3u8_client_get_next_higher_bw_playlist (demux->client); + if (!next_variant) { + GST_ERROR_OBJECT (demux, "no next higher variants.. need to exit"); + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; + return FALSE; + } + } + + /* change variant */ + GST_M3U8_CLIENT_LOCK (demux->client); + demux->client->main->current_variant = next_variant; + GST_M3U8_CLIENT_UNLOCK (demux->client); + + gst_m3u8_client_set_current (demux->client, next_variant->data); + + demux->fdownloader->get_next_frag = TRUE; + g_cond_signal (demux->fdownloader->cond); + + return TRUE; +#else + return FALSE; +#endif + } + } else if (g_strrstr(element_name, "playlisturisrc")) { + GList *next_variant = NULL; + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_NO_RECOVERY) + demux->pldownloader->recovery_mode = HLSDEMUX2_DOWNWARD_RECOVERY; + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_DOWNWARD_RECOVERY) { + /* get next available lower variant */ + next_variant = gst_m3u8_client_get_next_lower_bw_playlist (demux->client); + if (!next_variant) { + GST_WARNING_OBJECT (demux, "no next lower variants.. Go Upward"); + demux->pldownloader->recovery_mode = HLSDEMUX2_UPWARD_RECOVERY; + } + } + + if (demux->pldownloader->recovery_mode == HLSDEMUX2_UPWARD_RECOVERY) { + /* get next available lower variant */ + next_variant = gst_m3u8_client_get_next_higher_bw_playlist (demux->client); + if (!next_variant) { + GST_ERROR_OBJECT (demux, "no next higher variants.. need to exit"); + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; + return FALSE; + } + } + + /* change variant */ + GST_M3U8_CLIENT_LOCK (demux->client); + demux->client->main->current_variant = next_variant; + GST_M3U8_CLIENT_UNLOCK (demux->client); + + gst_m3u8_client_set_current (demux->client, next_variant->data); + + /* get new playlist uri */ + demux->playlist_uri = g_strdup (gst_m3u8_client_get_current_uri (demux->client)); + + if (demux->playlistCookie) + g_strfreev (demux->playlistCookie); + + g_object_get (demux->pldownloader->urisrc, "cookies", &demux->playlistCookie, NULL); + + GST_DEBUG_OBJECT (demux, "Got cookies after PLAYLIST download : %s", demux->playlistCookie ? *(demux->playlistCookie) : NULL); + + gst_hlsdemux2_destroy_playlist_download (demux); + + GST_INFO_OBJECT (demux, "========>>>>>Going to download recovery playlist : %s", demux->playlist_uri); + if (!gst_hlsdemux2_create_playlist_download (demux, demux->playlist_uri)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("Failed to create pipeline"), (NULL)); + return FALSE; + } + + gst_element_set_state (demux->pldownloader->pipe, GST_STATE_PLAYING); + + return TRUE; + + } else if (g_strrstr(element_name, "keyurisrc")) { + /* treating it as non-recoverable error */ + return FALSE; + } + + return FALSE; +} + +static gboolean +gst_hlsdemux2_handle_HTTP_error (GstHLSDemux2 *demux, GError *error, gchar *element_name) { + guint i = 0; + guint n_http_errors = sizeof (http_errors) / sizeof (http_errors[0]); + + if(!error) + return HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE; + for (i = 0; i < n_http_errors; i++) { + if (G_LIKELY (!strncmp(error->message, http_errors[i].error_phrase, strlen(error->message)))) { + if (http_errors[i].handle_error) { + return http_errors[i].handle_error (demux, element_name); + } + return http_errors[i].error_type; + } + } + return HLSDEMUX2_HTTP_ERROR_NONRECOVERABLE; +} + +static gboolean +gst_hlsdemux2_fragment_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GError *error = NULL; + gchar* debug = NULL; + gboolean bret = TRUE; + GstMessage *err_msg = NULL; + gchar *ele_name = gst_element_get_name (GST_MESSAGE_SRC (msg)); + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + GST_INFO_OBJECT (demux, "received EOS on download pipe from '%s'..", ele_name); + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; + g_cond_signal(demux->fdownloader->cond); + break; + } + case GST_MESSAGE_ERROR: { + GST_ERROR_OBJECT (demux, "Error from %s\n", ele_name); + + gst_message_parse_error( msg, &error, &debug ); + + demux->fdownloader->error_rcvd = TRUE; + + if (error) + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: error->message = %s and error->code = %d", error->message); + + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: debug = %s", debug); + + if (g_strrstr(ele_name, "fragurisrc") && !demux->cancelled && demux->soup_request_fail_cnt) { + + /* flush the error msgs pending.. as we are going to create new pipeline */ + gst_bus_set_flushing (bus, TRUE); + + bret = gst_hlsdemux2_handle_HTTP_error (demux, error, ele_name); + if (!bret) + goto post_error; + else { + demux->soup_request_fail_cnt--; + GST_WARNING_OBJECT (demux, "HTTP error count remaining = %d", demux->soup_request_fail_cnt); + goto exit; + } + } + +post_error: + + GST_ERROR_OBJECT (demux, "posting error from fragment download callback"); + + err_msg = gst_message_new_error (GST_OBJECT(demux), error, debug); + if (!gst_element_post_message (GST_ELEMENT(demux), err_msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + bret = FALSE; + goto exit; + } + gst_hlsdemux2_stop (demux); + break; + } + case GST_MESSAGE_WARNING: { + gst_message_parse_warning(msg, &error, &debug); + GST_WARNING_OBJECT(demux, "warning : %s\n", error->message); + GST_WARNING_OBJECT(demux, "debug : %s\n", debug); + break; + } + case GST_MESSAGE_ELEMENT: { + const GstStructure *s = gst_message_get_structure (msg); + + if (gst_structure_has_name (s, "cookies")) { + const GValue *value; + gchar **cookies = NULL; + gchar *cookie = NULL; + value = gst_structure_get_value (s, "cookies"); + cookie = g_strdup_value_contents(value); + + cookies = &cookie; + GST_ERROR_OBJECT (demux, "received cookies from soup : %s", *cookies); + } + break; + } + default : { + break; + } + } + +exit: + if (debug) + g_free( debug); + + if (error) + g_error_free( error); + + if (!bret) + gst_hlsdemux2_stop (demux); + + g_free (ele_name); + + return bret; +} + +static GstBusSyncReply +gst_hlsdemux2_playlist_download_bus_sync_cb (GstBus * bus, GstMessage *msg, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GstBusSyncReply reply = GST_BUS_DROP; + + GError *error = NULL; + gchar *debug = NULL; + gboolean bret = TRUE; + GstMessage *err_msg = NULL; + gchar *ele_name = gst_element_get_name (GST_MESSAGE_SRC (msg)); + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + GST_DEBUG_OBJECT (demux, "received EOS on playlist download pipe.."); + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; + g_mutex_lock (demux->pldownloader->lock); + g_cond_broadcast (demux->pldownloader->cond); + g_mutex_unlock (demux->pldownloader->lock); + break; + } + case GST_MESSAGE_ERROR: { + GST_ERROR_OBJECT (demux, "Error from %s element", ele_name); + + gst_message_parse_error( msg, &error, &debug ); + if (error) + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: error= %s", error->message); + + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: debug = %s", debug); + + if (g_strrstr(ele_name, "playlisturisrc") && !demux->cancelled && demux->soup_request_fail_cnt) { + + /* flush the error msgs pending.. as we are going to create new pipeline */ + gst_bus_set_flushing (bus, TRUE); + + bret = gst_hlsdemux2_handle_HTTP_error (demux, error, ele_name); + if (!bret) + goto post_error; + else { + demux->soup_request_fail_cnt--; + GST_WARNING_OBJECT (demux, "HTTP error count remaining = %d", demux->soup_request_fail_cnt); + goto exit; + } + } + +post_error: + + GST_ERROR_OBJECT (demux, "posting error from playlist callback..."); + + err_msg = gst_message_new_error (GST_OBJECT(demux), error, debug); + if (!gst_element_post_message (GST_ELEMENT(demux), err_msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + bret = FALSE; + goto exit; + } + gst_hlsdemux2_stop (demux); + break; + } + case GST_MESSAGE_WARNING: { + gst_message_parse_warning(msg, &error, &debug); + if (error) + GST_WARNING_OBJECT(demux, "warning : %s\n", error->message); + GST_WARNING_OBJECT(demux, "debug : %s\n", debug); + break; + } + case GST_MESSAGE_ELEMENT: { + const GstStructure *s = gst_message_get_structure (msg); + + if (gst_structure_has_name (s, "cookies")) { + const GValue *value; + gchar **cookies = NULL; + gchar *cookie = NULL; + value = gst_structure_get_value (s, "cookies"); + cookie = g_strdup_value_contents(value); + + cookies = &cookie; + GST_ERROR_OBJECT (demux, "received cookies from soup : %s", *cookies); + } + break; + } + default : { + //GST_LOG_OBJECT(demux, "unhandled message : %s\n", gst_message_type_get_name (GST_MESSAGE_TYPE (msg))); + break; + } + } + +exit: + if (debug) + g_free( debug); + + if (error) + g_error_free( error); + + if (!bret) + gst_hlsdemux2_stop (demux); + + g_free (ele_name); + + return reply; +} + +static gboolean +gst_hlsdemux2_key_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GError *error = NULL; + gchar* debug = NULL; + gboolean bret = TRUE; + GstMessage *err_msg = NULL; + gchar *ele_name = gst_element_get_name (GST_MESSAGE_SRC (msg)); + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + GST_DEBUG_OBJECT (demux, "received EOS on key download pipe.."); + demux->pldownloader->recovery_mode = HLSDEMUX2_NO_RECOVERY; + g_mutex_lock (demux->kdownloader->lock); + g_cond_signal (demux->kdownloader->cond); + g_mutex_unlock (demux->kdownloader->lock); + break; + } + case GST_MESSAGE_ERROR: { + GST_INFO_OBJECT (demux, "Error from %s element...", ele_name); + + gst_message_parse_error(msg, &error, &debug); + + if (error) + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: error= %s", error->message); + + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: debug = %s", debug); + + if (g_strrstr(ele_name, "keyurisrc") && !demux->cancelled && demux->soup_request_fail_cnt) { + + /* flush the error msgs pending.. as we are going to create new pipeline */ + gst_bus_set_flushing (bus, TRUE); + + bret = gst_hlsdemux2_handle_HTTP_error (demux, error, ele_name); + if (!bret) + goto post_error; + else { + demux->soup_request_fail_cnt--; + GST_WARNING_OBJECT (demux, "HTTP error count remaining = %d", demux->soup_request_fail_cnt); + goto exit; + } + } + +post_error: + GST_ERROR_OBJECT (demux, "Error posting from key downloader..."); + err_msg = gst_message_new_error (GST_OBJECT(demux), error, debug); + + if (!gst_element_post_message (GST_ELEMENT(demux), err_msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + gst_hlsdemux2_stop (demux); + bret = FALSE; + goto exit; + } + gst_hlsdemux2_stop (demux); + break; + } + case GST_MESSAGE_WARNING: { + gst_message_parse_warning(msg, &error, &debug); + if (error) + GST_WARNING_OBJECT(demux, "warning : %s\n", error->message); + GST_WARNING_OBJECT(demux, "debug : %s\n", debug); + break; + } + case GST_MESSAGE_ELEMENT: { + const GstStructure *s = gst_message_get_structure (msg); + + if (gst_structure_has_name (s, "cookies")) { + const GValue *value; + gchar **cookies = NULL; + gchar *cookie = NULL; + value = gst_structure_get_value (s, "cookies"); + cookie = g_strdup_value_contents(value); + + cookies = &cookie; + GST_ERROR_OBJECT (demux, "received cookies from soup : %s", *cookies); + } + break; + } + default : { + break; + } + } + +exit: + + if (debug) + g_free( debug); + + if (error) + g_error_free( error); + + if (!bret) + gst_hlsdemux2_stop (demux); + + g_free (ele_name); + + return bret; +} + +static void +gst_hlsdemux2_calculate_pushed_duration (GstHLSDemux2 *demux, GstHLSDemux2Stream *stream, + GstBuffer *inbuf) +{ + gint len = 0; + int qidx = 0; + gpointer data = NULL; + + // TODO: for all timestamps -1 case, we need to add max-bytes also + + g_queue_push_tail (stream->queue, inbuf); + + len = g_queue_get_length (stream->queue); + + /* peek the head buffer having valid timestamp to calculate cached duration */ + while (qidx < len) { + data = g_queue_peek_nth (stream->queue, qidx); + + if (GST_IS_BUFFER (data)) { + if (GST_BUFFER_TIMESTAMP_IS_VALID(data)) { + GST_LOG_OBJECT (stream->pad, "data found buffer with valid ts = %"GST_TIME_FORMAT " len = %d & qidx = %d", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(data)), len, qidx); + break; + } + } + qidx++; + } + if(GST_IS_BUFFER (data)) { + if (GST_BUFFER_TIMESTAMP (inbuf) >= GST_BUFFER_TIMESTAMP ((GstBuffer *)data)) { + stream->cached_duration = GST_BUFFER_TIMESTAMP (inbuf) - GST_BUFFER_TIMESTAMP ((GstBuffer *)data); + GST_LOG_OBJECT (stream->pad, "len = %d, cached duration = %"GST_TIME_FORMAT, + g_queue_get_length (stream->queue), GST_TIME_ARGS(stream->cached_duration)); + } else { + GST_WARNING_OBJECT (stream->pad, "Wrong order.. not calculating"); + } + } + return; +} + +static gboolean +gst_hlsdemux2_alter_timestamps (GstHLSDemux2Stream *stream, GstBuffer *inbuf) +{ + GstHLSDemux2 *demux = stream->parent; + GstClockTime cts = 0; + + /* set discontinuity only when there is real fragment discontinuity */ + if (GST_BUFFER_IS_DISCONT(inbuf)) { + if (!stream->apply_disc) { + GST_BUFFER_FLAG_UNSET (inbuf, GST_BUFFER_FLAG_DISCONT); + GST_INFO_OBJECT (stream->pad, "unsetting discontinuity flag..."); + } + } + + if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (inbuf))) { + if (GST_BUFFER_TIMESTAMP (inbuf) >= stream->base_ts) { + cts = GST_BUFFER_TIMESTAMP (inbuf) - stream->base_ts; + } else { + /* this buffer should be dropped at sink */ + GST_WARNING_OBJECT (stream->pad, "input timestamp [%"GST_TIME_FORMAT"] is less than base_ts [%"GST_TIME_FORMAT"]", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (inbuf)), GST_TIME_ARGS(stream->base_ts)); + if (stream->type == HLSDEMUX2_STREAM_AUDIO) { + return FALSE; + } else { + GST_BUFFER_TIMESTAMP (inbuf) = GST_CLOCK_TIME_NONE; + return TRUE; + } + } + } else { + /* this buffer should be dropped at sink */ + GST_LOG_OBJECT (stream->pad, "invalid input timestamp (i.e. GST_CLOCK_TIME_NONE)"); +#ifdef LATEST_AV_SYNC + if (!demux->is_live && (stream->type == HLSDEMUX2_STREAM_AUDIO) && !stream->valid_fts_rcvd){ + GST_WARNING_OBJECT (stream->pad, "dropping invalid ts buffer, due to no valid first ts yet..."); + return FALSE; + } +#endif + return TRUE; + } + + /* handle discontinuity in stream */ + if(GST_CLOCK_TIME_IS_VALID (stream->nts) && (GST_CLOCK_DIFF(stream->nts,cts) > (2 * GST_SECOND)) && stream->apply_disc) { + GST_INFO_OBJECT (stream->pad, "cts = %"GST_TIME_FORMAT" and prev_next_ts = %"GST_TIME_FORMAT, + GST_TIME_ARGS(cts), GST_TIME_ARGS(stream->nts)); + GST_INFO_OBJECT (stream->pad,"Received disc = %"GST_TIME_FORMAT, GST_TIME_ARGS(cts - stream->nts)); + stream->cdisc = cts - stream->nts; + stream->total_disc += (cts - stream->nts); + GST_INFO_OBJECT (stream->pad, "total disc = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->total_disc)); + stream->apply_disc = FALSE; + } + + cts -= stream->cdisc; + + /* get the max last ts, required because of frame reordering */ + stream->lts = cts > stream->lts ? cts : stream->lts; + + GST_DEBUG_OBJECT (stream->pad, "modifying buffer timestamp : %"GST_TIME_FORMAT" -> %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (inbuf)), GST_TIME_ARGS(cts)); + +#ifndef LATEST_AV_SYNC + /* store first valid timestamp of a fragment */ + if (stream->fts == GST_CLOCK_TIME_NONE) { + stream->fts = cts; + stream->nts = stream->fts + demux->cfrag_dur; + GST_INFO_OBJECT (stream->pad, "storing first ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->fts)); + if (demux->is_live && stream->type == HLSDEMUX2_STREAM_AUDIO) + demux->cur_audio_fts = cts; + } +#endif + +#ifdef LATEST_AV_SYNC + /* 10/31/2013: dont want to disturb live case at this moment */ + if (!stream->valid_fts_rcvd) { + if (stream->type == HLSDEMUX2_STREAM_AUDIO) { + if (!demux->is_live && (GST_CLOCK_DIFF(cts, stream->prev_nts) > (10 * GST_MSECOND))) { + GST_WARNING_OBJECT (stream->pad, "already seen audio timestamps[%"GST_TIME_FORMAT"]" + " and previous_nts = %"GST_TIME_FORMAT"...drop this", + GST_TIME_ARGS(cts), GST_TIME_ARGS(stream->prev_nts)); + return FALSE; + } else { + GST_INFO_OBJECT (stream->pad, "recevied valid audio first ts = %"GST_TIME_FORMAT, + GST_TIME_ARGS (cts)); + demux->cur_audio_fts = cts; + } + } + + stream->valid_fts_rcvd = TRUE; + stream->fts = cts; + stream->nts = stream->fts + demux->cfrag_dur; // Approximate nts + + GST_INFO_OBJECT (stream->pad, "storing first ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->fts)); + } else if (!stream->frame_duration) { + stream->frame_duration = cts - stream->fts; + GST_DEBUG_OBJECT (stream->pad, "frame duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->frame_duration)); + } + +#else + + /* 10/31/2013: dont want to disturb live case at this moment */ + if (!demux->is_live && stream->type == HLSDEMUX2_STREAM_AUDIO) { + if (!stream->valid_fts_rcvd) { + if (GST_CLOCK_DIFF(cts, stream->prev_nts) > 0) { + GST_WARNING_OBJECT (stream->pad, "already seen audio timestamps[%"GST_TIME_FORMAT"]" + " and previous_nts = %"GST_TIME_FORMAT"...drop this", + GST_TIME_ARGS(cts), GST_TIME_ARGS(stream->prev_nts)); + return FALSE; + } else { + GST_INFO_OBJECT (stream->pad, "recevied valid audio first ts = %"GST_TIME_FORMAT, + GST_TIME_ARGS (cts)); + demux->cur_audio_fts = cts; + stream->valid_fts_rcvd = TRUE; + } + } else if (!stream->frame_duration) { + stream->frame_duration = cts - demux->cur_audio_fts; + GST_DEBUG_OBJECT (demux, "audio frame duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->frame_duration)); + } + } +#endif + + GST_BUFFER_TIMESTAMP (inbuf) = cts; + + return TRUE; +} + +static void +gst_hlsdemux2_downloader_new_buffer (GstElement *appsink, void *user_data) +{ + GstHLSDemux2Stream *stream = (GstHLSDemux2Stream *)user_data; + GstHLSDemux2 *demux = stream->parent; + GstBuffer *inbuf = NULL; + gboolean bret = FALSE; + + if (demux->cancelled ) { + return; + } + + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_WARNING_OBJECT (demux, "Input buffer not available..."); + return; + } + + GST_LOG_OBJECT (stream->pad, "Received buffer with size = %d and ts = %"GST_TIME_FORMAT, + GST_BUFFER_SIZE(inbuf), GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(inbuf))); + + if (demux->fdownloader->force_timestamps) { + GST_BUFFER_TIMESTAMP(inbuf) += (stream->prev_nts + stream->base_ts); + GST_DEBUG_OBJECT (stream->pad, "forced timestamp = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(inbuf))); + } + + /* alter the timestamps */ + bret = gst_hlsdemux2_alter_timestamps (stream, inbuf); + if (!bret) { + gst_buffer_unref (inbuf); + return; + } + + /* store buffer in queue */ + g_queue_push_tail (stream->downloader_queue, inbuf); + + return; +} + +static gboolean +gst_hlsdemux2_imagebuf_pipe_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) +{ + GstHLSDemux2PvtStream *stream = (GstHLSDemux2PvtStream *)data; + GstHLSDemux2 *demux = (GstHLSDemux2 *)stream->parent; + gboolean bret = TRUE; + gchar *ele_name = gst_element_get_name (GST_MESSAGE_SRC (msg)); + + GST_INFO_OBJECT(demux, "Message on BUS : %s", gst_message_type_get_name(GST_MESSAGE_TYPE(msg))); + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + GST_INFO_OBJECT (demux, "received EOS on IMAGE pipe from '%s'.. Closing pipeline", ele_name); + g_cond_signal (stream->convert_cond); + gst_object_unref (stream->convert_pipe); + break; + } + case GST_MESSAGE_ERROR: { + GST_ERROR_OBJECT (demux, "Error Image Pipe from %s\n", ele_name); + bret = FALSE; + break; + } + default:{ + GST_DEBUG_OBJECT (demux, "Message on Image Pipe : %s from %s\n", gst_message_type_get_name(GST_MESSAGE_TYPE(msg)), ele_name); + bret = FALSE; + break; + } + } + g_free(ele_name); + ele_name = NULL; + return bret; +} + +static gboolean gst_hlsdemux2_done_video_buffer (GstPad * srcpad, GstEvent * event, gpointer user_data) +{ + GstHLSDemux2PvtStream *stream = (GstHLSDemux2PvtStream *)user_data; + GstHLSDemux2 *demux = (GstHLSDemux2 *)stream->parent; + GST_LOG_OBJECT(demux,"EVENT %s on pad : %s having caps : %"GST_PTR_FORMAT,GST_EVENT_TYPE_NAME (event), GST_PAD_NAME(srcpad), srcpad->caps); + if(event->type == GST_EVENT_EOS){ + GST_DEBUG_OBJECT(demux,"EVENT : %s Size : %d Pushing to demux video buffer [%d,%d]", + GST_EVENT_TYPE_NAME (event),GST_BUFFER_SIZE(stream->video_buffer), + stream->video_buffer->data[0],stream->video_buffer->data[1]); + g_cond_signal (stream->convert_cond); + } + return TRUE; +} + +static gboolean gst_hlsdemux2_set_video_buffer (GstPad * srcpad, GstBuffer * buffer, gpointer user_data) +{ + GstHLSDemux2PvtStream *pvt_stream = (GstHLSDemux2PvtStream *)user_data; + GstHLSDemux2 *demux = (GstHLSDemux2 *)pvt_stream->parent; + GST_LOG_OBJECT(demux,"BUFFER size:%d on pad having caps : %"GST_PTR_FORMAT,GST_BUFFER_SIZE(buffer), srcpad->caps); + GST_LOG_OBJECT(demux,"BUFFER DATA : %d %d",buffer->data[0],buffer->data[1]); + pvt_stream->video_buffer = buffer; + return TRUE; +} + +static void +gst_hlsdemux2_downloader_eos (GstElement * appsink, void* user_data) +{ + GstHLSDemux2Stream *stream = (GstHLSDemux2Stream *)user_data; + GstHLSDemux2 *demux = stream->parent; + GstBuffer *buf = NULL; + gint64 percent = 0; + + /* push all data to queue specific to this stream */ + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (demux, "returning due to cancelled / flushing"); + return; + } + + if (g_queue_is_empty (stream->downloader_queue)) { + GST_WARNING_OBJECT (demux, "EOS received without any buffer in downloader queue"); + return; + } + + if (demux->fdownloader->force_timestamps) { + demux->cur_audio_fts = stream->prev_nts; + } + + if (demux->fdownloader->cur_stream_cnt < demux->active_stream_cnt) { + gint idx = 0; + + GST_INFO_OBJECT (demux, "need to send dummy data.. check for the stream"); + + /* signal queue full condition to come out */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = demux->streams[idx]; + GError *error = NULL; + + if (cur_stream) { + if (g_queue_is_empty (cur_stream->downloader_queue)) { + GST_INFO_OBJECT (cur_stream->pad, "enable sending dummy data"); + + /* take first ts of audio as cur_stream fts */ + cur_stream->fts = demux->cur_audio_fts; + + /* create thread to send dummy data */ + cur_stream->dummy_data_thread = g_thread_create ((GThreadFunc) gst_hlsdemux2_push_dummy_data, + cur_stream, TRUE, &error); + } + } + } + } + + while (!g_queue_is_empty (stream->downloader_queue)) { + + if (demux->cancelled || demux->flushing) { + GST_WARNING_OBJECT (stream->pad, "on cancel/flushing stopping pushing"); + break; + } + + buf = (GstBuffer *) g_queue_pop_head (stream->downloader_queue); + + GST_DEBUG_OBJECT (stream->pad, "input buffer timestamp : %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (buf))); + + g_mutex_lock (stream->queue_lock); + + if (!GST_BUFFER_TIMESTAMP_IS_VALID(buf)){ + g_queue_push_tail (stream->queue, buf); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + continue; + } + + GST_LOG_OBJECT (stream->pad, "buffer size = %d, ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_BUFFER_SIZE(buf), GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buf)), GST_TIME_ARGS(GST_BUFFER_DURATION(buf))); + + /* calculate cached duration */ + gst_hlsdemux2_calculate_pushed_duration (demux, stream, buf); + + if (stream->cached_duration < 0) + stream->cached_duration = 0; + + percent = (stream->cached_duration * 100) / demux->total_cache_duration; + GST_LOG_OBJECT (stream->pad, "percent done = %"G_GINT64_FORMAT, (gint)percent, percent); + + if (percent > 100) { + guint64 overall_percent = 0; + + g_mutex_lock (demux->buffering_lock); + overall_percent = demux->percent; + g_mutex_unlock (demux->buffering_lock); + + if (overall_percent < 100) { /* otherwise, may cause blocking while buffering*/ + if (percent > 400) { + GST_ERROR_OBJECT (stream->pad,"having worrest buffering.. exiting"); + GST_ELEMENT_ERROR (demux, STREAM, FAILED, ("wrong buffering.. check implementation"), (NULL)); + } + GST_INFO_OBJECT (stream->pad, "@@@@@@ queue should not go to wait now @@@@@@@@"); + } else { + /* update buffering & wait if space is not available */ + GST_LOG_OBJECT (stream->pad, "Reached more than 100 percent, queue full & wait till free"); + g_cond_wait(stream->queue_full, stream->queue_lock); + GST_LOG_OBJECT (stream->pad,"Received signal to add more data..."); + } + } + + g_cond_signal (stream->queue_empty); + + g_mutex_unlock (stream->queue_lock); + } + + /* wait for dummy threads finish their processing */ + if (demux->fdownloader->cur_stream_cnt < demux->active_stream_cnt) { + gint idx = 0; + + GST_INFO_OBJECT (demux, "need to close dummy threads"); + + /* signal queue full condition to come out */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *cur_stream = demux->streams[idx]; + + if (cur_stream && cur_stream->dummy_data_thread) { + GST_INFO_OBJECT (stream->pad, "waiting for dummy push thread to finish..."); + g_thread_join(cur_stream->dummy_data_thread); + cur_stream->dummy_data_thread = NULL; + GST_INFO_OBJECT (stream->pad, "COMPLETED DUMMY PUSH..."); + } + } + } + +#ifdef LATEST_AV_SYNC + if (demux->is_live) { + stream->total_stream_time += (stream->lts - stream->fts); + } else { + stream->total_stream_time += (stream->lts - stream->fts + stream->frame_duration); + stream->nts = stream->total_stream_time; + } +#else + stream->total_stream_time += (stream->lts - stream->fts); +#endif + + GST_DEBUG_OBJECT (stream->pad, "---------------- TS VALUES ----------------"); + GST_DEBUG_OBJECT (stream->pad, "valid start ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->fts)); + GST_DEBUG_OBJECT (stream->pad, "valid end ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->lts)); + GST_DEBUG_OBJECT (stream->pad, "fragment duration received = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->lts - stream->fts)); + GST_DEBUG_OBJECT (stream->pad, "total stream time = %"GST_TIME_FORMAT,GST_TIME_ARGS(stream->total_stream_time)); + GST_DEBUG_OBJECT (stream->pad, "total disc time = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->total_disc)); + GST_DEBUG_OBJECT (stream->pad, "next expected start ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(stream->nts)); + GST_DEBUG_OBJECT (stream->pad, "---------------- DUMP VALUES END----------------"); + + stream->apply_disc = FALSE; + stream->fts = GST_CLOCK_TIME_NONE; + stream->valid_fts_rcvd = FALSE; + stream->prev_nts = stream->nts; + demux->fdownloader->force_timestamps = FALSE; + return; +} + +static void +gst_hlsdemux2_push_eos (GstHLSDemux2 *demux) +{ + guint idx = 0; + + /* signal queue full condition to come out */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + GstHLSDemux2Stream *stream = demux->streams[idx]; + + if (stream) { + g_mutex_lock (stream->queue_lock); + /* end of playlist, push EOS to queue */ + GST_INFO_OBJECT (stream->pad, "pushing EOS event to stream's queue"); + g_queue_push_tail (stream->queue, gst_event_new_eos ()); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + } + } +} + +static void +gst_hlsdemux2_on_playlist_buffer (GstElement *appsink, void *data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GstBuffer *inbuf = NULL; + + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_WARNING_OBJECT (demux, "Input buffer not available..."); + return; + } + + if (demux->pldownloader->playlist == NULL) { + demux->pldownloader->playlist = gst_buffer_copy (inbuf); + gst_buffer_unref (inbuf); + } else { + GstBuffer *buffer = NULL; + guint size = GST_BUFFER_SIZE(demux->pldownloader->playlist) + GST_BUFFER_SIZE(inbuf); + + buffer = gst_buffer_new_and_alloc (size); + if (!buffer) { + GST_ERROR_OBJECT (demux, "failed allocate memory..."); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + gst_buffer_unref (inbuf); + gst_buffer_unref (demux->pldownloader->playlist); + return; + } + + /*copy existing playlist buffer */ + memcpy (GST_BUFFER_DATA(buffer), GST_BUFFER_DATA(demux->pldownloader->playlist), GST_BUFFER_SIZE(demux->pldownloader->playlist)); + + /*copy new playlist buffer */ + memcpy (GST_BUFFER_DATA(buffer) + GST_BUFFER_SIZE(demux->pldownloader->playlist), + GST_BUFFER_DATA(inbuf), GST_BUFFER_SIZE(inbuf)); + + gst_buffer_unref (inbuf); + gst_buffer_unref (demux->pldownloader->playlist); + demux->pldownloader->playlist = buffer; + } + + return; +} + +static void +gst_hlsdemux2_on_key_buffer (GstElement *appsink, void *data) +{ + GstHLSDemux2 *demux = (GstHLSDemux2 *)data; + GstBuffer *inbuf = NULL; + + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_WARNING_OBJECT (demux, "Input buffer not available..."); + return; + } + + if (demux->kdownloader->key == NULL) { + demux->kdownloader->key = gst_buffer_copy (inbuf); + gst_buffer_unref (inbuf); + } else { + GstBuffer *buffer = NULL; + guint size = GST_BUFFER_SIZE(demux->kdownloader->key) + GST_BUFFER_SIZE(inbuf); + + buffer = gst_buffer_new_and_alloc (size); + if (!buffer) { + GST_ERROR_OBJECT (demux, "failed allocate memory..."); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("can't allocate memory"), (NULL)); + gst_buffer_unref (inbuf); + gst_buffer_unref (demux->kdownloader->key); + return; + } + + /*copy existing playlist buffer */ + memcpy (GST_BUFFER_DATA(buffer), GST_BUFFER_DATA(demux->kdownloader->key), GST_BUFFER_SIZE(demux->kdownloader->key)); + + /*copy new playlist buffer */ + memcpy (GST_BUFFER_DATA(buffer) + GST_BUFFER_SIZE(demux->kdownloader->key), + GST_BUFFER_DATA(inbuf), GST_BUFFER_SIZE(inbuf)); + + gst_buffer_unref (inbuf); + gst_buffer_unref (demux->kdownloader->key); + demux->kdownloader->key = buffer; + } + + return; +} + +static void +gst_hlsdemux2_stop (GstHLSDemux2 *demux) +{ + GST_INFO_OBJECT (demux, "entering..."); + + demux->cancelled = TRUE; + + g_cond_signal (demux->post_msg_start); + g_cond_signal (demux->post_msg_exit); + + /* special case: for exiting playlist downloader created from sink event */ + if (demux->pldownloader && demux->pldownloader->cond) + g_cond_broadcast (demux->pldownloader->cond); + + while (demux->download_task && (GST_TASK_STATE (demux->download_task) != GST_TASK_STOPPED)) { + int idx = 0; + GstHLSDemux2Stream *stream = NULL; + + GST_INFO_OBJECT (demux, "Closing Download task..."); + + /* signal queue full conditions */ + for (idx = 0; idx < HLSDEMUX2_STREAM_NUM; idx++) { + stream = demux->streams[idx]; + + if (stream && GST_PAD_TASK(stream->pad)) { + gst_pad_push_event (stream->pad, gst_event_new_flush_start ()); + g_cond_broadcast(stream->queue_full); + g_cond_broadcast(stream->queue_empty); + } + } + + if (demux->pl_update_cond) + g_cond_broadcast (demux->pl_update_cond); + + if (demux->fdownloader && demux->fdownloader->cond) + g_cond_broadcast (demux->fdownloader->cond); + if (demux->kdownloader && demux->kdownloader->cond) + g_cond_broadcast (demux->kdownloader->cond); + if (demux->pldownloader && demux->pldownloader->cond) + g_cond_broadcast (demux->pldownloader->cond); + + GST_INFO_OBJECT (demux, "Waiting to acquire download lock"); + g_static_rec_mutex_lock (&demux->download_lock); + g_static_rec_mutex_unlock (&demux->download_lock); + + GST_INFO_OBJECT (demux, "Waiting download task JOIN"); + gst_task_join (demux->download_task); + gst_object_unref (demux->download_task); + demux->download_task = NULL; + + GST_INFO_OBJECT (demux, "Completed closing of download task..."); + + g_thread_join(demux->buffering_posting_thread); + GST_INFO_OBJECT (demux, "Completed closing of download monitor thread..."); + + if (demux->fdownloader && demux->fdownloader->pipe) { + GST_WARNING_OBJECT (demux, "Still fragment download exist"); + gst_hlsdemux2_destroy_fragment_download (demux); + } + if (demux->pldownloader && demux->pldownloader->pipe) { + GST_WARNING_OBJECT (demux, "Still playlist download exist"); + gst_hlsdemux2_destroy_playlist_download (demux); + } + if (demux->kdownloader && demux->kdownloader->pipe) { + GST_WARNING_OBJECT (demux, "Still key download exist"); + gst_hlsdemux2_destroy_key_download (demux); + } + } + + gst_hlsdemux2_stop_stream (demux); + + GST_INFO_OBJECT (demux, "leaving..."); +} + +static void +gst_hlsdemux2_stop_stream (GstHLSDemux2 *demux) +{ + int n = 0; + GstHLSDemux2Stream *stream = NULL; + gchar *pad_name = NULL; + + GST_INFO_OBJECT (demux, "entering"); + + for (n = 0; n < HLSDEMUX2_STREAM_NUM; n++) { + stream = demux->streams[n]; + + if (stream && GST_PAD_TASK(stream->pad)) { + pad_name = gst_pad_get_name (stream->pad); + GST_INFO_OBJECT (stream->pad, "stopping pad task : %s", pad_name); + gst_pad_stop_task (stream->pad); + GST_INFO_OBJECT (stream->pad, "stopped pad task : %s", pad_name); + g_free(pad_name); + pad_name = NULL; + } + } + + for (n = 0; n < HLSDEMUX2_STREAM_NUM; n++) { + if (demux->streams[n]) { + gst_hlsdemux2_stream_deinit(demux->streams[n], demux); + demux->streams[n] = NULL; + } + } + demux->active_stream_cnt = 0; + GST_INFO_OBJECT (demux, "leaving"); +} + +static void +gst_hlsdemux2_stream_init (GstHLSDemux2 *demux, GstHLSDemux2Stream *stream, HLSDEMUX2_STREAM_TYPE stream_type, gchar *name, GstCaps *src_caps) +{ + stream->queue = g_queue_new (); + stream->queue_full = g_cond_new (); + stream->queue_empty = g_cond_new (); + stream->queue_lock = g_mutex_new (); + stream->parent = demux; + stream->type = stream_type; + stream->percent = 100; + stream->eos = FALSE; + stream->cached_duration = 0; + stream->lts = 0; + stream->dummy_data_thread = NULL; + stream->base_ts = GST_CLOCK_TIME_NONE; + stream->fts = GST_CLOCK_TIME_NONE; + stream->valid_fts_rcvd = FALSE; + stream->total_stream_time = 0; + stream->total_disc = 0; + stream->cdisc = 0; + stream->nts = GST_CLOCK_TIME_NONE; + stream->prev_nts = 0; + stream->downloader_queue = g_queue_new(); + stream->need_newsegment = TRUE; + stream->newsegment = NULL; + stream->frame_duration = 0; + + if (stream_type == HLSDEMUX2_STREAM_VIDEO) { + stream->pad = gst_pad_new_from_static_template (&hlsdemux2_videosrc_template, name); + GST_INFO_OBJECT (demux, "Its a Multi-variant stream.."); + demux->stream_config = HLSDEMUX2_MULTI_VARIANT; + } else if (stream_type == HLSDEMUX2_STREAM_AUDIO) { + stream->pad = gst_pad_new_from_static_template (&hlsdemux2_audiosrc_template, name); + } else if (stream_type == HLSDEMUX2_STREAM_TEXT) { + stream->pad = gst_pad_new_from_static_template (&hlsdemux2_subpicture_template, name); + } else if (stream_type == HLSDEMUX2_STREAM_PRIVATE) { + stream->pad = gst_pad_new_from_static_template (&hlsdemux2_private_template, name); + } + + GST_INFO_OBJECT (demux, "======>>>> created hlsdemux2 source pad : %s", name); + + GST_PAD_ELEMENT_PRIVATE (stream->pad) = stream; + + gst_pad_use_fixed_caps (stream->pad); + gst_pad_set_event_function (stream->pad, gst_hlsdemux2_handle_src_event); + gst_pad_set_query_function (stream->pad, gst_hlsdemux2_src_query); + gst_pad_set_caps (stream->pad, src_caps); + + GST_DEBUG_OBJECT (demux, "adding pad %s %p to demux %p", GST_OBJECT_NAME (stream->pad), stream->pad, demux); + gst_pad_set_active (stream->pad, TRUE); + gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->pad); + + if (!gst_pad_is_linked (stream->pad)) { + GST_WARNING_OBJECT (stream->pad, "'%s' pad is not linked...", GST_OBJECT_NAME (stream->pad)); + stream->is_linked = FALSE; + return; + } + stream->is_linked = TRUE; + + if (!gst_pad_start_task (stream->pad, (GstTaskFunction) gst_hlsdemux2_push_loop, stream)) { + GST_ERROR_OBJECT (demux, "failed to create stream task..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to create stream push loop"), (NULL)); + return; + } + +} + +static void +gst_hlsdemux2_stream_deinit (GstHLSDemux2Stream *stream, gpointer data) +{ + GstHLSDemux2 * demux = (GstHLSDemux2 *)data; + if (stream) { + + if (stream->queue) { + while (!g_queue_is_empty(stream->queue)) { + gst_buffer_unref (g_queue_pop_head (stream->queue)); + } + g_queue_free (stream->queue); + stream->queue = NULL; + } + + if (stream->pad) { + gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad); + stream->pad = NULL; + } + + if (stream->queue_lock) { + g_mutex_free (stream->queue_lock); + stream->queue_lock = NULL; + } + if (stream->queue_full) { + g_cond_free (stream->queue_full); + stream->queue_full = NULL; + } + if (stream->queue_empty) { + g_cond_free (stream->queue_empty); + stream->queue_empty= NULL; + } + g_free (stream); + } + +} + +static gboolean +gst_hlsdemux2_set_location (GstHLSDemux2 * demux, const gchar * uri) +{ + if (demux->client) + gst_m3u8_client_free (demux->client); + demux->client = gst_m3u8_client_new (uri); + GST_INFO_OBJECT (demux, "Changed location: %s", uri); + return TRUE; +} + +static gchar * +gst_hlsdemux2_src_buf_to_utf8_playlist (GstBuffer * buf) +{ + gint size; + gchar *data; + gchar *playlist; + + data = (gchar *) GST_BUFFER_DATA (buf); + size = GST_BUFFER_SIZE (buf); + +#if 0 /* giving error some times, so removing*/ + if (!g_utf8_validate (data, size, NULL)) + goto validate_error; +#endif + + /* alloc size + 1 to end with a null character */ + playlist = g_malloc0 (size + 1); + if (!playlist) { + GST_ERROR ("failed to create memory..."); + gst_buffer_unref (buf); + return NULL; + } + + memcpy (playlist, data, size); + playlist[size] = '\0'; + + gst_buffer_unref (buf); + return playlist; +#if 0 +validate_error: + gst_buffer_unref (buf); + GST_ERROR ("failed to validate playlist"); + return NULL; +#endif +} + +static void +gst_hlsdemux2_handle_private_pad (GstHLSDemux2 *demux, GstPad *srcpad) +{ + GstHLSDemux2PvtStream *pvt_stream = NULL; + gchar *sinkname = NULL; + GstPad *sinkpad = NULL; + + pvt_stream = g_new0 (GstHLSDemux2PvtStream, 1); + + demux->private_stream = pvt_stream; + pvt_stream->parent = demux; + pvt_stream->type = HLSDEMUX2_STREAM_PRIVATE; + pvt_stream->image_buffer = NULL; + pvt_stream->got_img_buffer = FALSE; + pvt_stream->video_buffer = NULL; + pvt_stream->id3_buffer = NULL; + pvt_stream->convert_lock = g_mutex_new (); + pvt_stream->convert_cond = g_cond_new (); + pvt_stream->sink = NULL; + pvt_stream->img_load_lock = g_mutex_new (); + pvt_stream->img_load_cond = g_cond_new (); + + /* create sink element */ + sinkname = g_strdup_printf("%s-%s", GST_PAD_NAME(srcpad) , "sink"); + pvt_stream->sink = gst_element_factory_make ("appsink", NULL); + if (!pvt_stream->sink) { + GST_ERROR_OBJECT (demux, "failed to create sink element - %s", sinkname); + GST_ELEMENT_ERROR (demux, CORE, FAILED, ("failed to create element - %s", sinkname), (NULL)); + g_free(sinkname); + sinkname = NULL; + return; + } + + /* set sink element to PLAYING state */ + gst_bin_add (GST_BIN (demux->fdownloader->pipe), pvt_stream->sink); + gst_element_set_state (pvt_stream->sink, GST_STATE_READY); + g_object_set (G_OBJECT (pvt_stream->sink), "sync", FALSE, "emit-signals", TRUE, NULL); + + sinkpad = gst_element_get_pad(pvt_stream->sink, "sink"); + if (!sinkpad) { + GST_ERROR_OBJECT (demux, "failed to get sinkpad from element - %s", sinkname); + GST_ELEMENT_ERROR (demux, CORE, PAD, ("Count not get sink pad"), (NULL)); + g_free(sinkname); + sinkname = NULL; + return; + } + + if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) { + GST_ERROR_OBJECT (demux, "failed to link sink bin elements"); + GST_ELEMENT_ERROR (demux, CORE, NEGOTIATION, ("Could not link pads.."), (NULL)); + gst_object_unref(sinkpad); + } + + gst_element_set_state (pvt_stream->sink, GST_STATE_PLAYING); + + g_signal_connect (pvt_stream->sink, "new-buffer", G_CALLBACK (gst_hlsdemux2_private_sink_on_new_buffer), pvt_stream); + g_signal_connect (pvt_stream->sink, "eos", G_CALLBACK (gst_hlsdemux2_private_sink_on_eos), pvt_stream); + + gst_object_unref(sinkpad); + + GST_INFO_OBJECT (demux, "successfully created private pad bin..."); + + g_free(sinkname); + sinkname = NULL; + return; +} + +static void +gst_hlsdemux2_private_sink_on_new_buffer (GstElement *appsink, void *user_data) +{ + GstHLSDemux2PvtStream *pvt_stream = (GstHLSDemux2PvtStream *)user_data; + GstHLSDemux2 *demux = pvt_stream->parent; + GstBuffer *inbuf = NULL; + + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_ERROR_OBJECT (demux, "Input buffer not available...."); + return; + } + + GST_LOG_OBJECT (demux, "Image buffer received of size = %d", GST_BUFFER_SIZE (inbuf)); + if(pvt_stream->id3_buffer==NULL) + pvt_stream->id3_buffer = gst_buffer_copy(inbuf); + else + pvt_stream->id3_buffer = gst_buffer_join (pvt_stream->id3_buffer, inbuf); + return; +} + +static void +gst_hlsdemux2_private_sink_on_eos (GstElement * appsink, void* user_data) +{ + GstHLSDemux2PvtStream *pvt_stream = (GstHLSDemux2PvtStream *)user_data; + GstHLSDemux2 *demux = pvt_stream->parent; + GstBuffer *image_buffer = NULL; + GstTagList *tag_list = gst_tag_list_from_id3v2_tag(pvt_stream->id3_buffer); + + GST_INFO_OBJECT (demux, "Processing image buffer"); + + if(!gst_tag_list_get_buffer (tag_list, GST_TAG_IMAGE, &image_buffer)) { + GST_ERROR_OBJECT(demux, "Failed to obtain image data."); + return; + } + + if(demux->stream_config == HLSDEMUX2_SINGLE_VARIANT) { + gchar *image_header = NULL; + GValue codec_type = G_VALUE_INIT; + GstMessage * tag_message = NULL; + + /* check whether it is same as previous image */ + if (demux->prev_image_buffer && + (GST_BUFFER_SIZE(demux->prev_image_buffer) == GST_BUFFER_SIZE(image_buffer))) { + if (!memcmp (GST_BUFFER_DATA(demux->prev_image_buffer), GST_BUFFER_DATA(image_buffer), GST_BUFFER_SIZE(image_buffer))) { + GST_INFO_OBJECT (demux, "current & previous embedded images are same..no need to post image again"); + gst_buffer_unref (image_buffer); + return; + } + } + + if (demux->prev_image_buffer) { + gst_buffer_unref (demux->prev_image_buffer); + } + demux->prev_image_buffer = gst_buffer_copy(image_buffer); + + image_header = g_strndup((gchar *) image_buffer->data, 8); + + g_value_init (&codec_type, G_TYPE_STRING); + + if((image_header[0] == 0xFF) && (image_header[1] == 0xD8)) { + GST_INFO_OBJECT(demux, "Found JPEG image header"); + g_value_set_static_string (&codec_type, "image/jpeg"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } else if (!g_strcmp0(image_header, "\211PNG\015\012\032\012")) { + GST_INFO_OBJECT(demux, "Found PNG image header"); + g_value_set_static_string (&codec_type, "image/png"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } else { + g_value_set_static_string (&codec_type, "image/unknown"); + GST_INFO_OBJECT(demux, "Unknown image header"); + gst_tag_list_add_value(tag_list, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, &codec_type); + } + + GST_INFO_OBJECT(demux, "Set value : %s", g_value_get_string (&codec_type)); + g_value_unset(&codec_type); + + tag_message = gst_message_new_tag (GST_OBJECT_CAST (demux), tag_list); + if(!gst_element_post_message (GST_ELEMENT_CAST (demux), tag_message)) { + GST_ERROR_OBJECT (demux, "failed to post image tag"); + gst_buffer_unref (image_buffer); + g_free (image_header); + return; + } + + GST_INFO_OBJECT (demux, "successfully posted image tag..."); + gst_buffer_unref (image_buffer); + g_free (image_header); + return; + } + + GST_INFO_OBJECT(demux, "image header : %d,%d", image_buffer->data[0],image_buffer->data[1]); + + pvt_stream->image_buffer = gst_buffer_copy(image_buffer); + gst_buffer_unref (image_buffer); + pvt_stream->got_img_buffer = TRUE; + + g_cond_signal (pvt_stream->img_load_cond); + demux->has_image_buffer = TRUE; + +} + +static gboolean +hlsdemux2_init (GstPlugin * plugin) +{ + if (!gst_element_register (plugin, "hlsdemux2", GST_RANK_PRIMARY + 1, GST_TYPE_HLSDEMUX2) || FALSE) + return FALSE; + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "hlsdemux2", + "HLS demux - 2 plugin", + hlsdemux2_init, + VERSION, + "LGPL", + PACKAGE_NAME, + "http://www.samsung.com/") + diff --git a/hlsdemux2/src/gsthlsdemux2.h b/hlsdemux2/src/gsthlsdemux2.h new file mode 100755 index 0000000..15269a4 --- /dev/null +++ b/hlsdemux2/src/gsthlsdemux2.h @@ -0,0 +1,297 @@ +/* + * hlsdemux2 + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , Naveen Cherukuri + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_HLSDEMUX2_H__ +#define __GST_HLSDEMUX2_H__ + +#include +#include +#include +#include +#include "m3u8.h" + +G_BEGIN_DECLS +#define GST_TYPE_HLSDEMUX2 (gst_hlsdemux2_get_type()) +#define GST_HLSDEMUX2(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_HLSDEMUX2, GstHLSDemux2)) +#define GST_HLSDEMUX2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_HLSDEMUX2,GstHLSDemux2Class)) +#define GST_IS_HLSDEMUX2(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_HLSDEMUX2)) +#define GST_IS_HLSDEMUX2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_HLSDEMUX2)) + +typedef struct _GstHLSDemux2 GstHLSDemux2; +typedef struct _GstHLSDemux2Class GstHLSDemux2Class; +typedef struct _GstHLSDemux2Stream GstHLSDemux2Stream; +typedef struct _GstHLSDemux2PvtStream GstHLSDemux2PvtStream; + +#define GST_HLS_DEMUX_AES_BLOCK_SIZE 16 + +#define ON_ERROR_REQUEST_AGAIN // Orange server giving soup errors. so, request for fail count times + +#define HLSDEMUX2_CHUNK_TIME_DURATION (0.5 * GST_SECOND) +#define HLSDEMUX2_NUM_CHUNK_DOWNLOADS_FAST_SWITCH 4 +#define HLSDEMUX2_MAX_N_PAST_FRAG_DOWNLOADRATES 3 + +#define HLSDEMUX2_FAST_CHECK_CRITICAL_TIME_FACTOR 1.2 +#define HLSDEMUX2_FAST_CHECK_WARNING_TIME_FACTOR 1 + +#ifdef USING_AVG_PAST_DOWNLOADRATES +#define HLSDEMUX2_MAX_N_PAST_DOWNLOADRATES 3 +#endif + + +#define PLAYLIST_REFRESH_TIMEOUT (20 * GST_SECOND) + +#define HLSDEMUX2_OVERHEAD (1 * GST_SECOND) + +#define LATEST_AV_SYNC + +typedef enum +{ + HLSDEMUX2_STREAM_VIDEO = 0, + HLSDEMUX2_STREAM_AUDIO, + HLSDEMUX2_STREAM_TEXT, + HLSDEMUX2_STREAM_PRIVATE, + HLSDEMUX2_STREAM_NUM, +}HLSDEMUX2_STREAM_TYPE; + +typedef enum +{ + HLSDEMUX2_DOWNWARD_RECOVERY = 0, + HLSDEMUX2_UPWARD_RECOVERY, + HLSDEMUX2_NO_RECOVERY, +}HLSDEMUX2_RECOVERY_MODE; + +typedef enum +{ + HLSDEMUX2_MULTI_VARIANT = 0, + HLSDEMUX2_SINGLE_VARIANT +}HLSDEMUX2_STREAM_CONFIGURATION; + +typedef struct +{ + GstBin *sinkbin; + GstElement *parser; /*only for .aac stream */ + GstElement *queue; + GstElement *sink; +}HLSDemux2SinkBin; + +typedef struct +{ + GstElement *pipe; + GstElement *urisrc; + GstElement *typefind; + GstElement *queue; + GstElement *demuxer; + GList *sinkbins; + + guint64 content_size; + gboolean applied_fast_switch; + + gchar *remaining_data; + guint remaining_size; + + GMutex *lock; + GCond *cond; + gboolean is_encrypted; + + gulong src_bprobe; + gboolean get_next_frag; /* on error like NOT_FOUND, request next fragment */ + + guint cur_stream_cnt; + gboolean first_buffer; + gboolean force_timestamps; /* useful in .aac files playback */ + gboolean error_rcvd; + gboolean find_mediaseq; + GstClockTime seeked_pos; + GstClockTime cur_running_dur; + + /* for fragment download rate calculation */ + guint64 download_rate; + GstClockTime download_start_ts; + GstClockTime download_stop_ts; + guint64 src_downloaded_size; + guint64 queue_downloaded_size; + gint ndownloaded; /* number of fragments downloaded */ + GArray *avg_chunk_drates; /* chunk download rates array */ + GArray *avg_frag_drates; /* fragment download rates array */ + guint64 chunk_downloaded_size; + GstClockTime chunk_start_ts; +}HLSDemux2FragDownloader; + +/* playlist downloader */ +typedef struct +{ + GstElement *pipe; + GstBus *bus; + GstElement *urisrc; + GstElement *sink; + GMutex *lock; + GCond *cond; + + GstBuffer *playlist; + HLSDEMUX2_RECOVERY_MODE recovery_mode; + GstClockTime download_start_ts; +}HLSDemux2PLDownloader; + +/* Key downloader */ +typedef struct +{ + GstElement *pipe; + GstBus *bus; + GstElement *urisrc; + GstElement *sink; + + GMutex *lock; + GCond *cond; + + GstBuffer *key; + gchar *prev_key_uri; +}HLSDemux2KeyDownloader; + +/** + * GstHLSDemux2: + * + * Opaque #GstHLSDemux2 data structure. + */ +struct _GstHLSDemux2 +{ + GstElement parent; + + GstPad *sinkpad; + + /* M3U8 client */ + GstM3U8Client *client; + + gboolean is_live; + + HLSDemux2FragDownloader *fdownloader; /* fragment downloader */ + HLSDemux2PLDownloader *pldownloader; /* playlist downloader */ + HLSDemux2KeyDownloader *kdownloader; /* key downloader */ + + /* properties */ + gint blocksize; + + /* master playlist got from upstream */ + GstBuffer *playlist; + + /* fragment download task */ + GstTask *download_task; + GStaticRecMutex download_lock; + + /* Playlist updates task for live session */ + GStaticRecMutex updates_lock; + GTimeVal next_update; /* Time of the next update */ + + /* playlist update condition */ + GCond *pl_update_cond; + GMutex *pl_update_lock; + + /* array of pointers to each stream's list */ + GstHLSDemux2Stream *streams[HLSDEMUX2_STREAM_NUM]; + gint active_stream_cnt; + + gint percent; /* buffering percentage posting */ + GMutex *buffering_lock; + gboolean is_buffering; + GThread *buffering_posting_thread; + GMutex *post_msg_lock; + GCond *post_msg_start; + GCond *post_msg_exit; + + /* HTTP request cookies. */ + gchar **lastCookie; + gchar **playlistCookie; + gchar **keyCookie; + gchar **fragCookie; + gchar *lastDomain; + gchar *playlistDomain; + gchar *keyDomain; + gchar *fragDomain; + + gchar *user_agent; + + /* Properties */ + gfloat bitrate_switch_tol; /* tolerance with respect to the fragment duration to switch the bitarate*/ + + gboolean cancelled; + gboolean end_of_playlist; + + guint64 total_cache_duration; + guint64 target_duration; + +#ifdef ON_ERROR_REQUEST_AGAIN + /* requesting the same uron error */ + gchar *playlist_uri; + gchar *frag_uri; /* NOT supporting YET for fragment download errors*/ + gchar *key_uri; +#endif + + int soup_request_fail_cnt; + /* can be removed [mainly for debugging & testing] */ + gboolean force_lower_bitrate; + + GstClockTime cfrag_dur; + gboolean error_posted; + gboolean flushing; + GstClockTime ns_start; + GstClockTime cur_audio_fts; + + GstHLSDemux2PvtStream * private_stream; + gboolean has_image_buffer; + HLSDEMUX2_STREAM_CONFIGURATION stream_config; + GstBuffer *prev_image_buffer; + GstBuffer *prev_video_buffer; +}; + +struct _GstHLSDemux2Class +{ + GstElementClass parent_class; +}; + +GType gst_hlsdemux2_get_type (void); + +G_END_DECLS +#endif /* __GST_HLSDEMUX2_H__ */ diff --git a/hlsdemux2/src/m3u8.c b/hlsdemux2/src/m3u8.c new file mode 100755 index 0000000..f2a8621 --- /dev/null +++ b/hlsdemux2/src/m3u8.c @@ -0,0 +1,1246 @@ +/* GStreamer + * Copyright (C) 2010 Marc-Andre Lureau + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * m3u8.c: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include "m3u8.h" + +static GstM3U8 *gst_m3u8_new (void); +static void gst_m3u8_free (GstM3U8 * m3u8); +static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data, + gboolean * updated); +static GstM3U8MediaFile * +gst_m3u8_media_file_new (gchar * uri, gchar * title, GstClockTime duration, + gchar *key_url, gchar *IV, guint sequence); +static void gst_m3u8_media_file_free (GstM3U8MediaFile * self); +static void gst_m3u8_key_free (GstM3U8Key * self); + +#define GST_CAT_DEFAULT hlsdemux2_m3u8_debug + +#define BITRATE_SWITCH_UPPER_THRESHOLD 0.3 +#define BITRATE_SWITCH_LOWER_THRESHOLD 0 +#define SWITCH_TRIGGER_POINT 1 + +static GstM3U8 * +gst_m3u8_new (void) +{ + GstM3U8 *m3u8; + + m3u8 = g_new0 (GstM3U8, 1); + m3u8->last_data = NULL; + return m3u8; +} + +static void +gst_m3u8_set_uri (GstM3U8 * self, gchar * uri) +{ + g_return_if_fail (self != NULL); + + if (self->uri) + g_free (self->uri); + self->uri = uri; +} + +static void +gst_m3u8_free (GstM3U8 * self) +{ + g_return_if_fail (self != NULL); + + g_free (self->uri); + g_free (self->allowcache); + g_free (self->codecs); + //g_free (self->cipher_ctx); + + g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL); + g_list_free (self->files); + + g_free (self->last_data); + g_list_foreach (self->lists, (GFunc) gst_m3u8_free, NULL); + g_list_free (self->lists); + + g_free (self); +} + +static GstM3U8MediaFile * +gst_m3u8_media_file_new (gchar * uri, gchar * title, GstClockTime duration, + gchar *key_url, gchar *IV, guint sequence) +{ + GstM3U8MediaFile *file; + + file = g_new0 (GstM3U8MediaFile, 1); + file->uri = uri; + file->title = title; + file->duration = duration; + file->sequence = sequence; + + GST_DEBUG ("Duration of the file = %"GST_TIME_FORMAT"\n", GST_TIME_ARGS(duration)); + + if (key_url != NULL) + file->key_url = g_strdup (key_url); + else + file->key_url = NULL; + + file->iv = IV; + + return file; +} + +static void +gst_m3u8_media_file_free (GstM3U8MediaFile * self) +{ + g_return_if_fail (self != NULL); + + if (self->key_url) { + g_free (self->key_url); + self->key_url = NULL; + } + if (self->iv) { + g_free (self->iv); + self->iv = NULL; + } + if (self->title) { + g_free (self->title); + self->title = NULL; + } + if (self->uri){ + g_free (self->uri); + self->uri = NULL; + } + g_free (self); +} + +static gchar * +gst_m3u8_getIV_from_mediasequence (GstM3U8 *self) +{ + gchar *IV = NULL; + + IV = g_malloc0 (16); + if (!IV) { + GST_ERROR ("Failed to allocate memory..."); + return NULL; + } + + if (self->mediasequence > INT_MAX) { + GST_ERROR ("media sequnece is greater than INT_MAX...yet to handle"); + } + + IV [15] = (gchar)(self->mediasequence); + IV [14] = (gchar)(self->mediasequence >> 8); + IV [13] = (gchar)(self->mediasequence >> 16); + IV [12] = (gchar)(self->mediasequence >> 24); + return IV; +} + +static gboolean +int_from_string (gchar * ptr, gchar ** endptr, gint * val, gint base) +{ + gchar *end; + + g_return_val_if_fail (ptr != NULL, FALSE); + g_return_val_if_fail (val != NULL, FALSE); + + errno = 0; + *val = strtol (ptr, &end, base); + if ((errno == ERANGE && (*val == LONG_MAX || *val == LONG_MIN)) + || (errno != 0 && *val == 0)) { + GST_WARNING ("%s", g_strerror (errno)); + return FALSE; + } + + if (endptr) + *endptr = end; + + return end != ptr; +} + +static gboolean +double_from_string (gchar * ptr, gchar ** endptr, gdouble * val) +{ + gchar *end; + gdouble ret; + + g_return_val_if_fail (ptr != NULL, FALSE); + g_return_val_if_fail (val != NULL, FALSE); + + errno = 0; + ret = g_strtod (ptr, &end); + if ((errno == ERANGE && (ret == HUGE_VAL || ret == -HUGE_VAL)) + || (errno != 0 && ret == 0)) { + GST_WARNING ("%s", g_strerror (errno)); + return FALSE; + } + + if (!isfinite (ret)) { + GST_WARNING ("%s", g_strerror (ERANGE)); + return FALSE; + } + + if (endptr) + *endptr = end; + + *val = (gdouble) ret; + + return end != ptr; +} + +static gboolean +iv_from_string (gchar * ptr, gchar ** endptr, guint8 * val) +{ + guint8 idx; + guint8 hex; + + g_return_val_if_fail (ptr != NULL, FALSE); + g_return_val_if_fail (val != NULL, FALSE); + + if (*ptr == '0' && (*(ptr + 1) == 'x' || *(ptr + 1) == 'X')) { + ptr = ptr + 2; /* skip 0x or 0X */ + } + + for (idx = 0; idx < GST_M3U8_IV_LEN; idx++) { + hex = *ptr++ - '0'; + if (hex >= 16) + return FALSE; + *(val + idx) = hex * 16; + hex = *ptr++ - '0'; + if (hex >= 16) + return FALSE; + *(val + idx) += hex; + } + + if (endptr) + *endptr = ptr; + + return TRUE; +} + +static gboolean +iv_from_uint (guint uint, guint8 * val) +{ + guint8 idx; + + g_return_val_if_fail (val != NULL, FALSE); + + val = val + GST_M3U8_IV_LEN - 1; + for (idx = 0; idx < sizeof(guint); idx++) { + *val-- = (guint8)uint; + uint = uint >> 8; + } + return TRUE; +} + +static gboolean +make_valid_uri (gchar *prefix, gchar *suffix, gchar **uri) +{ + gchar *slash; + + if (!prefix) { + GST_WARNING ("uri prefix not set, can't build a valid uri"); + return FALSE; + } + slash = g_utf8_strrchr (prefix, -1, '/'); + if (!slash) { + GST_WARNING ("Can't build a valid uri"); + return FALSE; + } + + *slash = '\0'; + *uri = g_strdup_printf ("%s/%s", prefix, suffix); + *slash = '/'; + + return TRUE; +} + +static gboolean +parse_attributes (gchar ** ptr, gchar ** a, gchar ** v) +{ + gchar *end, *p; + + g_return_val_if_fail (ptr != NULL, FALSE); + g_return_val_if_fail (*ptr != NULL, FALSE); + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (v != NULL, FALSE); + + /* [attribute=value,]* */ + + *a = *ptr; + end = p = g_utf8_strchr (*ptr, -1, ','); + if (end) { + do { + end = g_utf8_next_char (end); + } while (end && *end == ' '); + *p = '\0'; + } + + *v = p = g_utf8_strchr (*ptr, -1, '='); + if (*v) { + *v = g_utf8_next_char (*v); + *p = '\0'; + } else { + GST_WARNING ("missing = after attribute"); + return FALSE; + } + + *ptr = end; + return TRUE; +} + +static gint +_m3u8_compare_uri (GstM3U8 * a, gchar * uri) +{ + g_return_val_if_fail (a != NULL, 0); + g_return_val_if_fail (uri != NULL, 0); + + return g_strcmp0 (a->uri, uri); +} + +static gint +gst_m3u8_compare_playlist_by_bitrate (gconstpointer a, gconstpointer b) +{ + return ((GstM3U8 *) (a))->bandwidth - ((GstM3U8 *) (b))->bandwidth; +} + +/* + * @data: a m3u8 playlist text data, taking ownership + */ +static gboolean +gst_m3u8_update (GstM3U8 * self, gchar *data, gboolean * updated) +{ + gint val; + GstClockTime duration = 0; + gchar *title, *end; +// gboolean discontinuity; + GstM3U8 *list; + gchar *key_url = NULL; + gchar *IV = NULL; + gchar *actual_data = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (updated != NULL, FALSE); + + *updated = TRUE; + + /* check if the data changed since last update */ + if (self->last_data && g_str_equal (self->last_data, data)) { + GST_DEBUG ("Playlist is the same as previous one"); + *updated = FALSE; + g_free (data); + return TRUE; + } + + if (!g_str_has_prefix (data, "#EXTM3U")) { + GST_WARNING ("Data doesn't start with #EXTM3U"); + *updated = FALSE; + g_free (data); + return FALSE; + } + + if (self->last_data) + g_free (self->last_data); + + self->last_data = g_strdup(data); + + actual_data = data; + + if (self->files) { + g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL); + g_list_free (self->files); + self->files = NULL; + } + + list = NULL; + duration = 0; + title = NULL; + data += 7; + + while (TRUE) { + + end = g_utf8_strchr (data, -1, '\n'); + if (end) + *end = '\0'; + + if (data[0] != '#') { + gchar *r; + gchar *uri = NULL; + + if (duration <= 0 && list == NULL) { + GST_LOG ("%s: got line without EXTINF or EXTSTREAMINF, dropping", data); + goto next_line; + } + + if (!gst_uri_is_valid (data)) { + if (!make_valid_uri(self->uri, data, &uri)) + goto next_line; + } else { + uri = g_strdup (data); + } + + r = g_utf8_strchr (uri, -1, '\r'); + if (r) + *r = '\0'; + + if (list != NULL) { + if (g_list_find_custom (self->lists, uri, (GCompareFunc) _m3u8_compare_uri)) { + GST_DEBUG ("Already have a list with this URI"); + gst_m3u8_free (list); + g_free (uri); + } else { + gst_m3u8_set_uri (list, uri); + self->lists = g_list_append (self->lists, list); + } + list = NULL; + } else { + GstM3U8MediaFile *file; + gchar *send_IV = NULL; + + if (key_url) { + GST_DEBUG ("AES-128 key url = %s", key_url); + if (NULL == IV) { + /* IV is not present in EXT-X-KEY tag. Prepare IV based on mediasequence */ + GST_DEBUG ("IV is not in EXT-X-KEY tag... generating from media_seq_num = %d", self->mediasequence); + send_IV = gst_m3u8_getIV_from_mediasequence (self); + } else { + int i=0; + send_IV = g_malloc0(16); + for(i=0;i<16;i++){ + send_IV[i]=IV[i]; + } + } + } + + file = + gst_m3u8_media_file_new (uri, title, duration, key_url, send_IV, + self->mediasequence++); + duration = 0; + title = NULL; + send_IV = NULL; + + self->files = g_list_append (self->files, file); + GST_DEBUG ("------------>>>>>>appending uri = %s and key = %s\n", file->uri, file->key_url); + } + } else if (g_str_has_prefix (data, "#EXT-X-ENDLIST")) { + GST_DEBUG ("*************** End list is present ****************"); + self->endlist = TRUE; + } else if (g_str_has_prefix (data, "#EXT-X-VERSION:")) { + if (int_from_string (data + 15, &data, &val, 10)) + self->version = val; + } else if (g_str_has_prefix (data, "#EXT-X-STREAM-INF:")) { + gchar *v, *a; + + if (list != NULL) { + GST_WARNING ("Found a list without a uri..., dropping"); + gst_m3u8_free (list); + } + + list = gst_m3u8_new (); + data = data + 18; + while (data && parse_attributes (&data, &a, &v)) { + if (g_str_equal (a, "BANDWIDTH")) { + if (!int_from_string (v, NULL, &list->bandwidth, 10)) + GST_WARNING ("Error while reading BANDWIDTH"); + } else if (g_str_equal (a, "PROGRAM-ID")) { + if (!int_from_string (v, NULL, &list->program_id, 10)) + GST_WARNING ("Error while reading PROGRAM-ID"); + } else if (g_str_equal (a, "CODECS")) { + g_free (list->codecs); + list->codecs = g_strdup (v); + } else if (g_str_equal (a, "RESOLUTION")) { + if (!int_from_string (v, &v, &list->width, 10)) + GST_WARNING ("Error while reading RESOLUTION width"); + if (!v || *v != '=') { + GST_WARNING ("Missing height"); + } else { + v = g_utf8_next_char (v); + if (!int_from_string (v, NULL, &list->height, 10)) + GST_WARNING ("Error while reading RESOLUTION height"); + } + } + } + } else if (g_str_has_prefix (data, "#EXT-X-TARGETDURATION:")) { + if (int_from_string (data + 22, &data, &val, 10)) + self->targetduration = val * GST_SECOND; + } else if (g_str_has_prefix (data, "#EXT-X-MEDIA-SEQUENCE:")) { + if (int_from_string (data + 22, &data, &val, 10)) + self->mediasequence = val; + } else if (g_str_has_prefix (data, "#EXT-X-DISCONTINUITY")) { + /* discontinuity = TRUE; */ + } else if (g_str_has_prefix (data, "#EXT-X-PROGRAM-DATE-TIME:")) { + /* */ + GST_DEBUG ("FIXME parse date"); + } else if (g_str_has_prefix (data, "#EXT-X-ALLOW-CACHE:")) { + g_free (self->allowcache); + self->allowcache = g_strdup (data + 19); + } else if (g_str_has_prefix (data, "#EXTINF:")) { + gdouble fval; + if (!double_from_string (data + 8, &data, &fval)) { + GST_WARNING ("Can't read EXTINF duration"); + goto next_line; + } + duration = fval * (gdouble) GST_SECOND; + if (duration > self->targetduration) + GST_WARNING ("EXTINF duration > TARGETDURATION"); + if (!data || *data != ',') + goto next_line; + data = g_utf8_next_char (data); + if (data != end) { + g_free (title); + title = g_strdup (data); + } + } else if (g_str_has_prefix (data, "#EXT-X-KEY:")) { + gchar *val, *attr; + GST_DEBUG ("Found EXT-X-KEY tag..."); + + /* handling encrypted content */ + data = data + 11; /* skipping "#EXT-X-KEY:" tag */ + + while (data && parse_attributes (&data, &attr, &val)) { + if (g_str_equal (attr, "METHOD")) { + if (g_str_equal (val, "NONE")) { + GST_LOG ("Non encrypted file...and skipping current line and going to next line\n"); + goto next_line; + } else if (g_str_equal (val, "AES-128")) { + /* media files are encrypted */ + GST_LOG ("media files are encrypted with AES-128\n"); + // TODO: indicate in flag whether encrypted files or not + } + } else if (g_str_equal (attr, "URI")) { + gchar *end_dq = NULL; + + if (!val){ + GST_ERROR ("val is NULL"); + break; + } + + val = val + 1; /* eliminating first double quote in url */ + if (!val) { + GST_ERROR ("val is NULL"); + break; + } + + end_dq = g_utf8_strrchr (val, -1, '"'); + if (!end_dq) { + GST_ERROR ("end_dq is NULL"); + break; + } + + *end_dq = '\0'; + GST_DEBUG ("Key URI = %s\n", val); + + if (!gst_uri_is_valid (val)) { + gchar *slash; + if (!self->uri) { + GST_WARNING ("uri not set, can't build a valid uri"); + goto next_line; + } + slash = g_utf8_strrchr (self->uri, -1, '/'); + if (!slash) { + GST_WARNING ("Can't build a valid uri"); + goto next_line; + } + *slash = '\0'; + key_url = g_strdup_printf ("%s/%s", self->uri, val); + *slash = '/'; + } else { + key_url= g_strdup (val); + } + } else if (g_str_equal (attr, "IV")) { + gint iv_len = 0; + gchar tmp_byte[3]; + gint tmp_val = 0; + gint idx = 0; + gchar *car = NULL; + + if (IV) { + g_free (IV); + IV = NULL; + } + + IV = g_malloc0 (16); + if (NULL == IV) { + GST_ERROR ("Failed to allocate memory...\n"); + goto error; + } + + /* eliminating 0x/0X prefix */ + val = val + 2; + car = g_utf8_strchr (val, -1, '\r'); + if (car) + *car = '\0'; + + iv_len = g_utf8_strlen(val, -1); + if (iv_len < 1 || iv_len >32) { + GST_ERROR ("Wrong IV and iv_len = %d", iv_len); + goto error; + } + + val+=iv_len; + idx = 15; + while (iv_len > 0) { + // TODO: val need to incremented I feel.. check again + val-=(iv_len==1)?1:2; + g_utf8_strncpy(tmp_byte, val, (iv_len==1)?1:2); + tmp_byte[2] = '\0'; + tmp_val = 0; + if (!int_from_string (tmp_byte, NULL, &tmp_val, 16)) + GST_WARNING ("Error while reading PROGRAM-ID"); + IV[idx] = tmp_val; + idx--; + iv_len = iv_len - 2; + } + } + } + } else { + GST_LOG ("Ignored line: %s", data); + } + + next_line: + if (!end) + break; + data = g_utf8_next_char (end); /* skip \n */ + } + + /* redorder playlists by bitrate */ + if (self->lists) { + gchar *top_variant_uri = NULL; + + if (!self->current_variant) + top_variant_uri = GST_M3U8 (self->lists->data)->uri; + else + top_variant_uri = GST_M3U8 (self->current_variant->data)->uri; + + self->lists = + g_list_sort (self->lists, + (GCompareFunc) gst_m3u8_compare_playlist_by_bitrate); + + self->current_variant = g_list_find_custom (self->lists, top_variant_uri, + (GCompareFunc) _m3u8_compare_uri); + } + + g_free (actual_data); + actual_data = NULL; + g_free (key_url); + key_url = NULL; + g_free (title); + title = NULL; + return TRUE; + +error: + g_free (actual_data); + actual_data = NULL; + g_free (key_url); + key_url = NULL; + g_free (title); + title = NULL; + return FALSE; +} + + +GstM3U8Client * +gst_m3u8_client_new (const gchar * uri) +{ + GstM3U8Client *client; + + g_return_val_if_fail (uri != NULL, NULL); + + client = g_new0 (GstM3U8Client, 1); + client->main = gst_m3u8_new (); + client->current = NULL; + client->sequence = -1; + client->update_failed_count = 0; + client->lock = g_mutex_new (); + gst_m3u8_set_uri (client->main, g_strdup (uri)); + + return client; +} + +void +gst_m3u8_client_free (GstM3U8Client * self) +{ + g_return_if_fail (self != NULL); + + gst_m3u8_free (self->main); + g_mutex_free (self->lock); + g_free (self); +} + +void +gst_m3u8_client_set_current (GstM3U8Client * self, GstM3U8 * m3u8) +{ + g_return_if_fail (self != NULL); + + GST_M3U8_CLIENT_LOCK (self); + if (m3u8 != self->current) { + self->current = m3u8; + self->update_failed_count = 0; + } + GST_M3U8_CLIENT_UNLOCK (self); +} + +static guint +_get_start_sequence (GstM3U8Client * client) +{ + GList *l; + GstClockTime duration_limit, duration_count = 0; + guint sequence = -1; + + if (client->current->endlist) { + l = g_list_first (client->current->files); + sequence = GST_M3U8_MEDIA_FILE (l->data)->sequence; + } else { + duration_limit = client->current->targetduration * 3; + for (l = g_list_last (client->current->files); l; l = l->prev) { + duration_count += GST_M3U8_MEDIA_FILE (l->data)->duration; + sequence = GST_M3U8_MEDIA_FILE (l->data)->sequence; + if (duration_count >= duration_limit) { + break; + } + } + } + return sequence; +} + +gboolean +gst_m3u8_client_update (GstM3U8Client * self, gchar * data) +{ + GstM3U8 *m3u8; + gboolean updated = FALSE; + gboolean ret = FALSE; + + g_return_val_if_fail (self != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (self); + m3u8 = self->current ? self->current : self->main; + + if (!gst_m3u8_update (m3u8, data, &updated)) + goto out; + + if (!updated) { + self->update_failed_count++; + goto out; + } + + /* select the first playlist, for now */ + if (!self->current) { + if (self->main->lists) { + self->current = self->main->current_variant->data; + } else { + self->current = self->main; + } + } + + if (m3u8->files && self->sequence == -1) { +#if 0 + self->sequence = GST_M3U8_MEDIA_FILE (g_list_first (m3u8->files)->data)->sequence; +#else + /* (spec : 6.3.3) In live case, the client SHOULD NOT choose a segment + which starts less than three target durations from the end of the Playlist file */ + self->sequence = _get_start_sequence (self); +#endif + GST_DEBUG ("Setting first sequence at %d", self->sequence); + } + + ret = TRUE; +out: + GST_M3U8_CLIENT_UNLOCK (self); + return ret; +} + +static gboolean +_find_next (GstM3U8MediaFile * file, GstM3U8Client * client) +{ + GST_DEBUG ("Found fragment %d", file->sequence); + if (file->sequence >= client->sequence) + return FALSE; + return TRUE; +} + +static gboolean +_find_key (GstM3U8Key * key, GstM3U8Client * client) +{ + if (key->sequence <= client->sequence) + return FALSE; + return TRUE; +} + +void +gst_m3u8_client_get_current_position (GstM3U8Client * client, + GstClockTime * timestamp) +{ + GList *l; + GList *walk; + + l = g_list_find_custom (client->current->files, client, + (GCompareFunc) _find_next); + + *timestamp = 0; + for (walk = client->current->files; walk; walk = walk->next) { + if (walk == l) + break; + *timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration; + } +} + +gboolean +gst_m3u8_client_get_next_fragment (GstM3U8Client * client, GstClockTime cur_running_time, + gboolean * discontinuity, const gchar ** uri, GstClockTime * duration, + GstClockTime * timestamp, gchar **key_uri, gchar **iv) +{ + GList *l; + GstM3U8MediaFile *file; + + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (client->current != NULL, FALSE); + g_return_val_if_fail (discontinuity != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (client); + + GST_DEBUG ("Looking for fragment %d", client->sequence); + + if (client->main && client->main->lists && client->current->endlist) { + GList *walk = NULL; + GstClockTime current_pos, target_pos; + gint current_sequence; + gboolean found_sequence = FALSE; + + /* VOD playlist, so find mediasequence from time */ + // TODO: need to handle when live converts to VOD by putting END_LIST tag + + file = GST_M3U8_MEDIA_FILE (client->current->files->data); + current_sequence = file->sequence; + current_pos = 0 ; + target_pos = cur_running_time; + + for (walk = client->current->files; walk; walk = walk->next) { + file = walk->data; + + current_sequence = file->sequence; + if (current_pos <= target_pos && + target_pos < current_pos + file->duration) { + found_sequence = TRUE; + break; + } + current_pos += file->duration; + } + + if (found_sequence) { + GST_ERROR ("changing client sequence from %d -> %d", client->sequence, current_sequence); + client->sequence = current_sequence; + } else { + GST_WARNING ("max file_seq = %d and client_seq = %d", current_sequence, client->sequence); + GST_M3U8_CLIENT_UNLOCK (client); + return FALSE; + } + } + + l = g_list_find_custom (client->current->files, client, (GCompareFunc) _find_next); + if (l == NULL) { + GST_M3U8_CLIENT_UNLOCK (client); + return FALSE; + } + + gst_m3u8_client_get_current_position (client, timestamp); + + file = GST_M3U8_MEDIA_FILE (l->data); + + if (file->key_url) + *key_uri = g_strdup (file->key_url); + + if (file->iv) { + *iv = g_malloc0 (GST_M3U8_IV_LEN); + //*iv = file->iv; + memcpy (*iv, file->iv, GST_M3U8_IV_LEN); + } + + *discontinuity = client->sequence != file->sequence; + client->sequence = file->sequence + 1; + + if (file->uri) + *uri = g_strdup (file->uri); + + *duration = file->duration; + + GST_M3U8_CLIENT_UNLOCK (client); + return TRUE; +} + +void gst_m3u8_client_decrement_sequence (GstM3U8Client * client) +{ + GST_M3U8_CLIENT_LOCK (client); + client->sequence = client->sequence - 1; + GST_M3U8_CLIENT_UNLOCK (client); +} + +static void +_sum_duration (GstM3U8MediaFile * self, GstClockTime * duration) +{ + *duration += self->duration; +} + +GstClockTime +gst_m3u8_client_get_duration (GstM3U8Client * client) +{ + GstClockTime duration = 0; + + g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE); + + GST_M3U8_CLIENT_LOCK (client); + /* We can only get the duration for on-demand streams */ + if (!client->current->endlist) { + GST_M3U8_CLIENT_UNLOCK (client); + return GST_CLOCK_TIME_NONE; + } + + g_list_foreach (client->current->files, (GFunc) _sum_duration, &duration); + GST_M3U8_CLIENT_UNLOCK (client); + return duration; +} + +GstClockTime +gst_m3u8_client_get_target_duration (GstM3U8Client * client) +{ + GstClockTime duration = 0; + + g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE); + + GST_M3U8_CLIENT_LOCK (client); + duration = client->current->targetduration; + GST_M3U8_CLIENT_UNLOCK (client); + return duration; +} + +/* used for LIVE case only, to update playlist file */ +GstClockTime +gst_m3u8_client_get_last_fragment_duration (GstM3U8Client * client) +{ + GstClockTime duration = 0; + GstM3U8MediaFile *last_file = NULL; + GList *last_list = NULL; + + g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE); + + GST_M3U8_CLIENT_LOCK (client); + + if (!client->current) { + GST_ERROR ("current variant is NULL.. return CLOCK_NONE"); + GST_M3U8_CLIENT_UNLOCK (client); + return GST_CLOCK_TIME_NONE; + } + + if (!client->current->files) { + GST_WARNING ("Due to playlist updation problem.. did not update the playlist"); + GST_M3U8_CLIENT_UNLOCK (client); + return 0; /* update playlist immediately */ + } + + last_list = g_list_last (client->current->files); + + if (!last_list) { + GST_WARNING ("list does not have last object... return target_duration"); + GST_M3U8_CLIENT_UNLOCK (client); + return client->current->targetduration; + } + + last_file = (GstM3U8MediaFile *)(last_list->data); + if(last_file) + duration = last_file->duration; + else + duration=client->current->targetduration; + + GST_DEBUG ("Last file duration = %"GST_TIME_FORMAT"\n", GST_TIME_ARGS(duration)); + GST_M3U8_CLIENT_UNLOCK (client); + return duration; +} + +const gchar * +gst_m3u8_client_get_uri (GstM3U8Client * client) +{ + const gchar *uri; + + g_return_val_if_fail (client != NULL, NULL); + + GST_M3U8_CLIENT_LOCK (client); + uri = client->main->uri; + GST_M3U8_CLIENT_UNLOCK (client); + return uri; +} + +const gchar * +gst_m3u8_client_get_current_uri (GstM3U8Client * client) +{ + const gchar *uri; + + g_return_val_if_fail (client != NULL, NULL); + + GST_M3U8_CLIENT_LOCK (client); + uri = client->current->uri; + GST_M3U8_CLIENT_UNLOCK (client); + return uri; +} + +gint +gst_m3u8_client_get_current_bandwidth (GstM3U8Client * client) +{ + gint bandwidth; + + g_return_val_if_fail (client != NULL, -1); + + GST_M3U8_CLIENT_LOCK (client); + bandwidth = client->current->bandwidth; + GST_M3U8_CLIENT_UNLOCK (client); + return bandwidth; +} + +gboolean +gst_m3u8_client_has_variant_playlist (GstM3U8Client * client) +{ + gboolean ret; + + g_return_val_if_fail (client != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (client); + ret = (client->main->lists != NULL); + GST_M3U8_CLIENT_UNLOCK (client); + return ret; +} + +gboolean +gst_m3u8_client_is_live (GstM3U8Client * client) +{ + gboolean ret; + + g_return_val_if_fail (client != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (client); + if (!client->current || client->current->endlist) + ret = FALSE; + else + ret = TRUE; + GST_M3U8_CLIENT_UNLOCK (client); + return ret; +} + +GList * +gst_m3u8_client_get_next_higher_bw_playlist (GstM3U8Client * client) +{ + GList *current_variant; + + g_return_val_if_fail (client != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (client); + current_variant = g_list_next (client->main->current_variant); + if (!current_variant) { + GST_WARNING ("no next variant available..."); + GST_M3U8_CLIENT_UNLOCK (client); + return NULL; + } + + GST_DEBUG ("next variant = %p and uri = %s", current_variant, GST_M3U8(current_variant->data)->uri); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; + +} + +GList * +gst_m3u8_client_get_next_lower_bw_playlist (GstM3U8Client * client) +{ + GList *current_variant; + + g_return_val_if_fail (client != NULL, FALSE); + + GST_M3U8_CLIENT_LOCK (client); + current_variant = g_list_previous (client->main->current_variant); + if (!current_variant) { + GST_WARNING ("no previous variant available..."); + GST_M3U8_CLIENT_UNLOCK (client); + return NULL; + } + + GST_DEBUG ("previous variant = %p and uri = %s", current_variant, GST_M3U8(current_variant->data)->uri); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; +} + + +#ifndef SWITCH_TRIGGER_POINT +GList * +gst_m3u8_client_get_playlist_for_bitrate (GstM3U8Client * client, guint bitrate) +{ + GList *list, *current_variant; + + GST_M3U8_CLIENT_LOCK (client); + current_variant = client->main->current_variant; + + /* Go to the highest possible bandwidth allowed */ + while (GST_M3U8 (current_variant->data)->bandwidth < bitrate) { + list = g_list_next (current_variant); + if (!list) + break; + current_variant = list; + } + + while (GST_M3U8 (current_variant->data)->bandwidth > bitrate) { + list = g_list_previous (current_variant); + if (!list) + break; + current_variant = list; + } + GST_M3U8_CLIENT_UNLOCK (client); + + return current_variant; +} +#else +GList * +gst_m3u8_client_get_playlist_for_bitrate (GstM3U8Client * client, guint bitrate) +{ + GList *next_variant = NULL; + GList *current_variant = NULL; + guint current_bandwidth = 0; + + GST_M3U8_CLIENT_LOCK (client); + current_variant = client->main->current_variant; + current_bandwidth = GST_M3U8 (current_variant->data)->bandwidth; + + if ((current_bandwidth + BITRATE_SWITCH_UPPER_THRESHOLD * current_bandwidth) < bitrate) { + GST_DEBUG ("Switch to upper band...\n"); + + if (!g_list_next (current_variant)) { + GST_DEBUG ("no next upper fragment...\n"); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; + } else { + GST_DEBUG (">>>>> UP : current_bw = %d, bitrate = %d\n", current_bandwidth, bitrate); + next_variant = current_variant; + + /* Go to the highest possible bandwidth allowed */ + while ((current_bandwidth + BITRATE_SWITCH_UPPER_THRESHOLD * current_bandwidth) < bitrate) { + current_variant = next_variant; + next_variant = g_list_next (next_variant); + if (!next_variant) { + GST_DEBUG ("no next upper fragment...\n"); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; + } + + current_bandwidth = GST_M3U8 (next_variant->data)->bandwidth; + GST_DEBUG ("current_bw in while= %d & URI = %s\n", current_bandwidth, GST_M3U8 (next_variant->data)->uri); + } + + /* as condition failed fallback to previous */ + GST_M3U8_CLIENT_UNLOCK (client); + + return current_variant; + } + } else if ((current_bandwidth + BITRATE_SWITCH_LOWER_THRESHOLD * current_bandwidth) > bitrate) { + GST_DEBUG ("Switch to lower band...\n"); + + if (!g_list_previous (current_variant)) { + GST_DEBUG ("no previous lower fragment...to go further down\n"); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; + } else { + + GST_DEBUG (">>>>> LOW : current_bw = %d, bitrate = %d\n", current_bandwidth, bitrate); + next_variant = current_variant; + + /* Go to the lowest possible bandwidth allowed */ + while ((current_bandwidth + BITRATE_SWITCH_LOWER_THRESHOLD * current_bandwidth) > bitrate) { + + next_variant = g_list_previous (next_variant); + if (!next_variant) { + GST_DEBUG ("no previous lower fragment...\n"); + GST_M3U8_CLIENT_UNLOCK (client); + return current_variant; + } + + current_variant = next_variant; + + current_bandwidth = GST_M3U8 (current_variant->data)->bandwidth; + GST_DEBUG ("current_bw in while= %d\n", current_bandwidth); + } + + GST_M3U8_CLIENT_UNLOCK (client); + + /* as condition failed fallback to previous */ + return current_variant; + } + } else { + GST_DEBUG ("No need to switch .... returning current_variant..\n"); + } + + GST_M3U8_CLIENT_UNLOCK (client); + + return current_variant; +} +#endif + +gboolean +gst_m3u8_client_decrypt_init (GstM3U8Client * client, unsigned char *key, gchar *iv) +{ + //if (!client->current->cipher_ctx) + // client->current->cipher_ctx = g_malloc0 (sizeof(EVP_CIPHER_CTX)); + + EVP_CIPHER_CTX_init (&(client->cipher_ctx)); + EVP_CIPHER_CTX_set_padding(&(client->cipher_ctx), 0); // added to check avodining final buffer decryption error + + return EVP_DecryptInit_ex (&(client->cipher_ctx), EVP_aes_128_cbc(), NULL, key, iv); +} + +gboolean +gst_m3u8_client_decrypt_update (GstM3U8Client * client, guint8 * out_data, + gint * out_size, guint8 * in_data, gint in_size) +{ + //g_return_val_if_fail (client->current->cipher_ctx != NULL, FALSE); + + return EVP_DecryptUpdate (&(client->cipher_ctx), out_data, out_size, + in_data, in_size); +} + +gboolean +gst_m3u8_client_decrypt_final (GstM3U8Client * client, guint8 * out_data, + gint * out_size) +{ + //g_return_val_if_fail (client->current->cipher_ctx != NULL, FALSE); + + return EVP_DecryptFinal_ex (&(client->cipher_ctx), out_data, out_size); +} + +gboolean +gst_m3u8_client_decrypt_deinit (GstM3U8Client * client) +{ + //g_return_val_if_fail (client->current->cipher_ctx != NULL, FALSE); + + return EVP_CIPHER_CTX_cleanup (&(client->cipher_ctx)); +} + + +gboolean +gst_m3u8_client_is_playlist_download_needed (GstM3U8Client * self) +{ + /* download is not need, if last_data is present & not live (i.e. we can reuse last VOD child playlist)*/ + if (self->current->last_data && !gst_m3u8_client_is_live(self)) + return FALSE; + else + return TRUE; +} diff --git a/hlsdemux2/src/m3u8.h b/hlsdemux2/src/m3u8.h new file mode 100755 index 0000000..d2a67e2 --- /dev/null +++ b/hlsdemux2/src/m3u8.h @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) 2010 Marc-Andre Lureau + * Copyright (C) 2010 Andoni Morales Alastruey + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * m3u8.h: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __M3U8_H__ +#define __M3U8_H__ + +#include +#include +#include + +G_BEGIN_DECLS typedef struct _GstM3U8 GstM3U8; +typedef struct _GstM3U8MediaFile GstM3U8MediaFile; +typedef struct _GstM3U8Key GstM3U8Key; +typedef struct _GstM3U8Client GstM3U8Client; + +#define GST_M3U8(m) ((GstM3U8*)m) +#define GST_M3U8_KEY(k) ((GstM3U8Key*)k) +#define GST_M3U8_MEDIA_FILE(f) ((GstM3U8MediaFile*)f) + +#define GST_M3U8_CLIENT_LOCK(c) g_mutex_lock (c->lock); +#define GST_M3U8_CLIENT_UNLOCK(c) g_mutex_unlock (c->lock); + +#define GST_M3U8_IV_LEN 16 + +GST_DEBUG_CATEGORY_EXTERN (hlsdemux2_m3u8_debug); + +typedef enum { + GST_M3U8_ENCRYPTED_NONE, + GST_M3U8_ENCRYPTED_AES_128, +} GstM3U8EncryptionMethod; + +struct _GstM3U8 +{ + gchar *uri; + + gboolean endlist; /* if ENDLIST has been reached */ + gint version; /* last EXT-X-VERSION */ + GstClockTime targetduration; /* last EXT-X-TARGETDURATION */ + gchar *allowcache; /* last EXT-X-ALLOWCACHE */ + + gint bandwidth; + gint program_id; + gchar *codecs; + gint width; + gint height; + GList *files; + + /*< private > */ + gchar *last_data; + GList *lists; /* list of GstM3U8 from the main playlist */ + GList *current_variant; /* Current variant playlist used */ + GstM3U8 *parent; /* main playlist (if any) */ + guint mediasequence; /* EXT-X-MEDIA-SEQUENCE & increased with new media file */ +}; + +struct _GstM3U8MediaFile +{ + gchar *title; + GstClockTime duration; + gchar *uri; + guint sequence; /* the sequence nb of this file */ + gchar *key_url; + unsigned char *key; + unsigned char *iv; +}; + +struct _GstM3U8Key +{ + GstM3U8EncryptionMethod method; + gchar *uri; + guint8 *iv; + guint sequence; + guint8 *data; +}; + +struct _GstM3U8Client +{ + GstM3U8 *main; /* main playlist */ + GstM3U8 *current; + guint update_failed_count; + gint sequence; /* the next sequence for this client */ + GMutex *lock; + EVP_CIPHER_CTX cipher_ctx; +}; + + +GstM3U8Client *gst_m3u8_client_new (const gchar * uri); +void gst_m3u8_client_free (GstM3U8Client * client); +gboolean gst_m3u8_client_update (GstM3U8Client * client, gchar * data); +void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8); +gboolean gst_m3u8_client_get_next_fragment (GstM3U8Client * client, GstClockTime cur_running_time, + gboolean * discontinuity, const gchar ** uri, GstClockTime * duration, + GstClockTime * timestamp, gchar **key_uri, gchar **iv); +void gst_m3u8_client_get_current_position (GstM3U8Client * client, + GstClockTime * timestamp); +GstClockTime gst_m3u8_client_get_duration (GstM3U8Client * client); +GstClockTime gst_m3u8_client_get_target_duration (GstM3U8Client * client); +const gchar *gst_m3u8_client_get_uri(GstM3U8Client * client); +const gchar *gst_m3u8_client_get_current_uri(GstM3U8Client * client); +gboolean gst_m3u8_client_has_variant_playlist(GstM3U8Client * client); +gboolean gst_m3u8_client_is_live(GstM3U8Client * client); +GList * gst_m3u8_client_get_playlist_for_bitrate (GstM3U8Client * client, + guint bitrate); +gboolean gst_m3u8_client_decrypt_init (GstM3U8Client * client, unsigned char *key, gchar *iv); +gboolean gst_m3u8_client_decrypt_update (GstM3U8Client * client, + guint8 * out_data, gint * out_size, guint8 * in_data, gint in_size); +gboolean gst_m3u8_client_is_playlist_download_needed (GstM3U8Client * self); +GstClockTime gst_m3u8_client_get_last_fragment_duration (GstM3U8Client * client); +gint gst_m3u8_client_get_current_bandwidth (GstM3U8Client * client); +gboolean gst_m3u8_client_decrypt_final (GstM3U8Client * client, guint8 * out_data, gint * out_size); +gboolean gst_m3u8_client_decrypt_deinit (GstM3U8Client * client); +void gst_m3u8_client_decrement_sequence (GstM3U8Client * client); +GList *gst_m3u8_client_get_next_higher_bw_playlist (GstM3U8Client * client); +GList *gst_m3u8_client_get_next_lower_bw_playlist (GstM3U8Client * client); + +G_END_DECLS +#endif /* __M3U8_H__ */ diff --git a/wearable/install-sh b/install-sh similarity index 100% rename from wearable/install-sh rename to install-sh diff --git a/wearable/ltmain.sh b/ltmain.sh similarity index 100% rename from wearable/ltmain.sh rename to ltmain.sh diff --git a/wearable/m4/Makefile.am b/m4/Makefile.am similarity index 100% rename from wearable/m4/Makefile.am rename to m4/Makefile.am diff --git a/wearable/m4/as-compiler-flag.m4 b/m4/as-compiler-flag.m4 similarity index 100% rename from wearable/m4/as-compiler-flag.m4 rename to m4/as-compiler-flag.m4 diff --git a/wearable/m4/as-version.m4 b/m4/as-version.m4 similarity index 100% rename from wearable/m4/as-version.m4 rename to m4/as-version.m4 diff --git a/wearable/missing b/missing similarity index 100% rename from wearable/missing rename to missing diff --git a/mobile/AUTHORS b/mobile/AUTHORS deleted file mode 100644 index 6f522a8..0000000 --- a/mobile/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -JongHyuk Choi -Seungbae Shin -Younghwan Ahn -Jeongmo Yang -Sangchul Lee diff --git a/mobile/COPYING b/mobile/COPYING deleted file mode 100644 index 8add30a..0000000 --- a/mobile/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library 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.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/mobile/INSTALL b/mobile/INSTALL deleted file mode 100644 index 23e5f25..0000000 --- a/mobile/INSTALL +++ /dev/null @@ -1,236 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: - - /bin/bash ./configure CONFIG_SHELL=/bin/bash - -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/mobile/LICENSE.LGPLv2.1 b/mobile/LICENSE.LGPLv2.1 deleted file mode 100644 index 8add30a..0000000 --- a/mobile/LICENSE.LGPLv2.1 +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library 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.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/mobile/Makefile.am b/mobile/Makefile.am deleted file mode 100755 index 16eea53..0000000 --- a/mobile/Makefile.am +++ /dev/null @@ -1,82 +0,0 @@ - -ACLOCAL_AMFLAGS = -I common/m4 - -aclocaldir = $(datadir)/aclocal - -SUBDIRS = common - -if GST_EXT_USE_EXT_ENCODEBIN -SUBDIRS += encodebin -endif - -if GST_EXT_USE_EXT_AVSYSTEM -SUBDIRS += avsystem -endif - -if GST_EXT_USE_EXT_EVASIMAGESINK -SUBDIRS += evasimagesink -endif - -if GST_EXT_USE_EXT_EVASPIXMAPSINK -SUBDIRS += evaspixmapsink -endif - -if GST_EXT_USE_EXT_XVIMAGESRC -SUBDIRS += xvimagesrc -endif - -if GST_EXT_USE_EXT_DRMSRC -SUBDIRS += drmsrc -endif - -if GST_EXT_USE_EXT_TOGGLE -SUBDIRS += toggle -endif - -if GST_EXT_USE_EXT_AVSYSTEM -SUBDIRS += pdpushsrc -endif - -if GST_EXT_USE_EXT_AUDIOTP -SUBDIRS += audiotp -endif - -if GST_EXT_USE_EXT_AUDIOEQ -SUBDIRS += audioeq -endif - -DIST_SUBDIRS = common - -if GST_EXT_USE_EXT_ENCODEBIN -DIST_SUBDIRS += encodebin -endif - -if GST_EXT_USE_EXT_AVSYSTEM -DIST_SUBDIRS += avsystem -endif - -if GST_EXT_USE_EXT_EVASIMAGESINK -DIST_SUBDIRS += evasimagesink -endif - -if GST_EXT_USE_EXT_XVIMAGESRC -DIST_SUBDIRS += xvimagesrc -endif - -if GST_EXT_USE_EXT_DRMSRC -DIST_SUBDIRS += drmsrc -endif - -if GST_EXT_USE_EXT_TOGGLE -DIST_SUBDIRS += toggle -endif - - -EXTRA_DIST = \ - gstreamer.spec gstreamer.spec.in \ - configure.ac autogen.sh depcomp \ - MAINTAINERS ABOUT-NLS RELEASE gstreamer.doap \ - $(win32) - -check: check-exports - diff --git a/mobile/NOTICE b/mobile/NOTICE deleted file mode 100644 index 0e6ffbb..0000000 --- a/mobile/NOTICE +++ /dev/null @@ -1,3 +0,0 @@ -Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. -Except as noted, this software is licensed under GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1 -Please, see the LICENSE file for GNU LESSER GENERAL PUBLIC LICENSE terms and conditions. diff --git a/mobile/PLUGINS b/mobile/PLUGINS deleted file mode 100644 index a737f3a..0000000 --- a/mobile/PLUGINS +++ /dev/null @@ -1,15 +0,0 @@ -# This file is descriptions of the plugins which are included in gstreamer0.10-plugins-ext. -# If any plugin is added to the gstreamer0.10-plugins-ext, that shoud be described in this file. -# -# - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -PLUGIN Registered Elements Description -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -avsysaudiosrc avsysaudiosrc AV system audio source plugin -avsyssink avsysaudiosink, avsysmemsink AV system audio sink plugin -drmsrc drmsrc Plugin to read data from standad/DRM file -encodebin encodebin Extension encoder bin plugin -evasimagesink evasimagesink Evas video sink plugin -toggle toggle Base transform plugin -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/mobile/README b/mobile/README deleted file mode 100644 index 9681276..0000000 --- a/mobile/README +++ /dev/null @@ -1,12 +0,0 @@ -gst-plugin is a template for writing your own GStreamer plug-in. - -The code is deliberately kept simple so that you quickly understand the basics -of how to set up autotools and your source tree. - -This template demonstrates : -- what to do in autogen.sh -- how to setup configure.ac (your package name and version, GStreamer flags) -- how to setup your source dir -- what to put in Makefile.am - -More features might get added to this template later on. diff --git a/mobile/audioeq/Makefile.am b/mobile/audioeq/Makefile.am deleted file mode 100755 index 308a09c..0000000 --- a/mobile/audioeq/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/mobile/audioeq/src/Makefile.am b/mobile/audioeq/src/Makefile.am deleted file mode 100755 index 6981e78..0000000 --- a/mobile/audioeq/src/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# plugindir is set in configure - -############################################################################## -# change libgstplugin.la to something more suitable, e.g. libmysomething.la # -############################################################################## -plugin_LTLIBRARIES = libgstaudioeq.la - -############################################################################## -# for the next set of variables, rename the prefix if you renamed the .la, # -# e.g. libgstplugin_la_SOURCES => libmysomething_la_SOURCES # -# libgstplugin_la_CFLAGS => libmysomething_la_CFLAGS # -# libgstplugin_la_LIBADD => libmysomething_la_LIBADD # -# libgstplugin_la_LDFLAGS => libmysomething_la_LDFLAGS # -############################################################################## - -# sources used to compile this plug-in -libgstaudioeq_la_SOURCES = gstaudioeq.c - -# flags used to compile this plugin -# add other _CFLAGS and _LIBS as needed -libgstaudioeq_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CONTROLLER_CFLAGS) -libgstaudioeq_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(GST_BASE_LIBS) $(GST_CONTROLLER_LIBS) $(GST_LIBS) $(LIBM) -lgstbase-0.10 -lglib-2.0 -lgstcontroller-0.10 -libgstaudioeq_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -libgstequalizer_la_LIBTOOLFLAGS = --tag=disable-static - -# headers we need but don't want installed -noinst_HEADERS = gstaudioeq.h diff --git a/mobile/audioeq/src/gstaudioeq.c b/mobile/audioeq/src/gstaudioeq.c deleted file mode 100644 index 9185861..0000000 --- a/mobile/audioeq/src/gstaudioeq.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* - * audioeq - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Aditi Narula - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gstaudioeq.h" - -GST_DEBUG_CATEGORY_STATIC (gst_audioeq_debug); -#define GST_CAT_DEFAULT gst_audioeq_debug - -#define AUDIOEQ_ENABLE_DUMP -#define AUDIOEQ_REDUCE_MEMCPY - -/* Filter signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_FILTER_ACTION, - PROP_CUSTOM_EQ, - PROP_CUSTOM_EQ_NUM, - PROP_CUSTOM_EQ_FREQ, - PROP_CUSTOM_EQ_WIDTH, -}; - -enum FilterActionType -{ - FILTER_NONE, - FILTER_PRESET, - FILTER_ADVANCED_SETTING -}; - -enum SampleRate -{ - SAMPLERATE_48000Hz, - SAMPLERATE_44100Hz, - SAMPLERATE_32000Hz, - SAMPLERATE_24000Hz, - SAMPLERATE_22050Hz, - SAMPLERATE_16000Hz, - SAMPLERATE_12000Hz, - SAMPLERATE_11025Hz, - SAMPLERATE_8000Hz, - - SAMPLERATE_NUM -}; - -#define DEFAULT_SAMPLE_SIZE 2 -#define DEFAULT_VOLUME 15 -#define DEFAULT_GAIN 1 -#define DEFAULT_SAMPLE_RATE SAMPLERATE_44100Hz -#define DEAFULT_CHANNELS 2 -#define DEFAULT_FILTER_ACTION FILTER_NONE -#define DEFAULT_CUSTOM_EQ_NUM 7 - -static GstStaticPadTemplate sinktemplate = - GST_STATIC_PAD_TEMPLATE( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "audio/x-raw-int, " - "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", " - "signed = (boolean) true, " - "width = (int) 16, " - "depth = (int) 16, " - "channels = (int) [1,2]" - ) - ); - -static GstStaticPadTemplate srctemplate = - GST_STATIC_PAD_TEMPLATE( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "audio/x-raw-int, " - "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", " - "signed = (boolean) true, " - "width = (int) 16, " - "depth = (int) 16, " - "channels = (int) [1,2]" - ) - ); - -static void gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface, - gpointer iface_data); - -static void gst_iir_equalizer_finalize (GObject * object); - -static gboolean gst_iir_equalizer_setup (GstAudioFilter * filter, - GstRingBufferSpec * fmt); - -static void -_do_init (GType object_type) -{ - const GInterfaceInfo child_proxy_interface_info = { - (GInterfaceInitFunc) gst_iir_equalizer_child_proxy_interface_init, - NULL, /* interface_finalize */ - NULL /* interface_data */ - }; - - g_type_add_interface_static (object_type, GST_TYPE_CHILD_PROXY, - &child_proxy_interface_info); -} - -GST_BOILERPLATE_FULL(Gstaudioeq, gst_audioeq, GstBaseTransform, GST_TYPE_BASE_TRANSFORM,_do_init); - -static void gst_audioeq_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_audioeq_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -#ifdef AUDIOEQ_REDUCE_MEMCPY -static GstFlowReturn gst_audioeq_transform_ip (GstBaseTransform * base, GstBuffer * buf); -#else -static GstFlowReturn gst_audioeq_transform (GstBaseTransform * base, GstBuffer * inbuf, GstBuffer * outbuf); -#endif -static gboolean gst_audioeq_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps); - -static GstStateChangeReturn -gst_audioeq_change_state (GstElement * element, GstStateChange transition) -{ - GST_DEBUG ("gst_audioeq_change_state"); - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - Gstaudioeq *audioeq = GST_AUDIOEQ (element); - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - audioeq->need_update_filter = TRUE; - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - if (ret == GST_STATE_CHANGE_FAILURE) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - default: - break; - } - - return ret; -} - -static void -gst_audioeq_base_init (gpointer gclass) -{ - - GST_DEBUG ("gst_audioeq_base_init"); - static GstElementDetails element_details = { - "Audio Equalizer", - "Filter/Effect/Audio", - "Set equalisation effect on audio/raw streams", - "Samsung Electronics " - }; - - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template(element_class, - gst_static_pad_template_get (&sinktemplate)); - - gst_element_class_set_details(element_class, &element_details); -} - -static void -gst_audioeq_class_init (GstaudioeqClass * klass) -{ - GST_DEBUG ("gst_audioeq_class_init"); - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseTransformClass *basetransform_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstelement_class = GST_ELEMENT_CLASS (klass); - basetransform_class = GST_BASE_TRANSFORM_CLASS(klass); - - gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_audioeq_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_audioeq_get_property); - - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_audioeq_change_state); - - g_object_class_install_property(gobject_class, PROP_FILTER_ACTION, - g_param_spec_uint("filter-action", "filter action", "(0)none (1)preset (2)advanced setting", - 0, 2, DEFAULT_FILTER_ACTION, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_CUSTOM_EQ, - g_param_spec_pointer("custom-eq", "custom eq", - "pointer for 9 bands of EQ array", G_PARAM_READWRITE)); - - g_object_class_install_property(gobject_class, PROP_CUSTOM_EQ_NUM, - g_param_spec_uint("custom-eq-num", "custom eq num", "number of custom EQ bands", - 0, 9, DEFAULT_CUSTOM_EQ_NUM, G_PARAM_READABLE)); - - g_object_class_install_property(gobject_class, PROP_CUSTOM_EQ_FREQ, - g_param_spec_pointer("custom-eq-freq", "custom eq freq", "pointer for EQ bands central frequency(Hz) array", - G_PARAM_READABLE)); - - g_object_class_install_property(gobject_class, PROP_CUSTOM_EQ_WIDTH, - g_param_spec_pointer("custom-eq-width", "custom eq width", "pointer for EQ bands width(Hz) array", - G_PARAM_READABLE)); - - gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_iir_equalizer_finalize); - -/* It is possible to reduce memcpy by setting output same as input of AudioEq_InOutConfig */ -#ifdef AUDIOEQ_REDUCE_MEMCPY - basetransform_class->transform_ip = GST_DEBUG_FUNCPTR(gst_audioeq_transform_ip); -#endif - basetransform_class->set_caps = GST_DEBUG_FUNCPTR(gst_audioeq_set_caps); -} - -static void -gst_audioeq_init (Gstaudioeq * audioeq, GstaudioeqClass * gclass) -{ - GST_DEBUG ("gst_audioeq_init"); - audioeq->samplerate = DEFAULT_SAMPLE_RATE; - audioeq->channels = DEAFULT_CHANNELS; - - audioeq->filter_action = DEFAULT_FILTER_ACTION; - memset(audioeq->custom_eq, 0x00, sizeof(gint) * CUSTOM_EQ_BAND_MAX); - audioeq->need_update_filter = TRUE; - audioeq->equ.bands_lock = g_mutex_new (); - audioeq->equ.need_new_coefficients = TRUE; - gst_iir_equalizer_compute_frequencies (audioeq, DEFAULT_CUSTOM_EQ_NUM); -} -/* equalizer implementation */ - -static void -gst_iir_equalizer_finalize (GObject * object) -{ - GST_DEBUG ("gst_iir_equalizer_finalize"); - Gstaudioeq *audioeq = GST_AUDIOEQ(object); - GstIirEqualizer *equ = &audioeq->equ; - gint i; - - for (i = 0; i < equ->freq_band_count; i++) { - if (equ->bands[i]) - gst_object_unparent (GST_OBJECT (equ->bands[i])); - equ->bands[i] = NULL; - } - equ->freq_band_count = 0; - - g_free (equ->bands); - g_free (equ->history); - - g_mutex_free (equ->bands_lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -#define BANDS_LOCK(equ) g_mutex_lock(equ->bands_lock) -#define BANDS_UNLOCK(equ) g_mutex_unlock(equ->bands_lock) - -/* child object */ - -enum -{ - PROP_GAIN = 1, - PROP_FREQ, - PROP_BANDWIDTH, - PROP_TYPE -}; - -typedef enum -{ - BAND_TYPE_PEAK = 0, - BAND_TYPE_LOW_SHELF, - BAND_TYPE_HIGH_SHELF -} GstIirEqualizerBandType; - -#define GST_TYPE_IIR_EQUALIZER_BAND_TYPE (gst_iir_equalizer_band_type_get_type ()) -static GType -gst_iir_equalizer_band_type_get_type (void) -{ - GST_DEBUG ("gst_iir_equalizer_band_type_get_type"); - static GType gtype = 0; - - if (gtype == 0) { - static const GEnumValue values[] = { - {BAND_TYPE_PEAK, "Peak filter (default for inner bands)", "peak"}, - {BAND_TYPE_LOW_SHELF, "Low shelf filter (default for first band)", - "low-shelf"}, - {BAND_TYPE_HIGH_SHELF, "High shelf filter (default for last band)", - "high-shelf"}, - {0, NULL, NULL} - }; - - gtype = g_enum_register_static ("GstIirEqualizerBandType", values); - } - return gtype; -} - - -typedef struct _GstIirEqualizerBandClass GstIirEqualizerBandClass; - -#define GST_TYPE_IIR_EQUALIZER_BAND \ - (gst_iir_equalizer_band_get_type()) -#define GST_IIR_EQUALIZER_BAND(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBand)) -#define GST_IIR_EQUALIZER_BAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBandClass)) -#define GST_IS_IIR_EQUALIZER_BAND(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IIR_EQUALIZER_BAND)) -#define GST_IS_IIR_EQUALIZER_BAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IIR_EQUALIZER_BAND)) - -struct _GstIirEqualizerBand -{ - GstObject object; - - /*< private > */ - /* center frequency and gain */ - gdouble freq; - gdouble gain; - gdouble width; - GstIirEqualizerBandType type; - - /* second order iir filter */ - gdouble b1, b2; /* IIR coefficients for outputs */ - gdouble a0, a1, a2; /* IIR coefficients for inputs */ -}; - -struct _GstIirEqualizerBandClass -{ - GstObjectClass parent_class; -}; - -static GType gst_iir_equalizer_band_get_type (void); - -static void -gst_iir_equalizer_band_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GST_DEBUG ("gst_iir_equalizer_band_set_property"); - GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object); - Gstaudioeq *audioeq = GST_AUDIOEQ (gst_object_get_parent (GST_OBJECT (band))); - GstIirEqualizer *equ = &audioeq->equ; - - switch (prop_id) { - case PROP_GAIN:{ - gdouble gain; - - gain = g_value_get_double (value); - GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain); - if (gain != band->gain) { - BANDS_LOCK (equ); - equ->need_new_coefficients = TRUE; - band->gain = gain; - BANDS_UNLOCK (equ); - GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain); - } - break; - } - case PROP_FREQ:{ - gdouble freq; - - freq = g_value_get_double (value); - GST_DEBUG_OBJECT (band, "freq = %lf -> %lf", band->freq, freq); - if (freq != band->freq) { - BANDS_LOCK (equ); - equ->need_new_coefficients = TRUE; - band->freq = freq; - BANDS_UNLOCK (equ); - GST_DEBUG_OBJECT (band, "changed freq = %lf ", band->freq); - } - break; - } - case PROP_BANDWIDTH:{ - gdouble width; - - width = g_value_get_double (value); - GST_DEBUG_OBJECT (band, "width = %lf -> %lf", band->width, width); - if (width != band->width) { - BANDS_LOCK (equ); - equ->need_new_coefficients = TRUE; - band->width = width; - BANDS_UNLOCK (equ); - GST_DEBUG_OBJECT (band, "changed width = %lf ", band->width); - } - break; - } - case PROP_TYPE:{ - GstIirEqualizerBandType type; - - type = g_value_get_enum (value); - GST_DEBUG_OBJECT (band, "type = %d -> %d", band->type, type); - if (type != band->type) { - BANDS_LOCK (equ); - equ->need_new_coefficients = TRUE; - band->type = type; - BANDS_UNLOCK (equ); - GST_DEBUG_OBJECT (band, "changed type = %d ", band->type); - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - gst_object_unref (audioeq); -} - -static void -gst_iir_equalizer_band_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GST_DEBUG ("gst_iir_equalizer_band_get_property"); - GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object); - - switch (prop_id) { - case PROP_GAIN: - g_value_set_double (value, band->gain); - break; - case PROP_FREQ: - g_value_set_double (value, band->freq); - break; - case PROP_BANDWIDTH: - g_value_set_double (value, band->width); - break; - case PROP_TYPE: - g_value_set_enum (value, band->type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_iir_equalizer_band_class_init (GstIirEqualizerBandClass * klass) -{ - GST_DEBUG ("gst_iir_equalizer_band_class_init"); - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = gst_iir_equalizer_band_set_property; - gobject_class->get_property = gst_iir_equalizer_band_get_property; - - g_object_class_install_property (gobject_class, PROP_GAIN, - g_param_spec_double ("gain", "gain", - "gain for the frequency band ranging from -12.0 dB to +12.0 dB", - -12.0, 12.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE)); - - g_object_class_install_property (gobject_class, PROP_FREQ, - g_param_spec_double ("freq", "freq", - "center frequency of the band", - 0.0, 100000.0, 0.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE)); - - g_object_class_install_property (gobject_class, PROP_BANDWIDTH, - g_param_spec_double ("bandwidth", "bandwidth", - "difference between bandedges in Hz", - 0.0, 100000.0, 1.0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE)); - - g_object_class_install_property (gobject_class, PROP_TYPE, - g_param_spec_enum ("type", "Type", - "Filter type", GST_TYPE_IIR_EQUALIZER_BAND_TYPE, - BAND_TYPE_PEAK, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE)); -} - -static void -gst_iir_equalizer_band_init (GstIirEqualizerBand * band, - GstIirEqualizerBandClass * klass) -{ - GST_DEBUG ("gst_iir_equalizer_band_init"); - band->freq = 0.0; - band->gain = 0.0; - band->width = 1.0; - band->type = BAND_TYPE_PEAK; -} - -static GType -gst_iir_equalizer_band_get_type (void) -{ - GST_DEBUG ("gst_iir_equalizer_band_get_type"); - static GType type = 0; - - if (G_UNLIKELY (!type)) { - const GTypeInfo type_info = { - sizeof (GstIirEqualizerBandClass), - NULL, - NULL, - (GClassInitFunc) gst_iir_equalizer_band_class_init, - NULL, - NULL, - sizeof (GstIirEqualizerBand), - 0, - (GInstanceInitFunc) gst_iir_equalizer_band_init, - }; - type = - g_type_register_static (GST_TYPE_OBJECT, "GstIirEqualizerBand", - &type_info, 0); - } - return (type); -} - - -/* child proxy iface */ -static GstObject * -gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy, - guint index) -{ - GST_DEBUG ("gst_iir_equalizer_child_proxy_get_child_by_index"); - Gstaudioeq *audioeq = GST_AUDIOEQ(child_proxy); - GstIirEqualizer *equ = &audioeq->equ; - GstObject *ret; - - BANDS_LOCK (equ); - if (G_UNLIKELY (index >= equ->freq_band_count)) { - BANDS_UNLOCK (equ); - g_return_val_if_fail (index < equ->freq_band_count, NULL); - } - - ret = gst_object_ref (equ->bands[index]); - BANDS_UNLOCK (equ); - - GST_LOG_OBJECT (equ, "return child[%d] %" GST_PTR_FORMAT, index, ret); - return ret; -} - -static guint -gst_iir_equalizer_child_proxy_get_children_count (GstChildProxy * child_proxy) -{ - GST_DEBUG ("gst_iir_equalizer_child_proxy_get_children_count"); - Gstaudioeq *audioeq = GST_AUDIOEQ(child_proxy); - GstIirEqualizer *equ = &audioeq->equ; - - GST_LOG ("we have %d children", equ->freq_band_count); - return equ->freq_band_count; -} - -static void -gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface, - gpointer iface_data) -{ - GstChildProxyInterface *iface = g_iface; - - GST_DEBUG ("initializing iface"); - - iface->get_child_by_index = gst_iir_equalizer_child_proxy_get_child_by_index; - iface->get_children_count = gst_iir_equalizer_child_proxy_get_children_count; -} -static void -gst_iir_equalizer_class_init (GstIirEqualizerClass * klass) -{ - GST_DEBUG ("gst_iir_equalizer_class_init"); -} - -static void -gst_iir_equalizer_init (GstIirEqualizer * eq, GstIirEqualizerClass * g_class) -{ - GST_DEBUG ("gst_iir_equalizer_init"); - eq->bands_lock = g_mutex_new (); - eq->need_new_coefficients = TRUE; -} - -GType -gst_iir_equalizer_get_type (void) -{ - GST_DEBUG ("gst_iir_equalizer_get_type"); - static GType type = 0; - - if (G_UNLIKELY (!type)) { - const GTypeInfo type_info = { - sizeof (GstIirEqualizerClass), - NULL, - NULL, - (GClassInitFunc) gst_iir_equalizer_class_init, - NULL, - NULL, - sizeof (GstIirEqualizer), - 0, - (GInstanceInitFunc) gst_iir_equalizer_init, - }; - type = - g_type_register_static (GST_TYPE_OBJECT, "GstIirEqualizer", - &type_info, 0); - } - return (type); -} -/* Filter taken from - * - * The Equivalence of Various Methods of Computing - * Biquad Coefficients for Audio Parametric Equalizers - * - * by Robert Bristow-Johnson - * - * http://www.aes.org/e-lib/browse.cfm?elib=6326 - * http://www.musicdsp.org/files/EQ-Coefficients.pdf - * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt - * - * The bandwidth method that we use here is the preferred - * one from this article transformed from octaves to frequency - * in Hz. - */ -static inline gdouble -arg_to_scale (gdouble arg) -{ - GST_DEBUG ("arg_to_scale"); - return (pow (10.0, arg / 40.0)); -} - -static gdouble -calculate_omega (gdouble freq, gint rate) -{ - GST_DEBUG ("calculate_omega"); - gdouble omega; - - if (freq / rate >= 0.5) - omega = G_PI; - else if (freq <= 0.0) - omega = 0.0; - else - omega = 2.0 * G_PI * (freq / rate); - - return omega; -} - -static gdouble -calculate_bw (GstIirEqualizerBand * band, gint rate) -{ - GST_DEBUG ("calculate_bw"); - gdouble bw = 0.0; - - if (band->width / rate >= 0.5) { - /* If bandwidth == 0.5 the calculation below fails as tan(G_PI/2) - * is undefined. So set the bandwidth to a slightly smaller value. - */ - bw = G_PI - 0.00000001; - } else if (band->width <= 0.0) { - /* If bandwidth == 0 this band won't change anything so set - * the coefficients accordingly. The coefficient calculation - * below would create coefficients that for some reason amplify - * the band. - */ - band->a0 = 1.0; - band->a1 = 0.0; - band->a2 = 0.0; - band->b1 = 0.0; - band->b2 = 0.0; - } else { - bw = 2.0 * G_PI * (band->width / rate); - } - return bw; -} - -static void -setup_peak_filter (Gstaudioeq* audioeq, GstIirEqualizerBand * band) -{ - GST_DEBUG ("setup_peak_filter"); - //g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate); - - { - gdouble gain, omega, bw; - gdouble alpha, alpha1, alpha2, b0; - - gain = arg_to_scale (band->gain); - omega = calculate_omega (band->freq, audioeq->samplerate); - bw = calculate_bw (band, audioeq->samplerate); - if (bw == 0.0) - goto out; - - alpha = tan (bw / 2.0); - - alpha1 = alpha * gain; - alpha2 = alpha / gain; - - b0 = (1.0 + alpha2); - - band->a0 = (1.0 + alpha1) / b0; - band->a1 = (-2.0 * cos (omega)) / b0; - band->a2 = (1.0 - alpha1) / b0; - band->b1 = (2.0 * cos (omega)) / b0; - band->b2 = -(1.0 - alpha2) / b0; - - out: - GST_INFO - ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g", - band->gain, band->width, band->freq, band->a0, band->a1, band->a2, - band->b1, band->b2); - } -} - -static void -setup_low_shelf_filter (Gstaudioeq* audioeq, GstIirEqualizerBand * band) -{ - GST_DEBUG ("setup_low_shelf_filter"); - //g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate); - - { - gdouble gain, omega, bw; - gdouble alpha, delta, b0; - gdouble egp, egm; - - gain = arg_to_scale (band->gain); - omega = calculate_omega (band->freq, audioeq->samplerate); - bw = calculate_bw (band, audioeq->samplerate); - if (bw == 0.0) - goto out; - - egm = gain - 1.0; - egp = gain + 1.0; - alpha = tan (bw / 2.0); - - delta = 2.0 * sqrt (gain) * alpha; - b0 = egp + egm * cos (omega) + delta; - - band->a0 = ((egp - egm * cos (omega) + delta) * gain) / b0; - band->a1 = ((egm - egp * cos (omega)) * 2.0 * gain) / b0; - band->a2 = ((egp - egm * cos (omega) - delta) * gain) / b0; - band->b1 = ((egm + egp * cos (omega)) * 2.0) / b0; - band->b2 = -((egp + egm * cos (omega) - delta)) / b0; - - - out: - GST_INFO - ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g", - band->gain, band->width, band->freq, band->a0, band->a1, band->a2, - band->b1, band->b2); - } -} - -static void -setup_high_shelf_filter (Gstaudioeq* audioeq, GstIirEqualizerBand * band) -{ - GST_DEBUG ("setup_high_shelf_filter"); - { - gdouble gain, omega, bw; - gdouble alpha, delta, b0; - gdouble egp, egm; - - gain = arg_to_scale (band->gain); - omega = calculate_omega (band->freq, audioeq->samplerate); - bw = calculate_bw (band, audioeq->samplerate); - if (bw == 0.0) - goto out; - - egm = gain - 1.0; - egp = gain + 1.0; - alpha = tan (bw / 2.0); - - delta = 2.0 * sqrt (gain) * alpha; - b0 = egp - egm * cos (omega) + delta; - - band->a0 = ((egp + egm * cos (omega) + delta) * gain) / b0; - band->a1 = ((egm + egp * cos (omega)) * -2.0 * gain) / b0; - band->a2 = ((egp + egm * cos (omega) - delta) * gain) / b0; - band->b1 = ((egm - egp * cos (omega)) * -2.0) / b0; - band->b2 = -((egp - egm * cos (omega) - delta)) / b0; - - - out: - GST_INFO - ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g", - band->gain, band->width, band->freq, band->a0, band->a1, band->a2, - band->b1, band->b2); - } -} - -/* Must be called with bands_lock and transform lock! */ -static void -set_passthrough (Gstaudioeq* audioeq) -{ - GST_DEBUG ("set_passthrough"); - GstIirEqualizer* equ=&audioeq->equ; - gint i; - gboolean passthrough = TRUE; - - for (i = 0; i < equ->freq_band_count; i++) { - passthrough = passthrough && (equ->bands[i]->gain == 0.0); - } - - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (audioeq), passthrough); - GST_DEBUG ("Passthrough mode: %d\n", passthrough); -} - -/* Must be called with bands_lock and transform lock! */ -static void -update_coefficients (Gstaudioeq* audioeq) -{ - GST_DEBUG ("update_coefficients"); - GstIirEqualizer* equ=&audioeq->equ; - gint i, n = equ->freq_band_count; - - for (i = 0; i < n; i++) { - if (equ->bands[i]->type == BAND_TYPE_PEAK) - setup_peak_filter (audioeq, equ->bands[i]); - else if (equ->bands[i]->type == BAND_TYPE_LOW_SHELF) - setup_low_shelf_filter (audioeq, equ->bands[i]); - else - setup_high_shelf_filter (audioeq, equ->bands[i]); - } - - equ->need_new_coefficients = FALSE; -} - -/* Must be called with transform lock! */ -static void -alloc_history (GstIirEqualizer * equ) -{ - GST_DEBUG ("alloc_history"); - /* free + alloc = no memcpy */ - g_free (equ->history); - equ->history = - g_malloc0 (equ->history_size * equ->audiofilter.format.channels * - equ->freq_band_count); -} -void -gst_audioeq_band_set_property(Gstaudioeq * audioeq) -{ - GST_DEBUG ("gst_audioeq_band_set_property"); - GstIirEqualizer *equ = &audioeq->equ; - gshort i ; - for ( i = 0; i < DEFAULT_CUSTOM_EQ_NUM; i++){ - GST_DEBUG ("gain = %lf -> %d", equ->bands[i]->gain, audioeq->custom_eq[i] ); - if (audioeq->custom_eq[i] != equ->bands[i]->gain) { - equ->bands[i]->gain = audioeq->custom_eq[i]; - GST_DEBUG("changed gain = %lf ", equ->bands[i]->gain); - g_object_notify (G_OBJECT (equ->bands[i]), "gain"); - } - } -} - -void -gst_iir_equalizer_compute_frequencies (Gstaudioeq * audioeq, guint new_count) -{ - GST_DEBUG ("gst_iir_equalizer_compute_frequencies"); - - GstIirEqualizer *equ = &audioeq->equ; - guint old_count, i; - gdouble freq0, freq1, step; - gchar name[20]; - GST_DEBUG ("gst_iir_equalizer_compute_frequencies before calling equalizer object"); - if (equ->freq_band_count == new_count) - return; - - GST_DEBUG ("gst_iir_equalizer_compute_frequencies equalizer object"); - - BANDS_LOCK (equ); - GST_DEBUG ("gst_iir_equalizer_compute_frequencies 1"); - if (G_UNLIKELY (equ->freq_band_count == new_count)) { - BANDS_UNLOCK (equ); - return; - } - GST_DEBUG ("gst_iir_equalizer_compute_frequencies 2"); - old_count = equ->freq_band_count; - equ->freq_band_count = new_count; - GST_DEBUG ("bands %u -> %u", old_count, new_count); - - if (old_count < new_count) { - /* add new bands */ - equ->bands = g_realloc (equ->bands, sizeof (GstObject *) * new_count); - for (i = old_count; i < new_count; i++) { - equ->bands[i] = g_object_new (GST_TYPE_IIR_EQUALIZER_BAND, NULL); - /* otherwise they get names like 'iirequalizerband5' */ - sprintf (name, "band%u", i); - gst_object_set_name (GST_OBJECT (equ->bands[i]), name); - GST_DEBUG ("adding band[%d]=%p", i, equ->bands[i]); - - gst_object_set_parent (GST_OBJECT (equ->bands[i]), GST_OBJECT (audioeq)); - gst_child_proxy_child_added (GST_OBJECT (audioeq), - GST_OBJECT (equ->bands[i])); - } - } else { - /* free unused bands */ - for (i = new_count; i < old_count; i++) { - GST_DEBUG ("removing band[%d]=%p", i, equ->bands[i]); - gst_child_proxy_child_removed (GST_OBJECT (audioeq), - GST_OBJECT (equ->bands[i])); - gst_object_unparent (GST_OBJECT (equ->bands[i])); - equ->bands[i] = NULL; - } - } - - alloc_history (equ); - - /* set center frequencies and name band objects - * FIXME: arg! we can't change the name of parented objects :( - * application should read band->freq to get the name - */ - - step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / new_count); - freq0 = LOWEST_FREQ; - for (i = 0; i < new_count; i++) { - freq1 = freq0 * step; - - if (i == 0) - equ->bands[i]->type = BAND_TYPE_LOW_SHELF; - else if (i == new_count - 1) - equ->bands[i]->type = BAND_TYPE_HIGH_SHELF; - else - equ->bands[i]->type = BAND_TYPE_PEAK; - - equ->bands[i]->freq = freq0 + ((freq1 - freq0) / 2.0); - equ->bands[i]->width = freq1 - freq0; - GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq); - - g_object_notify (G_OBJECT (equ->bands[i]), "bandwidth"); - g_object_notify (G_OBJECT (equ->bands[i]), "freq"); - g_object_notify (G_OBJECT (equ->bands[i]), "type"); - - freq0 = freq1; - } - - equ->need_new_coefficients = TRUE; - - BANDS_UNLOCK (equ); -} -/* start of code that is type specific */ - -#define CREATE_OPTIMIZED_FUNCTIONS_INT(TYPE,BIG_TYPE,MIN_VAL,MAX_VAL) \ -typedef struct { \ - BIG_TYPE x1, x2; /* history of input values for a filter */ \ - BIG_TYPE y1, y2; /* history of output values for a filter */ \ -} SecondOrderHistory ## TYPE; \ - \ -static inline BIG_TYPE \ -one_step_ ## TYPE (GstIirEqualizerBand *filter, \ - SecondOrderHistory ## TYPE *history, BIG_TYPE input) \ -{ \ - /* calculate output */ \ - BIG_TYPE output = filter->a0 * input + \ - filter->a1 * history->x1 + filter->a2 * history->x2 + \ - filter->b1 * history->y1 + filter->b2 * history->y2; \ - /* update history */ \ - history->y2 = history->y1; \ - history->y1 = output; \ - history->x2 = history->x1; \ - history->x1 = input; \ - \ - return output; \ -} \ - \ -static const guint \ -history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \ - \ -static void \ -gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \ -guint size, guint channels) \ -{ \ - guint frames = size / channels / sizeof (TYPE); \ - guint i, c, f, nf = equ->freq_band_count; \ - BIG_TYPE cur; \ - GstIirEqualizerBand **filters = equ->bands; \ - \ - for (i = 0; i < frames; i++) { \ - SecondOrderHistory ## TYPE *history = equ->history; \ - for (c = 0; c < channels; c++) { \ - cur = *((TYPE *) data); \ - for (f = 0; f < nf; f++) { \ - cur = one_step_ ## TYPE (filters[f], history, cur); \ - history++; \ - } \ - cur = CLAMP (cur, MIN_VAL, MAX_VAL); \ - *((TYPE *) data) = (TYPE) floor (cur); \ - data += sizeof (TYPE); \ - } \ - } \ -} - -#define CREATE_OPTIMIZED_FUNCTIONS(TYPE) \ -typedef struct { \ - TYPE x1, x2; /* history of input values for a filter */ \ - TYPE y1, y2; /* history of output values for a filter */ \ -} SecondOrderHistory ## TYPE; \ - \ -static inline TYPE \ -one_step_ ## TYPE (GstIirEqualizerBand *filter, \ - SecondOrderHistory ## TYPE *history, TYPE input) \ -{ \ - /* calculate output */ \ - TYPE output = filter->a0 * input + filter->a1 * history->x1 + \ - filter->a2 * history->x2 + filter->b1 * history->y1 + \ - filter->b2 * history->y2; \ - /* update history */ \ - history->y2 = history->y1; \ - history->y1 = output; \ - history->x2 = history->x1; \ - history->x1 = input; \ - \ - return output; \ -} \ - \ -static const guint \ -history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \ - \ -static void \ -gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \ -guint size, guint channels) \ -{ \ - guint frames = size / channels / sizeof (TYPE); \ - guint i, c, f, nf = equ->freq_band_count; \ - TYPE cur; \ - GstIirEqualizerBand **filters = equ->bands; \ - \ - for (i = 0; i < frames; i++) { \ - SecondOrderHistory ## TYPE *history = equ->history; \ - for (c = 0; c < channels; c++) { \ - cur = *((TYPE *) data); \ - for (f = 0; f < nf; f++) { \ - cur = one_step_ ## TYPE (filters[f], history, cur); \ - history++; \ - } \ - *((TYPE *) data) = (TYPE) cur; \ - data += sizeof (TYPE); \ - } \ - } \ -} - -CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gfloat, -32768.0, 32767.0); -CREATE_OPTIMIZED_FUNCTIONS (gfloat); -CREATE_OPTIMIZED_FUNCTIONS (gdouble); - -#ifdef AUDIOEQ_REDUCE_MEMCPY -static GstFlowReturn -gst_audioeq_transform_ip (GstBaseTransform * base, GstBuffer * buf) -{ - GST_DEBUG ("gst_audioeq_transform_ip"); - Gstaudioeq *audioeq = GST_AUDIOEQ(base); - GstIirEqualizer *equ = &audioeq->equ; - - equ->history_size = history_size_gint16; - equ->process = gst_iir_equ_process_gint16; - g_free (equ->history); - equ->history = g_malloc0 (equ->history_size * audioeq->channels * equ->freq_band_count); - GstClockTime timestamp; - - if (G_UNLIKELY (audioeq->channels < 1 || equ->process == NULL)) { - GST_DEBUG ("gst_audioeq_transform_ip return GST_FLOW_NOT_NEGOTIATED;"); - if (G_UNLIKELY (equ->process == NULL)) - GST_DEBUG ("gst_audioeq_transform_ip equ->process "); - if (G_UNLIKELY (audioeq->channels < 1)) - GST_DEBUG ("gst_audioeq_transform_ip audioeq->channels"); - return GST_FLOW_NOT_NEGOTIATED; - } - GST_DEBUG ("gst_audioeq_transform_ip BANDS_LOCK (equ);"); - BANDS_LOCK (equ); - if (equ->need_new_coefficients) { - GST_DEBUG ("gst_audioeq_transform_ip update_coefficients"); - update_coefficients (audioeq); - set_passthrough (audioeq); - } - BANDS_UNLOCK (equ); - - if (gst_base_transform_is_passthrough (base)) { - GST_DEBUG ("gst_audioeq_transform_ip gst_base_transform_is_passthrough return GST_FLOW_OK;"); - return GST_FLOW_OK; - } - timestamp = GST_BUFFER_TIMESTAMP (buf); - timestamp = - gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp); - - if (GST_CLOCK_TIME_IS_VALID (timestamp)) - gst_object_sync_values (G_OBJECT (audioeq), timestamp); - GST_DEBUG (" equ->process ++"); - equ->process (equ, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), - audioeq->channels); - GST_DEBUG (" equ->process --"); - GST_DEBUG ("gst_audioeq_transform_ip return GST_FLOW_OK;"); - return GST_FLOW_OK; -} -#endif - -static gboolean -gst_audioeq_set_caps (GstBaseTransform * base, GstCaps * incaps, - GstCaps * outcaps) -{ - GST_DEBUG ("gst_audioeq_set_caps"); - Gstaudioeq *audioeq = GST_AUDIOEQ(base); - GstStructure *ins; - GstPad *pad; - gint samplerate; - gint channels; - gshort old_samplerate; - gshort old_channels; - - pad = gst_element_get_static_pad(GST_ELEMENT(audioeq), "src"); - - /* forward-negotiate */ - if(!gst_pad_set_caps(pad, incaps)) { - gst_object_unref(pad); - return FALSE; - } - - /* negotiation succeeded, so now configure ourselves */ - ins = gst_caps_get_structure(incaps, 0); - - /* get samplerate from caps & convert */ - old_samplerate = audioeq->samplerate; - old_channels = audioeq->channels; - gst_structure_get_int(ins, "rate", &samplerate); - switch (samplerate) { - case 48000: - audioeq->samplerate = SAMPLERATE_48000Hz; - break; - case 44100: - audioeq->samplerate = SAMPLERATE_44100Hz; - break; - case 32000: - audioeq->samplerate = SAMPLERATE_32000Hz; - break; - case 24000: - audioeq->samplerate = SAMPLERATE_24000Hz; - break; - case 22050: - audioeq->samplerate = SAMPLERATE_22050Hz; - break; - case 16000: - audioeq->samplerate = SAMPLERATE_16000Hz; - break; - case 12000: - audioeq->samplerate = SAMPLERATE_12000Hz; - break; - case 11025: - audioeq->samplerate = SAMPLERATE_11025Hz; - break; - case 8000: - audioeq->samplerate = SAMPLERATE_8000Hz; - break; - default: - if (samplerate < 8000) { - audioeq->samplerate = SAMPLERATE_8000Hz; - } else if (samplerate > 48000) { - audioeq->samplerate = SAMPLERATE_48000Hz; - } - break; - } - /* get number of channels from caps */ - gst_structure_get_int(ins, "channels", &channels); - audioeq->channels = (gshort)channels; - - if ((old_samplerate != audioeq->samplerate) - || (old_channels != audioeq->channels)) { - audioeq->need_update_filter = TRUE; - } - - gst_object_unref (pad); - - return TRUE; -} - -static void -gst_audioeq_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GST_DEBUG ("gst_audioeq_set_property"); - Gstaudioeq *audioeq = GST_AUDIOEQ (object); - GstIirEqualizer *equ = &audioeq->equ; - gshort *pointer; - - switch (prop_id) { - - case PROP_FILTER_ACTION: - audioeq->filter_action = g_value_get_uint(value); - BANDS_LOCK(equ); - equ->need_new_coefficients = TRUE; - BANDS_UNLOCK(equ); - break; - - case PROP_CUSTOM_EQ: - pointer = g_value_get_pointer(value); - if (pointer) { - memcpy(audioeq->custom_eq, pointer, sizeof(gint) * CUSTOM_EQ_BAND_MAX); - if (audioeq->filter_action == FILTER_ADVANCED_SETTING) { - BANDS_LOCK(equ); - equ->need_new_coefficients = TRUE; - gst_audioeq_band_set_property(audioeq); - BANDS_UNLOCK(equ); - } - } - break; - - default: - break; - } - GST_DEBUG ("gst_audioeq_set_property need_update_filter %d", audioeq->need_update_filter); -} - -static void -gst_audioeq_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) -{ -GST_DEBUG ("gst_audioeq_get_property"); - - Gstaudioeq *audioeq = GST_AUDIOEQ (object); - GstIirEqualizer *equ = &audioeq->equ; - gshort i; - gdouble widtharr[DEFAULT_CUSTOM_EQ_NUM],freqarr[DEFAULT_CUSTOM_EQ_NUM]; - - switch (prop_id) { - case PROP_FILTER_ACTION: - g_value_set_uint(value, audioeq->filter_action); - break; - - case PROP_CUSTOM_EQ: - g_value_set_pointer(value, audioeq->custom_eq); - break; - - case PROP_CUSTOM_EQ_NUM: - g_value_set_uint(value, DEFAULT_CUSTOM_EQ_NUM); - break; - - case PROP_CUSTOM_EQ_FREQ: - for(i=0;ibands[i]->freq; - } - g_value_set_pointer(value, &freqarr); - break; - - case PROP_CUSTOM_EQ_WIDTH: - for(i=0;ibands[i]->width; - } - g_value_set_pointer(value, &widtharr); - break; - - default: - break; - } -} - -static gboolean -gst_iir_equalizer_setup (GstAudioFilter * audio, GstRingBufferSpec * fmt) -{ -GST_DEBUG ("gst_iir_equalizer_setup"); - GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio); - - switch (fmt->type) { - case GST_BUFTYPE_LINEAR: - switch (fmt->width) { - case 16: - equ->history_size = history_size_gint16; - equ->process = gst_iir_equ_process_gint16; - break; - default: - return FALSE; - } - break; - case GST_BUFTYPE_FLOAT: - switch (fmt->width) { - case 32: - equ->history_size = history_size_gfloat; - equ->process = gst_iir_equ_process_gfloat; - break; - case 64: - equ->history_size = history_size_gdouble; - equ->process = gst_iir_equ_process_gdouble; - break; - default: - return FALSE; - } - break; - default: - return FALSE; - } - - alloc_history (equ); - return TRUE; -} - - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG ("audioeq plugin_init "); - GST_DEBUG_CATEGORY_INIT(gst_audioeq_debug, "audioeq", 0, "Audio Equalizer Plugin"); - return gst_element_register(plugin, "audioeq", GST_RANK_NONE, GST_TYPE_AUDIOEQ); -} - - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "audioeq", - "Audio Equalizer Plugin", - plugin_init, - VERSION, - "LGPL", - "gst-plugins-ext", - "https://www.tizen.org/") diff --git a/mobile/audioeq/src/gstaudioeq.h b/mobile/audioeq/src/gstaudioeq.h deleted file mode 100644 index a2c3815..0000000 --- a/mobile/audioeq/src/gstaudioeq.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * audioeq - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Aditi Narula - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef __GST_AUDIOEQ_H__ -#define __GST_AUDIOEQ_H__ - -#include -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AUDIOEQ \ - (gst_audioeq_get_type()) -#define GST_AUDIOEQ(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOEQ,Gstaudioeq)) -#define GST_audioeq_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOEQ,GstaudioeqClass)) -#define GST_IS_AUDIOEQ(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOEQ)) -#define GST_IS_AUDIOEQ_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOEQ)) -#define GST_TYPE_IIR_EQUALIZER \ - (gst_iir_equalizer_get_type()) -#define GST_IIR_EQUALIZER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IIR_EQUALIZER,GstIirEqualizer)) -#define GST_IIR_EQUALIZER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IIR_EQUALIZER,GstIirEqualizerClass)) -#define GST_IS_IIR_EQUALIZER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IIR_EQUALIZER)) -#define GST_IS_IIR_EQUALIZER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IIR_EQUALIZER)) - -typedef struct _Gstaudioeq Gstaudioeq; -typedef struct _GstaudioeqClass GstaudioeqClass; -typedef struct _GstIirEqualizer GstIirEqualizer; -typedef struct _GstIirEqualizerClass GstIirEqualizerClass; -typedef struct _GstIirEqualizerBand GstIirEqualizerBand; - -#define CUSTOM_EQ_BAND_MAX 9 - -#define LOWEST_FREQ (20.0) -#define HIGHEST_FREQ (20000.0) - -typedef void (*ProcessFunc) (GstIirEqualizer * eq, guint8 * data, guint size, - guint channels); - -struct _GstIirEqualizer -{ - GstAudioFilter audiofilter; - - /*< private >*/ - - GMutex *bands_lock; - GstIirEqualizerBand **bands; - - /* properties */ - guint freq_band_count; - /* for each band and channel */ - gpointer history; - guint history_size; - - gboolean need_new_coefficients; - - ProcessFunc process; -}; - -struct _GstIirEqualizerClass -{ - GstAudioFilterClass audiofilter_class; -}; - - - -struct _Gstaudioeq -{ - GstBaseTransform element; - - guint samplerate; - guint channels; - - /* properties */ - guint filter_action; - gint custom_eq[CUSTOM_EQ_BAND_MAX]; - gboolean need_update_filter; - GstIirEqualizer equ; -}; - -struct _GstaudioeqClass -{ - GstAudioFilterClass parent_class; -}; - -void gst_iir_equalizer_compute_frequencies (Gstaudioeq * audioeq, guint new_count); - -GType gst_iir_equalizer_get_type(void); - -GType gst_audioeq_get_type (void); - -G_END_DECLS - -#endif /* __GST_AUDIOEQ_H__ */ - diff --git a/mobile/audiotp/Makefile.am b/mobile/audiotp/Makefile.am deleted file mode 100755 index 308a09c..0000000 --- a/mobile/audiotp/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/mobile/audiotp/src/Makefile.am b/mobile/audiotp/src/Makefile.am deleted file mode 100755 index 436666c..0000000 --- a/mobile/audiotp/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# plugindir is set in configure - -############################################################################## -# change libgstplugin.la to something more suitable, e.g. libmysomething.la # -############################################################################## -plugin_LTLIBRARIES = libgstaudiotp.la - -############################################################################## -# for the next set of variables, rename the prefix if you renamed the .la, # -# e.g. libgstplugin_la_SOURCES => libmysomething_la_SOURCES # -# libgstplugin_la_CFLAGS => libmysomething_la_CFLAGS # -# libgstplugin_la_LIBADD => libmysomething_la_LIBADD # -# libgstplugin_la_LDFLAGS => libmysomething_la_LDFLAGS # -############################################################################## - -# sources used to compile this plug-in -libgstaudiotp_la_SOURCES = gstaudiotp.c - -# flags used to compile this plugin -# add other _CFLAGS and _LIBS as needed -libgstaudiotp_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) -libgstaudiotp_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) -libgstaudiotp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -# headers we need but don't want installed -noinst_HEADERS = gstaudiotp.h \ No newline at end of file diff --git a/mobile/audiotp/src/gstaudiotp.c b/mobile/audiotp/src/gstaudiotp.c deleted file mode 100644 index 1bdfe95..0000000 --- a/mobile/audiotp/src/gstaudiotp.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * audiotp - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstaudiotp.h" - -/* Plugin Detaills for gstreamer */ -static const GstElementDetails gst_audiotp_plugin_details = GST_ELEMENT_DETAILS ( - "Audio timestamp reversal plugin", - "Utility/Audio", - "Reverses audio timestamps for reverse playback", - "Samsung Electronics " - ); - -/*** GSTREAMER PROTOTYPES *****************************************************/ - -#define STATIC_CAPS \ -GST_STATIC_CAPS ( \ - "audio/x-raw-float, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 64;" \ - "audio/x-raw-float, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 32;" \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 32, " \ - "depth = (int) [ 1, 32 ], " \ - "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 24, " \ - "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 16, " \ - "depth = (int) [ 1, 16 ], " \ - "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 8, " \ - "depth = (int) [ 1, 8 ], " \ - "signed = (boolean) { true, false } " \ -) - -/* Element sink pad template */ -static GstStaticPadTemplate gst_audiotp_sink_template = GST_STATIC_PAD_TEMPLATE ( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - STATIC_CAPS); - -/* Element Source Pad template */ -static GstStaticPadTemplate gst_audiotp_src_template = GST_STATIC_PAD_TEMPLATE ( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - STATIC_CAPS); - - -//////////////////////////////////////////////////////// -// Gstreamer Base Prototype // -//////////////////////////////////////////////////////// - -GST_DEBUG_CATEGORY_STATIC(gst_audiotp_debug); -#define GST_CAT_DEFAULT gst_audiotp_debug -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT(GST_CAT_DEFAULT, "audiotp", 0, "Audio trickplay plugin"); \ - GST_DEBUG("audiotp is registered"); - -GST_BOILERPLATE_FULL(Gstaudiotp, gst_audiotp, GstElement, GST_TYPE_ELEMENT, _do_init); - -static void gst_audiotp_base_init(gpointer klass); -static void gst_audiotp_class_init(GstaudiotpClass *klass); -static void gst_audiotp_init(Gstaudiotp *dec, GstaudiotpClass *klass); -static GstFlowReturn gst_audiotp_chain(GstPad *pad, GstBuffer *buf); -static GstStateChangeReturn gst_audiotp_change_state(GstElement *element, GstStateChange transition); -static void gst_audiotp_finalize(GObject *object); -static gboolean gst_audiotp_sink_event (GstPad *pad, GstEvent *event); -static GstFlowReturn gst_audiotp_push_silent_frame (Gstaudiotp *audiotp, GstBuffer *MetaDataBuf); - - - -//////////////////////////////////////////////////////// -// Gstreamer Base Functions // -//////////////////////////////////////////////////////// - -/** - ** - ** Description: The element details and pad templates are registered with the plugin - ** In Params : @ gclass instance of Element class - ** return : None - ** Comments : 1. Adding templates of source and sink pad to element - ** 2. Setting element class deatils to element - ** - */ -static void -gst_audiotp_base_init(gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS(klass); - - gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&gst_audiotp_sink_template)); - gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&gst_audiotp_src_template)); - gst_element_class_set_details(element_class, &gst_audiotp_plugin_details); -} - - -/** - ** - ** Description: Initialization of the Element Class - ** In Param : @ gclass instance of Element class - ** return : None - ** Comments : 1. Overwriting base class virtual functions - ** 2. Installing the properties of the element - ** - */ -static void -gst_audiotp_class_init(GstaudiotpClass *klass) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass); - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_peek_parent(klass); - - gobject_class->finalize = gst_audiotp_finalize; - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_audiotp_change_state); -} - - -/** - ** - ** Description: Initialization of the Element instance - ** In Params : @ audio tp element instance - ** @ gclass instance of Element class - ** return : None - ** Comments : 1. Creating new source & sink pads using templates - ** 2. Setting the callback functions to the pads - ** 3. Local data initialization. - ** - */ -static void -gst_audiotp_init(Gstaudiotp *audiotp, GstaudiotpClass *klass) -{ - - audiotp->sinkpad = gst_pad_new_from_static_template(&gst_audiotp_sink_template, "sink"); - audiotp->srcpad = gst_pad_new_from_static_template(&gst_audiotp_src_template, "src"); - - gst_pad_set_chain_function (audiotp->sinkpad, GST_DEBUG_FUNCPTR(gst_audiotp_chain)); - gst_pad_set_event_function (audiotp->sinkpad, GST_DEBUG_FUNCPTR(gst_audiotp_sink_event)); - - gst_pad_use_fixed_caps(audiotp->srcpad); - - gst_element_add_pad(GST_ELEMENT(audiotp), audiotp->sinkpad); - gst_element_add_pad(GST_ELEMENT(audiotp), audiotp->srcpad); - - audiotp->reverse = g_queue_new (); - audiotp->head_prev = GST_CLOCK_TIME_NONE; - audiotp->tail_prev = GST_CLOCK_TIME_NONE; - -} - - -/** - ** - ** Description: Finalization of the Element instance (object) - ** In Params : @ audiotp element instance in the form of GObject - ** return : None - ** Comments : 1. Local data Deinitialization. - ** - ** - */ -static void -gst_audiotp_finalize(GObject *object) -{ - Gstaudiotp *audiotp = GST_AUDIOTP(object); - - while (!g_queue_is_empty (audiotp->reverse)) { - GstMiniObject *data = g_queue_pop_head (audiotp->reverse); - gst_mini_object_unref (data); - } - /* freeing dealy queue */ - g_queue_free(audiotp->reverse); - audiotp->reverse = NULL; - - G_OBJECT_CLASS(parent_class)->finalize(object); -} - - -/** - ** - ** Description: Callback function when the element's state gets changed - ** In Params : @ audiotp plugin element - ** @ type of state change - ** return : status of the state change processing - ** Comments : - ** - ** - */ -static GstStateChangeReturn -gst_audiotp_change_state(GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn res = GST_FLOW_ERROR; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - res = parent_class->change_state(element, transition); - if ( res != GST_STATE_CHANGE_SUCCESS ) { - GST_ERROR ("change state error in parent class\n"); - return GST_STATE_CHANGE_FAILURE; - } - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return res; -} - - -/** - ** - ** Description: Callback function when sinkpad gets an event - ** In Params : @ Sinkpad on which the event arrives - ** @ event type - ** return : TRUE/FALSE on success/failure of the event processing. - ** Comments : 1. Process the event and push it to the source pad. - ** - ** - */ -static gboolean -gst_audiotp_sink_event (GstPad *pad, GstEvent *event) -{ - Gstaudiotp *audiotp = NULL; - gboolean res = FALSE; - - audiotp = GST_AUDIOTP(GST_PAD_PARENT(pad)); - - switch (GST_EVENT_TYPE(event)) { - /* Arrives whenever there is a jump in the normal playback. Ex:SEEK */ - case GST_EVENT_NEWSEGMENT: { - GstFormat format; - gdouble rate, arate; - gint64 start, stop, time; - gboolean update; - - GST_INFO_OBJECT (audiotp, "GST_EVENT_NEWSEGMENT"); - gst_event_parse_new_segment_full(event, &update, &rate, &arate, &format, &start, &stop, &time); - - if (format != GST_FORMAT_TIME) { - GST_ERROR("Format is not supported\n"); - res = gst_pad_push_event(audiotp->srcpad, event); - goto done; - } - - GST_INFO_OBJECT (audiotp, "update: %d, rate: %0.3f, arate: %0.3f\n", update, rate, arate); - GST_INFO_OBJECT (audiotp, "start : %" GST_TIME_FORMAT, GST_TIME_ARGS(start)); - GST_INFO_OBJECT (audiotp, "stop : %" GST_TIME_FORMAT, GST_TIME_ARGS(stop)); - GST_INFO_OBJECT (audiotp, "time : %" GST_TIME_FORMAT, GST_TIME_ARGS(time)); - - /* If we receive new_segment without FLUSH events, then we will push all the frame in queue */ - while (!g_queue_is_empty (audiotp->reverse)) { - GstBuffer *MetaDataBuf; - GstFlowReturn ret = GST_FLOW_OK; - if(audiotp->is_reversed) - MetaDataBuf = g_queue_pop_head (audiotp->reverse); - else - MetaDataBuf = g_queue_pop_tail (audiotp->reverse); - ret = gst_audiotp_push_silent_frame (audiotp, MetaDataBuf); - if (GST_FLOW_OK != ret) - { - GST_WARNING_OBJECT (audiotp, "pad_push returned = %s", gst_flow_get_name (ret)); - } - } - gst_segment_set_newsegment_full(&audiotp->segment, update, rate, arate, format, start, stop, time); - res = gst_pad_push_event(audiotp->srcpad, event); - break; - } - - /* Indication of the end of the stream */ - case GST_EVENT_EOS: { - /* queue all buffer timestamps till we receive next discontinuity */ - while (!g_queue_is_empty (audiotp->reverse)) { - GstBuffer *MetaDataBuf; - GstFlowReturn ret = GST_FLOW_OK; - if(audiotp->is_reversed) - MetaDataBuf = g_queue_pop_head (audiotp->reverse); - else - MetaDataBuf = g_queue_pop_tail (audiotp->reverse); - ret = gst_audiotp_push_silent_frame (audiotp, MetaDataBuf); - if (GST_FLOW_OK != ret) { - GST_WARNING_OBJECT (audiotp, "pad_push returned = %s", gst_flow_get_name (ret)); - } - } - - res = gst_pad_push_event(audiotp->srcpad, event); - break; - } - - /* Indication of the SEEK operation start */ - case GST_EVENT_FLUSH_START: { - GST_INFO_OBJECT (audiotp, "GST_EVENT_FLUSH_START"); - res = gst_pad_push_event(audiotp->srcpad, event); - break; - } - - /* Indication of the SEEK operation stop */ - case GST_EVENT_FLUSH_STOP: { - GST_INFO_OBJECT (audiotp, "GST_EVENT_FLUSH_STOP"); - /* make sure that we empty the queue */ - while (!g_queue_is_empty (audiotp->reverse)) { - GST_DEBUG_OBJECT (audiotp, "Flushing buffers in reverse queue...."); - gst_buffer_unref(g_queue_pop_head (audiotp->reverse)); - } - - res = gst_pad_push_event(audiotp->srcpad, event); - break; - } - - default: { - res = gst_pad_push_event(audiotp->srcpad, event); - break; - } - } - - done: - return res; -} - - -/** - ** - ** Description: Callback function when sinkpad gets a buffer (from the previous element) - ** In Params : @ Sinkpad on which the buffer arrives - ** @ input buffer - ** return : status of the buffer processing. - ** Comments : 1. Handle the buffer discontinuity ( in terms of tmestamp) - ** 2. Push or pop buffer based on discontinuity. - ** - ** - */ -static GstFlowReturn -gst_audiotp_chain(GstPad *pad, GstBuffer *buf) -{ - Gstaudiotp *audiotp = GST_AUDIOTP(GST_PAD_PARENT(pad)); - GstFlowReturn ret = GST_FLOW_OK; - - if(buf == NULL) { - ret = GST_FLOW_ERROR; - goto error_exit; - } - - GST_LOG_OBJECT (audiotp, "Input buffer : ts =%" GST_TIME_FORMAT ", dur=%" GST_TIME_FORMAT ", size=%d", - GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buf)), - GST_TIME_ARGS(GST_BUFFER_DURATION(buf)), - GST_BUFFER_SIZE(buf), GST_BUFFER_IS_DISCONT (buf) ? " - discont" :""); - - if (audiotp->segment.rate < 0.0) { - goto send_reverse; - } - - - /* Push the input data to the next element */ - ret = gst_pad_push(audiotp->srcpad, buf); - if (ret != GST_FLOW_OK ) { - GST_WARNING("failed to push buffer %p. reason: %s", buf, gst_flow_get_name (ret)); - buf = NULL; - goto error_exit; - } - return ret; - -send_reverse: - { - GstBuffer *MetaDataBuf = NULL; - GstClockTime headbuf_ts = GST_CLOCK_TIME_NONE; - GstClockTime tailbuf_ts = GST_CLOCK_TIME_NONE; - - /* Discont buffers is mostly due to seek, when buffers of seeked timestamp gets pushed */ - if (GST_BUFFER_IS_DISCONT(buf)) { - if(!g_queue_is_empty (audiotp->reverse)) { - GstBuffer *headbuf = (GstBuffer*) (audiotp->reverse->head->data); - GstBuffer *tailbuf = (GstBuffer*) (audiotp->reverse->tail->data); - - headbuf_ts = GST_BUFFER_TIMESTAMP(headbuf); - tailbuf_ts = GST_BUFFER_TIMESTAMP(tailbuf); - - GST_DEBUG_OBJECT(audiotp,"Headbuf ts =%" GST_TIME_FORMAT ", TailBuf ts =%" GST_TIME_FORMAT "", - GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(headbuf)), - GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(tailbuf))); - - /* Check if the decoder is already having the reversal logic */ - if(GST_BUFFER_TIMESTAMP(headbuf) > GST_BUFFER_TIMESTAMP(tailbuf)) { - GST_INFO_OBJECT (audiotp, "Buffers arrived in reverse order, audiotp NO NEED to reverse..."); - audiotp->is_reversed = TRUE; - } else { - GST_INFO_OBJECT (audiotp, "Buffers arrived in forward order, audiotp NEED to reverse..."); - audiotp->is_reversed = FALSE; - } - } - - while (!g_queue_is_empty (audiotp->reverse)) { - - if(audiotp->is_reversed) - MetaDataBuf = g_queue_pop_head (audiotp->reverse); - else - MetaDataBuf = g_queue_pop_tail (audiotp->reverse); - - if (NULL == MetaDataBuf) { - GST_ERROR_OBJECT (audiotp, "NULL pointer..."); - ret = GST_FLOW_ERROR; - goto error_exit; - } - - /* If buffers arrive in forward order, compare the MetaDatabuf with - * previous head buffer timestamp. - * If buffers arrive in reverse order, compare the MetaDataBuf with - * previous tail buffer timestamp */ - if((GST_BUFFER_TIMESTAMP(MetaDataBuf) < audiotp->head_prev && !audiotp->is_reversed) - || (GST_BUFFER_TIMESTAMP(MetaDataBuf) < audiotp->tail_prev && audiotp->is_reversed)) { - ret = gst_audiotp_push_silent_frame (audiotp, MetaDataBuf); - if (MetaDataBuf) { - gst_buffer_unref (MetaDataBuf); - MetaDataBuf = NULL; - } - - if (GST_FLOW_OK != ret) { - GST_WARNING_OBJECT (audiotp, "pad_push returned = %s", gst_flow_get_name (ret)); - if (buf) { - gst_buffer_unref (buf); - buf = NULL; - } - return ret; - } - } else { - GST_DEBUG_OBJECT(audiotp, "Dropping the buffer out of segment with time-stamp %"GST_TIME_FORMAT, - GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(MetaDataBuf))); - if (MetaDataBuf) { - gst_buffer_unref (MetaDataBuf); - MetaDataBuf = NULL; - } - } - } - - audiotp->head_prev = headbuf_ts; - audiotp->tail_prev = tailbuf_ts; - } - - MetaDataBuf = gst_buffer_new (); - if (NULL == MetaDataBuf) { - GST_ERROR_OBJECT (audiotp, "Failed to create memory..."); - ret = GST_FLOW_ERROR; - goto error_exit; - } - - /* copy buffer timestamps & FLAGS to metadata buffer */ - gst_buffer_copy_metadata (MetaDataBuf, buf, GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_CAPS); - GST_BUFFER_SIZE(MetaDataBuf) = GST_BUFFER_SIZE(buf); - GST_DEBUG_OBJECT (audiotp, "Pushing into reverse queue data of size: %d", GST_BUFFER_SIZE(MetaDataBuf)); - - /* queue all buffer timestamps till we receive next discontinuity */ - g_queue_push_tail (audiotp->reverse, MetaDataBuf); - if (buf) { - gst_buffer_unref (buf); - buf = NULL; - } - return GST_FLOW_OK; - } - -#if 0 -/* May be useful in future */ -send_dummy: - { - - /* Resetting the buffer data to zero */ - memset(GST_BUFFER_DATA(buf), 0, GST_BUFFER_SIZE(buf)); - gst_buffer_set_caps(buf, GST_PAD_CAPS(audiotp->srcpad)); - - ret = gst_pad_push(audiotp->srcpad, buf); - if (ret != GST_FLOW_OK) { - GST_ERROR("Failed to push buffer. reason: %s\n", gst_flow_get_name(ret)); - buf = NULL; - goto error_exit; - } - return GST_FLOW_OK; - } -#endif - -error_exit: - - GST_WARNING_OBJECT(audiotp, "Returning from audiotp's chain with reason - %s", gst_flow_get_name (ret)); - if (buf) { - gst_buffer_unref (buf); - buf = NULL; - } - return ret; -} - - -static GstFlowReturn -gst_audiotp_push_silent_frame (Gstaudiotp *audiotp, GstBuffer *MetaDataBuf) -{ - - GstBuffer *out = NULL; - GstFlowReturn ret = GST_FLOW_OK; - - out = gst_buffer_new_and_alloc(GST_BUFFER_SIZE(MetaDataBuf)); - if(out == NULL) { - GST_ERROR_OBJECT (audiotp, "Failed to allocate memory..."); - return GST_FLOW_ERROR; - } - - /* Memset the data of the out buffer so that silent frame is sent */ - memset(GST_BUFFER_DATA(out), 0, GST_BUFFER_SIZE(out)); - - gst_buffer_copy_metadata (out, MetaDataBuf, GST_BUFFER_COPY_FLAGS); - GST_BUFFER_OFFSET (out) = GST_BUFFER_OFFSET_END (out) = 0; - GST_BUFFER_SIZE(out) = GST_BUFFER_SIZE(MetaDataBuf); - GST_BUFFER_TIMESTAMP(out) = GST_BUFFER_TIMESTAMP(MetaDataBuf); - GST_BUFFER_DURATION(out) = GST_BUFFER_DURATION(MetaDataBuf); - - GST_LOG_OBJECT(audiotp, "Out buffer ts =%" GST_TIME_FORMAT ", dur=%" GST_TIME_FORMAT ", size=%d", - GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(out)), - GST_TIME_ARGS(GST_BUFFER_DURATION(out)), - GST_BUFFER_SIZE(out)); - - gst_buffer_set_caps(out, GST_PAD_CAPS(audiotp->srcpad)); - - ret = gst_pad_push(audiotp->srcpad, out); - if (ret != GST_FLOW_OK) { - GST_ERROR_OBJECT (audiotp, "Failed to push buffer. reason: %s\n", gst_flow_get_name(ret)); - out = NULL; - } - - return ret; -} - -static gboolean -gst_audiotp_plugin_init (GstPlugin *plugin) -{ - if (!gst_element_register (plugin, "audiotp", GST_RANK_PRIMARY, gst_audiotp_get_type())) { - return FALSE; - } - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "audiotp", - "Audio trickplay plugin", - gst_audiotp_plugin_init, - VERSION, - "LGPL", - "Samsung Electronics Co", - "http://www.samsung.com") diff --git a/mobile/audiotp/src/gstaudiotp.h b/mobile/audiotp/src/gstaudiotp.h deleted file mode 100755 index 0b3dc92..0000000 --- a/mobile/audiotp/src/gstaudiotp.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * audiotp - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_AUDIOTP_H__ -#define __GST_AUDIOTP_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AUDIOTP (gst_audiotp_get_type()) -#define GST_AUDIOTP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOTP,Gstaudiotp)) -#define GST_AUDIOTP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOTP,GstaudiotpClass)) -#define GST_AUDIOTP_GET_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS((klass),GST_TYPE_AUDIOTP,GstaudiotpClass)) -#define GST_IS_AUDIOTP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOTP)) -#define GST_IS_AUDIOTP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOTP)) -#define GST_AUDIOTP_CAST(obj) ((Gstaudiotp *)(obj)) - -typedef struct _Gstaudiotp Gstaudiotp; -typedef struct _GstaudiotpClass GstaudiotpClass; - -struct _Gstaudiotp -{ - GstElement element; - GstPad *sinkpad; - GstPad *srcpad; - GQueue *reverse; /* used in reverse trickplay */ - GstSegment segment; - - /* Flag to indicate the new buffer recieved is discountinued in - its time-stamp */ - gboolean discont; - gboolean is_reversed; - GstClockTime head_prev; - GstClockTime tail_prev; -}; - -struct _GstaudiotpClass -{ - GstElementClass parent_class; -}; - -GType gst_audiotp_get_type (void); - -G_END_DECLS - -#endif /* __GST_AUDIOTP_H__ */ \ No newline at end of file diff --git a/mobile/autogen.sh b/mobile/autogen.sh deleted file mode 100755 index d4c6d40..0000000 --- a/mobile/autogen.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# you can either set the environment variables AUTOCONF and AUTOMAKE -# to the right versions, or leave them unset and get the RedHat 7.3 defaults - -aclocal -I m4 -I common/m4 -libtoolize --copy --force -autoheader -autoconf -automake --add-missing --copy --foreign - -echo "Now type 'make' to compile $package." - diff --git a/mobile/autoregen.sh b/mobile/autoregen.sh deleted file mode 100755 index c67a299..0000000 --- a/mobile/autoregen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./autogen.sh $@ diff --git a/mobile/avsystem/Makefile.am b/mobile/avsystem/Makefile.am deleted file mode 100644 index af437a6..0000000 --- a/mobile/avsystem/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/mobile/avsystem/src/Makefile.am b/mobile/avsystem/src/Makefile.am deleted file mode 100644 index dd1576e..0000000 --- a/mobile/avsystem/src/Makefile.am +++ /dev/null @@ -1,60 +0,0 @@ - -# plugindir is set in configure - -plugin_LTLIBRARIES = libgstavsysaudiosrc.la - -# sources used to compile this plug-in -libgstavsysaudiosrc_la_SOURCES = gstavsyssrc.c \ - gstavsysaudiosrc.c - -libgstavsysaudiosrc_la_CFLAGS = $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(AVSYSTEM_CFLAGS) \ - $(GST_VIDEO_FLAGS) \ - -I$(includedir)/mmf \ - $(MMTA_CFLAGS) \ - $(GST_AUDIO_CFLAGS) \ - $(VCONF_CFLAGS) \ - $(AVSYSAUDIO_CFLAGS) - -libgstavsysaudiosrc_la_LIBADD = $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(DATACOMLIB_LIBS) \ - $(HTTPLIB_LIBS) \ - $(AVSYSTEM_LIBS) \ - $(GST_VIDEO_LIBS) \ - -lgstaudio-0.10 \ - $(MMTA_LIBS) \ - $(GST_AUDIO_LIBS) \ - -ldl \ - $(VCONF_LIBS) \ - $(AVSYSAUDIO_LIBS) - -libgstavsysaudiosrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -if IS_I386 -libgstavsysaudiosrc_la_CFLAGS += -DI386_SIMULATOR -else -endif - -plugin_LTLIBRARIES += libgstavsyssink.la - -## sources used to compile this plug-in -libgstavsyssink_la_SOURCES = gstavsyssink.c \ - gstavsysmemsink.c - -libgstavsyssink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(AVSYSVIDEO_CFLAGS) $(AVSYSTEM_CFLAGS) -I$(includedir)/mmf -libgstavsyssink_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(DATACOMLIB_LIBS) $(HTTPLIB_LIBS) $(AVSYSVIDEO_LIBS) $(AVSYSTEM_LIBS) $(GST_VIDEO_LIBS) -lgstaudio-0.10 -ldl -libgstavsyssink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - - -libgstavsyssink_la_SOURCES += gstavsysaudiosink.c -libgstavsyssink_la_CFLAGS += $(AVSYSAUDIO_CFLAGS) -libgstavsyssink_la_LIBADD += $(AVSYSAUDIO_LIBS) - -if IS_I386 -libgstavsyssink_la_CFLAGS += -DI386_SIMULATOR -else -endif - - diff --git a/mobile/avsystem/src/gstavsysaudiosink.c b/mobile/avsystem/src/gstavsysaudiosink.c deleted file mode 100644 index b6e5c94..0000000 --- a/mobile/avsystem/src/gstavsysaudiosink.c +++ /dev/null @@ -1,905 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - - -#include -#include - -#include - -#include "gstavsysaudiosink.h" - -#define _ALSA_DAPM_ -#define __REPLACE_RESET_WITH_CLOSE_AND_REOPEN__ - -#define CONVERT_MUTE_VALUE(_mute) ((_mute) ? AVSYS_AUDIO_MUTE : AVSYS_AUDIO_UNMUTE) - -GST_DEBUG_CATEGORY_EXTERN (avsystem_sink_debug); -#define GST_CAT_DEFAULT avsystem_sink_debug - -#define DEFAULT_USER_ROUTE AVSYSAUDIOSINK_USERROUTE_AUTO -#define DEFAULT_AUDIO_ROUTE AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING -#define DEFAULT_VOLUME_TYPE AVSYS_AUDIO_VOLUME_TYPE_MEDIA -#define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE -#define DEFAULT_FADEUP_VOLUME FALSE -#define DEFAULT_AUDIO_MUTE AVSYSAUDIOSINK_AUDIO_UNMUTE -#define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSINK_LATENCY_MID -#define DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE FALSE - -//GST_DEBUG_CATEGORY_STATIC (gst_avsystemsink_debug); - -/* element factory information */ -static const GstElementDetails gst_avsysaudiosink_details = - GST_ELEMENT_DETAILS ("AV-system Audio OUT", - "Sink/Audio", - "Output to AV System", - "Samsung Electronics co., ltd"); - -enum -{ - PROP_0, - PROP_AUDIO_MUTE, - PROP_AUDIO_VOLUME_TYPE, - PROP_AUDIO_PRIORITY, - PROP_AUDIO_FADEUPVOLUME, - PROP_AUDIO_ROUTE_POLICY, - PROP_AUDIO_USER_ROUTE, - PROP_AUDIO_LATENCY, - PROP_AUDIO_HANDLE, - PROP_AUDIO_CALLBACK, - PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE, -}; - -GType -gst_avsysaudiosink_audio_mute_get_type (void) -{ - static GType avaudio_mute_type = 0; - static const GEnumValue avaudio_mute[] = { - {AVSYSAUDIOSINK_AUDIO_UNMUTE, "Unmute", "unmute"}, - {AVSYSAUDIOSINK_AUDIO_MUTE, "Mute immediately", "mute"}, - {AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, "Mute with fadedown effect", "fadedown"}, - {0, NULL, NULL}, - }; - - if (!avaudio_mute_type) { - avaudio_mute_type = - g_enum_register_static ("GstAvsysAudioSinkAudioMute", avaudio_mute); - } - return avaudio_mute_type; -} - -GType -gst_avsysaudiosink_user_route_get_type (void) -{ - static GType user_route_type = 0; - static const GEnumValue user_route[] = { - {AVSYSAUDIOSINK_USERROUTE_AUTO, "Route automatically", "auto"}, - {AVSYSAUDIOSINK_USERROUTE_PHONE, "Route to phone only", "phone"}, - {0, NULL, NULL}, - }; - - if (!user_route_type) { - user_route_type = - g_enum_register_static ("GstAvsysAudioSinkUserRoutePolicy",user_route); - } - return user_route_type; -} - -GType -gst_avsysaudiosink_audio_route_get_type (void) -{ - static GType playback_audio_route_type = 0; - static const GEnumValue playback_audio_route[] = { - {AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING, "Use external sound path", "external"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, "Auto change between speaker & earphone", "normal"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, "Play via both speaker & earphone", "alert"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY, "Play via earphone only", "headset"}, - {0, NULL, NULL}, - }; - - if (!playback_audio_route_type) { - playback_audio_route_type = - g_enum_register_static ("GstAvsysAudioSinkAudioRoutePolicy", playback_audio_route); - } - return playback_audio_route_type; -} - -GType -gst_avsysaudiosink_latency_get_type (void) -{ - static GType avsysaudio_latency_type = 0; - static const GEnumValue avsysaudio_latency[] = { - {AVSYSAUDIOSINK_LATENCY_LOW, "Low latency", "low"}, - {AVSYSAUDIOSINK_LATENCY_MID, "Mid latency", "mid"}, - {AVSYSAUDIOSINK_LATENCY_HIGH, "High latency", "high"}, - {0, NULL, NULL}, - }; - - if (!avsysaudio_latency_type) { - avsysaudio_latency_type = - g_enum_register_static ("GstAvsysAudioSinkLatency", avsysaudio_latency); - } - return avsysaudio_latency_type; -} - -static void gst_avsysaudiosink_init_interfaces (GType type); - -//#define GST_BOILERPLATE_FULL(type, type_as_function, parent_type, parent_type_macro, additional_initializations) - -GST_BOILERPLATE_FULL (GstAvsysAudioSink, gst_avsysaudiosink, GstAudioSink, - GST_TYPE_AUDIO_SINK, gst_avsysaudiosink_init_interfaces); - - -static void gst_avsysaudiosink_finalise (GObject * object); -static void gst_avsysaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_avsysaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -#if 0 /*not use*/ -static GstCaps *gst_avsysaudiosink_getcaps (GstBaseSink * bsink); -#endif - -static gboolean gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio); -static gboolean gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio); - -static gboolean gst_avsysaudiosink_open (GstAudioSink * asink); -static gboolean gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec); -static gboolean gst_avsysaudiosink_unprepare (GstAudioSink * asink); -static gboolean gst_avsysaudiosink_close (GstAudioSink * asink); -static guint gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length); -static guint gst_avsysaudiosink_delay (GstAudioSink * asink); -static void gst_avsysaudiosink_reset (GstAudioSink * asink); -static gboolean avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode); - - -#define AVSYS_AUDIO_FACTORY_ENDIANNESS "LITTLE_ENDIAN" - - -static GstStaticPadTemplate avsysaudiosink_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "endianness = (int) { " AVSYS_AUDIO_FACTORY_ENDIANNESS " }, " - "signed = (boolean) { TRUE }, " - "width = (int) 16, " - "depth = (int) 16, " - "rate = (int) 44100, " - "channels = (int) [ 1, 6 ]; " - "audio/x-raw-int, " - "signed = (boolean) { FALSE }, " - "width = (int) 8, " - "depth = (int) 8, " - "rate = (int) 44100, " - "channels = (int) [ 1, 6 ] " - ) - ); -/* -static inline guint _time_to_sample(GstAvsysAudioSink * asink, GstClockTime diff) -{ - guint result = 0; - result =(GST_TIME_AS_USECONDS(diff) * asink->audio_param.samplerate)/1000000; - return result; -} -*/ - -static void -gst_avsysaudiosink_finalise (GObject * object) -{ - GstAvsysAudioSink *sink = NULL; - - sink = GST_AVSYS_AUDIO_SINK (object); - gst_avsysaudiosink_avsys_close(sink); - g_mutex_free (sink->avsys_audio_lock); - g_mutex_free (sink->avsys_audio_reset_lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_avsysaudiosink_init_interfaces (GType type) -{ - /* None */ -} - -static void -gst_avsysaudiosink_base_init (gpointer g_class) -{ - GstElementClass *element_class = NULL; - - element_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_set_details (element_class, &gst_avsysaudiosink_details); - gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&avsysaudiosink_sink_factory)); -} - -static GstStateChangeReturn -gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition); - - -static void -gst_avsysaudiosink_class_init (GstAvsysAudioSinkClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - GstBaseAudioSinkClass *gstbaseaudiosink_class; - GstAudioSinkClass *gstaudiosink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass; - gstaudiosink_class = (GstAudioSinkClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_avsyssudiosink_change_state); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_finalise); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_get_property); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_set_property); - - // gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_getcaps); - - gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_open); - gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_prepare); - gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_unprepare); - gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_close); - gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_write); - gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_delay); - gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_reset); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_VOLUME_TYPE, - g_param_spec_int ("volumetype", "Avsystem Volume Type", - "Select avsystem audio software volume type", 0, G_MAXINT, - DEFAULT_VOLUME_TYPE, G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_PRIORITY, - g_param_spec_int ("priority", "Avsystem Sound Priority", "Avsystem sound priority", - AVSYS_AUDIO_PRIORITY_NORMAL, AVSYS_AUDIO_PRIORITY_SOLO_WITH_TRANSITION_EFFECT, - AVSYS_AUDIO_PRIORITY_NORMAL, G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_HANDLE, - g_param_spec_pointer("audio-handle", "Avsystem handle", - "Avsystem audio handle", - G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_CALLBACK, - g_param_spec_pointer("audio-callback", "Avsystem callback", - "Avsystem audio callback", - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_AUDIO_FADEUPVOLUME, - g_param_spec_boolean ("fadeup", "Avsystem fadeup volume", - "Enable avsystem audio fadeup volume when pause to play", - DEFAULT_FADEUP_VOLUME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_MUTE, - g_param_spec_enum("mute", "Avsystem mute", - "Avsystem audio mute", - GST_AVSYS_AUDIO_SINK_MUTE, DEFAULT_AUDIO_MUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_ROUTE_POLICY, - g_param_spec_enum("audio-route", "Audio Route Policy", - "Audio route policy of system", - GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE, DEFAULT_AUDIO_ROUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_USER_ROUTE, - g_param_spec_enum("user-route", "User Route Policy", - "User route policy", - GST_AVSYS_AUDIO_SINK_USER_ROUTE, DEFAULT_USER_ROUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY, - g_param_spec_enum("latency", "Audio Backend Latency", - "Audio backend latency", - GST_AVSYS_AUDIO_SINK_LATENCY_TYPE, DEFAULT_AUDIO_LATENCY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class, PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE, - g_param_spec_boolean ("close-handle-on-prepare", "Close Handle on Prepare", - "Close Handle on Prepare", - DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE, G_PARAM_READWRITE)); -} - -static void -gst_avsysaudiosink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSink *sink = NULL; - int nvalue = 0; - gboolean nbool = FALSE; - - sink = GST_AVSYS_AUDIO_SINK (object); - - switch (prop_id) { - case PROP_AUDIO_HANDLE: - sink->cbHandle = g_value_get_pointer(value); - break; - case PROP_AUDIO_CALLBACK: - sink->audio_stream_cb = g_value_get_pointer(value); - break; - case PROP_AUDIO_VOLUME_TYPE: - nvalue = g_value_get_int(value); - sink->volume_type = nvalue; - if (sink->audio_handle != (avsys_handle_t)-1) { - avsys_audio_update_volume_config(sink->audio_handle, sink->volume_type); - } - break; - case PROP_AUDIO_PRIORITY: - nvalue = g_value_get_int(value); - sink->sound_priority = nvalue; - break; - case PROP_AUDIO_MUTE: - nvalue = g_value_get_enum(value); - if (sink->audio_handle != (avsys_handle_t)-1) { - if(AVSYS_SUCCESS(avsys_audio_set_mute_fadedown(sink->audio_handle))) - sink->mute = nvalue; - } else { - sink->mute = nvalue; - } - break; - case PROP_AUDIO_FADEUPVOLUME: - nbool = g_value_get_boolean(value); - sink->use_fadeup_volume = nbool; - break; - case PROP_AUDIO_ROUTE_POLICY: - nvalue = g_value_get_enum(value); - sink->audio_route_policy = nvalue; - switch (sink->audio_route_policy) { - case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING: - GST_INFO_OBJECT(sink, "use external audio route setting"); - break; - default: - g_print("AVSYSAUDIOSINK :: Unknown audio route option %d\n", sink->audio_route_policy); - GST_ERROR_OBJECT(sink, "Unknown audio route option %d", sink->audio_route_policy); - break; - } - break; - case PROP_AUDIO_USER_ROUTE: - nvalue = g_value_get_enum(value); - sink->user_route_policy = nvalue; - break; - case PROP_AUDIO_LATENCY: - nvalue = g_value_get_enum(value); - sink->latency = nvalue; - break; - case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE: - nbool = g_value_get_boolean(value); - sink->close_handle_on_prepare = nbool; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSink *sink = NULL; - - sink = GST_AVSYS_AUDIO_SINK (object); - - switch (prop_id) { - case PROP_AUDIO_VOLUME_TYPE: - g_value_set_int(value, sink->volume_type); - break; - case PROP_AUDIO_PRIORITY: - g_value_set_int(value, sink->sound_priority); - break; - case PROP_AUDIO_MUTE: - g_value_set_enum(value, sink->mute); - break; - case PROP_AUDIO_FADEUPVOLUME: - g_value_set_boolean(value, sink->use_fadeup_volume); - break; - case PROP_AUDIO_ROUTE_POLICY: - g_value_set_enum(value, sink->audio_route_policy); - break; - case PROP_AUDIO_USER_ROUTE: - g_value_set_enum(value, sink->user_route_policy); - break; - case PROP_AUDIO_LATENCY: - g_value_set_enum(value, sink->latency); - break; - case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE: - g_value_set_boolean(value, sink->close_handle_on_prepare); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosink_init (GstAvsysAudioSink * avsysaudiosink, GstAvsysAudioSinkClass * g_class) -{ - GST_DEBUG_OBJECT (avsysaudiosink, "initializing avsysaudiosink"); - - avsysaudiosink->audio_handle = (avsys_handle_t)-1; - avsysaudiosink->cached_caps = NULL; - avsysaudiosink->avsys_audio_lock = g_mutex_new (); - avsysaudiosink->avsys_audio_reset_lock = g_mutex_new (); - avsysaudiosink->volume_type = DEFAULT_VOLUME_TYPE; - avsysaudiosink->sound_priority = AVSYS_AUDIO_PRIORITY_NORMAL; - avsysaudiosink->mute = DEFAULT_AUDIO_MUTE; - avsysaudiosink->use_fadeup_volume = DEFAULT_FADEUP_VOLUME; - avsysaudiosink->latency = DEFAULT_AUDIO_LATENCY; - avsysaudiosink->audio_route_policy = DEFAULT_AUDIO_ROUTE; - avsysaudiosink->bytes_per_sample = 1; - avsysaudiosink->close_handle_on_prepare = DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE; -#if defined (LPCM_DUMP_SUPPORT) - avsysaudiosink->dumpFp = NULL; -#endif - -} -#if 0 -static GstCaps * -gst_avsysaudiosink_getcaps (GstBaseSink * bsink) -{ - GstElementClass *element_class = NULL; - GstPadTemplate *pad_template = NULL; - GstAvsysAudioSink *sink = GST_AVSYS_AUDIO_SINK (bsink); - GstCaps *caps; - -// debug_fenter(); - - sink = GST_AVSYS_AUDIO_SINK (bsink); - if (sink->audio_handle == -1) - { - GST_DEBUG_OBJECT (sink, "avsystem audio not open, using template caps"); - return NULL; /* base class will get template caps for us */ - } - - if (sink->cached_caps) - { - GST_LOG_OBJECT (sink, "Returning cached caps"); - return gst_caps_ref (sink->cached_caps); - } - - element_class = GST_ELEMENT_GET_CLASS (sink); - pad_template = gst_element_class_get_pad_template (element_class, "sink"); - g_return_val_if_fail (pad_template != NULL, NULL); - - // todo : get supported format. - //caps = gst_avsysaudio_probe_supported_formats (GST_OBJECT (sink), sink->, - //gst_pad_template_get_caps (pad_template)); - - //if (caps) { - //sink->cached_caps = gst_caps_ref (caps); - //} - - GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps); - - return caps; -} -#endif - -static gboolean -avsysaudiosink_parse_spec (GstAvsysAudioSink * avsys_audio, GstRingBufferSpec * spec) -{ - /* Check param */ - if (spec->type != GST_BUFTYPE_LINEAR || - spec->channels > 6 || spec->channels < 1 || - !(spec->format == GST_S8 || spec->format == GST_S16_LE) ) - return FALSE; - - switch (spec->format) { - case GST_S8: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT; - avsys_audio->bytes_per_sample = 1; - break; - case GST_S16_LE: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT; - avsys_audio->bytes_per_sample = 2; - break; - default: - return FALSE; - } - - /// set audio parameter for avsys audio open - switch (avsys_audio->latency) { - case AVSYSAUDIOSINK_LATENCY_LOW: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY; - break; - case AVSYSAUDIOSINK_LATENCY_MID: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT; - break; - case AVSYSAUDIOSINK_LATENCY_HIGH: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_CLOCK; - break; - } - - avsys_audio->audio_param.priority = 0; - avsys_audio->audio_param.samplerate = spec->rate; - avsys_audio->audio_param.channels = spec->channels; - avsys_audio->bytes_per_sample *= spec->channels; - - /* set software volume table type */ - avsys_audio->audio_param.vol_type = avsys_audio->volume_type; - avsys_audio->audio_param.priority = avsys_audio->sound_priority; - avsys_audio->audio_param.handle_route = avsys_audio->user_route_policy; - - return TRUE; -} - -static gboolean -gst_avsysaudiosink_open (GstAudioSink * asink) -{ - return TRUE; -} - -static gboolean -gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) -{ - GstAvsysAudioSink *avsys_audio = NULL; - guint p_time = 0, b_time = 0; - - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - - GST_WARNING("Start"); - - // set avsys audio param - if (!avsysaudiosink_parse_spec (avsys_audio, spec)) - goto spec_parse; - - if (gst_avsysaudiosink_avsys_open(avsys_audio) == FALSE) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_open() failed"); - goto OPEN_FAILED; - } - - /* Ring buffer size */ - if (AVSYS_STATE_SUCCESS == - avsys_audio_get_period_buffer_time(avsys_audio->audio_handle, &p_time, &b_time)) { - if(p_time == 0 || b_time == 0) - return FALSE; - - spec->latency_time = (guint64)p_time; - spec->buffer_time = (guint64)b_time; - } else { - GST_WARNING_OBJECT(avsys_audio, ""); - return FALSE; - } - spec->segsize = avsys_audio->avsys_size; /* '/16' see avsys_audio_open */ - spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0); - //spec->segtotal+2; - - if (avsys_audio->close_handle_on_prepare) { - if (gst_avsysaudiosink_avsys_close(avsys_audio) == FALSE) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed"); - return FALSE; - } - } - - GST_WARNING("End"); - GST_WARNING_OBJECT (avsys_audio, "latency time %u, buffer time %u, seg total %u\n", - (unsigned int)(spec->latency_time/1000), (unsigned int)(spec->buffer_time/1000), spec->segtotal); - return TRUE; - -spec_parse: - { - GST_ELEMENT_ERROR (avsys_audio, RESOURCE, SETTINGS, (NULL), - ("Setting of swparams failed: " )); - return FALSE; - } - -OPEN_FAILED: - avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ); - return FALSE; -} - -static gboolean -gst_avsysaudiosink_unprepare (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = NULL; - gboolean result = TRUE; - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - - GST_WARNING("Start"); - if(!gst_avsysaudiosink_avsys_close(avsys_audio)) - { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed"); - result = FALSE; - } - GST_WARNING("End"); - - return result; -} - -static gboolean -gst_avsysaudiosink_close (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = NULL; - - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - gst_caps_replace (&avsys_audio->cached_caps, NULL); - - return TRUE; -} - - -/* - * Underrun and suspend recovery - */ - -static guint -gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length) -{ - GstAvsysAudioSink *avsys_audio = NULL; - gint write_len = 0; - - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - GST_AVSYS_AUDIO_SINK_LOCK (asink); - - if (avsys_audio->audio_stream_cb == NULL) { - write_len = avsys_audio_write(avsys_audio->audio_handle, data, length); - -#if defined (LPCM_DUMP_SUPPORT) - fwrite(data, 1, write_len, avsys_audio->dumpFp); //This is for original data (no volume convert) -#endif - if(write_len != length) - { - goto write_error; - } - - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - - return write_len; -write_error: - { - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - - if(AVSYS_FAIL(write_len)) - { - GST_ERROR_OBJECT(avsys_audio, "avsys_audio_write() failed with %d\n", write_len); - } - return length; /* skip one period */ - } - } else { - gboolean result; - result = avsys_audio->audio_stream_cb(data, length, avsys_audio->cbHandle); - if(!result) - { - GST_ERROR_OBJECT(avsys_audio,"auido stream callback failed\n"); - } - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - return length; - } -} - -static guint -gst_avsysaudiosink_delay (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = NULL; - int delay = 0; - guint retValue = 0; - - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink); - if ((int)avsys_audio->audio_handle != -1) { - if (AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) { - retValue = delay; - } - } - GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink); - return retValue; -} - -static void -gst_avsysaudiosink_reset (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = NULL; - int avsys_result = AVSYS_STATE_SUCCESS; - - GST_WARNING("Start"); - GST_AVSYS_AUDIO_SINK_LOCK (asink); - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - -#if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__) - GST_AVSYS_AUDIO_SINK_RESET_LOCK (asink); - avsys_result = avsys_audio_close (avsys_audio->audio_handle); - if(AVSYS_FAIL(avsys_result)) { - GST_ERROR_OBJECT (avsys_audio, "avsys_audio_close: internal error: "); - } else { - avsys_audio->audio_handle =(avsys_handle_t) -1; - } - GST_AVSYS_AUDIO_SINK_RESET_UNLOCK (asink); -#else - if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle)) { - GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: "); - } -#endif - - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - GST_WARNING("End"); - - return; -} - - -static gboolean -gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio) -{ - int avsys_result; - - GST_AVSYS_AUDIO_SINK_LOCK(avsys_audio); - if (avsys_audio->audio_handle == (avsys_handle_t)-1) { - - GST_LOG_OBJECT (avsys_audio, "avsys_audio_open() with user policy [%d] ", avsys_audio->user_route_policy); - - avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size); - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ); - return FALSE; - } - - GST_LOG_OBJECT (avsys_audio, "Opened av system "); - - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - } else { - GST_WARNING_OBJECT(avsys_audio, "audio handle has already opened"); - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - return FALSE; - } -#if defined (LPCM_DUMP_SUPPORT) - if (avsys_audio->dumpFp == NULL) { - avsys_audio->dumpFp = fopen("/root/dump.lpcm","w"); - } -#endif - return TRUE; -} - -static gboolean -gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio) -{ - int avsys_result = AVSYS_STATE_SUCCESS; - - GST_AVSYS_AUDIO_SINK_LOCK (avsys_audio); - - if (avsys_audio->audio_handle != (avsys_handle_t)-1 ) { - avsys_result = avsys_audio_close(avsys_audio->audio_handle); - - if (AVSYS_FAIL(avsys_result)) - { - GST_ERROR_OBJECT(avsys_audio, - "avsys_audio_close() failed with 0x%x", avsys_result); - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - return FALSE; - } else { - avsys_audio->audio_handle = (avsys_handle_t) -1; - GST_INFO_OBJECT(avsys_audio, "avsys_audio_close() success"); - } - - GST_LOG_OBJECT (avsys_audio, "Closed av system "); - } else { - GST_WARNING_OBJECT(avsys_audio, "audio handle has already closed"); - } - - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); -#if defined (LPCM_DUMP_SUPPORT) - if(avsys_audio->dumpFp != NULL) - { - fclose(avsys_audio->dumpFp); - avsys_audio->dumpFp = NULL; - } -#endif - return TRUE; -} - -static GstStateChangeReturn -gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (element); - - int avsys_result = AVSYS_STATE_SUCCESS; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: -#if defined(_ALSA_DAPM_) - switch(avsys_audio->audio_route_policy) { - case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING: - GST_INFO_OBJECT(avsys_audio, "audio route uses external setting"); - break; - default: - GST_ERROR_OBJECT(avsys_audio, "Unknown audio route option %d\n", avsys_audio->audio_route_policy); - break; - } -#endif -#if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__) - if (avsys_audio->audio_handle == (avsys_handle_t)-1) { - avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size); - if (AVSYS_FAIL(avsys_result)) { - GST_ERROR_OBJECT (avsys_audio, "avsys_audio_open: internal error: "); - return GST_STATE_CHANGE_FAILURE; - } - } -#endif - - if (avsys_audio->use_fadeup_volume) { - GST_INFO_OBJECT(avsys_audio, "Set fadeup volume"); - avsys_audio_set_volume_fadeup(avsys_audio->audio_handle); - } - - if(AVSYS_STATE_SUCCESS != avsys_audio_set_mute(avsys_audio->audio_handle, CONVERT_MUTE_VALUE(avsys_audio->mute))) - { - GST_ERROR_OBJECT(avsys_audio, "Set mute failed %d", CONVERT_MUTE_VALUE(avsys_audio->mute)); - } - break; - default: - break; - } - ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) { - return ret; - } - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - return ret; -} - - -static gboolean -avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode) -{ - GST_DEBUG("avsysaudiosink_post_message\n"); - gboolean ret = TRUE; - GstMessage *Msg = NULL; - GQuark domain; - gboolean status = FALSE; - GError *error = NULL; - gint error_code; - /* - if(errorcode>0) - error_code = errorcode; - else - error_code = GST_STREAM_ERROR_TYPE_NOT_FOUND; */ - error_code = errorcode; - domain = gst_resource_error_quark(); - error = g_error_new (domain, error_code, "AVSYSAUDIOSINK_RESOURCE_ERROR"); - Msg = gst_message_new_error(GST_ELEMENT(self), error, "AVSYSAUDIOSINK_ERROR"); - status = gst_element_post_message (GST_ELEMENT(self), Msg); - if (status == FALSE) - { - GST_ERROR("Error in posting message on the bus ...\n"); - ret = FALSE; - } - - return ret; -} diff --git a/mobile/avsystem/src/gstavsysaudiosink.h b/mobile/avsystem/src/gstavsysaudiosink.h deleted file mode 100644 index 47da754..0000000 --- a/mobile/avsystem/src/gstavsysaudiosink.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef __GST_AVSYSAUDIOSINK_H__ -#define __GST_AVSYSAUDIOSINK_H__ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_AUDIO_SINK (gst_avsysaudiosink_get_type()) -#define GST_AVSYS_AUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_AUDIO_SINK,GstAvsysAudioSink)) -#define GST_AVSYS_AUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_AUDIO_SINK,GstAvsysAudioSinkClass)) -#define GST_IS_AVSYS_AUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_AUDIO_SINK)) -#define GST_IS_AVSYS_AUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_AUDIO_SINK)) -//#define GST_AVSYS_AUDIO_SINK_CAST(obj) ((GstAvsysAudioSink *) (obj)) - -typedef struct _GstAvsysAudioSink GstAvsysAudioSink; -typedef struct _GstAvsysAudioSinkClass GstAvsysAudioSinkClass; - -#define GST_AVSYS_AUDIO_SINK_GET_LOCK(obj) (GST_AVSYS_AUDIO_SINK (obj)->avsys_audio_lock) -#define GST_AVSYS_AUDIO_SINK_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SINK_GET_LOCK(obj))) -#define GST_AVSYS_AUDIO_SINK_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SINK_GET_LOCK(obj))) - -#define GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj) (GST_AVSYS_AUDIO_SINK (obj)->avsys_audio_reset_lock) -#define GST_AVSYS_AUDIO_SINK_RESET_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj))) -#define GST_AVSYS_AUDIO_SINK_RESET_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj))) - - -typedef enum { - AVSYSAUDIOSINK_AUDIO_UNMUTE = 0, - AVSYSAUDIOSINK_AUDIO_MUTE, - AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, -}GstAvsysAudioSinkAudioMute; - - -typedef enum { - AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING = -1, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY -}GstAvsysAudioSinkAudioRoutePolicy; - - -typedef enum { - AVSYSAUDIOSINK_USERROUTE_AUTO = 0, - AVSYSAUDIOSINK_USERROUTE_PHONE -}GstAvsysAudioSinkUserRoutePolicy; - -typedef enum { - AVSYSAUDIOSINK_LATENCY_LOW = 0, - AVSYSAUDIOSINK_LATENCY_MID, - AVSYSAUDIOSINK_LATENCY_HIGH, -}GstAvsysAudioSinkLatency; - -#define GST_AVSYS_AUDIO_SINK_USER_ROUTE (gst_avsysaudiosink_user_route_get_type ()) -#define GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE (gst_avsysaudiosink_audio_route_get_type ()) -#define GST_AVSYS_AUDIO_SINK_MUTE (gst_avsysaudiosink_audio_mute_get_type()) -#define GST_AVSYS_AUDIO_SINK_LATENCY_TYPE (gst_avsysaudiosink_latency_get_type ()) - -//this define if for debugging -//#define LPCM_DUMP_SUPPORT -struct _GstAvsysAudioSink { - GstAudioSink sink; - - avsys_handle_t audio_handle; - avsys_audio_param_t audio_param; - gint avsys_size; - gint mute; - gint use_fadeup_volume; - gint close_handle_on_prepare; - gint audio_route_policy; - gint user_route_policy; - gint latency; - - GstCaps *cached_caps; - - GMutex *avsys_audio_lock; - GMutex *avsys_audio_reset_lock; - gint volume_type; - gint sound_priority; - gint bytes_per_sample; - - gpointer cbHandle; - gboolean (*audio_stream_cb) (void *stream, int stream_size, void *user_param); -}; - - -struct _GstAvsysAudioSinkClass { - GstAudioSinkClass parent_class; -}; - -GType gst_avsysaudiosink_get_type (void); -GType gst_avsysaudiosink_audio_route_get_type (void); -GType gst_avsysaudiosink_audio_mute_get_type(void); -GType gst_avsysaudiosink_latency_get_type (void); - -G_END_DECLS - -#endif /* __GST_AVSYSAUDIOSINK_H__ */ diff --git a/mobile/avsystem/src/gstavsysaudiosrc.c b/mobile/avsystem/src/gstavsysaudiosrc.c deleted file mode 100644 index 3a4fdc0..0000000 --- a/mobile/avsystem/src/gstavsysaudiosrc.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include - -#include -#include -//#include - -#include /*gettimeofday*/ -#include - -#include "gstavsysaudiosrc.h" - -/** - * Define for Release - * - * _ENABLE_FAKE_READ: enable fake read instead of avsys_audio_read(). (default: 0) - */ -#define _ENABLE_FAKE_READ 0 -//#define USE_GPT8 - - -#define _MIN_RATE 8000 -#define _MAX_RATE 48000 -#define _MIN_CHANNEL 1 -#define _MAX_CHANNEL 2 - - -#define DEFAULT_GPT8_FREQ 26 - -#if _ENABLE_FAKE_READ -static long g_delay_time; -#endif - -#define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE -#define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSRC_LATENCY_MID - -GST_DEBUG_CATEGORY_EXTERN (avsystem_src_debug); -#define GST_CAT_DEFAULT avsystem_src_debug - -/* elementfactory information */ -static const GstElementDetails gst_avsysaudiosrc_details = - GST_ELEMENT_DETAILS ("AV system source", - "Source/Audio", - "Read from a AV system audio in", - "Samsung Electronics co., ltd."); - - -enum { - PROP_0, -#if 0 -#if !defined(I386_SIMULATOR) - PROP_AUDIO_MEDIA_CALL, -#endif -#endif - PROP_AUDIO_LATENCY, -}; - -enum { - CAPTURE_UNCORK = 0, - CAPTURE_CORK, -}; - -GType -gst_avsysaudiosrc_audio_latency_get_type (void) -{ - static GType capture_audio_latency_type = 0; - static const GEnumValue capture_audio_latency[] = { - {AVSYSAUDIOSRC_LATENCY_LOW, "Set capture latency as low", "low"}, - {AVSYSAUDIOSRC_LATENCY_MID, "Set capture latency as mid", "mid"}, - {AVSYSAUDIOSRC_LATENCY_HIGH, "Set capture latency as high", "high"}, - {0, NULL, NULL}, - }; - - if (!capture_audio_latency_type) { - capture_audio_latency_type = - g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency); - } - return capture_audio_latency_type; -} - - -GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC); - -#if _ENABLE_FAKE_READ -static unsigned long fake_delay (unsigned long usec); -#endif - -static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc); - -static void gst_avsysaudiosrc_finalize (GObject * object); -static void gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); - -static GstCaps* gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc); - -static gboolean gst_avsysaudiosrc_open (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec); -static gboolean gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_close (GstAudioSrc * asrc); -static guint gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length); -static void gst_avsysaudiosrc_reset (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_avsys_close (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork); -static gboolean gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *src); -#if defined(_USE_CAPS_) -static GstCaps *gst_avsysaudiosrc_detect_rates (GstObject * obj, avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_detect_channels (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_detect_formats (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_probe_supported_formats (GstObject * obj, avsys_handle_t handle, const GstCaps * template_caps); -#endif -static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ; - - - -/* AvsysAudioSrc signals and args */ -enum { - LAST_SIGNAL -}; - -# define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS "LITTLE_ENDIAN" - -static GstStaticPadTemplate avsysaudiosrc_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "audio/x-raw-int, " - "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, " - "signed = (boolean) { TRUE }, " - "width = (int) 16, " - "depth = (int) 16, " - "rate = (int) [ 8000, 48000 ], " - "channels = (int) [ 1, 2 ]; " - "audio/x-raw-int, " - "signed = (boolean) { FALSE }, " - "width = (int) 8, " - "depth = (int) 8, " - "rate = (int) [ 8000, 48000 ], " - "channels = (int) [ 1, 2 ]") - ); - -static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc, GstClockTime diff) -{ - guint result = 0; - // sample rate : asrc->audio_param.samplerate - result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000; - return result; -} - - -static void -gst_avsysaudiosrc_finalize (GObject * object) -{ - GstAvsysAudioSrc *src = NULL; - - - src = GST_AVSYS_AUDIO_SRC (object); - g_mutex_free (src->avsysaudio_lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_avsysaudiosrc_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&avsysaudiosrc_src_factory)); -} - -static void -gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; - GstBaseAudioSrcClass *gstbaseaudiosrc_class; - GstAudioSrcClass *gstaudiosrc_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; - gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass; - gstaudiosrc_class = (GstAudioSrcClass *) klass; - - gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_finalize); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_get_property); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_set_property); -#if defined(_USE_CAPS_) - gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_getcaps); -#endif - gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_open); - gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_prepare); - gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_unprepare); - gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_close); - gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_read); - gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_delay); - gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_reset); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY, - g_param_spec_enum("latency", "Audio Latency", - "Audio latency", - GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); -} - - - -/** - *@note useful range 0 - 1000000 microsecond - */ -#if _ENABLE_FAKE_READ -static unsigned long -fake_delay (unsigned long usec) -{ - struct timeval s_time; - struct timeval c_time; - long s_sec = 0L; - long s_usec = 0L; - long c_sec = 0L; - long c_usec = 0L; - long t_sec = 0L; - long t_usec = 0L; - unsigned long total_usec = 0UL; - unsigned long t = 0UL; - - if (usec == 0UL) { - usleep (0); - return 0; - } - - /*get start time*/ - if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) { - s_sec = s_time.tv_sec; - s_usec = s_time.tv_usec; - } else { - return 0; - } - - for (;;) { - /*get current time*/ - if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) { - c_sec = c_time.tv_sec; - c_usec = c_time.tv_usec; - } else { - return 0; - } - - /*get elasped sec*/ - t_sec = c_sec - s_sec; - - /*get elapsed usec*/ - if ((s_usec) > (c_usec)) { - t_usec = 1000000L - (s_usec) + (c_usec); - t_sec--; - } else { - t_usec = (c_usec) - (s_usec); - } - - /*get total elapsed time*/ - total_usec = (t_sec * 1000000UL) + t_usec; - - t = usec - total_usec; - - if (total_usec >= usec) { - break; - } else { - if (t > 10000UL) { - /*this function does not work in precision*/ - usleep (1); - } - } - } - - return total_usec; -} -#endif - -static guint -gst_avsysaudiosrc_delay (GstAudioSrc *asrc) -{ - GstAvsysAudioSrc *avsys_audio = NULL; - int delay; - guint retValue = 0; - - avsys_audio = GST_AVSYS_AUDIO_SRC (asrc); - if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) - retValue = delay; - - return retValue; -} - - - -static void -gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSrc *src = NULL; -// gint getvalue = 0; - src = GST_AVSYS_AUDIO_SRC (object); - - if (src->cached_caps == NULL) - { - switch (prop_id) - { - case PROP_AUDIO_LATENCY: - src->latency = g_value_get_enum(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } -} - -static void -gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSrc *src; - - src = GST_AVSYS_AUDIO_SRC (object); - - switch (prop_id) - { - case PROP_AUDIO_LATENCY: - g_value_set_enum(value, src->latency); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class) -{ - GST_DEBUG_OBJECT (avsysaudiosrc, "initializing"); - - avsysaudiosrc->cached_caps = NULL; - avsysaudiosrc->audio_handle = (avsys_handle_t)-1; - avsysaudiosrc->buffer_size = 0; - avsysaudiosrc->avsysaudio_lock = g_mutex_new (); - avsysaudiosrc->latency = DEFAULT_AUDIO_LATENCY; -} - -#if defined(_USE_CAPS_) -static GstCaps * -gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc) -{ - GstElementClass *element_class; - GstPadTemplate *pad_template; - GstAvsysAudioSrc *src; - GstCaps *caps = NULL; - - src = GST_AVSYS_AUDIO_SRC (bsrc); - - if(src->audio_handle==(avsys_handle_t)-1){ - GST_DEBUG_OBJECT(src,"device not open, using template caps"); - return NULL; - } - - if (src->cached_caps) - { - GST_LOG_OBJECT (src, "Returning cached caps"); - return gst_caps_ref(src->cached_caps); - } - element_class = GST_ELEMENT_GET_CLASS (src); - pad_template = gst_element_class_get_pad_template (element_class, "src"); - g_return_val_if_fail (pad_template != NULL, NULL); - - caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle, - gst_pad_template_get_caps (pad_template)); - - if (caps) { - src->cached_caps = gst_caps_ref (caps); - } - - GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps); - - return caps; -} -#endif -static gboolean -gst_avsysaudiosrc_open (GstAudioSrc * asrc) -{ - return TRUE; -} - -static gboolean -avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec) -{ - /* Check param */ - if (spec->type != GST_BUFTYPE_LINEAR || - spec->channels > 2 || spec->channels < 1 || - !(spec->format == GST_S8 || spec->format == GST_S16_LE) ) - return FALSE; - - switch(spec->format) - { - case GST_S8: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT; - avsys_audio->bytes_per_sample = 1; - break; - case GST_S16_LE: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT; - avsys_audio->bytes_per_sample = 2; - break; - default: - GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format"); - return FALSE; - } - - // set audio parameter for avsys audio open - - switch(avsys_audio->latency) - { - case AVSYSAUDIOSRC_LATENCY_LOW: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY; - break; - case AVSYSAUDIOSRC_LATENCY_MID: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT; - break; - case AVSYSAUDIOSRC_LATENCY_HIGH: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY; - break; - default: - break; - } - - avsys_audio->audio_param.priority = 0; - avsys_audio->audio_param.samplerate = spec->rate; - avsys_audio->audio_param.channels = spec->channels; - - if(spec->channels == 2) - avsys_audio->bytes_per_sample *= 2; - else if(spec->channels > 2) - { - GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels); - return FALSE; - } - - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - guint p_time = 0, b_time = 0; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec)) - { - GST_ERROR("avsysaudiosrc_parse_spec failed"); - return FALSE; - } - - /*open avsys audio*/ - if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc)) - { - GST_ERROR("gst_avsysaudiosrc_avsys_open failed"); - return FALSE; - } - - /* Ring buffer size */ - if (AVSYS_STATE_SUCCESS == - avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time)) - { - if(p_time == 0 || b_time == 0) - return FALSE; - - spec->latency_time = (guint64)p_time; - spec->buffer_time = (guint64)b_time; - } - else - { - return FALSE; - } - spec->segsize = avsysaudiosrc->buffer_size; - spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0); - spec->segtotal += 2; - - GST_INFO_OBJECT(avsysaudiosrc, "audio buffer spec : latency_time(%llu), buffer_time(%llu), segtotal(%d), segsize(%d)\n", - spec->latency_time, spec->buffer_time, spec->segtotal, spec->segsize); - - - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - gboolean ret = TRUE; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - /*close*/ - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - - if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc)) - { - GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed"); - ret = FALSE; - } - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - - - - return ret; -} - -static gboolean -gst_avsysaudiosrc_close (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - gst_caps_replace (&avsysaudiosrc->cached_caps, NULL); - - return TRUE; -} - -static void -gst_avsysaudiosrc_reset (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsys_audio = NULL; - - avsys_audio = GST_AVSYS_AUDIO_SRC (asrc); - GST_AVSYS_AUDIO_SRC_LOCK (asrc); - - if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle)) - { - GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: "); - } - - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - - return; -} - - -static GstStateChangeReturn -gst_avsys_src_change_state (GstElement * element, GstStateChange transition) -{ - GstAvsysAudioSrc *avsys = NULL; - GstStateChangeReturn ret ; - - avsys = GST_AVSYS_AUDIO_SRC (element); - GST_DEBUG("gst_avsys_src_change_state"); - - switch (transition) - { - case GST_STATE_CHANGE_NULL_TO_READY: - { - GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ; - break ; - } - case GST_STATE_CHANGE_READY_TO_PAUSED: - { - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ; - break ; - } - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - { - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ; - /* Capture Start */ - if (!gst_avsysaudiosrc_avsys_start (avsys)) { - GST_ERROR("gst_avsysaudiosrc_avsys_start failed"); - } - break ; - } - default: - break ; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - GST_DEBUG ("After parent_class->change_state...\n") ; - switch (transition) - { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - { - GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ; - /* Capture Stop */ - if (!gst_avsysaudiosrc_avsys_stop (avsys)) { - GST_ERROR("gst_avsysaudiosrc_avsys_stop failed"); - } - break ; - } - case GST_STATE_CHANGE_PAUSED_TO_READY: - { - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ; - break ; - } - case GST_STATE_CHANGE_READY_TO_NULL: - { - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ; - break ; - } - default: - break ; - } - - return ret; -} - - - -static guint -gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - gint readed = 0; - gpointer ptr = NULL; - guint used_length = 0; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - ptr = data; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); -#if _ENABLE_FAKE_READ - readed = avsysaudiosrc->buffer_size; - memset (ptr, 10, avsysaudiosrc->buffer_size); /*maybe can't hear*/ - fake_delay (1000000UL / g_delay_time); -#else - ptr = data; - readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length); - if (readed < 0) - goto _READ_ERROR; -#endif //_ENABLE_FAKE_READ - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return readed; - -_READ_ERROR: - { - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - return length; /* skip one period */ - } -} - -static gboolean -gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork) -{ - int avsys_result = avsys_audio_cork (avsysaudiosrc->audio_handle, cork); - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_cork() error. [0x%x]\n", avsys_result); - return FALSE; - } - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *avsysaudiosrc) -{ - gboolean result; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_UNCORK); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return result; -} - -static gboolean -gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *avsysaudiosrc) -{ - gboolean result; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_CORK); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return result; -} - -static gboolean -gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc) -{ - int avsys_result = 0; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - - avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size); - - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_open() error. [0x%x]\n", avsys_result); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - return FALSE; - } - -#if _ENABLE_FAKE_READ - g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size); -#endif - - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src) -{ - int ret; - - if (src->audio_handle != (avsys_handle_t)-1) - { - /*close avsys audio*/ - ret = avsys_audio_close (src->audio_handle); - if (AVSYS_FAIL(ret)) - { - GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret); - return FALSE; - } - src->audio_handle = (avsys_handle_t)-1; - GST_DEBUG_OBJECT(src, "AVsys audio handle closed"); - } - else - { - GST_WARNING_OBJECT(src,"avsys audio handle has already closed"); - } - - return TRUE; -} -#if defined(_USE_CAPS_) -static GstCaps * -gst_avsysaudiosrc_detect_rates(GstObject *obj, - avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps) -{ - GstCaps *caps; - guint min, max; - gint err, dir, min_rate, max_rate, i; - - GST_LOG_OBJECT(obj, "probing sample rates ..."); - - if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0) - goto min_rate_err; - - if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0) - goto max_rate_err; - - min_rate = min; - max_rate = max; - - if (min_rate < _MIN_RATE) - min_rate = _MIN_RATE; /* random 'sensible minimum' */ - - if (max_rate <= 0) - max_rate = _MAX_RATE; /* or maybe just use 192400 or so? */ - else if (max_rate > 0 && max_rate < _MIN_RATE) - max_rate = MAX (_MIN_RATE, min_rate); - - GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min); - GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max); - - caps = gst_caps_make_writable(in_caps); - - for (i = 0; i < gst_caps_get_size(caps); ++i) - { - GstStructure *s; - - s = gst_caps_get_structure(caps, i); - if (min_rate == max_rate) - { - gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL); - } - else - { - gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate, - max_rate, NULL); - } - } - - return caps; - /* ERRORS */ - min_rate_err: - { - GST_ERROR_OBJECT(obj, "failed to query minimum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } - max_rate_err: - { - GST_ERROR_OBJECT(obj, "failed to query maximum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } -} - - -static GstCaps * -gst_avsysaudiosrc_detect_formats(GstObject * obj, - avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps) -{ - avsys_pcm_format_mask_t *mask; - GstStructure *s; - GstCaps *caps; - gint i; - - avsys_pcm_format_mask_malloc(&mask); - avsys_pcm_hw_params_get_format_mask(hw_params, mask); - - caps = gst_caps_new_empty(); - - for (i = 0; i < gst_caps_get_size(in_caps); ++i) - { - GstStructure *scopy; - //gint w; - gint width = 0, depth = 0; - gint sndformat; - - s = gst_caps_get_structure(in_caps, i); - if (!gst_structure_has_name(s, "audio/x-raw-int")) - { - GST_WARNING_OBJECT(obj, "skipping non-int format"); - continue; - } - if (!gst_structure_get_int(s, "width", &width) - || !gst_structure_get_int(s, "depth", &depth)) - continue; - - GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth); - if (width == 8) - sndformat = 0;//SND_PCM_FORMAT_S8 - else - //width==16 - sndformat = 2; //SND_PCM_FORMAT_S16_LE - if (avsys_pcm_format_mask_test(mask, sndformat)) - { //must be implemented - /* template contains { true, false } or just one, leave it as it is */ - scopy = gst_structure_copy(s); - - } - else - { - scopy = NULL; - } - if (scopy) - { - /* TODO: proper endianness detection, for now it's CPU endianness only */ - gst_structure_set(scopy, "signed", G_TYPE_BOOLEAN, TRUE, NULL); - gst_structure_set(scopy, "endianness", G_TYPE_INT, G_BYTE_ORDER, - NULL); - gst_caps_append_structure(caps, scopy); - } - - } - - avsys_pcm_format_mask_free(mask); - gst_caps_unref(in_caps); - return caps; -} - - -static GstCaps * -gst_avsysaudiosrc_detect_channels(GstObject * obj, - avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps) -{ - GstCaps *caps; - guint min, max; - gint err, min_channel, max_channel, i; -// gint dir; - - GST_LOG_OBJECT(obj, "probing sample rates ..."); - - if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0) - goto min_chan_err; - - if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0) - goto max_chan_err; - - min_channel = min; - max_channel = max; - - if (min_channel < _MIN_CHANNEL) - min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */ - - if (max_channel <= 0) - max_channel = _MAX_CHANNEL; /* or maybe just use 192400 or so? */ - else if (max_channel > 0 && max_channel < _MIN_CHANNEL) - max_channel = MAX (_MAX_CHANNEL, min_channel); - - GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min); - GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max); - - caps = gst_caps_make_writable(in_caps); - - for (i = 0; i < gst_caps_get_size(caps); ++i) - { - GstStructure *s; - - s = gst_caps_get_structure(caps, i); - if (min_channel == max_channel) - { - gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL); - } - else - { - gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel, - max_channel, NULL); - } - } - - return caps; - - /* ERRORS */ - min_chan_err: - { - GST_ERROR_OBJECT(obj, "failed to query minimum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } - max_chan_err: - { - GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:"); - gst_caps_unref(in_caps); - return NULL; - } -} - -/* - * gst_avsys_probe_supported_formats: - * - * Takes the template caps and returns the subset which is actually - * supported by this device. - * - */ - -static GstCaps * -gst_avsysaudiosrc_probe_supported_formats(GstObject * obj, - avsys_handle_t handle, const GstCaps * template_caps) -{ - - avsys_pcm_hw_params_t *hw_params; - GstCaps *caps; - gint err; - - avsys_pcm_hw_params_malloc(&hw_params); - if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0) - goto error; - - caps = gst_caps_copy(template_caps); - - if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps))) - goto subroutine_error; - - if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps))) - goto subroutine_error; - - if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps))) - goto subroutine_error; - - avsys_pcm_hw_params_free(hw_params); - return caps; - - /* ERRORS */ - error: - { - GST_ERROR_OBJECT(obj, "failed to query formats"); - return NULL; - } - subroutine_error: - { - GST_ERROR_OBJECT(obj, "failed to query formats"); - return NULL; - } -} -#endif diff --git a/mobile/avsystem/src/gstavsysaudiosrc.h b/mobile/avsystem/src/gstavsysaudiosrc.h deleted file mode 100644 index 4031e04..0000000 --- a/mobile/avsystem/src/gstavsysaudiosrc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_AVSYS_AUDIO_SRC_H__ -#define __GST_AVSYS_AUDIO_SRC_H__ - -//#undef _MMCAMCORDER_MERGE_TEMP - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_AUDIO_SRC (gst_avsysaudiosrc_get_type()) -#define GST_AVSYS_AUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_AUDIO_SRC,GstAvsysAudioSrc)) -#define GST_AVSYS_AUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_AUDIO_SRC,GstAvsysAudioSrcClass)) -#define GST_IS_AVSYS_AUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_AUDIO_SRC)) -#define GST_IS_AVSYS_AUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_AUDIO_SRC)) -#define GST_AVSYS_AUDIO_SRC_CAST(obj) ((GstAvsysAudioSrc *)(obj)) - -#define GST_AVSYS_AUDIO_SRC_GET_LOCK(obj) (GST_AVSYS_AUDIO_SRC_CAST (obj)->avsysaudio_lock) -#define GST_AVSYS_AUDIO_SRC_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SRC_GET_LOCK (obj))) -#define GST_AVSYS_AUDIO_SRC_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SRC_GET_LOCK (obj))) - -typedef struct _GstAvsysAudioSrc GstAvsysAudioSrc; -typedef struct _GstAvsysAudioSrcClass GstAvsysAudioSrcClass; - -typedef enum { - AVSYSAUDIOSRC_LATENCY_LOW = 0, - AVSYSAUDIOSRC_LATENCY_MID, - AVSYSAUDIOSRC_LATENCY_HIGH, -}GstAvsysAudioSrcAudioLatency; - -#define GST_AVSYS_AUDIO_SRC_LATENCY (gst_avsysaudiosrc_audio_latency_get_type()) - - - -/** - * GstAvsysAudioSrc: - * - * Opaque data structure - */ -struct _GstAvsysAudioSrc { - GstAudioSrc src; - - avsys_handle_t audio_handle; - avsys_audio_param_t audio_param; - - gint buffer_size; - GstCaps *cached_caps; - GMutex *avsysaudio_lock; - - gint media_call; - gint bytes_per_sample; - gint latency; - -}; - -struct _GstAvsysAudioSrcClass { - GstAudioSrcClass parent_class; -}; - - -GType gst_avsysaudiosrc_get_type (void); -GType gst_avsysaudiosrc_audio_latency_get_type(void); - -G_END_DECLS - -#endif /* __GST_AVSYS_AUDIO_SRC_H__ */ diff --git a/mobile/avsystem/src/gstavsysmemsink.c b/mobile/avsystem/src/gstavsysmemsink.c deleted file mode 100644 index a47ceaa..0000000 --- a/mobile/avsystem/src/gstavsysmemsink.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#if defined(_MM_PROJECT_FLOATER) || defined(_MM_PROJECT_PROTECTOR) || defined(_MM_PROJECT_VOLANS) -#define VERSION "0.10.19" // sec -#define PACKAGE "gstreamer" -#elif defined(_MM_PROJECT_ADORA) -#define VERSION "0.10.9" // mavell -#define PACKAGE "gstreamer" -#else -#include -#endif - -#include -#include - -#include "gstavsysmemsink.h" - -#define debug_enter g_print -#define debug_leave g_print -#define debug_fenter() g_print("enter: %s\n",__FUNCTION__) -#define debug_fleave() g_print("leave: %s\n",__FUNCTION__) -#define debug_msg g_print -#define debug_verbose g_print -#define debug_warning g_print -#define debug_error g_print - -#define GST_CAT_DEFAULT avsysmemsink_debug - -#define DISABLE_YUV_FORMAT_ON_SINK_CAPS - -GST_DEBUG_CATEGORY_STATIC (avsysmemsink_debug); - -enum -{ - SIGNAL_VIDEO_STREAM, - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ROTATE, -}; - -static GstStaticPadTemplate sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ( -#ifndef DISABLE_YUV_FORMAT_ON_SINK_CAPS - "video/x-raw-yuv, " - "format = (fourcc){YV12}, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " - "video/x-raw-yuv, " - "format = (fourcc){I420}, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " - "video/x-raw-rgb, " - "bpp = (int)32, " - "depth = (int)24; " -#else /* BGRA */ - "video/x-raw-rgb, " - "bpp = (int)32, " - "endianness = (int)4321, " - "red_mask = (int)65280, " - "green_mask = (int)16711680, " - "blue_mask = (int)-16777216, " - "alpha_mask = (int)255, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " - "framerate = (fraction) [ 0, MAX ]; " -#endif - ) - ); - -static GstElementDetails AvsysMemSink_details = { - "AV-system Stream callback", - "Sink/Video", - "Stream sink for AV-System GStreamer Plug-in", - "" -}; - -static guint gst_avsysmemsink_signals[LAST_SIGNAL] = { 0 }; - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#else /* !G_ENABLE_DEBUG */ -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -#define GET_PIXEL(buf, x, y, stride) (*((unsigned char*)(buf) + (x) + (y)*(stride))) - -#define GET_RED(Y,U,V) ((9535 * (Y - 16) + 13074 * (V - 128)) >> 13) -#define GET_GREEN(Y,U,V) ((9535 * (Y - 16) - 6660 * (V - 128) - 3203 * (U - 128)) >> 13 ) -#define GET_BLUE(Y,U,V) ((9535 * (Y - 16) + 16531 * (U - 128)) >> 13 ) - -#define UCLIP(a) (((a)<0)?0:((a)>255)?255:(a)) - - -static void -yuv420toargb(unsigned char *src, unsigned char *dst, int width, int height) -{ - int h,w; - int y=0,u=0,v=0; - int a=0,r=0,g=0,b=0; - - unsigned char* pixel; - - int index=0; - - unsigned char *pY; - unsigned char *pU; - unsigned char *pV; - - GST_DEBUG ("converting yuv420 to argb"); - - pY = src ; - pU = src + (width * height) ; - pV = src + (width * height) + (width * height /4) ; - - a = 255; - - for(h = 0 ; h < height; h++) - { - for(w = 0 ; w < width; w++) - { - y = GET_PIXEL(pY,w,h,width); - u = GET_PIXEL(pU,w/2,h/2,width/2); - v = GET_PIXEL(pV,w/2,h/2,width/2); - - r = GET_RED(y,u,v); - g = GET_GREEN(y,u,v); - b = GET_BLUE(y,u,v); - - r = UCLIP(r); - g = UCLIP(g); - b = UCLIP(b); - - index = (w + (h* width)) * 4; - dst[index] = r; - dst[index+1] = g; - dst[index+2] = b; - dst[index+3] = a; - } - } -} - -static void -rotate_pure(unsigned char *src, unsigned char *dst, int width,int height,int angle,int bpp) -{ - - int size; - int new_x,new_y; - int org_x,org_y; - int dst_width; - int src_idx, dst_idx; - - size = width * height * bpp; - - if(angle == 0) - { - memcpy(dst,src,size); - return; - } - - for(org_y =0; org_y < height; org_y++) - { - for(org_x = 0; org_x < width ; org_x++) - { - if(angle == 90) - { - new_x = height - org_y; - new_y = org_x; - - dst_width = height; - } - else if(angle == 180) - { - new_x = width - org_x; - new_y = height - org_y; - dst_width = width; - } - else if(angle == 270) - { - new_x = org_y; - new_y = width - org_x; - dst_width = height; - } - else - { - g_print("Not support Rotate : %d\n",angle); - return; - } - - src_idx = org_x + (org_y * width); - dst_idx = new_x + (new_y * dst_width); - - memcpy(dst + (dst_idx*bpp), src+(src_idx *bpp),bpp); - } - } - -} - -static void -resize_pure(unsigned char *src, unsigned char *dst, int src_width, int src_height, int dst_width,int dst_height, int bpp) -{ - float xFactor,yFactor; - - float org_fx,org_fy; - int org_x,org_y; - - int x,y; - - int src_index,dst_index; - - unsigned short *pshortSrc; - unsigned short *pshortDst; - - if(bpp == 2) - { - pshortSrc = (unsigned short*)src; - pshortDst = (unsigned short*)dst; - } - - xFactor = (float)((dst_width<<16) / src_width); - yFactor = (float)((dst_height<<16) / src_height); - - for(y = 0; y < dst_height; y++) - { - for(x = 0; x < dst_width; x++) - { - org_fx = (float)((x<<16)/xFactor); - org_fy = (float)((y<<16)/yFactor); - - org_x = (int)(org_fx); - org_y = (int)(org_fy); - - src_index = org_x + (org_y * src_width); - dst_index = x + (y*dst_width); - - memcpy(dst+(dst_index *bpp ),src+(src_index *bpp),bpp); - } - } -} - -/* BOOLEAN:POINTER,INT,INT (avsysvideosink.c:1) */ -void -gst_avsysmemsink_BOOLEAN__POINTER_INT_INT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_INT_INT) (gpointer data1, - gpointer arg_1, - gint arg_2, - gint arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__POINTER_INT_INT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__POINTER_INT_INT) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_int (param_values + 2), - g_marshal_value_peek_int (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -static void gst_avsysmemsink_init_interfaces (GType type); - - -GST_BOILERPLATE_FULL (GstAvsysMemSink, gst_avsysmemsink, GstVideoSink, GST_TYPE_VIDEO_SINK, gst_avsysmemsink_init_interfaces); - - -static void -gst_avsysmemsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (object); - switch (prop_id) { - case PROP_0: - break; - case PROP_WIDTH: - if(AvsysMemSink->dst_width != g_value_get_int (value)) - { - AvsysMemSink->dst_width = g_value_get_int (value); - AvsysMemSink->dst_changed = 1; - } - break; - case PROP_HEIGHT: - if(AvsysMemSink->dst_height != g_value_get_int (value)) - { - AvsysMemSink->dst_height = g_value_get_int (value); - AvsysMemSink->dst_changed = 1; - } - break; - case PROP_ROTATE: - if(AvsysMemSink->rotate != g_value_get_int(value)) - { - AvsysMemSink->rotate = g_value_get_int(value); - AvsysMemSink->dst_changed = 1; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_print ("invalid property id\n"); - break; - }; -} - -static void -gst_avsysmemsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (object); - - switch (prop_id) { - case PROP_0: - break; - case PROP_WIDTH: - g_value_set_int (value, AvsysMemSink->dst_width); - break; - case PROP_HEIGHT: - g_value_set_int (value, AvsysMemSink->dst_height); - break; - case PROP_ROTATE: - g_value_set_int (value, AvsysMemSink->rotate); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - debug_warning ("invalid property id\n"); - break; - } -} - -static void -free_buffer(GstAvsysMemSink *AvsysMemSink) -{ - if(AvsysMemSink->con_buf) - free(AvsysMemSink->con_buf); - - if(AvsysMemSink->rot_buf) - free(AvsysMemSink->rot_buf); - - if(AvsysMemSink->rsz_buf) - free(AvsysMemSink->rsz_buf); - - AvsysMemSink->con_buf = NULL; - AvsysMemSink->rot_buf = NULL; - AvsysMemSink->rsz_buf = NULL; - -} -static GstStateChangeReturn -gst_avsysmemsink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (element); - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - debug_msg ("GST AVSYS DISPLAY SINK: NULL -> READY\n"); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - debug_msg ("GST AVSYS DISPLAY SINK: READY -> PAUSED\n"); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - debug_msg ("GST AVSYS DISPLAY SINK: PAUSED -> PLAYING\n"); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) { - return ret; - } - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - debug_msg ("GST AVSYS MEM SINK: PLAYING -> PAUSED\n"); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - debug_msg ("GST AVSYS MEM SINK: PAUSED -> READY\n"); - free_buffer(AvsysMemSink); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - debug_msg ("GST AVSYS MEM SINK: READY -> NULL\n"); - break; - default: - break; - } - - return ret; - - -} - - -static gboolean -gst_avsysmemsink_set_caps (GstBaseSink * bs, GstCaps * caps) -{ - GstAvsysMemSink *s = GST_AVSYS_MEM_SINK (bs); - GstStructure *structure; - gint width = 0; - gint height = 0; - - if (caps != NULL) - { - guint32 fourcc; - char *name = NULL; - int bpp = 0, depth = 0; - - structure = gst_caps_get_structure (caps, 0); - - /**/ - name = (char *) gst_structure_get_name (structure); - GST_DEBUG_OBJECT (s, "CAPS NAME: %s", name); - - if (gst_structure_has_name (structure, "video/x-raw-rgb")) - { - s->is_rgb = TRUE; - } - else if (gst_structure_has_name (structure, "video/x-raw-yuv")) - { - s->is_rgb = FALSE; - } - - /* get source size */ - gst_structure_get_int (structure, "height", &height); - gst_structure_get_int (structure, "width", &width); - - if (gst_structure_get_fourcc (structure, "format", &fourcc)) - { - switch (fourcc) - { - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - debug_warning("set format AVSYS_VIDEO_FORMAT_UYVY\n"); - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '6'): - case GST_MAKE_FOURCC ('Y', '4', '2', 'B'): - debug_warning("set format AVSYS_VIDEO_FORMAT_YUV422\n"); - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - debug_warning("set format AVSYS_VIDEO_FORMAT_YUV420\n"); - break; - case GST_MAKE_FOURCC ('R', 'G', 'B', ' '): - debug_warning("set format AVSYS_VIDEO_FORMAT_RGB565\n"); - break; - default: - debug_warning("set default format AVSYS_VIDEO_FORMAT_RGB565\n"); - break; - } - } - - if( s->src_width != width || - s->src_height != height) - { - debug_warning ("DISPLAY: Video Source Changed! [%d x %d] -> [%d x %d]\n", - s->src_width, s->src_height, width, height); - s->src_changed = TRUE; - } - - s->src_width = width; - s->src_height = height; - - if(s->dst_width ==0) - { - s->dst_width = width; - s->dst_changed = 1; - } - - if(s->dst_height == 0) - { - s->dst_height = height; - s->dst_changed = 1; - } - debug_msg ("SRC CAPS: width:%d, height:%d \n", width, height); - } - else - { - debug_warning ("caps is NULL.\n"); - } - - debug_fleave (); - - return TRUE; -} - -static GstFlowReturn -gst_avsysmemsink_preroll (GstBaseSink * bsink, GstBuffer * buf) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (bsink); - - AvsysMemSink->src_length = GST_BUFFER_SIZE (buf); - debug_msg ("SRC LENGTH: %d\n", AvsysMemSink->src_length); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_avsysmemsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) -{ - GstAvsysMemSink *s = GST_AVSYS_MEM_SINK (bsink); - gboolean res = FALSE; - int f_size; - f_size = GST_BUFFER_SIZE (buf); - unsigned char *dst_buf; - - if ( ! s->is_rgb ) - { - GST_DEBUG_OBJECT (s, "src format is not rgb"); - if (s->dst_changed == TRUE) - { - if(s->con_buf) - { - free(s->con_buf); - s->con_buf = NULL; - } - - if(s->rot_buf) - { - free(s->rot_buf); - s->rot_buf = NULL; - } - - if(s->rsz_buf) - { - free(s->rsz_buf); - s->rsz_buf = NULL; - } - - s->con_buf = malloc(s->src_width * s->src_height * 4); - if(s->rotate != 0) - { - s->rot_buf = malloc(s->src_width * s->src_height * 4); - } - - s->rsz_buf = malloc(s->dst_width * s->dst_height *4); - - s->dst_changed = FALSE; - } - - yuv420toargb(GST_BUFFER_DATA (buf),s->con_buf,s->src_width, s->src_height); - if(s->rotate != 0) - { - rotate_pure(s->con_buf,s->rot_buf,s->src_width, s->src_height,s->rotate,4); - if(s->rotate == 90 || s->rotate == 270) - { - resize_pure(s->rot_buf,s->rsz_buf,s->src_height,s->src_width, - s->dst_width, s->dst_height,4); - } - else - { - resize_pure(s->rot_buf,s->rsz_buf,s->src_width,s->src_height, - s->dst_width, s->dst_height,4); - } - } - else - { - resize_pure(s->con_buf,s->rsz_buf,s->src_width,s->src_height, - s->dst_width, s->dst_height,4); - } - - /* emit signal for video-stream */ - g_signal_emit (s,gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM], - 0,s->rsz_buf, - s->dst_width,s->dst_height, - &res); - } - else - { - GST_DEBUG_OBJECT (s, "src format is rgb"); - - /* NOTE : video can be resized by convert plugin's set caps on running time. - * So, it should notice it to application through callback func. - */ - g_signal_emit (s, gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM], - 0, GST_BUFFER_DATA (buf), - s->src_width, s->src_height, - &res); - } - GST_DEBUG_OBJECT (s, "g_signal_emit : src_width=%d, src_height=%d, GST_BUFFER_SIZE=%d", s->src_width,s->src_height,GST_BUFFER_SIZE(buf)); - - /*check video stream callback result.*/ - if (res) - { - //debug_verbose("Video stream is called.\n"); - return GST_FLOW_OK; - } - - return GST_FLOW_OK; -} - -static void -gst_avsysmemsink_init_interfaces (GType type) -{ - /*void*/ -} - - -static void -gst_avsysmemsink_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &AvsysMemSink_details); -} - -static void -gst_avsysmemsink_class_init (GstAvsysMemSinkClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - GstElementClass *gstelement_class = (GstElementClass*) klass; - GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass; - - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_avsysmemsink_set_property; - gobject_class->get_property = gst_avsysmemsink_get_property; - - - g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_int ("width", - "Width", - "Width of display", - 0, G_MAXINT, 176, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - g_object_class_install_property (gobject_class, PROP_HEIGHT, - g_param_spec_int ("height", - "Height", - "Height of display", - 0, G_MAXINT, 144, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_ROTATE, - g_param_spec_int ("rotate", - "Rotate", - "Rotate of display", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - /** - * GstAvsysVideoSink::video-stream: - */ - gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM] = g_signal_new ( - "video-stream", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - gst_avsysmemsink_BOOLEAN__POINTER_INT_INT, - G_TYPE_BOOLEAN, - 3, - G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT); - - gstelement_class->change_state = gst_avsysmemsink_change_state; - - gstbasesink_class->set_caps = gst_avsysmemsink_set_caps; - gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_avsysmemsink_preroll); - gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_avsysmemsink_show_frame); - - - GST_DEBUG_CATEGORY_INIT (avsysmemsink_debug, - "avsysmemsink", - 0, - "AV system based GStreamer Plug-in"); -} - - -static void -gst_avsysmemsink_init (GstAvsysMemSink *AvsysMemSink, GstAvsysMemSinkClass *klass) -{ - /*private*/ - AvsysMemSink->src_width = 0; - AvsysMemSink->src_height = 0; - - AvsysMemSink->src_changed = 0; - - /*property*/ - AvsysMemSink->dst_width = 0; - AvsysMemSink->dst_height = 0; - - AvsysMemSink->dst_changed = 0; - - AvsysMemSink->rotate = 0; - - AvsysMemSink->con_buf = NULL; - AvsysMemSink->rot_buf = NULL; - AvsysMemSink->rsz_buf = NULL; - - AvsysMemSink->is_rgb = FALSE; -} - - -/* EOF */ diff --git a/mobile/avsystem/src/gstavsysmemsink.h b/mobile/avsystem/src/gstavsysmemsink.h deleted file mode 100644 index bc28029..0000000 --- a/mobile/avsystem/src/gstavsysmemsink.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef __GST_AVSYSMEMSINK_H__ -#define __GST_AVSYSMEMSINK_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_MEM_SINK (gst_avsysmemsink_get_type()) -#define GST_AVSYS_MEM_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_MEM_SINK, GstAvsysMemSink)) -#define GST_AVSYS_MEM_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_MEM_SINK, GstAvsysMemSinkClass)) -#define GST_IS_AVSYS_MEM_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_MEM_SINK)) -#define GST_IS_AVSYS_MEM_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_MEM_SINK)) - - -typedef struct _GstAvsysMemSink GstAvsysMemSink; -typedef struct _GstAvsysMemSinkClass GstAvsysMemSinkClass; - -struct _GstAvsysMemSink -{ - GstVideoSink videosink; - - int src_width; - int src_height; - - int src_changed; - int src_length; - - - int dst_width; - int dst_height; - - int dst_length; - int dst_changed; - - unsigned char *con_buf; - unsigned char *rot_buf; - unsigned char *rsz_buf; - - int rotate; - - int is_rgb; -}; - -struct _GstAvsysMemSinkClass -{ - GstVideoSinkClass parent_class; -}; - -GType gst_avsysmemsink_get_type (void); - -G_END_DECLS - - -#endif /* __GST_AVSYSMEMSINK_H__ */ - -/* EOF */ diff --git a/mobile/avsystem/src/gstavsyssink.c b/mobile/avsystem/src/gstavsyssink.c deleted file mode 100644 index a1ab29e..0000000 --- a/mobile/avsystem/src/gstavsyssink.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "gstavsysaudiosink.h" -#include "gstavsysmemsink.h" - -GST_DEBUG_CATEGORY (avsystem_sink_debug); - -static gboolean -plugin_init (GstPlugin *plugin) -{ - gboolean error; - /*register the exact name you can find in the framework*/ - error = gst_element_register (plugin, "avsysaudiosink", - GST_RANK_PRIMARY + 100, - GST_TYPE_AVSYS_AUDIO_SINK); - - error = gst_element_register (plugin, "avsysmemsink", - GST_RANK_NONE, - GST_TYPE_AVSYS_MEM_SINK); - - if (!error) - goto failed; - - GST_DEBUG_CATEGORY_INIT (avsystem_sink_debug, "avsystemsink", 0, "avsystem sink plugins"); - return TRUE; - -failed: - - return FALSE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "avsyssink", - "AV system video/audio sink plug-in", - plugin_init, - PACKAGE_VERSION, - "LGPL", - "AV System Sink", - "http://www.samsung.com") diff --git a/mobile/avsystem/src/gstavsyssrc.c b/mobile/avsystem/src/gstavsyssrc.c deleted file mode 100644 index adde8df..0000000 --- a/mobile/avsystem/src/gstavsyssrc.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstavsysaudiosrc.h" - -GST_DEBUG_CATEGORY (avsystem_src_debug); - -static gboolean -plugin_init (GstPlugin *plugin) -{ - gboolean error; - /*register the exact name you can find in the framework*/ - error = gst_element_register (plugin, "avsysaudiosrc", - GST_RANK_NONE, - GST_TYPE_AVSYS_AUDIO_SRC); - if (!error) - goto failed; - - GST_DEBUG_CATEGORY_INIT (avsystem_src_debug, "avsystemsrc", 0, "avsystem src plugins"); - return TRUE; - -failed: - - return FALSE; -} - - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "avsysaudiosrc", - "AV system audio source plug-in", - plugin_init, - PACKAGE_VERSION, - "LGPL", - "AV System Source", - "http://www.samsung.com") - diff --git a/mobile/common/ChangeLog b/mobile/common/ChangeLog deleted file mode 100755 index 72f093a..0000000 --- a/mobile/common/ChangeLog +++ /dev/null @@ -1,1343 +0,0 @@ -2008-03-07 Edward Hervey - - * m4/gtk-doc.m4: (GTK_DOC_CHECK): - The previous commit to this file by Stefan Kost mentionned checking for - SED, but NOT checking for gtkdoc-check (wth is that doing there ??). - Therefore, removing the check for gtkdoc-check - -2008-03-03 David Schleef - - * m4/ax_create_stdint_h.m4: Oops, checked in the wrong copy of - this file. (Update from upstream) - -2008-03-03 David Schleef - - * m4/ax_create_stdint_h.m4: Update from upstream. Fixes a bug - compiling with MSVC. - -2008-03-03 Edward Hervey - - * m4/pkg.m4: - Allow override of pkg-config results, as proposed by configure --help. - This is in fact just a backport from upstream pkg.m4. - Fixes #518892 - -2008-03-03 Peter Kjellerstedt - - * ChangeLog: - Changelog surgery of my previous commit to add bugzilla reference. - * m4/gst-args.m4: - Add AG_GST_CHECK_PLUGIN and AG_GST_DISABLE_PLUGIN to make it easier - to include and exclude plug-ins without external references, i.e., - plug-ins listed in GST_PLUGINS_SELECTED. (#498222) - -2008-03-03 Sebastian Dröge - - * gst.supp: - Add another glibc suppression. - -2008-02-29 Peter Kjellerstedt - - * m4/gst-feature.m4: - Make the comment before defines generated via AG_GST_CHECK_FEATURE - look nicer. (#498222) - -2008-02-26 Jan Schmidt - - * m4/Makefile.am: - * m4/as-gcc-inline-assembly.m4: - Add Dave Schleef's GCC inline assembly detection macro - for using in gst-plugins-good in the goom 2k4 plugin. - -2008-02-25 Andy Wingo - - * gst-autogen.sh: Instead of only passing certain arguments to - configure, pass anything that we didn't handle. Much friendlier. - Fixes #34412. - -2008-02-23 Jan Schmidt - - * m4/gst-error.m4: - Store the detected compiler flags into ERROR_CFLAGS rather than - ERROR_CXXFLAGS, and use the macro that checks the C compiler, not - the C++ one. - -2008-02-23 Tim-Philipp Müller - - * m4/gst-error.m4: - Reflow checks for additional warning flags so they're not - nested, which fixes the result reporting in the configure - output. - -2008-02-22 Tim-Philipp Müller - - * m4/as-compiler-flag.m4: - Add AS_CXX_COMPILER_FLAG - - * m4/gst-error.m4: - Add AG_GST_SET_ERROR_CXXFLAGS (Forte bits need testing) - -2008-02-22 Tim-Philipp Müller - - * gtk-doc-plugins.mak: - Add 'check-inspected-versions' target; this helps identify - files that should have been removed or where the version - number should (ideally) be updated before a release - (which doesn't happen automatically if the releaser doesn't - build that plugin locally). Not adding at a distcheck hook - yet though, because it's not really that important and would - probably also be a problem on buildbots. - -2008-02-22 Sebastian Dröge - - * gst.supp: - Add even more glibc 2.7 suppressions. - -2008-02-22 Sebastian Dröge - - * gst.supp: - Add another suppression for GLib caching some values after - the first call. - -2008-02-12 Sebastian Dröge - - Patch by: - Tim Mooney - - * m4/gst-error.m4: - Use no%E_MACRO_REDEFINED on Solaris to prevent compiler warnings. - Fixes bug #515905. - -2008-02-11 Sebastian Dröge - - * gst.supp: - Add a few more glibc 2.7 suppressions to make the avisubtitle unit - test valgrind clean. Fixes bug #515703. - -2008-02-08 Stefan Kost - - * ChangeLog: - Changelog surgery for last commit. - -2008-02-08 Stefan Kost - - * m4/gtk-doc.m4: - Conditionally check for SED. Also sync a bit with upstream macro. - -2008-02-08 Stefan Kost - - * gtk-doc-plugins.mak: - * gtk-doc.mak: - Use '$(SED)' instead of 'sed'. Don't use -i for in-place as its gnu - only, move to a temp file instead. - -2008-02-06 Stefan Kost - - * gtk-doc-plugins.mak: - * gtk-doc.mak: - As our docs are versioned, we need to patch the index.sgml file to have - correct paths there, unless we also want to fork gtk-doc's xsl (which - we don't). This hopefully fixes xrefs between modules. - -2008-02-02 Sebastian Dröge - - * m4/gst-feature.m4: - Use printf instead of echo as "echo -e" isn't POSIX and doesn't work - with strict POSIX shells like tcsh or dash and also not every platform - has a /bin/echo that supports it. - -2008-01-24 Stefan Kost - - * ChangeLog: - ChangeLog surgery. - - * gstdoc-scangobj: - Sync the object scanner with gtk-doc fixes. Update args and hierarchy - files. - -2008-01-20 Sebastian Dröge - - * check.mak: - * coverage/lcov.mak: - * gtk-doc-plugins.mak: - * release.mak: - Use $(MAKE) instead of make to fix the build if GNU make is called - something else on the system. - - * m4/as-docbook.m4: - Fix path for docbook.xsl if we have no /etc/xml/catalog and add a - docbook-xsl search path for FreeBSD. - -2008-01-18 Sebastian Dröge - - * gst.supp: - Add a suppression for a glibc bug: - http://valgrind.org/docs/manual/faq.html#faq.exit_errors> - -2008-01-18 Sebastian Dröge - - * gst.supp: - Add some more glibc 2.7 suppressions and make the GLib suppressions - for the home/tmp/etc directory caching a bit more generic. - -2008-01-18 Sebastian Dröge - - * gst.supp: - Add some glibc 2.7 supressions as found on Debian/unstable. - -2008-01-14 Jan Schmidt - - * download-translations: - Apparently I have problems with leaving things commented out when - I edit shell scripts. - -2008-01-12 Jan Schmidt - - * download-translations: - Remove bash-isms - -2008-01-12 Jan Schmidt - - * check-exports: - Restore the cleanup rm of our tmp file which I didn't mean to leave - commented out. - -2008-01-12 Jan Schmidt - - * check-exports: - Fixes to make check-export work on both Solaris and Linux - - * m4/gst-error.m4: - Disable extra warning category (argument mismatch) as an error - on Forte, as it prevents the libcheck fail_if macros from compiling. - - * win32.mak: - Substitute the GStreamer version so things will keep working in 0.11 - -2008-01-11 Tim-Philipp Müller - - Patch by: Peter Kjellerstedt - - * m4/gst-glib2.m4: - * m4/gst-libxml2.m4: - Improve/fix output from configure if either glib-2.0 or - libxml2 are not installed (#498222). - -2008-01-09 Stefan Kost - - * coverage/lcov.mak: - Update coverage make-rules: use them conditionaly, use libtool mode - and use lcov to cleanup. - -2007-12-18 Sebastian Dröge - - * glib-gen.mak: - Also use #include "header" instead of #include
for the - headers that were used to generate the source files for the same - reason as below. - - Remove whitespace before #include. - -2007-12-18 Sebastian Dröge - - * glib-gen.mak: - Use #include "header" instead of #include
for the generated - enum C files as the file will always be in the same directory and - some compilers seem to be a bit strict about that unless . is added - to the include path. - - Include all headers that were used to generate the source files in - the C file as they're used there. - -2007-12-17 Tim-Philipp Müller - - * win32.mak: (win32), (win32defs), (win32crlf): - Make check for CR LF in Visual C++ 6.0 project files - work, based on patch by David Schleef (#496722, #393626). - -2007-12-17 Tim-Philipp Müller - - * Makefile.am: - Don't forget to dist the new win32.mak. - -2007-12-17 Tim-Philipp Müller - - * win32.mak: (win32), (win32defs): - Move common win32 Makefile foo into this new file. - -2007-12-15 Stefan Kost - - * gtk-doc-plugins.mak: - * gtk-doc.mak: - We should have never forked this that much :/. - -2007-12-13 Tim-Philipp Müller - - * check-exports: - Fix build on the ppc64 build bot. - -2007-12-13 Tim-Philipp Müller - - * check-exports: - Suppress more unintentional exports (too much hassle to rename them, - since the win32 project files would need changing too). - -2007-12-12 Tim-Philipp Müller - - * Makefile.am: - check-exports should be disted. - -2007-12-12 Tim-Philipp Müller - - * check-exports: - Add quick'n'dirty script to check the exported symbols of a library - against the symbols in the corresponding .def file (#493983). Based - on script by Ole André Vadla Ravnås. - -2007-11-06 Jan Schmidt - - * gtk-doc-plugins.mak: - Fix distcheck by making sure the types files are treated like the - other gtkdoc-scangobj generated files. - -2007-09-21 Sebastian Dröge - - * m4/gst-args.m4: - Let the AG_GST_ARG_ENABLE_EXPERIMENTAL macro default to disable - building of experimental plugins. Nobody uses it yet and the - --enable--experimental stuff from gst-plugins-good defaults to - disable too. - -2007-09-06 Tim-Philipp Müller - - * gtk-doc-plugins.mak: - Just use the normal 'check' target and avoid a circular - dependency. - -2007-09-06 Tim-Philipp Müller - - * gtk-doc-plugins.mak: - Add rule to error out if .hierarchy file contains tabs. - -2007-08-20 Tim-Philipp Müller - - * download-translations: - * po.mak: - If there are new languages, they need to be added to po/LINGUAS. - -2007-08-20 Tim-Philipp Müller - - * download-translations: - * po.mak: - Fix up 'download-po' a bit, so that we find new translations - for languages that aren't in our po/LINGUAS file yet too. - -2007-07-16 Jan Schmidt - - * gst.supp: - Add a suppression for GLib caching the tmp dir seen on an - Ubuntu Feisty system. - -2007-07-13 Jan Schmidt - - * m4/gst-feature.m4: - If we want to use 'echo -e', call /bin/echo instead of the shell's - since -e is a bash extension, and our /bin/sh might not be being - provided by bash. - -2007-07-01 Thomas Vander Stichele - - * po.mak: - Translation project has moved. Also, no idea how this used to - work given that we weren't downloading a .po file. - -2007-06-25 Stefan Kost - - * gst-xmlinspect.py: - * plugins.xsl: - Also extract element caps for plugin-docs. Fixes parts of #117692. - -2007-06-21 Tim-Philipp Müller - - Patch by: Andreas Schwab - - * m4/gst-feature.m4: - Fix quoting (#449493). - -2007-06-10 Sebastian Dröge - - * m4/gst-parser.m4: - Only generate the parser if bison >= 1.875 _and_ flex >= 2.5.31 is - installed and use pre-generated sources otherwise. Fixes bug #444820. - -2007-05-11 Michael Smith - - * gst.supp: - Suppression variant for our good friend the TLS leak, this time for - Ubuntu Feisty/x86. - -2007-05-09 Tim-Philipp Müller - - * gtk-doc-plugins.mak: - Fix make distcheck again; change some spaces to tabs in makefile. - -2007-04-29 Thomas Vander Stichele - - * gtk-doc-plugins.mak (-module): - Error out when the html build step gives warnings, so they get - fixed properly. - -2007-04-23 Stefan Kost - - * m4/gst-feature.m4: - Add macro AG_GST_PARSE_SUBSYSTEM_DISABLES that checks the defines in - the configuration header and AC_DEFINES the setings. - -2007-04-19 Sebastian Dröge - - Patch by: Vincent Torri - - * m4/gst-parser.m4: - Put the AC_MSG_RESULT output in brackets to get it properly written to - the terminal. - -2007-04-18 Sebastian Dröge - - * m4/gst-parser.m4: - Check for flex >= 2.5.31 and set GENERATE_PARSER if we have at least - that version. Otherwise use pre-generated parser sources as we can't - raise the required flex version. HAVE_MT_SAVE_FLEX is obsolete now - as we use a new enough flex version anyway. First part of #349180 - -2007-04-10 Thomas Vander Stichele - - * m4/gst-check.m4: - Allow pre-setting the GST(PB)_TOOLS/PLUGINS_DIR variables to help - builds against older GStreamer. - -2007-03-25 Sebastian Dröge - - * m4/gst-parser.m4: - Fix the flex version check. It ignored the micro version before. - -2007-03-09 Jan Schmidt - - * check.mak: - Use the same timeout when generating valgrind suppressions as - running the valgrind test. - - * gst.supp: - Add some more suppressions and stuff. - -2007-03-08 Jan Schmidt - - * check.mak: - Make sure GSlice is disabled when building suppressions too. - - * gst.supp: - Add around *850* lines of suppressions for one-time initialisations - inside libasound and gconf/bonobo/ORBit. I feel so dirty. - -2007-03-07 Jan Schmidt - - * gst.supp: - add a suppression for this GConf flup on the FC5 buildbot. - -2007-03-06 Jan Schmidt - - * gst.supp: - Make the suppression a little more generic, to catch the FC5 - backtrace too. - -2007-03-06 Jan Schmidt - - * gst.supp: - Add a suppression for libcdio 0.76. It leaks an internal struct - when the CD-ROM device is not accessible. - -2007-02-28 Thomas Vander Stichele - - * m4/gst-arch.m4: - Move a line that was in the wrong macro - -2007-02-28 Thomas Vander Stichele - - * m4/gst.m4: - Add - * m4/gst-arch.m4: - * m4/gst-args.m4: - * m4/gst-check.m4: - * m4/gst-debuginfo.m4: - * m4/gst-default.m4: - * m4/gst-doc.m4: - * m4/gst-error.m4: - * m4/gst-feature.m4: - * m4/gst-function.m4: - * m4/gst-gettext.m4: - * m4/gst-glib2.m4: - * m4/gst-libxml2.m4: - * m4/gst-parser.m4: - * m4/gst-plugin-docs.m4: - * m4/gst-plugindir.m4: - * m4/gst-valgrind.m4: - * m4/gst-x11.m4: - Convert all macros to use AG_GST style so we can properly warn - when they're missing if configure.ac calls AG_GST_INIT - Will require update in all GStreamer modules. - -2007-02-11 Stefan Kost - - * m4/gst-args.m4: - Remove 'enable' from configure switch description as this leads to - confusing lines like "disable enable builing ...". - * m4/gst-feature.m4: - Fix comment to sound less horrible. - -2007-02-07 Tim-Philipp Müller - - Patch by: Will Newton - - * m4/gst-check.m4: - Use $PKG_CONFIG rather than pkg-config directly, the one in our path - might not be the one we want, like when cross-compiling. Also, other - macros such as PKG_CHECK_MODULES use $PKG_CONFIG, so we should - probably too just for consistency. Fixes #405288. - -2007-01-08 Tim-Philipp Müller - - * m4/gst-parser.m4: - Need to use double square brackets again so m4 doesn't remove them - (fixes #378931). - - * m4/gst-args.m4: - Use double square brackets here as well, for the same reason. - -2007-01-05 Tim-Philipp Müller - - * m4/gst-parser.m4: - Use 'sed' rather than 'tr' to strip trailing letters from version - numbers, since 'tr' might not be available and we know sed is - (#378931). - -2006-10-21 Tim-Philipp Müller - - * check.mak: - Increase default timeout under valgrind, 60 is just too short and - some tests take a bit longer these days and not everyone has a - beefy machine. - -2006-09-29 Michael Smith - - * gst.supp: - More suppressions for edgy. - -2006-09-28 Jan Schmidt - - * m4/gst-glib2.m4: - Use gmodule-no-export-2.0.pc instead of gmodule-2.0.pc - we neither - want nor need --export-dynamic (which ends up making us export a bunch - of unneeded symbols) - -2006-09-14 Tim-Philipp Müller - - * gst.supp: - Some suppressions for the more recent ld.so in ubuntu edgy. - -2006-08-23 Tim-Philipp Müller - - * gst.supp: - Shorten function trail so the suppression works on - my ubuntu dapper system with core cvs as well. - -2006-07-28 Jan Schmidt - - * gst.supp: - Extra suppressions from my Ubuntu x86_64 machine - -2006-07-24 Tim-Philipp Müller - - Patch by: Frederic Peters - - * m4/gst-parser.m4: - Need to double square brackets in .m4 files. Should fix bison - version detection with version numbers like 1.23a (#348354). - -2006-07-24 Jan Schmidt - - * check.mak: - Valgrind fails to find tests written in tests/check/ directly (rather - than a subdir) - because valgrind gets run with a filename that - doesn't contain a relative path, it goes searching /usr/bin instead. - Run with ./.... to make things work either way. - - * gtk-doc-plugins.mak: - Add $(top_builddir)/src as a place to look for plugins - when building too, since that's where gst-template keeps things - -2006-07-23 Stefan Kost - - Patch by: Frederic Peters - - * m4/gst-parser.m4: - Fix bison detection (#348354) - -2006-07-21 Stefan Kost - - * m4/gst-parser.m4: - check for bison and flex - -2006-07-13 Thomas Vander Stichele - - * m4/gst-plugin-docs.m4: - remove the configure argument for enabling plugin doc build; - having gtk-doc enabled and pyxml present is enough of a trigger - -2006-07-03 Thomas Vander Stichele - - * coverage/lcov.mak: - fix up rules to work with gst-python as well - run "make lcov" to test and generate the reports - run "make lcov-reset" to redo it after that - -2006-07-02 Thomas Vander Stichele - - * Makefile.am: - * check.mak: - add an inspect target that inspects every element feature, - so we can have that added for coverage - * coverage/lcov.mak: - add support for lcov - -2006-07-02 Thomas Vander Stichele - - * m4/gst-args.m4: - when building with gcov, reset CFLAGS and friends to O0 - -2006-07-02 Thomas Vander Stichele - - * m4/gst-args.m4: - Find the gcov that matches the gcc version - Only allow gcov if we use gcc - -2006-07-02 Thomas Vander Stichele - - * Makefile.am: - * coverage/coverage-report-entry.pl: - * coverage/coverage-report.pl: - * coverage/coverage-report.xsl: - copy coverage reporting files from dbus - -2006-07-01 Thomas Vander Stichele - - * m4/gst-args.m4: - libtool strips gcov's -f flags, so libgcov does not get - linked in. Setting GCOV_LIBS with -lgcov fixes libtool's - stripping - also show what pkg-config-path we set - -2006-06-22 Tim-Philipp Müller - - Patch by: Peter Kjellerstedt - - * m4/gst-feature.m4: - Show list of plugins without external dependencies that - will not be built as well (#344136). - -2006-06-15 Tim-Philipp Müller - - * m4/gst-plugin-docs.m4: - add GST_PLUGIN_DOCS, which checks for everything needed - to build the plugin docs (namely gtk-doc and pyxml); also - adds a new --enable-plugin-docs configure switch; will - set ENABLE_PLUGIN_DOCS conditional for use in Makefile.am - files (see #344039). - -2006-06-11 Thomas Vander Stichele - - * m4/gst-check.m4: - add GST_PKG_CHECK_MODULES, which in the normal case of checking - for a dependency lib for a plug-in only needs two arguments - to do the right thing. - * m4/gst-feature.m4: - clean up output a little of feature checking; also deal with - non-plug-in feature checks - * m4/Makefile.am: - * m4/gst-gstreamer.m4: - remove this file; it's a useless check - -2006-06-06 Thomas Vander Stichele - - * m4/gst-arch.m4: - add PPC64 so we can have separate structure sizes for it - -2006-06-05 Edward Hervey - - * gtk-doc.mak: - Check for the proper .devhelp2 file to remove. - -2006-05-31 Thomas Vander Stichele - - * gtk-doc.mak: - allow a magic variable to suppress errors from docbuilding - -2006-05-30 Thomas Vander Stichele - - * gtk-doc.mak: - error out if gtkdoc-mktmpl finds unused declarations - -2006-05-28 Edward Hervey - - * gst.supp: - Reverting previous commit. That's good to know, Edward, but why ? - -2006-05-28 Edward Hervey - - * gst.supp: - Added suppresion for memleak in g_option_context_parse on fc5-64 - -2006-05-19 Thomas Vander Stichele - - * m4/gst-check.m4: - set GSTPB_PLUGINS_DIR just like GST_PLUGINS_DIR - -2006-05-18 Tim-Philipp Müller - - * check.mak: - Fix 'make help' in check directories, it should be - 'valgrind.gen-suppressions' not 'valgrind-gen-suppressions' - (not changing target to match help string on purpose to keep - scripts etc. functional). - -2006-05-18 Thomas Vander Stichele - - Patch by: Peter Kjellerstedt - - * m4/gst-arch.m4: - add support for CRIS and CRISv32. - -2006-05-17 Jan Schmidt - - * m4/gst-args.m4: - Fix the macros for command-line supplied package and origin names - so they don't end up being configure as "" (Fixes #341479) - -2006-05-14 Jan Schmidt - - * gtk-doc.mak: - Add uninstall rule to remove .devhelp2 files. - -2006-05-09 Edward Hervey - - * gst.supp: - Add suppression for GSlice version of - g_type_init calloc leak - -2006-04-05 Michael Smith - - * gst.supp: - Delete a bogus suppression for the registry code. - Generalise a suppression for a glib bug (see #337404) - -2006-04-04 Michael Smith - - * gst.supp: - Add a leak suppression: the existing glibc-doesn't-free-TLS one - wasn't triggering here. - -2006-04-04 Michael Smith - - * gst.supp: - Add some minimally-neccesary suppressions for my x86/dapper system. - -2006-04-01 Thomas Vander Stichele - - * plugins.xsl: - Do not display an origin link if origin does not start with http - See #323798 - -2006-04-01 Thomas Vander Stichele - - * m4/gst-args.m4: - * m4/gst-feature.m4: - add more macros - * m4/gst-x11.m4: - X11-related checks - -2006-04-01 Thomas Vander Stichele - - * m4/as-version.m4: - newer version - * m4/gst-args.m4: - * m4/gst-doc.m4: - update and add other macros to be shared across projects - -2006-03-24 Thomas Vander Stichele - - * gst.supp: - add a suppression for g_parse_debug_string - -2006-03-23 Stefan Kost - - * gstdoc-scangobj: - sync fully with gtkdoc-0.15 - -2006-03-23 Stefan Kost - - * gstdoc-scangobj: - * gtk-doc.mak: - sync a little with gtk-doc mainline - -2006-03-17 Wim Taymans - - * gst.supp: - add another clone suppression - change all glibc suppressions to match 2.3.* - -2006-03-09 Thomas Vander Stichele - - * m4/check.m4: - fix test so it actually works when the normal check is used - over debian's/ubuntu's - -2006-03-08 Jan Schmidt - - * check.mak: - Set G_SLICE=always-malloc when valgrinding tests - (closes #333272) - -2006-02-21 Jan Schmidt - - * m4/gst-glib2.m4: - Fix debug output when the GLib version prerequisite is not found - -2006-02-13 Andy Wingo - - * m4/check.m4: Hack around Debian/Ubuntu's broken installation of - the PIC version of check as libcheck_pic.a. Should work with - cross-compilation too. Grr. - -2006-02-06 Thomas Vander Stichele - - * m4/gst-default.m4: - switch to auto* sinks for defaults - -2006-02-02 Wim Taymans - - * check.mak: - add a .valgrind.gen-suppressions target to aid in generating - suppressions - * gst.supp: - add more repressions from my debian glibc as of today - -2006-02-02 Thomas Vander Stichele - - * gtk-doc-plugins.mak: - only add srcdir/gst if it exists - -2006-01-30 Thomas Vander Stichele - - * release.mak: - don't complain about disted enums in win32 - -2006-01-20 Thomas Vander Stichele - - * m4/gst-check.m4: - AC_SUBST CFLAGS and LIBS - do a non-command because something is stripping out our AC_SUBST - -2006-01-20 Thomas Vander Stichele - - * m4/gst-args.m4: - * m4/gst-valgrind.m4: - properly give a "no" result manually when providing a - not-found action to fix configure output - -2006-01-20 Thomas Vander Stichele - - * m4/pkg.m4: - update with a more recent version - -2006-01-07 Thomas Vander Stichele - - * gettext.patch: - make Makefile depend on LINGUAS, so rebuilds work when adding - a language - -2006-01-03 Michael Smith - - * check.mak: - Clarify error message from valgrind test runs. - -2005-12-16 Thomas Vander Stichele - - * m4/gst-arch.m4: - define HOST_CPU - -2005-11-29 Thomas Vander Stichele - - * check.mak: - add a valgrind-forever target for tests - -2005-11-28 Thomas Vander Stichele - - * check.mak: - when a "make test.check" run fails, make it rerun the test with - at least debug level 2 - -2005-11-14 Thomas Vander Stichele - - * m4/Makefile.am: - * m4/gst-check.m4: - fix check for base plugins - * m4/gst-default.m4: - add m4 to set default elements - -2005-10-18 Thomas Vander Stichele - - * m4/gst-check.m4: - check for tools correctly - -2005-10-18 Thomas Vander Stichele - - * gtk-doc.mak: - only enable breaking on new API when make distcheck passes, - not before - -2005-10-18 Thomas Vander Stichele - - * m4/gst-check.m4: - Resurrect Julien's dead body and wipe his mind clean - -2005-10-18 Thomas Vander Stichele - - * m4/gst-check.m4: - Kill Julien - -2005-10-17 Julien MOUTTE - - * m4/gst-check.m4: I know Thomas will kill me but this - ifelse statement seems incorrect as it is always setting - required to "yes". With this one it seems to work. Fixes - build of gst-plugins-base on my setup where gstreamer-check - is definitely not present/required. - -2005-10-18 Stefan Kost - - * gtk-doc.mak: - make build break on new api that has not been added to the - sections file - -2005-10-17 Thomas Vander Stichele - - * m4/gst-glib2.m4: - * m4/Makefile.am: - * m4/gst-check.m4: - add macro for easy checks for GStreamer libs - -2005-10-16 Thomas Vander Stichele - - * m4/gst-glib2.m4: - update, warn in error cases - -2005-10-16 Thomas Vander Stichele - - * m4/gst-error.m4: - add GST_SET_DEFAULT_LEVEL - -2005-10-16 Thomas Vander Stichele - - * m4/Makefile.am: - * m4/gst-gettext.m4: - remove the AM_GNU_GETTEXT* calls, they need to be in configure.ac - * m4/gst-glib2.m4: - clean up and re-use in core soon - * m4/gst-plugindir.m4: - macro to set up PLUGINDIR and plugindir define/var - -2005-10-15 Thomas Vander Stichele - - * m4/Makefile.am: - * m4/gst-gettext.m4: - add macro for setting up gettext - -2005-10-15 Thomas Vander Stichele - - * m4/gst-args.m4: - add some .m4's for argument checking that can be shared among modules - -2005-10-15 Thomas Vander Stichele - - * m4/as-libtool.m4: - set _LT_LDFLAGS - * m4/gst-libxml2.m4: - document - -2005-10-15 Thomas Vander Stichele - - * m4/gst-arch.m4: - indent a little - add AC_REQUIRE - * m4/gst-error.m4: - clean up - -2005-10-12 Thomas Vander Stichele - - * gst-autogen.sh: - update version detection expression to catch stuff like - Libtool (libtool15) 1.5.0 - -2005-10-11 Thomas Vander Stichele - - * gst.supp: - commit 6 new suppressions related to g_module_open; can these - really not be folded into one ? - -2005-10-11 Edward Hervey - - * gst.supp: - made the suppression more generic - Added pthread memleak suppresions - Added nss_parse_* memleak suppresion (used by g_option_context_parse) - -2005-10-11 Thomas Vander Stichele - - * check.mak: - be more strict, more leak resolution - * gst.supp: - clean up the g_type_init suppressions - -2005-10-07 Thomas Vander Stichele - - * m4/Makefile.am: - * m4/gst-valgrind.m4: - put the valgrind detection in an .m4 - -2005-09-29 Thomas Vander Stichele - - * check.mak: - add some more targets, like "help", but also more intensive tests - -2005-09-23 Thomas Vander Stichele - - * gtk-doc.mak: - make certain doc warnings fatal so people maintain docs again - -2005-09-23 Thomas Vander Stichele - - * Makefile.am: - * gtk-doc-plugins.mak: - * scangobj-merge.py: - merge additions from the .signals.new and .args.new file in - the original ones, only updating if necessary - -2005-09-23 Thomas Vander Stichele - - * gst-xmlinspect.py: - * gstdoc-scangobj: - * gtk-doc-plugins.mak: - fix properly for new API; make update in plugins dir now works - -2005-09-20 Thomas Vander Stichele - - * gst-xmlinspect.py: - * gstdoc-scangobj: - some fixes for new API - * gtk-doc-plugins.mak: - set environment properly - -2005-09-17 David Schleef - - * gtk-doc-plugins.mak: Use new environment variables. - -2005-09-16 Michael Smith - - * gstdoc-scangobj: - Make the scanobj code reflect registry/plugin API changes - -2005-09-15 Thomas Vander Stichele - - * gtk-doc-plugins.mak: - split out scanobj step (which will be run by doc maintainer) - from scan step (which will be run on every build) - clean up some of the commands for make distcheck - -2005-09-15 Thomas Vander Stichele - - * gtk-doc-plugins.mak: - * mangle-tmpl.py: - first stab at reorganizing the plugins build so we can maintain - element docs - -2005-09-14 David Schleef - - * as-libtool.mak: Remove - * m4/as-libtool.m4: The libtool bug that this worked around has - been fixed. - * m4/as-version.m4: Don't define GST_RELEASE, since it causes - config.h to be regenerated needlessly, and we don't use it. - -2005-09-14 Thomas Vander Stichele - - * gtk-doc-plugins.mak: - error out on inspect failure - -2005-09-14 Michael Smith - - * glib-gen.mak: - Don't call glib-mkenums with arguments that confuse/break MinGW, - fixes 316155. - -2005-09-03 Thomas Vander Stichele - - * gtk-doc-plugins.mak: - * gtk-doc.mak: - * m4/gst-doc.m4: - separate out gtk-doc and docbook stuff - have two separate --enable configure flags - -2005-08-26 Thomas Vander Stichele - - * check.mak: - add a .gdb target; rebuild registry for each target, otherwise - a code rebuild always triggers a reg rebuild, and it's just too - annoying - * gstdoc-scangobj: - -2005-08-21 Thomas Vander Stichele - - * check.mak: - separate out REGISTRY_ENVIRONMENT; we want to use that from - our valgrind runs, but we also want TESTS_ENVIRONMENT to contain - everything that the first test, gst-register, needs - -2005-08-21 Thomas Vander Stichele - - * check.mak: - parse output of valgrind and check for definitely lost, and error - out; somehow I was led to believe valgrind returns non-zero for - leaks, but I can't make it do that, so let's parse - -2005-08-20 Thomas Vander Stichele - - * check.mak: - for some weird reason valgrind does not report actual memleaks - if GST_PLUGIN_PATH is set to anything but the core gstreamer dir - while valgrind is running. Since the registry is going to go - anyway, I don't want to waste any more time on this; I just run - valgrind without GST_PLUGIN_PATH set. Since the registry loading - doesn't check if GST_PLUGIN_PATH got changed as a reason to rebuild - the registry, that's actually fine. - -2005-08-15 Thomas Vander Stichele - - * mangle-tmpl.py: - keep original Long_Description; only insert an include if it's - not already the first line in there - * plugins.xsl: - output more information for plugins, including an origin hyperlink - -2005-08-15 Thomas Vander Stichele - - * gst-xmlinspect.py: - a first stab at inspecting plugins and outputting an xml description - * gtk-doc-plugins.mak: - a gtk-doc using snippet for plugins documentation - * plugins.xsl: - a stylesheet to convert gst-xmlinspect.py output to docbook output - for inclusion in the gtk-doc stuff - -2005-07-20 Ronald S. Bultje - - * m4/gst-doc.m4: - s/pdf/eps/ in test for whether we output EPS images (#309379). - -2005-07-18 Andy Wingo - - * m4/as-libtool-tags.m4: Ooh, backported from libtool 1.6. Much - better. Thanks, Paolo Bonzini! - - * m4/Makefile.am (EXTRA_DIST): - * m4/as-libtool-tags.m4: New file, tries to disable some CXX and - fortran checks. - -2005-07-08 Thomas Vander Stichele - - * m4/gst-error.m4: - add macro to set ERROR_CFLAGS - -2005-06-30 Jan Schmidt - - * gst-autogen.sh: - Remove the old autoregen.sh if it exists before recreating it, - to prevent confusing any shell process that might be reading it - currently. - -2005-06-29 Thomas Vander Stichele - - * m4/gtk-doc.m4: - added - -2005-06-03 Stefan Kost - - * gst-autogen.sh: create autoregen.sh *before* shifting the options - -2005-05-17 Thomas Vander Stichele - - * gst-autogen.sh: only update autoregen.sh on actual runs - -2005-03-11 Thomas Vander Stichele - - * m4/check.m4: m4 from the check unit test suite - -2004-12-14 David Schleef - - * m4/gst-arch.m4: remove MMX stuff, since it doesn't work and - isn't needed anywhere - -2004-12-08 Thomas Vander Stichele - - * gst-autogen.sh: - allow failure command to be run so we can clean upfrom autopoint - -2004-09-03 Zeeshan Ali Khattak - * m4/gst-feature.m4: Trying to correct the GST_CHECK_CONFIGPROG macro - -2004-07-21 Benjamin Otte - - * m4/.cvsignore: exciting updates for libtool m4 files - -2004-07-12 David Schleef - - * m4/as-objc.m4: Add a macro to test for objective C - -2004-06-12 Thomas Vander Stichele - - * m4/gst-feature.m4: - not all of them support --plugin-libs, so redirect stderr - -2004-06-12 Thomas Vander Stichele - - * m4/as-scrub-include.m4: - sync with upstream to 0.1.4. Fixes #132440 - -2004-06-07 Benjamin Otte - - * m4/gst-feature.m4: - write a big marker into configure output when checking next plugin - to allow easier parsing of why plugins are(n't) built. - -2004-06-01 Thomas Vander Stichele - - * m4/as-compiler-flag.m4: - * m4/as-compiler.m4: - * m4/as-libtool.m4: - * m4/as-version.m4: - sync with upstream, change sticky options to -ko - -2004-05-24 Thomas Vander Stichele - - * m4/as-scrub-include.m4: synced with upstream - -2004-05-03 Thomas Vander Stichele - - * po.mak: - snippet for updating .po files - -2004-03-18 Thomas Vander Stichele - - * Makefile.am: - * m4/Makefile.am: - integrate these with the dist - -2004-03-17 Thomas Vander Stichele - - * release.mak: add a release target - -2004-03-09 Thomas Vander Stichele - - patch by: Stephane Loeuillet - - * m4/ax_create_stdint_h.m4: - use head -n instead of head - (#136500) - -2004-03-05 Thomas Vander Stichele - - * m4/gst-doc.m4: don't build PS without dvips binary - -2004-02-22 Julio M. Merino Vidal - - reviewed by: Benjamin Otte - - * m4/as-docbook.m4: - don't use == operator with test(1) (fixes #135115) - -2004-02-16 Thomas Vander Stichele - - * common/m4/gst-arch.m4: x86_64 is x86 too (clue from Fedora 2 test) - -2004-02-13 Thomas Vander Stichele - - * m4/gst-feature.m4: - remove AM_CONDITIONAL for the subsystem since automake 1.6.x - requires that call be in configure.ac - -2004-02-13 Thomas Vander Stichele - - * m4/gst-libxml2.m4: - take required version as argument, and default to 2.4.9 if not - specified - -2004-02-12 Thomas Vander Stichele - - * m4/gst-feature.m4: - rename and fix up GST_CHECK_DISABLE_SUBSYSTEM - -2004-02-11 Thomas Vander Stichele - - * common/m4/as-ac-expand.m4: - * common/m4/as-auto-alt.m4: - * common/m4/as-compiler-flag.m4: - * common/m4/as-compiler.m4: - * common/m4/as-docbook.m4: - * common/m4/as-libtool.m4: - * common/m4/as-scrub-include.m4: - * common/m4/as-version.m4: - * common/m4/glib-gettext.m4: - * common/m4/gst-arch.m4: - * common/m4/gst-debuginfo.m4: - * common/m4/gst-doc.m4: - * common/m4/gst-feature.m4: - * common/m4/gst-function.m4: - * common/m4/gst-glib2.m4: - * common/m4/gst-gstreamer.m4: - * common/m4/gst-libxml2.m4: - * common/m4/gst-makecontext.m4: - * common/m4/gst-mcsc.m4: - * common/m4/pkg.m4: - fix underquoted macros as reported by automake 1.8.x (#133800) - -2004-02-11 Johan Dahlin - - * gst-autogen.sh: Use A-Z instead of A-z in sed expression to - avoid a warning - -2004-02-05 Thomas Vander Stichele - - * m4/gst-doc.m4: - we use --output-format=xml and --ingnore-files options to - gtkdoc-mkdb, which got added between 0.9 and 1.0 - -2004-02-04 Thomas Vander Stichele - - * m4/as-libtool.m4: remove AM_PROG_LIBTOOL so it can move back - to configure.ac to shut up libtoolize - -2004-02-03 Thomas Vander Stichele - - * glib-gen.mak: added; used to generate enums and marshal code - -2004-01-13 Thomas Vander Stichele - - * gettext.patch: added; used by autogen.sh to make sure - GETTEXT_PACKAGE is understood from po/Makefile.in.in -> po/Makefile.in - diff --git a/mobile/common/Makefile.am b/mobile/common/Makefile.am deleted file mode 100644 index cac4ff5..0000000 --- a/mobile/common/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -SUBDIRS = m4 - -EXTRA_DIST = \ - ChangeLog \ - gettext.patch \ - glib-gen.mak gtk-doc.mak upload.mak release.mak win32.mak \ - gst-autogen.sh \ - check-exports \ - c-to-xml.py gst-xmlinspect.py mangle-tmpl.py scangobj-merge.py \ - gtk-doc-plugins.mak \ - plugins.xsl gstdoc-scangobj \ - gst.supp check.mak \ - coverage/lcov.mak \ - coverage/coverage-report.pl \ - coverage/coverage-report.xsl \ - coverage/coverage-report-entry.pl diff --git a/mobile/common/c-to-xml.py b/mobile/common/c-to-xml.py deleted file mode 100755 index 8448fd2..0000000 --- a/mobile/common/c-to-xml.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- Mode: Python -*- -# vi:si:et:sw=4:sts=4:ts=4 - -""" -Convert a C program to valid XML to be included in docbook -""" - -import sys -import os -from xml.sax import saxutils - -def main(): - if len(sys.argv) == 1: - sys.stderr.write("Please specify a source file to convert") - sys.exit(1) - source = sys.argv[1] - - if not os.path.exists(source): - sys.stderr.write("%s does not exist.\n" % source) - sys.exit(1) - - content = open(source, "r").read() - - # print header - print '' - print '' - print - print '' - - # print content - print saxutils.escape(content).encode('UTF-8') - print '' - -main() diff --git a/mobile/common/check-exports b/mobile/common/check-exports deleted file mode 100755 index 16df41f..0000000 --- a/mobile/common/check-exports +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# check-exports -# -# quick'n'dirty script that retrieves the list of exported symbols of a given -# library using 'nm', and compares that against the list of symbols-to-export -# of our win32/common/libfoo.def files. - -if [ $# -ne 2 ]; then - echo "Usage: $0 library.def library.so" - exit 1 -fi - -def_path="$1" -def_name="$(basename $def_path)" -lib_path="$2" - -lib_result="`mktemp /tmp/defname.XXXXXX`" - -LC_ALL=C -export LC_ALL - -# On Solaris, add -p to get the correct output format -NMARGS= -if nm -V 2>&1 |grep Solaris > /dev/null; then - NMARGS=-p -fi - -# FIXME 0.11: in 0.11, we should change the export filter to only export -# _gst_foo, but not __gst_foo (we can't change this now, since we added -# __gst_debug_min and __gst_debug_enabled at some point and need to keep -# ABI compatibility). So below we special-case some symbols that shouldn't -# really be exported, either because we're too lazy to rename them to something -# that's not exported (like the _gst_parse_* stuff) or because we had them in -# public headers at some point although they shouldn't be and so we need to -# keep them exported now (like _gst_debug_init, -# __gst_element_factory_add_interface or -# __gst_element_factory_add_static_pad_template). We suppress them here to -# make sure they're at least not exported in the windows msvc build (they -# were never in the .def file, so they never got exported). -# _end is special cased because for some reason it is reported as an exported -# BSS symbol, unlike on linux where it's a local absolute symbol. -nm $NMARGS $lib_path | awk \ - '{ - if ($3 !~ /^_gst_parse_yy/ && \ - $3 !~ /^_gst_[a-z]*_init/ && \ - $3 !~ /^_gst_parse_launch/ && \ - $3 !~ /^__gst_element_details_/ && \ - $3 !~ /^__gst_element_factory_add_/ && \ - $3 !~ /^gst_interfaces_marshal/ && \ - $3 ~ /^[_]*(gst_|Gst|GST_).*/) - { - if ($2 ~ /^[BSDG]$/) - print "\t" $3 " DATA" - else if ($2 == "T") - print "\t" $3 - } - }' | sort | awk '{ if (NR == 1) print "EXPORTS"; print $0; }' \ - > $lib_result - -diffoutput=`diff -u $def_path $lib_result` - -rm $lib_result - -if test "x$diffoutput" = "x"; then - exit 0; -else - echo -n "$diffoutput" >&2 - echo >&2 - exit 1; -fi - diff --git a/mobile/common/check.mak b/mobile/common/check.mak deleted file mode 100755 index d31569f..0000000 --- a/mobile/common/check.mak +++ /dev/null @@ -1,149 +0,0 @@ -clean-local-check: - for i in `find . -name ".libs" -type d`; do \ - rm -rf $$i; \ - done - -if HAVE_VALGRIND -# hangs spectacularly on some machines, so let's not do this by default yet -check-valgrind: - $(MAKE) valgrind -else -check-valgrind: - @true -endif - -LOOPS = 10 - -# run any given test by running make test.check -# if the test fails, run it again at at least debug level 2 -%.check: % - @$(TESTS_ENVIRONMENT) \ - CK_DEFAULT_TIMEOUT=20 \ - $* || \ - $(TESTS_ENVIRONMENT) \ - GST_DEBUG=$$GST_DEBUG,*:2 \ - CK_DEFAULT_TIMEOUT=20 \ - $* - -# run any given test in a loop -%.torture: % - @for i in `seq 1 $(LOOPS)`; do \ - $(TESTS_ENVIRONMENT) \ - CK_DEFAULT_TIMEOUT=20 \ - $*; done - -# run any given test in an infinite loop -%.forever: % - @while true; do \ - $(TESTS_ENVIRONMENT) \ - CK_DEFAULT_TIMEOUT=20 \ - $* || break; done - -# valgrind any given test by running make test.valgrind -%.valgrind: % - $(TESTS_ENVIRONMENT) \ - CK_DEFAULT_TIMEOUT=360 \ - G_SLICE=always-malloc \ - libtool --mode=execute \ - $(VALGRIND_PATH) -q \ - $(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \ - --tool=memcheck --leak-check=full --trace-children=yes \ - --leak-resolution=high --num-callers=20 \ - ./$* 2>&1 | tee valgrind.log - @if grep "==" valgrind.log > /dev/null 2>&1; then \ - rm valgrind.log; \ - exit 1; \ - fi - @rm valgrind.log - -# valgrind any given test and generate suppressions for it -%.valgrind.gen-suppressions: % - $(TESTS_ENVIRONMENT) \ - CK_DEFAULT_TIMEOUT=360 \ - G_SLICE=always-malloc \ - libtool --mode=execute \ - $(VALGRIND_PATH) -q \ - $(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \ - --tool=memcheck --leak-check=full --trace-children=yes \ - --leak-resolution=high --num-callers=20 \ - --gen-suppressions=all \ - ./$* 2>&1 | tee suppressions.log - -# valgrind any given test until failure by running make test.valgrind-forever -%.valgrind-forever: % - @while $(MAKE) $*.valgrind; do \ - true; done - -# gdb any given test by running make test.gdb -%.gdb: % - $(TESTS_ENVIRONMENT) \ - CK_FORK=no \ - libtool --mode=execute \ - gdb $* - -# torture tests -torture: $(TESTS) - -rm test-registry.xml - @echo "Torturing tests ..." - for i in `seq 1 $(LOOPS)`; do \ - $(MAKE) check || \ - (echo "Failure after $$i runs"; exit 1) || \ - exit 1; \ - done - @banner="All $(LOOPS) loops passed"; \ - dashes=`echo "$$banner" | sed s/./=/g`; \ - echo $$dashes; echo $$banner; echo $$dashes - -# forever tests -forever: $(TESTS) - -rm test-registry.xml - @echo "Forever tests ..." - while true; do \ - $(MAKE) check || \ - (echo "Failure"; exit 1) || \ - exit 1; \ - done - -# valgrind all tests -valgrind: $(TESTS) - @echo "Valgrinding tests ..." - @failed=0; \ - for t in $(filter-out $(VALGRIND_TESTS_DISABLE),$(TESTS)); do \ - $(MAKE) $$t.valgrind; \ - if test "$$?" -ne 0; then \ - echo "Valgrind error for test $$t"; \ - failed=`expr $$failed + 1`; \ - whicht="$$whicht $$t"; \ - fi; \ - done; \ - if test "$$failed" -ne 0; then \ - echo "$$failed tests had leaks or errors under valgrind:"; \ - echo "$$whicht"; \ - false; \ - fi - -# inspect every plugin feature -GST_INSPECT = $(GST_TOOLS_DIR)/gst-inspect-$(GST_MAJORMINOR) -inspect: - @echo "Inspecting features ..." - for e in `$(TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 \ - | cut -d: -f2`; \ - do echo Inspecting $$e; \ - $(GST_INSPECT) $$e > /dev/null 2>&1; done - -help: - @echo "make check -- run all checks" - @echo "make torture -- run all checks $(LOOPS) times" - @echo "make (dir)/(test).check -- run the given check once" - @echo "make (dir)/(test).forever -- run the given check forever" - @echo "make (dir)/(test).torture -- run the given check $(LOOPS) times" - @echo - @echo "make (dir)/(test).gdb -- start up gdb for the given test" - @echo - @echo "make valgrind -- valgrind all tests" - @echo "make (dir)/(test).valgrind -- valgrind the given test" - @echo "make (dir)/(test).valgrind-forever -- valgrind the given test forever" - @echo "make (dir)/(test).valgrind.gen-suppressions -- generate suppressions" - @echo " and save to suppressions.log" - @echo "make inspect -- inspect all plugin features" - diff --git a/mobile/common/coverage/coverage-report-entry.pl b/mobile/common/coverage/coverage-report-entry.pl deleted file mode 100755 index 8f653af..0000000 --- a/mobile/common/coverage/coverage-report-entry.pl +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (C) 2006 Daniel Berrange -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -print < - -Coverage report for $ARGV[0] - - - -

Coverage report for $ARGV[0]

- -
-EOF
-
-
-while (<>) {
-    s/&/&/g;
-    s//>/g;
-
-    if (/^\s*function (\S+) called (\d+) returned \d+% blocks executed \d+%/) {
-	my $class = $2 > 0 ? "perfect" : "terrible";
-	$_ = "$_";
-    } elsif (/^\s*branch\s+\d+\s+taken\s+(\d+)%\s+.*$/) {
-	my $class = $1 > 0 ? "perfect" : "terrible";
-	$_ = "$_";
-    } elsif (/^\s*branch\s+\d+\s+never executed.*$/) {
-	my $class = "terrible";
-	$_ = "$_";
-    } elsif (/^\s*call\s+\d+\s+never executed.*$/) {
-	my $class = "terrible";
-	$_ = "$_";
-    } elsif (/^\s*call\s+\d+\s+returned\s+(\d+)%.*$/) {
-	my $class = $1 > 0 ? "perfect" : "terrible";
-	$_ = "$_";
-    }
-    
-
-    print;
-}
-
-print <
-
-
-EOF
diff --git a/mobile/common/coverage/coverage-report.pl b/mobile/common/coverage/coverage-report.pl
deleted file mode 100755
index 046bc37..0000000
--- a/mobile/common/coverage/coverage-report.pl
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright (C) 2006 Daniel Berrange
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-use warnings;
-use strict;
-
-my %coverage = ( functions => {}, files => {} );
-
-my %filemap;
-
-my $type;
-my $name;
-
-my @functions;
-
-while (<>) {
-    if (/^Function '(.*)'\s*$/) {
-	$type = "function";
-	$name = $1;
-	$coverage{$type}->{$name} = {};
-	push @functions, $name;
-    } elsif (/^File '(.*?)'\s*$/) {
-	$type = "file";
-	$name = $1;
-	$coverage{$type}->{$name} = {};
-	
-	foreach my $func (@functions) {
-	    $coverage{"function"}->{$func}->{file} = $name;
-	}
-	@functions = ();
-    } elsif (/^Lines executed:(.*)%\s*of\s*(\d+)\s*$/) {
-	$coverage{$type}->{$name}->{lines} = $2;
-	$coverage{$type}->{$name}->{linesCoverage} = $1;
-    } elsif (/^Branches executed:(.*)%\s*of\s*(\d+)\s*$/) {
-	$coverage{$type}->{$name}->{branches} = $2;
-	$coverage{$type}->{$name}->{branchesCoverage} = $1;
-    } elsif (/^Taken at least once:(.*)%\s*of\s*(\d+)\s*$/) {
-	$coverage{$type}->{$name}->{conds} = $2;
-	$coverage{$type}->{$name}->{condsCoverage} = $1;
-    } elsif (/^Calls executed:(.*)%\s*of\s*(\d+)\s*$/) {
-	$coverage{$type}->{$name}->{calls} = $2;
-	$coverage{$type}->{$name}->{callsCoverage} = $1;
-    } elsif (/^No branches$/) {
-	$coverage{$type}->{$name}->{branches} = 0;
-	$coverage{$type}->{$name}->{branchesCoverage} = "100.00";
-	$coverage{$type}->{$name}->{conds} = 0;
-	$coverage{$type}->{$name}->{condsCoverage} = "100.00";
-    } elsif (/^No calls$/) {
-	$coverage{$type}->{$name}->{calls} = 0;
-	$coverage{$type}->{$name}->{callsCoverage} = "100.00";
-    } elsif (/^\s*(.*):creating '(.*)'\s*$/) {
-	$filemap{$1} = $2;
-    } elsif (/^\s*$/) {
-	# nada
-    } else {
-	warn "Shit [$_]\n";
-    }
-}
-
-my %summary;
-foreach my $type ("function", "file") {
-    $summary{$type} = {};
-    foreach my $m ("lines", "branches", "conds", "calls") {
-	my $totalGot = 0;
-	my $totalMiss = 0;
-	my $count = 0;
-	foreach my $func (keys %{$coverage{function}}) {
-	    $count++;
-	    my $got = $coverage{function}->{$func}->{$m};
-	    $totalGot += $got;
-	    my $miss = $got * $coverage{function}->{$func}->{$m ."Coverage"} / 100;
-	    $totalMiss += $miss;
-	}
-	$summary{$type}->{$m} = sprintf("%d", $totalGot);
-	$summary{$type}->{$m . "Coverage"} = sprintf("%.2f", $totalMiss / $totalGot * 100);
-    }
-}
-
-
-
-print "\n";
-
-foreach my $type ("function", "file") {
-    printf "<%ss>\n", $type;
-    foreach my $name (sort { $a cmp $b } keys %{$coverage{$type}}) {
-	my $rec = $coverage{$type}->{$name};
-	printf "  \n", $name, ($type eq "file" ? $filemap{$name} : $filemap{$rec->{file}});
-	printf "    \n", $rec->{lines}, $rec->{linesCoverage};
-	if (exists $rec->{branches}) {
-	    printf "    \n", $rec->{branches}, $rec->{branchesCoverage};
-	}
-	if (exists $rec->{conds}) {
-	    printf "    \n", $rec->{conds}, $rec->{condsCoverage};
-	}
-	if (exists $rec->{calls}) {
-	    printf "    \n", $rec->{calls}, $rec->{callsCoverage};
-	}
-	print  "  \n";
-    }
-    
-    printf "  \n";
-    printf "    \n", $summary{$type}->{lines}, $summary{$type}->{linesCoverage};
-    printf "    \n", $summary{$type}->{branches}, $summary{$type}->{branchesCoverage};
-    printf "    \n", $summary{$type}->{conds}, $summary{$type}->{condsCoverage};
-    printf "    \n", $summary{$type}->{calls}, $summary{$type}->{callsCoverage};
-    printf  "  \n";
-    printf "\n", $type;
-}
-
-print "\n";
diff --git a/mobile/common/coverage/coverage-report.xsl b/mobile/common/coverage/coverage-report.xsl
deleted file mode 100755
index b19ebb6..0000000
--- a/mobile/common/coverage/coverage-report.xsl
+++ /dev/null
@@ -1,235 +0,0 @@
-
-
-
-
-  
-
-  
-    
-      
-        Coverage report
-        
-      
-      
-        

Coverage report

- - - -
- - -

Function coverage

- - - -
- - - -

File coverage

- - - -
- - - - - - - - - - - - - - - - - - - - - odd - - - even - - - - - - - - - - - - - - odd - - - even - - - - - - -
NameLinesBranchesConditionsCalls
-
- - - - - - - - - - - - - - Summary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - perfect - - - excellant - - - good - - - poor - - - bad - - - terrible - - - - - % of - - -
diff --git a/mobile/common/coverage/lcov.mak b/mobile/common/coverage/lcov.mak deleted file mode 100755 index 0ca9456..0000000 --- a/mobile/common/coverage/lcov.mak +++ /dev/null @@ -1,42 +0,0 @@ -## .PHONY so it always rebuilds it -.PHONY: lcov-reset lcov lcov-run lcov-report lcov-upload - -# run lcov from scratch, always -lcov-reset: - $(MAKE) lcov-run - $(MAKE) lcov-report - -# run lcov from scratch if the dir is not there -lcov: - $(MAKE) lcov-reset - -if GST_GCOV_ENABLED -# reset run coverage tests -lcov-run: - @-rm -rf lcov - lcov --directory . --zerocounters - -if test -d tests/check; then $(MAKE) -C tests/check inspect; fi - -$(MAKE) check - -# generate report based on current coverage data -lcov-report: - mkdir lcov - lcov --compat-libtool --directory . --capture --output-file lcov/lcov.info - lcov -l lcov/lcov.info | grep -v "`cd $(top_srcdir) && pwd`" | cut -d: -f1 > lcov/remove - lcov -l lcov/lcov.info | grep "tests/check/" | cut -d: -f1 >> lcov/remove - lcov -r lcov/lcov.info `cat lcov/remove` > lcov/lcov.cleaned.info - rm lcov/remove - mv lcov/lcov.cleaned.info lcov/lcov.info - genhtml -t "$(PACKAGE_STRING)" -o lcov --num-spaces 2 lcov/lcov.info - -lcov-upload: lcov - rsync -rvz -e ssh --delete lcov/* gstreamer.freedesktop.org:/srv/gstreamer.freedesktop.org/www/data/coverage/lcov/$(PACKAGE) - -else -lcov-run: - echo "Need to reconfigure with --enable-gcov" - -lcov-report: - echo "Need to reconfigure with --enable-gcov" -endif - diff --git a/mobile/common/gettext.patch b/mobile/common/gettext.patch deleted file mode 100755 index 659718e..0000000 --- a/mobile/common/gettext.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- po/Makefile.in.in.orig 2006-01-07 12:03:45.000000000 +0100 -+++ po/Makefile.in.in 2006-01-07 12:04:23.000000000 +0100 -@@ -11,6 +11,9 @@ - PACKAGE = @PACKAGE@ - VERSION = @VERSION@ - -+# thomas: add GETTEXT_PACKAGE substitution as used in Makevars -+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -+ - SHELL = /bin/sh - @SET_MAKE@ - -@@ -305,7 +308,9 @@ - update-gmo: Makefile $(GMOFILES) - @: - --Makefile: Makefile.in.in $(top_builddir)/config.status POTFILES.in -+# thomas: add LINGUAS as a dependency so that the Makefile gets rebuilt -+# properly when we add languages -+Makefile: Makefile.in.in $(top_builddir)/config.status POTFILES.in LINGUAS - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ - $(SHELL) ./config.status diff --git a/mobile/common/glib-gen.mak b/mobile/common/glib-gen.mak deleted file mode 100755 index f9027da..0000000 --- a/mobile/common/glib-gen.mak +++ /dev/null @@ -1,44 +0,0 @@ -# these are the variables your Makefile.am should set -# the example is based on the colorbalance interface - -#glib_enum_headers=$(colorbalance_headers) -#glib_enum_define=GST_COLOR_BALANCE -#glib_enum_prefix=gst_color_balance - -enum_headers=$(foreach h,$(glib_enum_headers),\n\#include \"$(h)\") - -# these are all the rules generating the relevant files -%-marshal.h: %-marshal.list - glib-genmarshal --header --prefix=$(glib_enum_prefix)_marshal $^ > $*-marshal.h.tmp - mv $*-marshal.h.tmp $*-marshal.h - -%-marshal.c: %-marshal.list - echo "#include \"$*-marshal.h\"" >> $*-marshal.c.tmp - glib-genmarshal --body --prefix=$(glib_enum_prefix)_marshal $^ >> $*-marshal.c.tmp - mv $*-marshal.c.tmp $*-marshal.c - -%-enumtypes.h: $(glib_enum_headers) - glib-mkenums \ - --fhead "#ifndef __$(glib_enum_define)_ENUM_TYPES_H__\n#define __$(glib_enum_define)_ENUM_TYPES_H__\n\n#include \n\nG_BEGIN_DECLS\n" \ - --fprod "\n/* enumerations from \"@filename@\" */\n" \ - --vhead "GType @enum_name@_get_type (void);\n#define GST_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ - --ftail "G_END_DECLS\n\n#endif /* __$(glib_enum_define)_ENUM_TYPES_H__ */" \ - $^ > $@ - -%-enumtypes.c: $(glib_enum_headers) - @if test "x$(glib_enum_headers)" == "x"; then echo "ERROR: glib_enum_headers is empty, please fix Makefile"; exit 1; fi - glib-mkenums \ - --fhead "#include \"$*-enumtypes.h\"\n$(enum_headers)" \ - --fprod "\n/* enumerations from \"@filename@\" */" \ - --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ - --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ - --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ - $^ > $@ - -# a hack rule to make sure .Plo files exist because they get include'd -# from Makefile's -.deps/%-marshal.Plo: - touch $@ - -.deps/%-enumtypes.Plo: - touch $@ diff --git a/mobile/common/gst-autogen.sh b/mobile/common/gst-autogen.sh deleted file mode 100755 index ae60f7e..0000000 --- a/mobile/common/gst-autogen.sh +++ /dev/null @@ -1,294 +0,0 @@ -# a silly hack that generates autoregen.sh but it's handy -# Remove the old autoregen.sh first to create a new file, -# as the current one may be being read by the shell executing -# this script. -if [ -f "autoregen.sh" ]; then - rm autoregen.sh -fi -echo "#!/bin/sh" > autoregen.sh -echo "./autogen.sh $@ \$@" >> autoregen.sh -chmod +x autoregen.sh - -# helper functions for autogen.sh - -debug () -# print out a debug message if DEBUG is a defined variable -{ - if test ! -z "$DEBUG" - then - echo "DEBUG: $1" - fi -} - -version_check () -# check the version of a package -# first argument : package name (executable) -# second argument : optional path where to look for it instead -# third argument : source download url -# rest of arguments : major, minor, micro version -# all consecutive ones : suggestions for binaries to use -# (if not specified in second argument) -{ - PACKAGE=$1 - PKG_PATH=$2 - URL=$3 - MAJOR=$4 - MINOR=$5 - MICRO=$6 - - # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null - if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi - debug "major $MAJOR minor $MINOR micro $MICRO" - VERSION=$MAJOR - if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi - if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi - - debug "major $MAJOR minor $MINOR micro $MICRO" - - for SUGGESTION in $PKG_PATH; do - COMMAND="$SUGGESTION" - - # don't check if asked not to - test -z "$NOCHECK" && { - echo -n " checking for $COMMAND >= $VERSION ... " - } || { - # we set a var with the same name as the package, but stripped of - # unwanted chars - VAR=`echo $PACKAGE | sed 's/-//g'` - debug "setting $VAR" - eval $VAR="$COMMAND" - return 0 - } - - debug "checking version with $COMMAND" - ($COMMAND --version) < /dev/null > /dev/null 2>&1 || - { - echo "not found." - continue - } - # strip everything that's not a digit, then use cut to get the first field - pkg_version=`$COMMAND --version|head -n 1|sed 's/^.*)[^0-9]*//'|cut -d' ' -f1` - debug "pkg_version $pkg_version" - # remove any non-digit characters from the version numbers to permit numeric - # comparison - pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g` - pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g` - pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g` - test -z "$pkg_major" && pkg_major=0 - test -z "$pkg_minor" && pkg_minor=0 - test -z "$pkg_micro" && pkg_micro=0 - debug "found major $pkg_major minor $pkg_minor micro $pkg_micro" - - #start checking the version - debug "version check" - - # reset check - WRONG= - - if [ ! "$pkg_major" -gt "$MAJOR" ]; then - debug "major: $pkg_major <= $MAJOR" - if [ "$pkg_major" -lt "$MAJOR" ]; then - debug "major: $pkg_major < $MAJOR" - WRONG=1 - elif [ ! "$pkg_minor" -gt "$MINOR" ]; then - debug "minor: $pkg_minor <= $MINOR" - if [ "$pkg_minor" -lt "$MINOR" ]; then - debug "minor: $pkg_minor < $MINOR" - WRONG=1 - elif [ "$pkg_micro" -lt "$MICRO" ]; then - debug "micro: $pkg_micro < $MICRO" - WRONG=1 - fi - fi - fi - - if test ! -z "$WRONG"; then - echo "found $pkg_version, not ok !" - continue - else - echo "found $pkg_version, ok." - # we set a var with the same name as the package, but stripped of - # unwanted chars - VAR=`echo $PACKAGE | sed 's/-//g'` - debug "setting $VAR" - eval $VAR="$COMMAND" - return 0 - fi - done - - echo "not found !" - echo "You must have $PACKAGE installed to compile $package." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at $URL" - return 1; -} - -aclocal_check () -{ - # normally aclocal is part of automake - # so we expect it to be in the same place as automake - # so if a different automake is supplied, we need to adapt as well - # so how's about replacing automake with aclocal in the set var, - # and saving that in $aclocal ? - # note, this will fail if the actual automake isn't called automake* - # or if part of the path before it contains it - if [ -z "$automake" ]; then - echo "Error: no automake variable set !" - return 1 - else - aclocal=`echo $automake | sed s/automake/aclocal/` - debug "aclocal: $aclocal" - if [ "$aclocal" != "aclocal" ]; - then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal" - fi - if [ ! -x `which $aclocal` ]; then - echo "Error: cannot execute $aclocal !" - return 1 - fi - fi -} - -autoheader_check () -{ - # same here - autoheader is part of autoconf - # use the same voodoo - if [ -z "$autoconf" ]; then - echo "Error: no autoconf variable set !" - return 1 - else - autoheader=`echo $autoconf | sed s/autoconf/autoheader/` - debug "autoheader: $autoheader" - if [ "$autoheader" != "autoheader" ]; - then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader" - fi - if [ ! -x `which $autoheader` ]; then - echo "Error: cannot execute $autoheader !" - return 1 - fi - fi - -} -autoconf_2_52d_check () -{ - # autoconf 2.52d has a weird issue involving a yes:no error - # so don't allow it's use - test -z "$NOCHECK" && { - ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'` - if test "$ac_version" = "2.52d"; then - echo "autoconf 2.52d has an issue with our current build." - echo "We don't know who's to blame however. So until we do, get a" - echo "regular version. RPM's of a working version are on the gstreamer site." - exit 1 - fi - } - return 0 -} - -die_check () -{ - # call with $DIE - # if set to 1, we need to print something helpful then die - DIE=$1 - if test "x$DIE" = "x1"; - then - echo - echo "- Please get the right tools before proceeding." - echo "- Alternatively, if you're sure we're wrong, run with --nocheck." - exit 1 - fi -} - -autogen_options () -{ - if test "x$1" = "x"; then - return 0 - fi - - while test "x$1" != "x" ; do - optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - case "$1" in - --noconfigure) - NOCONFIGURE=defined - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure" - echo "+ configure run disabled" - shift - ;; - --nocheck) - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck" - NOCHECK=defined - echo "+ autotools version check disabled" - shift - ;; - --debug) - DEBUG=defined - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug" - echo "+ debug output enabled" - shift - ;; - -h|--help) - echo "autogen.sh (autogen options) -- (configure options)" - echo "autogen.sh help options: " - echo " --noconfigure don't run the configure script" - echo " --nocheck don't do version checks" - echo " --debug debug the autogen process" - echo - echo " --with-autoconf PATH use autoconf in PATH" - echo " --with-automake PATH use automake in PATH" - echo - echo "Any argument either not in the above list or after a '--' will be " - echo "passed to ./configure." - exit 1 - ;; - --with-automake=*) - AUTOMAKE=$optarg - echo "+ using alternate automake in $optarg" - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE" - shift - ;; - --with-autoconf=*) - AUTOCONF=$optarg - echo "+ using alternate autoconf in $optarg" - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF" - shift - ;; - --) shift ; break ;; - *) - echo "+ passing argument $1 to configure" - CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1" - shift - ;; - esac - done - - for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done - if test ! -z "$CONFIGURE_EXT_OPT" - then - echo "+ options passed to configure: $CONFIGURE_EXT_OPT" - fi -} - -toplevel_check () -{ - srcfile=$1 - test -f $srcfile || { - echo "You must run this script in the top-level $package directory" - exit 1 - } -} - - -tool_run () -{ - tool=$1 - options=$2 - run_if_fail=$3 - echo "+ running $tool $options..." - $tool $options || { - echo - echo $tool failed - eval $run_if_fail - exit 1 - } -} diff --git a/mobile/common/gst-xmlinspect.py b/mobile/common/gst-xmlinspect.py deleted file mode 100755 index 0d7f696..0000000 --- a/mobile/common/gst-xmlinspect.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- Mode: Python -*- -# vi:si:et:sw=4:sts=4:ts=4 - -""" -examine all plugins and elements and output xml documentation for them -used as part of the plugin documentation build -""" - -import sys -import os -import pygst -pygst.require('0.10') -import gst - -INDENT_SIZE = 2 - -# all templates - -PAD_TEMPLATE = """ - %(name)s - %(direction)s - %(presence)s -
%(details)s
-
""" - -ELEMENT_TEMPLATE = """ - %(name)s - %(longname)s - %(class)s - %(description)s - %(author)s - -%(pads)s - -""" - -PLUGIN_TEMPLATE = """ - %(name)s - %(description)s - %(filename)s - %(basename)s - %(version)s - %(license)s - %(source)s - %(package)s - %(origin)s - -%(elements)s - -""" - -def xmlencode(line): - """ - Replace &, <, and > - """ - line = "&".join(line.split("&")) - line = "<".join(line.split("<")) - line = ">".join(line.split(">")) - return line - -def get_offset(indent): - return " " * INDENT_SIZE * indent - -def output_pad_template(pt, indent=0): - print "PAD TEMPLATE", pt.name_template - paddir = ("unknown","source","sink") - padpres = ("always","sometimes","request") - - d = { - 'name': xmlencode(pt.name_template), - 'direction': xmlencode(paddir[pt.direction]), - 'presence': xmlencode(padpres[pt.presence]), - 'details': xmlencode(pt.static_caps.string), - } - block = PAD_TEMPLATE % d - - offset = get_offset(indent) - return offset + ("\n" + offset).join(block.split("\n")) - -def output_element_factory(elf, indent=0): - print "ELEMENT", elf.get_name() - - padsoutput = [] - padtemplates = elf.get_static_pad_templates() - for padtemplate in padtemplates: - padsoutput.append(output_pad_template(padtemplate, indent)) - - d = { - 'name': xmlencode(elf.get_name()), - 'longname': xmlencode(elf.get_longname()), - 'class': xmlencode(elf.get_klass()), - 'description': xmlencode(elf.get_description()), - 'author': xmlencode(elf.get_author()), - 'pads': "\n".join(padsoutput), - } - block = ELEMENT_TEMPLATE % d - - offset = get_offset(indent) - return offset + ("\n" + offset).join(block.split("\n")) - -def output_plugin(plugin, indent=0): - print "PLUGIN", plugin.get_name() - version = plugin.get_version() - - elements = {} - gst.debug('getting features for plugin %s' % plugin.get_name()) - registry = gst.registry_get_default() - features = registry.get_feature_list_by_plugin(plugin.get_name()) - gst.debug('plugin %s has %d features' % (plugin.get_name(), len(features))) - for feature in features: - if isinstance(feature, gst.ElementFactory): - elements[feature.get_name()] = feature - #gst.debug("got features") - - elementsoutput = [] - keys = elements.keys() - keys.sort() - for name in keys: - feature = elements[name] - elementsoutput.append(output_element_factory(feature, indent + 2)) - - filename = plugin.get_filename() - basename = filename - if basename: - basename = os.path.basename(basename) - d = { - 'name': xmlencode(plugin.get_name()), - 'description': xmlencode(plugin.get_description()), - 'filename': filename, - 'basename': basename, - 'version': version, - 'license': xmlencode(plugin.get_license()), - 'source': xmlencode(plugin.get_source()), - 'package': xmlencode(plugin.get_package()), - 'origin': xmlencode(plugin.get_origin()), - 'elements': "\n".join(elementsoutput), - } - block = PLUGIN_TEMPLATE % d - - offset = get_offset(indent) - return offset + ("\n" + offset).join(block.split("\n")) - -def main(): - if len(sys.argv) == 1: - sys.stderr.write("Please specify a source module to inspect") - sys.exit(1) - source = sys.argv[1] - - if len(sys.argv) > 2: - os.chdir(sys.argv[2]) - - registry = gst.registry_get_default() - all = registry.get_plugin_list() - for plugin in all: - gst.debug("inspecting plugin %s from source %s" % ( - plugin.get_name(), plugin.get_source())) - # this skips gstcoreelements, with bin and pipeline - if plugin.get_filename() is None: - continue - if plugin.get_source() != source: - continue - - filename = "plugin-%s.xml" % plugin.get_name() - handle = open(filename, "w") - handle.write(output_plugin(plugin)) - handle.close() - -main() diff --git a/mobile/common/gst.supp b/mobile/common/gst.supp deleted file mode 100755 index 9b2a3a2..0000000 --- a/mobile/common/gst.supp +++ /dev/null @@ -1,1988 +0,0 @@ -### this file contains suppressions for valgrind when running -### the gstreamer unit tests -### it might be useful for wider use as well - -### syscall suppressions - -{ - - Memcheck:Param - clone(parent_tidptr) - fun:clone - fun:clone -} - -{ - - Memcheck:Param - clone(child_tidptr) - fun:clone - fun:clone -} - -{ - - Memcheck:Param - clone(tlsinfo) - fun:clone - fun:clone -} - -### glibc suppressions - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file -} - -# glibc does not deallocate thread-local storage - -{ - - Memcheck:Leak - fun:calloc - fun:_dl_allocate_tls - fun:pthread_create@@* -} - -# I get an extra stack entry on x86/dapper -{ - - Memcheck:Leak - fun:calloc - obj:/lib/ld-2.3.*.so - fun:_dl_allocate_tls - fun:pthread_create@@* -} - - -{ - - Memcheck:Cond - fun:strstr - fun:__pthread_initialize_minimal - obj:/lib/libpthread-*.so - obj:/lib/libpthread-*.so - fun:call_init - fun:_dl_init - obj:/lib/ld-*.so -} - -# a thread-related free problem in glibc from Edgard -{ - __libc_freeres_rw_acess - Memcheck:Addr4 - obj:* - obj:* - obj:* - obj:* - obj:* - fun:__libc_freeres -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so -} - -# g_module_open-related problems -{ - - Memcheck:Addr2 - fun:memcpy - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file - fun:gst_registry_scan_path_level - fun:gst_registry_scan_path_level - fun:gst_registry_scan_path_level - fun:init_post - fun:g_option_context_parse - fun:gst_init_check - fun:gst_init - fun:gst_check_init - fun:main -} - -{ - - Memcheck:Addr4 - fun:memcpy - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file - fun:gst_registry_scan_path_level - fun:gst_registry_scan_path_level - fun:gst_registry_scan_path_level - fun:init_post - fun:g_option_context_parse - fun:gst_init_check - fun:gst_init - fun:gst_check_init - fun:main -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:do_sym - fun:_dl_sym - fun:dlsym_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlsym - fun:g_module_symbol - fun:g_module_open - fun:gst_plugin_load_file -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file -} -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file - fun:gst_plugin_load_by_name - fun:gst_plugin_feature_load -} - -{ - - Memcheck:Leak - fun:malloc - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open - fun:gst_plugin_load_file - fun:gst_plugin_load_by_name -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:dl_open_worker - obj:/lib/ld-2.3.*.so - fun:_dl_open - fun:dlopen_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:do_sym - fun:_dl_sym - fun:dlsym_doit - obj:/lib/ld-2.3.*.so - fun:_dlerror_run - fun:dlsym - fun:g_module_symbol - fun:g_module_open -} - -{ - - Memcheck:Param - futex(uaddr2) - fun:pthread_once - obj:/lib/libc-2.3.*.so - obj:/lib/libc-2.3.*.so - fun:mbsnrtowcs - fun:vfprintf - fun:vsprintf - fun:sprintf - obj:/lib/libc-2.3.*.so - fun:tmpfile - fun:setup_pipe - fun:setup_messaging_with_key - fun:setup_messaging -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - fun:_dl_sym - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlsym - fun:g_module_symbol - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen - fun:g_module_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/ld-2.7.so - fun:__libc_dlopen_mode -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/ld-2.7.so - fun:__libc_dlopen_mode -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/ld-2.7.so - fun:__libc_dlopen_mode - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - fun:iconv_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/ld-2.7.so - fun:__libc_dlopen_mode - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - obj:/lib/i686/cmov/libc-2.7.so - fun:iconv_open -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - obj:/lib/ld-2.7.so - obj:/lib/i686/cmov/libdl-2.7.so - fun:dlopen -} - -# suppression for a glibc bug: -# http://valgrind.org/docs/manual/faq.html#faq.exit_errors> -{ - - Memcheck:Free - fun:free - obj:*libc-*.so - fun:__libc_freeres - fun:* - fun:_Exit -} - -# valgrind doesn't allow me to specify a suppression for Addr1, Addr2, Addr4 -# as Addr*, so 3 copies for that; and then 2 of each for that pesky memcpy -{ - - Memcheck:Addr1 - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr2 - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} -{ - - Memcheck:Addr4 - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr1 - fun:memcpy - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr2 - fun:memcpy - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} -{ - - Memcheck:Addr4 - fun:memcpy - fun:_dl_signal_error - fun:_dl_map_object_deps - fun:dl_open_worker - fun:_dl_catch_error - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 - fun:g_module_open -} - -{ - - Memcheck:Addr8 - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/libc-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:_dl_open - obj:/lib/libdl-2.3.*.so - obj:/lib/ld-2.3.*.so -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.*.so - obj:/lib/libc-2.3.*.so - obj:/lib/ld-2.3.*.so - fun:_dl_open - obj:/lib/libdl-2.3.*.so - obj:/lib/ld-2.3.*.so - obj:/lib/libdl-2.3.*.so - fun:dlopen - fun:g_module_open - fun:gst_plugin_load_file - fun:gst_plugin_load_by_name - fun:gst_plugin_feature_load -} - -{ - - Memcheck:Addr4 - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libc-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libc-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - fun:dlopen -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libc-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/tls/i686/cmov/libdl-2.3.6.so - fun:dlopen -} - -### glib suppressions -{ - - Memcheck:Cond - fun:g_parse_debug_string - obj:/usr/lib*/libglib-2.0.so.* - fun:g_slice_alloc - fun:g_slice_alloc0 -} - -{ - - Memcheck:Leak - fun:malloc - fun:g_malloc - fun:g_strdup - fun:g_quark_from_string - obj:* - obj:* - fun:g_type_register_fundamental - obj:* - fun:g_type_init_with_debug_flags - fun:g_type_init - fun:init_pre -} - -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - obj:* - obj:* - fun:g_type_register_fundamental -} - -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - obj:* - obj:* - fun:g_type_init_with_debug_flags -} - -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:g_slice_alloc - obj:* - obj:* - fun:g_type_init_with_debug_flags -} - -#pthread memleaks - -{ - Thread creation leak - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate* - fun:_dl_allocate* - fun:__pthread_initialize_minimal -} - -{ - Thread management leak - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate* - fun:_dl_allocate* - fun:__pthread_* -} - -{ - Thread management leak 2 - Memcheck:Leak - fun:memalign - fun:_dl_allocate* - fun:_dl_allocate* - fun:__pthread_* -} - -{ - pthread_create Syscall param write(buf) points to uninitialised byte(s) - Memcheck:Param - write(buf) - fun:pthread_create@@GLIBC_2.2.5 - fun:g_thread_create* - -} - -# nss_parse_* memleak (used by g_option_context_parse) -{ - nss_parse_* memleak - Memcheck:Leak - fun:malloc - fun:nss_parse_service_list - fun:__nss_database_lookup -} - -# liboil suppressions -{ - - Memcheck:Value8 - obj:/usr/lib/liboil-0.3.so.0.1.0 - obj:/usr/lib/liboil-0.3.so.0.1.0 - obj:/usr/lib/liboil-0.3.so.0.1.0 - fun:oil_cpu_fault_check_try - fun:oil_test_check_impl - fun:oil_class_optimize - fun:oil_optimize_all - fun:oil_init -} - -{ - - Memcheck:Addr8 - obj:/lib/ld-2.3.6.so -} - -{ - - Memcheck:Param - futex(uaddr2) - fun:pthread_once - obj:/lib/libc-2.3.6.so - obj:/lib/libc-2.3.6.so - fun:setlocale - fun:init_pre - fun:g_option_context_parse - fun:gst_init_check - fun:gst_init - fun:gst_check_init - fun:main -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.3.6.so - obj:/lib/ld-2.3.6.so - fun:_dl_open - obj:/lib/libdl-2.3.6.so - obj:/lib/ld-2.3.6.so - obj:/lib/libdl-2.3.6.so - fun:dlopen - fun:g_module_open - fun:gst_plugin_load_file -} -# this exists in a bunch of different variations, hence the short tail/trace -{ - - Memcheck:Addr4 - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so -} -{ - - Memcheck:Addr8 - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so -} - -# More edgy suppressions (Mike) -{ - - Memcheck:Cond - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - fun:dlopen_doit - obj:/lib/ld-2.4.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - fun:dlopen_doit - obj:/lib/ld-2.4.so - fun:_dlerror_run - fun:dlopen@@GLIBC_2.1 -} - -{ - - Memcheck:Cond - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - fun:do_sym - fun:_dl_sym -} - -# This one's overly general, but there's zero other information in the stack -# trace - just these five lines! -{ - - Memcheck:Cond - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so -} - -{ - - Memcheck:Leak - fun:calloc - obj:/lib/ld-2.4.so - fun:_dl_allocate_tls - fun:pthread_create@@GLIBC_2.1 -} - -# TLS leaks for feisty/x86 -{ - - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate_tls - fun:pthread_create@@GLIBC_2.1 -} - -{ - - Memcheck:Leak - fun:calloc - obj:/usr/lib/libcdio.so.6.0.1 - fun:cdio_open_am_linux - obj:/usr/lib/libcdio.so.6.0.1 - fun:cdio_open_am -} - -{ - - Memcheck:Addr8 - obj:/lib/ld-2.5.so -} - -{ - - Memcheck:Cond - fun:snd_pcm_direct_shm_create_or_connect - fun:snd_pcm_dsnoop_open - fun:_snd_pcm_dsnoop_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_plug_open - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_asym_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 -} - -{ - - Memcheck:Cond - fun:snd_pcm_hw_param_set_near - fun:set_hwparams -} - -{ - - Memcheck:Cond - fun:_snd_pcm_hw_param_set_min - fun:snd_pcm_hw_param_set_min - fun:snd_pcm_hw_param_set_near - fun:set_hwparams -} - -{ - - Memcheck:Cond - fun:_snd_pcm_hw_param_set_min - fun:snd_pcm_hw_param_set_min - fun:snd_pcm_hw_param_set_near - fun:set_hwparams -} - -{ - - Memcheck:Cond - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_hw_param_set_near - fun:set_hwparams -} -{ - - Memcheck:Cond - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_close - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Cond - fun:snd_pcm_direct_shm_create_or_connect - fun:snd_pcm_dmix_open - fun:_snd_pcm_dmix_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_softvol_open - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_plug_open - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_asym_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:malloc - fun:strdup - fun:snd_dlobj_cache_add - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:snd_pcm_dsnoop_open - fun:_snd_pcm_dsnoop_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_plug_open - obj:/*lib/libasound.so.2.0.0 - fun:snd_pcm_open_slave - fun:_snd_pcm_asym_open - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 -} -# Catch about 15 variations on inserting info into an ALSA -# internal cache -{ - - Memcheck:Leak - fun:malloc - fun:snd_dlobj_cache_add - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:malloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks -} -{ - - Memcheck:Leak - fun:malloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_update_r - fun:snd_config_update -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:calloc - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_hook_load - fun:snd_config_hook_load_for_all_cards - obj:/*lib/libasound.so.2.0.0 - fun:snd_config_searcha_hooks - fun:snd_config_search_alias_hooks - fun:snd_config_search_definition - obj:/*lib/libasound.so.2.0.0 -} -{ - - Memcheck:Leak - fun:malloc - obj:/lib/libc*.so - fun:__nss_database_lookup - obj:* - obj:* - fun:getgrnam_r - fun:getgrnam - fun:snd_pcm_direct_parse_open_conf -} - -{ - - Memcheck:Leak - fun:calloc - fun:_XCBInitDisplayLock - fun:XOpenDisplay -} - -# GConf internal initialisations related to getting the default client. -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_tcval - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:CORBA_ORB_string_to_object - obj:/usr/lib/libgconf-2.so.* - fun:gconf_get_current_lock_holder - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_tcval - obj:/usr/lib/libORBit-2.so.* - fun:PortableServer_POA_servant_to_reference - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_tcval - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:CORBA_ORB_string_to_object - obj:/usr/lib/libgconf-2.so.* - fun:gconf_get_current_lock_holder - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:ORBit_demarshal_value - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_small_invoke_stub - fun:ConfigServer_get_default_database - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - obj:/usr/lib/libORBit-2.so.* - fun:IOP_generate_profiles - fun:ORBit_marshal_object - fun:ORBit_marshal_value - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_small_invoke_stub - fun:ConfigServer_add_client - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_by_tc - obj:/usr/lib/libORBit-2.so.* - fun:PortableServer_POA_servant_to_reference - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_by_tc - obj:/usr/lib/libORBit-2.so.* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:CORBA_ORB_string_to_object - obj:/usr/lib/libgconf-2.so.* - fun:gconf_get_current_lock_holder - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so.* - obj:/usr/lib/libgconf-2.so.* - fun:gconf_engine_get_default -} - -# Some libORBit/bonobo initialisation stuff -{ - - Memcheck:Leak - fun:malloc - fun:g_malloc - fun:ORBit_alloc_string - fun:CORBA_string_dup - fun:Bonobo_ActivationEnvValue_set - fun:bonobo_activation_init_activation_env - fun:bonobo_activation_orb_init - fun:bonobo_activation_init -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc* - obj:/usr/lib/libORBit-2.so* - fun:PortableServer_POA_servant_to_reference - obj:/usr/lib/libbonobo-2.so* -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_tcval - fun:ORBit_small_allocbuf - fun:ORBit_adaptor_setup - obj:/usr/lib/libORBit-2.so* - fun:ORBit_POA_setup_root - fun:ORBit_init_internals - fun:CORBA_ORB_init -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc_tcval - fun:ORBit_adaptor_setup - obj:/usr/lib/libORBit-2.so* - fun:ORBit_POA_setup_root - fun:ORBit_init_internals - fun:CORBA_ORB_init -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_allocbuf - fun:bonobo_activation_init_activation_env - fun:bonobo_activation_orb_init - fun:bonobo_activation_init -} - -# More GConf stuff from the FC5 buildbot, mostly variations on the -# above stack traces -{ - - Memcheck:Param - writev(vector[...]) - fun:writev - obj:/usr/lib/libORBit-2.so* - fun:link_connection_writev - fun:giop_send_buffer_write - obj:/usr/lib/libORBit-2.so* - fun:ORBit_small_invoke_stub - fun:ORBit_small_invoke_stub_n - fun:ORBit_c_stub_invoke - fun:ConfigServer_ping - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc* - obj:/usr/lib/libORBit-2.so* - fun:PortableServer_POA_servant_to_reference - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc - obj:/usr/lib/libORBit-2.so* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:CORBA_ORB_string_to_object - obj:/usr/lib/libgconf-2.so* - fun:gconf_get_current_lock_holder - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc* - obj:/usr/lib/libORBit-2.so* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:CORBA_ORB_string_to_object - obj:/usr/lib/libgconf-2.so* - fun:gconf_get_current_lock_holder - fun:gconf_activate_server - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc* - obj:/usr/lib/libORBit-2.so* - fun:ORBit_demarshal_IOR - fun:ORBit_demarshal_object - fun:ORBit_demarshal_value - obj:/usr/lib/libORBit-2.so* - fun:ORBit_small_invoke_stub - fun:ORBit_small_invoke_stub_n - fun:ORBit_c_stub_invoke - fun:ConfigServer_get_default_database - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:calloc - fun:g_malloc0 - fun:ORBit_alloc* - fun:ORBit_small_alloc* - obj:/usr/lib/libORBit-2.so* - fun:ORBit_OAObject_object_to_objkey - fun:IOP_generate_profiles - fun:ORBit_marshal_object - fun:ORBit_marshal_value - obj:/usr/lib/libORBit-2.so* - fun:ORBit_small_invoke_stub - fun:ORBit_small_invoke_stub_n - fun:ORBit_c_stub_invoke - fun:ConfigServer_add_client - obj:/usr/lib/libgconf-2.so* - obj:/usr/lib/libgconf-2.so* - fun:gconf_engine_get_default -} -{ - - Memcheck:Leak - fun:malloc - obj:*libc-*.so - fun:__nss_database_lookup - obj:* - obj:* - fun:getpwnam_r - obj:/usr/lib*/libglib-2.0.so.* - fun:g_get_home_dir -} -{ - - Memcheck:Leak - fun:malloc - obj:*libc-*.so - fun:__nss_database_lookup - obj:* - obj:* - fun:getpwnam_r - obj:/usr/lib*/libglib-2.0.so.* - fun:g_get_user_name -} -{ - - Memcheck:Leak - fun:malloc - obj:*libc-*.so - fun:__nss_database_lookup - obj:* - obj:* - fun:getpwnam_r - obj:/usr/lib*/libglib-2.0.so.* - fun:g_get_tmp_dir -} - -{ - - Memcheck:Leak - fun:malloc - obj:*libc-*.so - fun:__nss_database_lookup - obj:* - obj:* - fun:getpwnam_r - obj:/usr/lib*/libglib-2.0.so.0.* - fun:g_get_host_name -} - - -## Some Fontconfig errors. -{ - - Memcheck:Leak - fun:malloc - fun:FcPatternObjectInsertElt - fun:FcPatternObjectAddWithBinding - fun:FcPatternAppend - fun:FcEndElement - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - fun:XML_ParseBuffer - fun:FcConfigParseAndLoad - fun:FcConfigParseAndLoad - fun:FcParseInclude - fun:FcEndElement - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - fun:XML_ParseBuffer - fun:FcConfigParseAndLoad -} -{ - - Memcheck:Leak - fun:malloc - fun:FcStrCopy - fun:FcEndElement - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - fun:XML_ParseBuffer - fun:FcConfigParseAndLoad - fun:FcConfigParseAndLoad - fun:FcParseInclude - fun:FcEndElement - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - obj:/usr/lib/libexpat.so.1.0.0 - fun:XML_ParseBuffer - fun:FcConfigParseAndLoad - fun:FcInitLoadConfig - fun:FcInitLoadConfigAndFonts -} - diff --git a/mobile/common/gstdoc-scangobj b/mobile/common/gstdoc-scangobj deleted file mode 100755 index 90ba889..0000000 --- a/mobile/common/gstdoc-scangobj +++ /dev/null @@ -1,1607 +0,0 @@ -#!/usr/bin/perl -w -# -*- cperl -*- -# -# gtk-doc - GTK DocBook documentation generator. -# Copyright (C) 1998 Damon Chaplin -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# - -# -# This gets information about object heirarchies and signals -# by compiling a small C program. CFLAGS and LDFLAGS must be -# set appropriately before running this script. -# -# NOTE: the lookup_signal_arg_names() function contains the argument names of -# standard GTK signal handlers. This may need to be updated for new -# GTK signals or Gnome widget signals. - -use Getopt::Long; - -unshift @INC, '/usr/share/gtk-doc/data'; -require "gtkdoc-common.pl"; - -# Options - -# name of documentation module -my $MODULE; -my $OUTPUT_DIR; -my $PRINT_VERSION; -my $PRINT_HELP; -my $TYPE_INIT_FUNC="g_type_init ()"; - -# --nogtkinit is deprecated, as it is the default now anyway. -%optctl = (module => \$MODULE, - source => \$SOURCE, - types => \$TYPES_FILE, - nogtkinit => \$NO_GTK_INIT, - 'type-init-func' => \$TYPE_INIT_FUNC, - 'output-dir' => \$OUTPUT_DIR, - 'version' => \$PRINT_VERSION, - 'help' => \$PRINT_HELP); - -GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help"); - -if ($NO_GTK_INIT) { - # Do nothing. This just avoids a warning. -} - -if ($PRINT_VERSION) { - print "1.5\n"; - exit 0; -} - -if (!$MODULE) { - $PRINT_HELP = 1; -} - -if ($PRINT_HELP) { - print "gstdoc-scangobj version 1.5\n"; - print "\n--module=MODULE_NAME Name of the doc module being parsed"; - print "\n--source=SOURCE_NAME Name of the source module for plugins"; - print "\n--types=FILE The name of the file to store the types in"; - print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()"; - print "\n--output-dir=DIRNAME The directory where the results are stored"; - print "\n--version Print the version of this program"; - print "\n--help Print this help\n"; - exit 0; -} - -$OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : "."; - -# THOMAS: dynamic types; only use types file for headers - $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types"; - -open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n"; -open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n"; - -my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals"; -my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new"; -my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy"; -my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new"; -my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces"; -my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new"; -my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites"; -my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new"; -my $old_args_filename = "$OUTPUT_DIR/$MODULE.args"; -my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new"; - -# write a C program to scan the types - -$includes = ""; -#@types = (); - -for () { - if (/^#include/) { - $includes .= $_; -# } elsif (/^%/) { -# next; -# } elsif (/^\s*$/) { -# next; -# } else { -# chomp; -# push @types, $_; - } -} - -#$ntypes = @types + 1; - -print OUTPUT < -#include -#include -#include - -$includes -#ifdef GTK_IS_WIDGET_CLASS -#include -#endif -GType *object_types = NULL; - -static GType * -get_object_types (void) -{ - GList *plugins = NULL; - GList *factories = NULL; - GList *l; - GstElementFactory *factory = NULL; - - gint i = 0; - - /* get a list of features from plugins in our source module */ - plugins = gst_registry_get_plugin_list (gst_registry_get_default()); - - while (plugins) { - GList *features; - GstPlugin *plugin; - const gchar *source; - - plugin = (GstPlugin *) (plugins->data); - plugins = g_list_next (plugins); - source = gst_plugin_get_source (plugin); - /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/ - if (!source || strcmp (source, "$SOURCE") != 0) { - continue; - } - g_print ("plugin: %s source: %s\\n", plugin->desc.name, source); - - features = - gst_registry_get_feature_list_by_plugin (gst_registry_get_default (), - plugin->desc.name); - while (features) { - GstPluginFeature *feature; - feature = GST_PLUGIN_FEATURE (features->data); - feature = gst_plugin_feature_load (feature); - if (!feature) { - g_warning ("Could not load plugin feature %s", - gst_plugin_feature_get_name (feature)); - } - - if (GST_IS_ELEMENT_FACTORY (feature)) { - factory = GST_ELEMENT_FACTORY (feature); - factories = g_list_prepend (factories, factory); - } - features = g_list_next (features); - } - } - - g_message ("number of element factories: %d", g_list_length (factories)); - - /* allocate the object_types array to hold them */ - object_types = g_new0 (GType, g_list_length (factories)+1); - - l = factories; - i = 0; - - /* fill it */ - while (l) { - GType type; - factory = GST_ELEMENT_FACTORY (l->data); - type = gst_element_factory_get_element_type (factory); - g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory)); - object_types[i] = type; - i++; - l = g_list_next (l); - } - object_types[i] = 0; -EOT - -print OUTPUT <\\n%s::%s\\n%s\\n%s\\n%s\\n\\n", - object_name, query_info.signal_name, ret_type_buffer, flags, buffer); -} - - -/* Returns the type name to use for a signal argument or return value, given - the GtkType from the signal info. It also sets is_pointer to TRUE if the - argument needs a '*' since it is a pointer. */ -static const gchar * -get_type_name (GType type, gboolean * is_pointer) -{ - const gchar *type_name; - - *is_pointer = FALSE; - type_name = g_type_name (type); - - switch (type) { - case G_TYPE_NONE: - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - case G_TYPE_LONG: - case G_TYPE_ULONG: - case G_TYPE_FLOAT: - case G_TYPE_DOUBLE: - case G_TYPE_POINTER: - /* These all have normal C type names so they are OK. */ - return type_name; - - case G_TYPE_STRING: - /* A GtkString is really a gchar*. */ - *is_pointer = TRUE; - return "gchar"; - - case G_TYPE_ENUM: - case G_TYPE_FLAGS: - /* We use a gint for both of these. Hopefully a subtype with a decent - name will be registered and used instead, as GTK+ does itself. */ - return "gint"; - - case G_TYPE_BOXED: - /* The boxed type shouldn't be used itself, only subtypes. Though we - return 'gpointer' just in case. */ - return "gpointer"; - - case G_TYPE_PARAM: - /* A GParam is really a GParamSpec*. */ - *is_pointer = TRUE; - return "GParamSpec"; - - default: - break; - } - - /* For all GObject subclasses we can use the class name with a "*", - e.g. 'GtkWidget *'. */ - if (g_type_is_a (type, G_TYPE_OBJECT)) - *is_pointer = TRUE; - - if (G_TYPE_IS_CLASSED (type)) - *is_pointer = TRUE; - - /* All boxed subtypes will be pointers as well. */ - if (g_type_is_a (type, G_TYPE_BOXED)) - *is_pointer = TRUE; - - /* All pointer subtypes will be pointers as well. */ - if (g_type_is_a (type, G_TYPE_POINTER)) - *is_pointer = TRUE; - - /* But enums are not */ - if (g_type_is_a (type, G_TYPE_ENUM) || - g_type_is_a (type, G_TYPE_FLAGS)) - *is_pointer = FALSE; - - return type_name; -} - - -static const gchar * -get_gdk_event (const gchar * signal_name) -{ - static const gchar *GbGDKEvents[] = - { - "button_press_event", "GdkEventButton", - "button_release_event", "GdkEventButton", - "motion_notify_event", "GdkEventMotion", - "delete_event", "GdkEvent", - "destroy_event", "GdkEvent", - "expose_event", "GdkEventExpose", - "key_press_event", "GdkEventKey", - "key_release_event", "GdkEventKey", - "enter_notify_event", "GdkEventCrossing", - "leave_notify_event", "GdkEventCrossing", - "configure_event", "GdkEventConfigure", - "focus_in_event", "GdkEventFocus", - "focus_out_event", "GdkEventFocus", - "map_event", "GdkEvent", - "unmap_event", "GdkEvent", - "property_notify_event", "GdkEventProperty", - "selection_clear_event", "GdkEventSelection", - "selection_request_event", "GdkEventSelection", - "selection_notify_event", "GdkEventSelection", - "proximity_in_event", "GdkEventProximity", - "proximity_out_event", "GdkEventProximity", - "drag_begin_event", "GdkEventDragBegin", - "drag_request_event", "GdkEventDragRequest", - "drag_end_event", "GdkEventDragRequest", - "drop_enter_event", "GdkEventDropEnter", - "drop_leave_event", "GdkEventDropLeave", - "drop_data_available_event", "GdkEventDropDataAvailable", - "other_event", "GdkEventOther", - "client_event", "GdkEventClient", - "no_expose_event", "GdkEventNoExpose", - "visibility_notify_event", "GdkEventVisibility", - "window_state_event", "GdkEventWindowState", - "scroll_event", "GdkEventScroll", - NULL - }; - - gint i; - - for (i = 0; GbGDKEvents[i]; i += 2) - { - if (!strcmp (signal_name, GbGDKEvents[i])) - return GbGDKEvents[i + 1]; - } - return "GdkEvent"; -} - - -/* This returns argument names to use for some known GTK signals. - It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g. - 'select_row' and it returns a pointer to an array of argument types and - names. */ -static const gchar ** -lookup_signal_arg_names (const gchar * type, const gchar * signal_name) -{ - /* Each arg array starts with the object type name and the signal name, - and then signal arguments follow. */ - static const gchar *GbArgTable[][16] = - { - {"GtkCList", "select_row", - "gint row", - "gint column", - "GdkEventButton *event"}, - {"GtkCList", "unselect_row", - "gint row", - "gint column", - "GdkEventButton *event"}, - {"GtkCList", "click_column", - "gint column"}, - - {"GtkCList", "resize_column", - "gint column", - "gint width"}, - - {"GtkCList", "extend_selection", - "GtkScrollType scroll_type", - "gfloat position", - "gboolean auto_start_selection"}, - {"GtkCList", "scroll_vertical", - "GtkScrollType scroll_type", - "gfloat position"}, - {"GtkCList", "scroll_horizontal", - "GtkScrollType scroll_type", - "gfloat position"}, - - {"GtkCTree", "tree_select_row", - "GtkCTreeNode *node", - "gint column"}, - {"GtkCTree", "tree_unselect_row", - "GtkCTreeNode *node", - "gint column"}, - {"GtkCTree", "tree_expand", - "GtkCTreeNode *node"}, - {"GtkCTree", "tree_collapse", - "GtkCTreeNode *node"}, - {"GtkCTree", "tree_move", - "GtkCTreeNode *node", - "GtkCTreeNode *new_parent", - "GtkCTreeNode *new_sibling"}, - {"GtkCTree", "change_focus_row_expansion", - "GtkCTreeExpansionType expansion"}, - - {"GtkEditable", "insert_text", - "gchar *new_text", - "gint new_text_length", - "gint *position"}, - {"GtkEditable", "delete_text", - "gint start_pos", - "gint end_pos"}, - {"GtkEditable", "set_editable", - "gboolean is_editable"}, - {"GtkEditable", "move_cursor", - "gint x", - "gint y"}, - {"GtkEditable", "move_word", - "gint num_words"}, - {"GtkEditable", "move_page", - "gint x", - "gint y"}, - {"GtkEditable", "move_to_row", - "gint row"}, - {"GtkEditable", "move_to_column", - "gint column"}, - - {"GtkEditable", "kill_char", - "gint direction"}, - {"GtkEditable", "kill_word", - "gint direction"}, - {"GtkEditable", "kill_line", - "gint direction"}, - - - {"GtkInputDialog", "enable_device", - "GdkDevice *deviceid"}, - {"GtkInputDialog", "disable_device", - "GdkDevice *deviceid"}, - - {"GtkListItem", "extend_selection", - "GtkScrollType scroll_type", - "gfloat position", - "gboolean auto_start_selection"}, - {"GtkListItem", "scroll_vertical", - "GtkScrollType scroll_type", - "gfloat position"}, - {"GtkListItem", "scroll_horizontal", - "GtkScrollType scroll_type", - "gfloat position"}, - - {"GtkMenuShell", "move_current", - "GtkMenuDirectionType direction"}, - {"GtkMenuShell", "activate_current", - "gboolean force_hide"}, - - - {"GtkNotebook", "switch_page", - "GtkNotebookPage *page", - "guint page_num"}, - {"GtkStatusbar", "text_pushed", - "guint context_id", - "gchar *text"}, - {"GtkStatusbar", "text_popped", - "guint context_id", - "gchar *text"}, - {"GtkTipsQuery", "widget_entered", - "GtkWidget *widget", - "gchar *tip_text", - "gchar *tip_private"}, - {"GtkTipsQuery", "widget_selected", - "GtkWidget *widget", - "gchar *tip_text", - "gchar *tip_private", - "GdkEventButton *event"}, - {"GtkToolbar", "orientation_changed", - "GtkOrientation orientation"}, - {"GtkToolbar", "style_changed", - "GtkToolbarStyle style"}, - {"GtkWidget", "draw", - "GdkRectangle *area"}, - {"GtkWidget", "size_request", - "GtkRequisition *requisition"}, - {"GtkWidget", "size_allocate", - "GtkAllocation *allocation"}, - {"GtkWidget", "state_changed", - "GtkStateType state"}, - {"GtkWidget", "style_set", - "GtkStyle *previous_style"}, - - {"GtkWidget", "install_accelerator", - "gchar *signal_name", - "gchar key", - "gint modifiers"}, - - {"GtkWidget", "add_accelerator", - "guint accel_signal_id", - "GtkAccelGroup *accel_group", - "guint accel_key", - "GdkModifierType accel_mods", - "GtkAccelFlags accel_flags"}, - - {"GtkWidget", "parent_set", - "GtkObject *old_parent"}, - - {"GtkWidget", "remove_accelerator", - "GtkAccelGroup *accel_group", - "guint accel_key", - "GdkModifierType accel_mods"}, - {"GtkWidget", "debug_msg", - "gchar *message"}, - {"GtkWindow", "move_resize", - "gint *x", - "gint *y", - "gint width", - "gint height"}, - {"GtkWindow", "set_focus", - "GtkWidget *widget"}, - - {"GtkWidget", "selection_get", - "GtkSelectionData *data", - "guint info", - "guint time"}, - {"GtkWidget", "selection_received", - "GtkSelectionData *data", - "guint time"}, - - {"GtkWidget", "drag_begin", - "GdkDragContext *drag_context"}, - {"GtkWidget", "drag_end", - "GdkDragContext *drag_context"}, - {"GtkWidget", "drag_data_delete", - "GdkDragContext *drag_context"}, - {"GtkWidget", "drag_leave", - "GdkDragContext *drag_context", - "guint time"}, - {"GtkWidget", "drag_motion", - "GdkDragContext *drag_context", - "gint x", - "gint y", - "guint time"}, - {"GtkWidget", "drag_drop", - "GdkDragContext *drag_context", - "gint x", - "gint y", - "guint time"}, - {"GtkWidget", "drag_data_get", - "GdkDragContext *drag_context", - "GtkSelectionData *data", - "guint info", - "guint time"}, - {"GtkWidget", "drag_data_received", - "GdkDragContext *drag_context", - "gint x", - "gint y", - "GtkSelectionData *data", - "guint info", - "guint time"}, - - {NULL} - }; - - gint i; - - for (i = 0; GbArgTable[i][0]; i++) - { -#if 1 - if (!strcmp (type, GbArgTable[i][0]) - && !strcmp (signal_name, GbArgTable[i][1])) - return &GbArgTable[i][2]; -#endif - } - return NULL; -} - -/* This outputs the hierarchy of all objects which have been initialized, - i.e. by calling their XXX_get_type() initialization function. */ -static void -output_object_hierarchy (void) -{ - FILE *fp; - gint i; - - fp = fopen (hierarchy_filename, "w"); - if (fp == NULL) - { - g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno)); - return; - } - output_hierarchy (fp, G_TYPE_OBJECT, 0); - output_hierarchy (fp, G_TYPE_INTERFACE, 0); - - for (i=0; object_types[i]; i++) { - if (!g_type_parent (object_types[i]) && - (object_types[i] != G_TYPE_NONE) && - (object_types[i] != G_TYPE_OBJECT) && - (object_types[i] != G_TYPE_INTERFACE) - ) { - g_warning ("printing hierarchy for root type: %s", - g_type_name (object_types[i])); - output_hierarchy (fp, object_types[i], 0); - } - } - /* for debugging - for (i=0; object_types[i]; i++) { - if(object_types[i] != G_TYPE_NONE) { - g_print ("type has not been added to hierarchy: %s\\n", - g_type_name (object_types[i])); - } - } - for debugging */ - - fclose (fp); -} - -/* This is called recursively to output the hierarchy of a widget. */ -static void -output_hierarchy (FILE *fp, - GType type, - guint level) -{ - guint i; - GType *children; - guint n_children; - - if (!type) - return; - - /* for debugging - for (i=0; object_types[i]; i++) { - if(object_types[i] == type) { - g_print ("added type to hierarchy (level %d): %s\\n", - level, g_type_name (type)); - object_types[i] = G_TYPE_NONE; - break; - } - } - for debugging */ - - for (i = 0; i < level; i++) - fprintf (fp, " "); - fprintf (fp, g_type_name (type)); - fprintf (fp, "\\n"); - - children = g_type_children (type, &n_children); - - for (i=0; i < n_children; i++) { - output_hierarchy (fp, children[i], level + 1); - } - - g_free (children); -} - -static void output_object_interfaces (void) -{ - guint i; - FILE *fp; - - fp = fopen (interfaces_filename, "w"); - if (fp == NULL) - { - g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno)); - return; - } - output_interfaces (fp, G_TYPE_OBJECT); - - for (i = 0; object_types[i]; i++) - { - if (!g_type_parent (object_types[i]) && - (object_types[i] != G_TYPE_OBJECT) && - G_TYPE_IS_INSTANTIATABLE (object_types[i])) - { - output_interfaces (fp, object_types[i]); - } - } - fclose (fp); -} - -static void -output_interfaces (FILE *fp, - GType type) -{ - guint i; - GType *children, *interfaces; - guint n_children, n_interfaces; - - if (!type) - return; - - interfaces = g_type_interfaces (type, &n_interfaces); - - if (n_interfaces > 0) - { - fprintf (fp, g_type_name (type)); - for (i=0; i < n_interfaces; i++) - fprintf (fp, " %s", g_type_name (interfaces[i])); - fprintf (fp, "\\n"); - } - g_free (interfaces); - - children = g_type_children (type, &n_children); - - for (i=0; i < n_children; i++) - output_interfaces (fp, children[i]); - - g_free (children); -} - -static void output_interface_prerequisites (void) -{ - FILE *fp; - - fp = fopen (prerequisites_filename, "w"); - if (fp == NULL) - { - g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno)); - return; - } - output_prerequisites (fp, G_TYPE_INTERFACE); - fclose (fp); -} - -static void -output_prerequisites (FILE *fp, - GType type) -{ -#if GLIB_CHECK_VERSION(2,1,0) - guint i; - GType *children, *prerequisites; - guint n_children, n_prerequisites; - - if (!type) - return; - - prerequisites = g_type_interface_prerequisites (type, &n_prerequisites); - - if (n_prerequisites > 0) - { - fprintf (fp, g_type_name (type)); - for (i=0; i < n_prerequisites; i++) - fprintf (fp, " %s", g_type_name (prerequisites[i])); - fprintf (fp, "\\n"); - } - g_free (prerequisites); - - children = g_type_children (type, &n_children); - - for (i=0; i < n_children; i++) - output_prerequisites (fp, children[i]); - - g_free (children); -#endif -} - -static void -output_args (void) -{ - FILE *fp; - gint i; - - fp = fopen (args_filename, "w"); - if (fp == NULL) - { - g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno)); - return; - } - - for (i = 0; object_types[i]; i++) { - output_object_args (fp, object_types[i]); - } - - fclose (fp); -} - -static gint -compare_param_specs (const void *a, const void *b) -{ - GParamSpec *spec_a = *(GParamSpec **)a; - GParamSpec *spec_b = *(GParamSpec **)b; - - return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b)); -} - -/* Its common to have unsigned properties restricted - * to the signed range. Therefore we make this look - * a bit nicer by spelling out the max constants. - */ - -/* Don't use "==" with floats, it might trigger a gcc warning. */ -#define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y) - -static gchar* -describe_double_constant (gdouble value) -{ - gchar *desc; - - if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE)) - desc = g_strdup ("G_MAXDOUBLE"); - else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE)) - desc = g_strdup ("G_MINDOUBLE"); - else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE)) - desc = g_strdup ("-G_MAXDOUBLE"); - else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT)) - desc = g_strdup ("G_MAXFLOAT"); - else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT)) - desc = g_strdup ("G_MINFLOAT"); - else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT)) - desc = g_strdup ("-G_MAXFLOAT"); - else - desc = g_strdup_printf ("%lg", value); - - return desc; -} - -static gchar* -describe_signed_constant (gint64 value) -{ - gchar *desc; - - if (value == G_MAXINT) - desc = g_strdup ("G_MAXINT"); - else if (value == G_MININT) - desc = g_strdup ("G_MININT"); - else if (value == G_MAXUINT) - desc = g_strdup ("G_MAXUINT"); - else if (value == G_MAXLONG) - desc = g_strdup ("G_MAXLONG"); - else if (value == G_MINLONG) - desc = g_strdup ("G_MINLONG"); - else if (value == G_MAXULONG) - desc = g_strdup ("G_MAXULONG"); - else if (value == G_MAXINT64) - desc = g_strdup ("G_MAXINT64"); - else if (value == G_MININT64) - desc = g_strdup ("G_MININT64"); - else - desc = g_strdup_printf ("%" G_GINT64_FORMAT, value); - - return desc; -} - -static gchar* -describe_unsigned_constant (guint64 value) -{ - gchar *desc; - - if (value == G_MAXINT) - desc = g_strdup ("G_MAXINT"); - else if (value == G_MININT) - desc = g_strdup ("G_MININT"); - else if (value == G_MAXUINT) - desc = g_strdup ("G_MAXUINT"); - else if (value == G_MAXLONG) - desc = g_strdup ("G_MAXLONG"); - else if (value == G_MINLONG) - desc = g_strdup ("G_MINLONG"); - else if (value == G_MAXULONG) - desc = g_strdup ("G_MAXULONG"); - else if (value == G_MAXINT64) - desc = g_strdup ("G_MAXINT64"); - else if (value == G_MININT64) - desc = g_strdup ("G_MININT64"); - else if (value == G_MAXUINT64) - desc = g_strdup ("G_MAXUINT64"); - else - desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value); - - return desc; -} - -static gchar* -describe_type (GParamSpec *spec) -{ - gchar *desc; - gchar *lower; - gchar *upper; - - if (G_IS_PARAM_SPEC_CHAR (spec)) - { - GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec); - - lower = describe_signed_constant (pspec->minimum); - upper = describe_signed_constant (pspec->maximum); - if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8) - desc = g_strdup (""); - else if (pspec->minimum == G_MININT8) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXINT8) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_UCHAR (spec)) - { - GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec); - - lower = describe_unsigned_constant (pspec->minimum); - upper = describe_unsigned_constant (pspec->maximum); - if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8) - desc = g_strdup (""); - else if (pspec->minimum == 0) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXUINT8) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_INT (spec)) - { - GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec); - - lower = describe_signed_constant (pspec->minimum); - upper = describe_signed_constant (pspec->maximum); - if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT) - desc = g_strdup (""); - else if (pspec->minimum == G_MININT) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXINT) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_UINT (spec)) - { - GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec); - - lower = describe_unsigned_constant (pspec->minimum); - upper = describe_unsigned_constant (pspec->maximum); - if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT) - desc = g_strdup (""); - else if (pspec->minimum == 0) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXUINT) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_LONG (spec)) - { - GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec); - - lower = describe_signed_constant (pspec->minimum); - upper = describe_signed_constant (pspec->maximum); - if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG) - desc = g_strdup (""); - else if (pspec->minimum == G_MINLONG) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXLONG) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_ULONG (spec)) - { - GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec); - gchar *upper; - - lower = describe_unsigned_constant (pspec->minimum); - upper = describe_unsigned_constant (pspec->maximum); - if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG) - desc = g_strdup (""); - else if (pspec->minimum == 0) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXULONG) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_INT64 (spec)) - { - GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec); - - lower = describe_signed_constant (pspec->minimum); - upper = describe_signed_constant (pspec->maximum); - if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64) - desc = g_strdup (""); - else if (pspec->minimum == G_MININT64) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXINT64) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_UINT64 (spec)) - { - GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec); - - lower = describe_unsigned_constant (pspec->minimum); - upper = describe_unsigned_constant (pspec->maximum); - if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64) - desc = g_strdup (""); - else if (pspec->minimum == 0) - desc = g_strdup_printf ("<= %s", upper); - else if (pspec->maximum == G_MAXUINT64) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_FLOAT (spec)) - { - GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec); - - lower = describe_double_constant (pspec->minimum); - upper = describe_double_constant (pspec->maximum); - if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT)) - { - if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT)) - desc = g_strdup (""); - else - desc = g_strdup_printf ("<= %s", upper); - } - else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT)) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else if (G_IS_PARAM_SPEC_DOUBLE (spec)) - { - GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec); - - lower = describe_double_constant (pspec->minimum); - upper = describe_double_constant (pspec->maximum); - if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE)) - { - if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE)) - desc = g_strdup (""); - else - desc = g_strdup_printf ("<= %s", upper); - } - else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE)) - desc = g_strdup_printf (">= %s", lower); - else - desc = g_strdup_printf ("[%s,%s]", lower, upper); - g_free (lower); - g_free (upper); - } - else - { - desc = g_strdup (""); - } - - return desc; -} - -static gchar* -describe_default (GParamSpec *spec) -{ - gchar *desc; - - if (G_IS_PARAM_SPEC_CHAR (spec)) - { - GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec); - - desc = g_strdup_printf ("%d", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_UCHAR (spec)) - { - GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec); - - desc = g_strdup_printf ("%u", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_BOOLEAN (spec)) - { - GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec); - - desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE"); - } - else if (G_IS_PARAM_SPEC_INT (spec)) - { - GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec); - - desc = g_strdup_printf ("%d", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_UINT (spec)) - { - GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec); - - desc = g_strdup_printf ("%u", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_LONG (spec)) - { - GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec); - - desc = g_strdup_printf ("%ld", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_LONG (spec)) - { - GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec); - - desc = g_strdup_printf ("%lu", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_INT64 (spec)) - { - GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec); - - desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value); - } - else if (G_IS_PARAM_SPEC_UINT64 (spec)) - { - GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec); - - desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value); - } - else if (G_IS_PARAM_SPEC_UNICHAR (spec)) - { - GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec); - - if (g_unichar_isprint (pspec->default_value)) - desc = g_strdup_printf ("'%c'", pspec->default_value); - else - desc = g_strdup_printf ("%u", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_ENUM (spec)) - { - GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec); - - GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value); - if (value) - desc = g_strdup_printf ("%s", value->value_name); - else - desc = g_strdup_printf ("%d", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_FLAGS (spec)) - { - GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec); - guint default_value; - GString *acc; - - default_value = pspec->default_value; - acc = g_string_new (""); - - while (default_value) - { - GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value); - - if (!value) - break; - - if (acc->len > 0) - g_string_append (acc, "|"); - g_string_append (acc, value->value_name); - - default_value &= ~value->value; - } - - if (default_value == 0) - desc = g_string_free (acc, FALSE); - else - { - desc = g_strdup_printf ("%d", pspec->default_value); - g_string_free (acc, TRUE); - } - } - else if (G_IS_PARAM_SPEC_FLOAT (spec)) - { - GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec); - - desc = g_strdup_printf ("%g", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_DOUBLE (spec)) - { - GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec); - - desc = g_strdup_printf ("%lg", pspec->default_value); - } - else if (G_IS_PARAM_SPEC_STRING (spec)) - { - GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec); - - if (pspec->default_value) - { - gchar *esc = g_strescape (pspec->default_value, NULL); - - desc = g_strdup_printf ("\\"%s\\"", esc); - - g_free (esc); - } - else - desc = g_strdup_printf ("NULL"); - } - else - { - desc = g_strdup (""); - } - - return desc; -} - - -static void -output_object_args (FILE *fp, GType object_type) -{ - gpointer class; - const gchar *object_class_name; - guint arg; - gchar flags[16], *pos; - GParamSpec **properties; - guint n_properties; - gboolean child_prop; - gboolean style_prop; - gboolean is_pointer; - const gchar *type_name; - gchar *type_desc; - gchar *default_value; - - if (G_TYPE_IS_OBJECT (object_type)) - { - class = g_type_class_peek (object_type); - if (!class) - return; - - properties = g_object_class_list_properties (class, &n_properties); - } -#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3) - else if (G_TYPE_IS_INTERFACE (object_type)) - { - class = g_type_default_interface_ref (object_type); - - if (!class) - return; - - properties = g_object_interface_list_properties (class, &n_properties); - } -#endif - else - return; - - object_class_name = g_type_name (object_type); - - child_prop = FALSE; - style_prop = FALSE; - - while (TRUE) { - qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs); - for (arg = 0; arg < n_properties; arg++) - { - GParamSpec *spec = properties[arg]; - const gchar *nick, *blurb, *dot; - - if (spec->owner_type != object_type) - continue; - - pos = flags; - /* We use one-character flags for simplicity. */ - if (child_prop && !style_prop) - *pos++ = 'c'; - if (style_prop) - *pos++ = 's'; - if (spec->flags & G_PARAM_READABLE) - *pos++ = 'r'; - if (spec->flags & G_PARAM_WRITABLE) - *pos++ = 'w'; - if (spec->flags & G_PARAM_CONSTRUCT) - *pos++ = 'x'; - if (spec->flags & G_PARAM_CONSTRUCT_ONLY) - *pos++ = 'X'; - *pos = 0; - - nick = g_param_spec_get_nick (spec); - blurb = g_param_spec_get_blurb (spec); - - dot = ""; - if (blurb) { - int str_len = strlen (blurb); - if (str_len > 0 && blurb[str_len - 1] != '.') - dot = "."; - } - - type_desc = describe_type (spec); - default_value = describe_default (spec); - type_name = get_type_name (spec->value_type, &is_pointer); - fprintf (fp, "\\n%s::%s\\n%s%s\\n%s\\n%s\\n%s\\n%s%s\\n%s\\n\\n\\n", - object_class_name, g_param_spec_get_name (spec), type_name, is_pointer ? "*" : "", type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value); - g_free (type_desc); - g_free (default_value); - } - - g_free (properties); - -#ifdef GTK_IS_CONTAINER_CLASS - if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) { - properties = gtk_container_class_list_child_properties (class, &n_properties); - child_prop = TRUE; - continue; - } -#endif - -#ifdef GTK_IS_WIDGET_CLASS -#if GTK_CHECK_VERSION(2,1,0) - if (!style_prop && GTK_IS_WIDGET_CLASS (class)) { - properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties); - style_prop = TRUE; - continue; - } -#endif -#endif - - break; - } -} -EOT - -close OUTPUT; - -# Compile and run our file - -$CC = $ENV{CC} ? $ENV{CC} : "gcc"; -$LD = $ENV{LD} ? $ENV{LD} : $CC; -$CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g"; -$LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : ""; - -my $o_file; -if ($CC =~ /libtool/) { - $o_file = "$MODULE-scan.lo" -} else { - $o_file = "$MODULE-scan.o" -} - -print "gtk-doc: Compiling scanner\n"; -$command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c"; -system($command) == 0 or die "Compilation of scanner failed: $!\n"; - -print "gtk-doc: Linking scanner\n"; -$command = "$LD -o $MODULE-scan $o_file $LDFLAGS"; -system($command) == 0 or die "Linking of scanner failed: $!\n"; - -print "gtk-doc: Running scanner $MODULE-scan\n"; -system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n"; - -unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan"; - -#&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0); -&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0); -&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0); -&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0); -#&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0); - - diff --git a/mobile/common/gtk-doc-plugins.mak b/mobile/common/gtk-doc-plugins.mak deleted file mode 100755 index 71f60ba..0000000 --- a/mobile/common/gtk-doc-plugins.mak +++ /dev/null @@ -1,397 +0,0 @@ -# This is an include file specifically tuned for building documentation -# for GStreamer plug-ins - -help: - @echo - @echo "If you are a doc maintainer, run 'make update' to update" - @echo "the documentation files maintained in CVS" - @echo - @echo Other useful make targets: - @echo - @echo check-inspected-versions: make sure the inspected plugin info - @echo is up to date before a release - @echo - -# update the stuff maintained by doc maintainers -update: - $(MAKE) inspect-update - $(MAKE) scanobj-update - -# We set GPATH here; this gives us semantics for GNU make -# which are more like other make's VPATH, when it comes to -# whether a source that is a target of one rule is then -# searched for in VPATH/GPATH. -# -GPATH = $(srcdir) - -# thomas: make docs parallel installable -TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@ - -EXTRA_DIST = \ - scanobj-build.stamp \ - $(srcdir)/inspect/*.xml \ - inspect.stamp \ - inspect-build.stamp \ - $(SCANOBJ_FILES) \ - $(content_files) \ - $(extra_files) \ - $(HTML_IMAGES) \ - $(DOC_MAIN_SGML_FILE) \ - $(DOC_OVERRIDES) \ - $(DOC_MODULE)-sections.txt - -MAINTAINER_DOC_STAMPS = \ - scanobj-build.stamp \ - inspect-build.stamp \ - inspect.stamp - -# we don't add inspect-build.stamp and scanobj-build.stamp here since they are -# built manually by docs maintainers and result is commited to CVS -DOC_STAMPS = \ - scan-build.stamp \ - tmpl-build.stamp \ - sgml-build.stamp \ - html-build.stamp \ - scan.stamp \ - tmpl.stamp \ - sgml.stamp \ - html.stamp - -# files generated/updated by gtkdoc-scangobj -SCANOBJ_FILES = \ - $(DOC_MODULE).signals \ - $(DOC_MODULE).hierarchy \ - $(DOC_MODULE).interfaces \ - $(DOC_MODULE).prerequisites \ - $(DOC_MODULE).types \ - $(DOC_MODULE).args - -SCANOBJ_FILES_O = \ - .libs/$(DOC_MODULE)-scan.o - -# files generated/updated by gtkdoc-scan -SCAN_FILES = \ - $(DOC_MODULE)-sections.txt \ - $(DOC_MODULE)-overrides.txt \ - $(DOC_MODULE)-undocumented.txt \ - $(DOC_MODULE)-decl.txt \ - $(DOC_MODULE)-decl-list.txt - - -REPORT_FILES = \ - $(DOC_MODULE)-undocumented.txt \ - $(DOC_MODULE)-undeclared.txt \ - $(DOC_MODULE)-unused.txt - -# FC3 seems to need -scan.c to be part of CLEANFILES for distcheck -# no idea why FC4 can do without -CLEANFILES = \ - $(SCANOBJ_FILES_O) \ - $(DOC_MODULE)-scan.c \ - $(REPORT_FILES) \ - $(DOC_STAMPS) \ - inspect-registry.xml - - -if ENABLE_GTK_DOC -all-local: html-build.stamp - -#### scan gobjects; done by documentation maintainer #### -scanobj-update: - -rm scanobj-build.stamp - $(MAKE) scanobj-build.stamp - -# in the case of non-srcdir builds, the built gst directory gets added -# to gtk-doc scanning; but only then, to avoid duplicates -# FIXME: since we don't have the scan step as part of the build anymore, -# we could remove that -# TODO: finish elite script that updates the output files of this step -# instead of rewriting them, so that multiple maintainers can generate -# a collective set of args and signals -scanobj-build.stamp: $(SCANOBJ_DEPS) $(basefiles) - @echo '*** Scanning GObjects ***' - if test x"$(srcdir)" != x. ; then \ - for f in $(SCANOBJ_FILES); \ - do \ - cp $(srcdir)/$$f . ; \ - done; \ - else \ - $(INSPECT_ENVIRONMENT) \ - CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" \ - CFLAGS="-g $(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" \ - $(GST_DOC_SCANOBJ) --type-init-func="gst_init(NULL,NULL)" \ - --module=$(DOC_MODULE) --source=$(PACKAGE) && \ - $(PYTHON) \ - $(top_srcdir)/common/scangobj-merge.py $(DOC_MODULE); \ - fi - touch scanobj-build.stamp - -$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(SCANOBJ_FILES_O): scan-build.stamp - @true - -### inspect GStreamer plug-ins; done by documentation maintainer ### - -# only look at the plugins in this module when building inspect .xml stuff -INSPECT_REGISTRY=$(top_builddir)/docs/plugins/inspect-registry.xml -INSPECT_ENVIRONMENT=\ - GST_PLUGIN_SYSTEM_PATH= \ - GST_PLUGIN_PATH=$(top_builddir)/gst:$(top_builddir)/sys:$(top_builddir)/ext:$(top_builddir)/plugins:$(top_builddir)/src \ - GST_REGISTRY=$(INSPECT_REGISTRY) - -# update the element and plugin XML descriptions; store in inspect/ -inspect: - mkdir inspect - -inspect-update: inspect - -rm $(INSPECT_REGISTRY) - -rm inspect-build.stamp - $(MAKE) inspect-build.stamp - -# FIXME: inspect.stamp should be written to by gst-xmlinspect.py -# IF the output changed; see gtkdoc-mktmpl -inspect-build.stamp: - @echo '*** Rebuilding plugin inspection files ***' - if test x"$(srcdir)" != x. ; then \ - cp $(srcdir)/inspect.stamp . ; \ - cp $(srcdir)/inspect-build.stamp . ; \ - else \ - $(INSPECT_ENVIRONMENT) $(PYTHON) \ - $(top_srcdir)/common/gst-xmlinspect.py $(PACKAGE) inspect && \ - echo -n "timestamp" > inspect.stamp && \ - touch inspect-build.stamp; \ - fi - -### scan headers; done on every build ### -scan-build.stamp: $(HFILE_GLOB) $(EXTRA_HFILES) $(basefiles) scanobj-build.stamp inspect-build.stamp - if test "x$(top_srcdir)" != "x$(top_builddir)" && \ - test -d "$(top_builddir)/gst"; \ - then \ - export BUILT_OPTIONS="--source-dir=$(top_builddir)/gst"; \ - fi; \ - gtkdoc-scan \ - $(SCAN_OPTIONS) $(EXTRA_HFILES) \ - --module=$(DOC_MODULE) \ - $$BUILT_OPTIONS \ - --ignore-headers="$(IGNORE_HFILES)"; \ - touch scan-build.stamp - -#### update templates; done on every build #### - -### FIXME: make this error out again when docs are fixed for 0.9 -# in a non-srcdir build, we need to copy files from the previous step -# and the files from previous runs of this step -tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES) - @echo '*** Rebuilding template files ***' - if test x"$(srcdir)" != x. ; then \ - for f in $(SCANOBJ_FILES) $(SCAN_FILES); \ - do \ - if test -e $(srcdir)/$$f; then cp $(srcdir)/$$f . ; fi; \ - done; \ - fi - gtkdoc-mktmpl --module=$(DOC_MODULE) | tee tmpl-build.log - $(PYTHON) \ - $(top_srcdir)/common/mangle-tmpl.py $(srcdir)/inspect tmpl - @cat $(DOC_MODULE)-unused.txt - rm -f tmpl-build.log - touch tmpl-build.stamp - -tmpl.stamp: tmpl-build.stamp - @true - -#### build xml; done on every build #### - -### FIXME: make this error out again when docs are fixed for 0.9 -sgml-build.stamp: tmpl.stamp inspect.stamp $(CFILE_GLOB) $(top_srcdir)/common/plugins.xsl - @echo '*** Building XML ***' - @-mkdir -p xml - @for a in $(srcdir)/inspect/*.xml; do \ - xsltproc --stringparam module $(MODULE) \ - $(top_srcdir)/common/plugins.xsl $$a > xml/`basename $$a`; done - @for f in $(EXAMPLE_CFILES); do \ - $(PYTHON) $(top_srcdir)/common/c-to-xml.py $$f > xml/element-`basename $$f .c`.xml; done - gtkdoc-mkdb \ - --module=$(DOC_MODULE) \ - --source-dir=$(DOC_SOURCE_DIR) \ - --main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) \ - --output-format=xml \ - --ignore-files="$(IGNORE_HFILES) $(IGNORE_CFILES)" \ - $(MKDB_OPTIONS) \ - | tee sgml-build.log - @if grep "WARNING:" sgml-build.log > /dev/null; then true; fi # exit 1; fi - cp ../version.entities xml - rm sgml-build.log - touch sgml-build.stamp - -sgml.stamp: sgml-build.stamp - @true - -#### build html; done on every step #### - -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) - @echo '*** Building HTML ***' - if test -d html; then rm -rf html; fi - mkdir html - cp $(srcdir)/$(DOC_MAIN_SGML_FILE) html - @for f in $(content_files); do cp $(srcdir)/$$f html; done - cp -pr xml html - cp ../version.entities html - cd html && gtkdoc-mkhtml $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) \ - 2>&1 | tee ../html-build.log - @if grep "warning:" html-build.log > /dev/null; then \ - echo "ERROR"; grep "warning:" html-build.log; exit 1; fi - @rm html-build.log - mv html/index.sgml html/index.sgml.bak - $(SED) "s/ href=\"$(DOC_MODULE)\// href=\"$(DOC_MODULE)-@GST_MAJORMINOR@\//g" html/index.sgml.bak >html/index.sgml - rm -f html/index.sgml.bak - rm -f html/$(DOC_MAIN_SGML_FILE) - rm -rf html/xml - rm -f html/version.entities - test "x$(HTML_IMAGES)" = "x" || for i in "" $(HTML_IMAGES) ; do \ - if test "$$i" != ""; then cp $(srcdir)/$$i html ; fi; done - @echo '-- Fixing Crossreferences' - gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) - touch html-build.stamp -else -all-local: -endif - -# FIXME: these rules need a little cleaning up -clean-local: - rm -f *~ *.bak - rm -rf .libs -# clean files generated for tmpl build - -rm -rf tmpl -# clean files copied/generated for nonsrcdir tmpl build - if test x"$(srcdir)" != x. ; then \ - rm -rf $(SCANOBJ_FILES) $(SCAN_FILES); \ - fi -# clean files generated for xml build - -rm -rf xml -# clean files generate for html build - -rm -rf html - -distclean-local: clean - rm -rf tmpl/*.sgml.bak - rm -f *.stamp || true - rm -rf *.o - -# thomas: make docs parallel installable; devhelp requires majorminor too -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) - (installfiles=`echo ./html/*.html`; \ - if test "$$installfiles" = './html/*.html'; \ - then echo '-- Nothing to install' ; \ - else \ - for i in $$installfiles; do \ - echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - pngfiles=`echo ./html/*.png`; \ - if test "$$pngfiles" != './html/*.png'; then \ - for i in $$pngfiles; do \ - echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - fi; \ - echo '-- Installing $(srcdir)/html/$(DOC_MODULE).devhelp' ; \ - $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp \ - $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ - if test -e $(srcdir)/html/$(DOC_MODULE).devhelp2; then \ - $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp2 \ - $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ - fi; \ - echo '-- Installing $(srcdir)/html/index.sgml' ; \ - $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ - if test -e $(srcdir)/html/style.css; then \ - echo '-- Installing $(srcdir)/html/style.css' ; \ - $(INSTALL_DATA) $(srcdir)/html/style.css $(DESTDIR)$(TARGET_DIR); \ - fi; \ - fi) -uninstall-local: - (installfiles=`echo ./html/*.html`; \ - if test "$$installfiles" = './html/*.html'; \ - then echo '-- Nothing to uninstall' ; \ - else \ - for i in $$installfiles; do \ - rmfile=`basename $$i` ; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ - done; \ - pngfiles=`echo ./html/*.png`; \ - if test "$$pngfiles" != './html/*.png'; then \ - for i in $$pngfiles; do \ - rmfile=`basename $$i` ; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ - done; \ - fi; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ - if test -e $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; then \ - rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ - fi; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ - if test -e $(DESTDIR)$(TARGET_DIR)/style.css; then \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/style.css' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/style.css; \ - fi; \ - fi) - if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi; true - -# -# Checks -# -check-hierarchy: $(DOC_MODULE).hierarchy - @if grep ' ' $(DOC_MODULE).hierarchy; then \ - echo "$(DOC_MODULE).hierarchy contains tabs, please fix"; \ - /bin/false; \ - fi - -check: check-hierarchy - -# wildcard is apparently not portable to other makes, hence the use of find -inspect_files = $(shell find $(top_srcdir)/docs/plugins/inspect -name '*.xml') - -check-inspected-versions: - @echo Checking plugin versions of inspected plugin data ...; \ - fail=0 ; \ - for each in $(inspect_files) ; do \ - if (grep -H '' $$each | grep -v '$(VERSION)'); then \ - echo $$each should be fixed to say version $(VERSION) or be removed ; \ - echo "sed -i -e 's//$(VERSION)<\/version>/'" $$each; \ - echo ; \ - fail=1; \ - fi ; \ - done ; \ - exit $$fail - -# -# Require gtk-doc when making dist -# -if ENABLE_GTK_DOC -dist-check-gtkdoc: -else -dist-check-gtkdoc: - @echo "*** gtk-doc must be installed and enabled in order to make dist" - @false -endif - -# FIXME: decide whether we want to dist generated html or not -dist-hook: dist-check-gtkdoc dist-hook-local - mkdir $(distdir)/tmpl - mkdir $(distdir)/xml - mkdir $(distdir)/html - -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl - -cp $(srcdir)/sgml/*.xml $(distdir)/xml - -cp $(srcdir)/html/index.sgml $(distdir)/html - -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html - -cp $(srcdir)/html/$(DOC_MODULE).devhelp* $(distdir)/html - - images=$(HTML_IMAGES) ; \ - for i in "" $$images ; do \ - if test "$$i" != ""; then cp $(srcdir)/$$i $(distdir)/html ; fi; \ - done - -.PHONY : dist-hook-local - diff --git a/mobile/common/gtk-doc.mak b/mobile/common/gtk-doc.mak deleted file mode 100755 index 1c9ece1..0000000 --- a/mobile/common/gtk-doc.mak +++ /dev/null @@ -1,267 +0,0 @@ -########################################################################### -# Everything below here is generic and you shouldn't need to change it. -########################################################################### -# thomas: except of course that we did - -# thomas: copied from glib-2 -# We set GPATH here; this gives us semantics for GNU make -# which are more like other make's VPATH, when it comes to -# whether a source that is a target of one rule is then -# searched for in VPATH/GPATH. -# -GPATH = $(srcdir) - -# thomas: make docs parallel installable -TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@ - -EXTRA_DIST = \ - $(content_files) \ - $(extra_files) \ - $(HTML_IMAGES) \ - $(DOC_MAIN_SGML_FILE) \ - $(DOC_MODULE).types \ - $(DOC_OVERRIDES) \ - $(DOC_MODULE)-sections.txt - -DOC_STAMPS = \ - scan-build.stamp \ - tmpl-build.stamp \ - sgml-build.stamp \ - html-build.stamp \ - $(srcdir)/tmpl.stamp \ - $(srcdir)/sgml.stamp \ - $(srcdir)/html.stamp - -SCANOBJ_FILES = \ - $(DOC_MODULE).args \ - $(DOC_MODULE).hierarchy \ - $(DOC_MODULE).interfaces \ - $(DOC_MODULE).prerequisites \ - .libs/$(DOC_MODULE)-scan.o \ - $(DOC_MODULE).signals - -REPORT_FILES = \ - $(DOC_MODULE)-undocumented.txt \ - $(DOC_MODULE)-undeclared.txt \ - $(DOC_MODULE)-unused.txt - -CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) - -if ENABLE_GTK_DOC -all-local: html-build.stamp - -#### scan #### - -# in the case of non-srcdir builds, the built gst directory gets added -# to gtk-doc scanning; but only then, to avoid duplicates -scan-build.stamp: $(HFILE_GLOB) $(SCANOBJ_DEPS) $(basefiles) - @echo '*** Scanning header files ***' - if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null; \ - then \ - if test x"$(srcdir)" != x. ; then \ - cp $(srcdir)/$(DOC_MODULE).types . ; \ - chmod u+w $(DOC_MODULE).types ; \ - fi ; \ - GST_PLUGIN_SYSTEM_PATH=`cd $(top_builddir) && pwd` \ - GST_PLUGIN_PATH= \ - CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" \ - CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" \ - gtkdoc-scangobj --type-init-func="gst_init(NULL,NULL)" \ - --module=$(DOC_MODULE) ; \ - else \ - cd $(srcdir) ; \ - for i in $(SCANOBJ_FILES) ; do \ - test -f $$i || touch $$i ; \ - done \ - fi - if test "x$(top_srcdir)" != "x$(top_builddir)"; \ - then \ - export BUILT_OPTIONS="--source-dir=$(DOC_BUILD_DIR)"; \ - fi; \ - gtkdoc-scan \ - $(SCAN_OPTIONS) $(EXTRA_HFILES) \ - --module=$(DOC_MODULE) \ - --source-dir=$(DOC_SOURCE_DIR) \ - $$BUILT_OPTIONS \ - --ignore-headers="$(IGNORE_HFILES)" - touch scan-build.stamp - -$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp - @true - -#### templates #### - -tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES) - @echo '*** Rebuilding template files ***' - if test x"$(srcdir)" != x. ; then \ - cp $(srcdir)/$(DOC_MODULE)-sections.txt . ; \ - touch $(DOC_MODULE)-decl.txt ; \ - fi - gtkdoc-mktmpl --module=$(DOC_MODULE) | tee tmpl-build.log - @if test -s $(DOC_MODULE)-unused.txt; then \ - exit $(if $(DOCS_ARE_INCOMPLETE_PLEASE_FIXME),0,1); fi - rm -f tmpl-build.log - touch tmpl-build.stamp - -tmpl.stamp: tmpl-build.stamp - @true - -#### xml #### - -### FIXME: make this error out again when docs are complete -sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) - @echo '*** Building XML ***' - gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS) | tee sgml-build.log - @if grep "WARNING:" sgml-build.log > /dev/null; then true; fi # exit 1; fi - rm sgml-build.log - touch sgml-build.stamp - -sgml.stamp: sgml-build.stamp - @true - -#### html #### - -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) - @echo '*** Building HTML ***' - if test -d html; then rm -rf html; fi - mkdir html - cp $(srcdir)/$(DOC_MAIN_SGML_FILE) html - @for f in $(content_files); do cp $(srcdir)/$$f html; done - cp -pr xml html - cp ../version.entities html - cd html && gtkdoc-mkhtml $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) - mv html/index.sgml html/index.sgml.bak - $(SED) "s/ href=\"$(DOC_MODULE)\// href=\"$(DOC_MODULE)-@GST_MAJORMINOR@\//g" html/index.sgml.bak >html/index.sgml - rm -f html/index.sgml.bak - rm -f html/$(DOC_MAIN_SGML_FILE) - rm -rf html/xml - rm -f html/version.entities - test "x$(HTML_IMAGES)" = "x" || for i in "" $(HTML_IMAGES) ; do \ - if test "$$i" != ""; then cp $(srcdir)/$$i html ; fi; done - @echo '-- Fixing Crossreferences' - gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) - touch html-build.stamp -else -all-local: -endif - -clean-local: - rm -f *~ *.bak - rm -rf xml html - rm -rf .libs - -maintainer-clean-local: clean - cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt - -# company: don't delete .sgml and -sections.txt as they're in CVS -# FIXME : thomas added all sgml files and some other things to make -# make distcheck work -distclean-local: clean - rm -f $(DOC_MODULE)-decl-list.txt - rm -f $(DOC_MODULE)-decl.txt - rm -f $(REPORT_FILES) - rm -rf tmpl/*.sgml.bak - rm -f $(DOC_MODULE).hierarchy - rm -f *.stamp || true - if test x"$(srcdir)" != x. ; then \ - rm -f $(DOC_MODULE)-docs.sgml ; \ - rm -f $(DOC_MODULE).types ; \ - rm -f $(DOC_MODULE).interfaces ; \ - rm -f $(DOC_MODULE)-overrides.txt ; \ - rm -f $(DOC_MODULE).prerequisites ; \ - rm -f $(DOC_MODULE)-sections.txt ; \ - rm -rf tmpl/*.sgml ; \ - fi - rm -rf *.o - -# thomas: make docs parallel installable; devhelp requires majorminor too -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) - (installfiles=`echo ./html/*.html`; \ - if test "$$installfiles" = './html/*.html'; \ - then echo '-- Nothing to install' ; \ - else \ - for i in $$installfiles; do \ - echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - pngfiles=`echo ./html/*.png`; \ - if test "$$pngfiles" != './html/*.png'; then \ - for i in $$pngfiles; do \ - echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - fi; \ - echo '-- Installing $(srcdir)/html/$(DOC_MODULE).devhelp' ; \ - $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp \ - $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ - if test -e $(srcdir)/html/$(DOC_MODULE).devhelp2; then \ - $(INSTALL_DATA) $(srcdir)/html/$(DOC_MODULE).devhelp2 \ - $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ - fi; \ - echo '-- Installing $(srcdir)/html/index.sgml' ; \ - $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \ - if test -e $(srcdir)/html/style.css; then \ - echo '-- Installing $(srcdir)/html/style.css' ; \ - $(INSTALL_DATA) $(srcdir)/html/style.css $(DESTDIR)$(TARGET_DIR); \ - fi; \ - fi) -uninstall-local: - (installfiles=`echo ./html/*.html`; \ - if test "$$installfiles" = './html/*.html'; \ - then echo '-- Nothing to uninstall' ; \ - else \ - for i in $$installfiles; do \ - rmfile=`basename $$i` ; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ - done; \ - pngfiles=`echo ./html/*.png`; \ - if test "$$pngfiles" != './html/*.png'; then \ - for i in $$pngfiles; do \ - rmfile=`basename $$i` ; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \ - done; \ - fi; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \ - if test -e $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; then \ - rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp2; \ - fi; \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ - if test -e $(DESTDIR)$(TARGET_DIR)/style.css; then \ - echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/style.css' ; \ - rm -f $(DESTDIR)$(TARGET_DIR)/style.css; \ - fi; \ - fi) - if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi; true - -# -# Require gtk-doc when making dist -# -if ENABLE_GTK_DOC -dist-check-gtkdoc: -else -dist-check-gtkdoc: - @echo "*** gtk-doc must be installed and enabled in order to make dist" - @false -endif - -dist-hook: dist-check-gtkdoc dist-hook-local - mkdir $(distdir)/tmpl - mkdir $(distdir)/xml - mkdir $(distdir)/html - -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl - -cp $(srcdir)/sgml/*.xml $(distdir)/xml - -cp $(srcdir)/html/index.sgml $(distdir)/html - -cp $(srcdir)/html/*.html $(srcdir)/html/*.css $(distdir)/html - -cp $(srcdir)/html/$(DOC_MODULE).devhelp* $(distdir)/html - - images=$(HTML_IMAGES) ; \ - for i in "" $$images ; do \ - if test "$$i" != ""; then cp $(srcdir)/$$i $(distdir)/html ; fi; \ - done - -.PHONY : dist-hook-local diff --git a/mobile/common/m4/Makefile.am b/mobile/common/m4/Makefile.am deleted file mode 100644 index 99ead5c..0000000 --- a/mobile/common/m4/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -EXTRA_DIST = \ - README \ - as-ac-expand.m4 \ - as-auto-alt.m4 \ - as-compiler-flag.m4 \ - as-compiler.m4 \ - as-docbook.m4 \ - as-gcc-inline-assembly.m4 \ - as-libtool.m4 \ - as-libtool-tags.m4 \ - as-python.m4 \ - as-scrub-include.m4 \ - as-version.m4 \ - ax_create_stdint_h.m4 \ - glib-gettext.m4 \ - gst-arch.m4 \ - gst-args.m4 \ - gst-check.m4 \ - gst-debuginfo.m4 \ - gst-default.m4 \ - gst-doc.m4 \ - gst-feature.m4 \ - gst-function.m4 \ - gst-gettext.m4 \ - gst-glib2.m4 \ - gst-libxml2.m4 \ - gst-plugindir.m4 \ - gst-valgrind.m4 \ - pkg.m4 diff --git a/mobile/common/m4/README b/mobile/common/m4/README deleted file mode 100755 index f044598..0000000 --- a/mobile/common/m4/README +++ /dev/null @@ -1,3 +0,0 @@ -All aclocal .m4 files we need are put here and cat'd to acinclude.m4 in -the source root. Official ones (taken from the relevant devel packages) -are named as-is, unofficial ones (or changed ones) get a gst-prefix. diff --git a/mobile/common/m4/as-ac-expand.m4 b/mobile/common/m4/as-ac-expand.m4 deleted file mode 100755 index d6c9e33..0000000 --- a/mobile/common/m4/as-ac-expand.m4 +++ /dev/null @@ -1,43 +0,0 @@ -dnl as-ac-expand.m4 0.2.0 -dnl autostars m4 macro for expanding directories using configure's prefix -dnl thomas@apestaart.org - -dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) -dnl example -dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) -dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local - -AC_DEFUN([AS_AC_EXPAND], -[ - EXP_VAR=[$1] - FROM_VAR=[$2] - - dnl first expand prefix and exec_prefix if necessary - prefix_save=$prefix - exec_prefix_save=$exec_prefix - - dnl if no prefix given, then use /usr/local, the default prefix - if test "x$prefix" = "xNONE"; then - prefix="$ac_default_prefix" - fi - dnl if no exec_prefix given, then use prefix - if test "x$exec_prefix" = "xNONE"; then - exec_prefix=$prefix - fi - - full_var="$FROM_VAR" - dnl loop until it doesn't change anymore - while true; do - new_full_var="`eval echo $full_var`" - if test "x$new_full_var" = "x$full_var"; then break; fi - full_var=$new_full_var - done - - dnl clean up - full_var=$new_full_var - AC_SUBST([$1], "$full_var") - - dnl restore prefix and exec_prefix - prefix=$prefix_save - exec_prefix=$exec_prefix_save -]) diff --git a/mobile/common/m4/as-auto-alt.m4 b/mobile/common/m4/as-auto-alt.m4 deleted file mode 100755 index 3f7920d..0000000 --- a/mobile/common/m4/as-auto-alt.m4 +++ /dev/null @@ -1,50 +0,0 @@ -dnl as-auto-alt.m4 0.0.2 -dnl autostars m4 macro for supplying alternate autotools versions to configure -dnl thomas@apestaart.org -dnl -dnl AS_AUTOTOOLS_ALTERNATE() -dnl -dnl supplies --with arguments for autoconf, autoheader, automake, aclocal - -AC_DEFUN([AS_AUTOTOOLS_ALTERNATE], -[ - dnl allow for different autoconf version - AC_ARG_WITH(autoconf, - AC_HELP_STRING([--with-autoconf], - [use a different autoconf for regeneration of Makefiles]), - [ - unset AUTOCONF - AM_MISSING_PROG(AUTOCONF, ${withval}) - AC_MSG_NOTICE([Using $AUTOCONF as autoconf]) - ]) - - dnl allow for different autoheader version - AC_ARG_WITH(autoheader, - AC_HELP_STRING([--with-autoheader], - [use a different autoheader for regeneration of Makefiles]), - [ - unset AUTOHEADER - AM_MISSING_PROG(AUTOHEADER, ${withval}) - AC_MSG_NOTICE([Using $AUTOHEADER as autoheader]) - ]) - - dnl allow for different automake version - AC_ARG_WITH(automake, - AC_HELP_STRING([--with-automake], - [use a different automake for regeneration of Makefiles]), - [ - unset AUTOMAKE - AM_MISSING_PROG(AUTOMAKE, ${withval}) - AC_MSG_NOTICE([Using $AUTOMAKE as automake]) - ]) - - dnl allow for different aclocal version - AC_ARG_WITH(aclocal, - AC_HELP_STRING([--with-aclocal], - [use a different aclocal for regeneration of Makefiles]), - [ - unset ACLOCAL - AM_MISSING_PROG(ACLOCAL, ${withval}) - AC_MSG_NOTICE([Using $ACLOCAL as aclocal]) - ]) -]) diff --git a/mobile/common/m4/as-compiler-flag.m4 b/mobile/common/m4/as-compiler-flag.m4 deleted file mode 100755 index 882a4c7..0000000 --- a/mobile/common/m4/as-compiler-flag.m4 +++ /dev/null @@ -1,64 +0,0 @@ -dnl as-compiler-flag.m4 0.1.0 - -dnl autostars m4 macro for detection of compiler flags - -dnl David Schleef -dnl Tim-Philipp Müller - -dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_COMPILER_FLAG], -[ - AC_MSG_CHECKING([to see if compiler understands $1]) - - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - $2 - true - else - $3 - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - -dnl AS_CXX_COMPILER_FLAG(CPPFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CPPFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_CXX_COMPILER_FLAG], -[ - AC_REQUIRE([AC_PROG_CXX]) - - AC_MSG_CHECKING([to see if c++ compiler understands $1]) - - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $1" - - AC_LANG_PUSH(C++) - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CPPFLAGS="$save_CPPFLAGS" - - if test "X$flag_ok" = Xyes ; then - $2 - true - else - $3 - true - fi - - AC_LANG_POP(C++) - - AC_MSG_RESULT([$flag_ok]) -]) - diff --git a/mobile/common/m4/as-compiler.m4 b/mobile/common/m4/as-compiler.m4 deleted file mode 100755 index 233a719..0000000 --- a/mobile/common/m4/as-compiler.m4 +++ /dev/null @@ -1,44 +0,0 @@ -dnl as-compiler.m4 0.1.0 - -dnl autostars m4 macro for detection of compiler flavor - -dnl Thomas Vander Stichele - -dnl $Id: as-compiler.m4,v 1.4 2004/06/01 09:33:45 thomasvs Exp $ - -dnl AS_COMPILER(COMPILER) -dnl will set variable COMPILER to -dnl - gcc -dnl - forte -dnl - (empty) if no guess could be made - -AC_DEFUN([AS_COMPILER], -[ - as_compiler= - AC_MSG_CHECKING(for compiler flavour) - - dnl is it gcc ? - if test "x$GCC" = "xyes"; then - as_compiler="gcc" - fi - - dnl is it forte ? - AC_TRY_RUN([ -int main -(int argc, char *argv[]) -{ -#ifdef __sun - return 0; -#else - return 1; -#endif -} - ], as_compiler="forte", ,) - - if test "x$as_compiler" = "x"; then - AC_MSG_RESULT([unknown !]) - else - AC_MSG_RESULT($as_compiler) - fi - [$1]=$as_compiler -]) diff --git a/mobile/common/m4/as-docbook.m4 b/mobile/common/m4/as-docbook.m4 deleted file mode 100755 index 8a1b32a..0000000 --- a/mobile/common/m4/as-docbook.m4 +++ /dev/null @@ -1,66 +0,0 @@ -dnl AS_DOCBOOK([, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl checks if xsltproc can build docbook documentation -dnl (which is possible if the catalog is set up properly -dnl I also tried checking for a specific version and type of docbook -dnl but xsltproc seemed to happily run anyway, so we can't check for that -dnl and version -dnl this macro takes inspiration from -dnl http://www.movement.uklinux.net/docs/docbook-autotools/configure.html -AC_DEFUN([AS_DOCBOOK], -[ - XSLTPROC_FLAGS=--nonet - DOCBOOK_ROOT= - TYPE_LC=xml - TYPE_UC=XML - DOCBOOK_VERSION=4.1.2 - - if test ! -f /etc/xml/catalog; then - for i in /usr/share/sgml/docbook/stylesheet/xsl/nwalsh /usr/share/sgml/docbook/xsl-stylesheets/ /usr/local/share/xsl/docbook ; - do - if test -d "$i"; then - DOCBOOK_ROOT=$i - fi - done - else - XML_CATALOG=/etc/xml/catalog - CAT_ENTRY_START='' - fi - - dnl We need xsltproc to process the test - AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,) - XSLTPROC_WORKS=no - if test -n "$XSLTPROC"; then - AC_MSG_CHECKING([whether xsltproc docbook processing works]) - - if test -n "$XML_CATALOG"; then - DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl" - else - DB_FILE="$DOCBOOK_ROOT/xhtml/docbook.xsl" - fi - $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END - - - - -END - if test "$?" = 0; then - XSLTPROC_WORKS=yes - fi - AC_MSG_RESULT($XSLTPROC_WORKS) - fi - - if test "x$XSLTPROC_WORKS" = "xyes"; then - dnl execute ACTION-IF-FOUND - ifelse([$1], , :, [$1]) - else - dnl execute ACTION-IF-NOT-FOUND - ifelse([$2], , :, [$2]) - fi - - AC_SUBST(XML_CATALOG) - AC_SUBST(XSLTPROC_FLAGS) - AC_SUBST(DOCBOOK_ROOT) - AC_SUBST(CAT_ENTRY_START) - AC_SUBST(CAT_ENTRY_END) -]) diff --git a/mobile/common/m4/as-gcc-inline-assembly.m4 b/mobile/common/m4/as-gcc-inline-assembly.m4 deleted file mode 100755 index 799e80e..0000000 --- a/mobile/common/m4/as-gcc-inline-assembly.m4 +++ /dev/null @@ -1,52 +0,0 @@ -dnl as-gcc-inline-assembly.m4 0.1.0 - -dnl autostars m4 macro for detection of gcc inline assembly - -dnl David Schleef - -dnl $Id: as-gcc-inline-assembly.m4,v 1.1 2008-02-26 09:38:00 thaytan Exp $ - -dnl AS_COMPILER_FLAG(ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_GCC_INLINE_ASSEMBLY], -[ - AC_MSG_CHECKING([if compiler supports gcc-style inline assembly]) - - AC_TRY_COMPILE([], [ -#ifdef __GNUC_MINOR__ -#if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004 -#error GCC before 3.4 has critical bugs compiling inline assembly -#endif -#endif -__asm__ (""::) ], [flag_ok=yes], [flag_ok=no]) - - if test "X$flag_ok" = Xyes ; then - $1 - true - else - $2 - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - - -AC_DEFUN([AS_GCC_ASM_POWERPC_FPU], -[ - AC_MSG_CHECKING([if compiler supports FPU instructions on PowerPC]) - - AC_TRY_COMPILE([], [__asm__ ("fadd 0,0,0"::) ], [flag_ok=yes], [flag_ok=no]) - - if test "X$flag_ok" = Xyes ; then - $1 - true - else - $2 - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - diff --git a/mobile/common/m4/as-libtool-tags.m4 b/mobile/common/m4/as-libtool-tags.m4 deleted file mode 100755 index c522ff2..0000000 --- a/mobile/common/m4/as-libtool-tags.m4 +++ /dev/null @@ -1,83 +0,0 @@ -dnl as-libtool-tags.m4 0.1.4 - -dnl autostars m4 macro for selecting libtool "tags" (languages) - -dnl Andy Wingo does not claim credit for this macro -dnl backported from libtool 1.6 by Paolo Bonzini -dnl see http://lists.gnu.org/archive/html/libtool/2003-12/msg00007.html - -dnl $Id: as-libtool-tags.m4,v 1.3 2006-04-01 15:30:56 thomasvs Exp $ - -dnl AS_LIBTOOL_TAGS([tags...]) - -dnl example -dnl AS_LIBTOOL_TAGS([]) for only C (no fortran, etc) - -dnl When AC_LIBTOOL_TAGS is used, I redefine _LT_AC_TAGCONFIG -dnl to be more similar to the libtool 1.6 implementation, which -dnl uses an m4 loop and m4 case instead of a shell loop. This -dnl way the CXX/GCJ/F77/RC tests are not always expanded. - -dnl AS_LIBTOOL_TAGS -dnl --------------- -dnl tags to enable -AC_DEFUN([AS_LIBTOOL_TAGS], -[m4_define([_LT_TAGS],[$1]) -m4_define([_LT_AC_TAGCONFIG], [ - # redefined LT AC TAGCONFIG - if test -f "$ltmain"; then - if test ! -f "${ofile}"; then - AC_MSG_WARN([output file `$ofile' does not exist]) - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) - else - AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) - fi - fi - - AC_FOREACH([_LT_TAG], _LT_TAGS, - echo THOMAS: tag _LT_TAG - [m4_case(_LT_TAG, - [CXX], [ - if test -n "$CXX" && test "X$CXX" != "Xno"; then - echo "THOMAS: YAY CXX" - AC_LIBTOOL_LANG_CXX_CONFIG - available_tags="$available_tags _LT_TAG" - fi], - [F77], [ - if test -n "$F77" && test "X$F77" != "Xno"; then - AC_LIBTOOL_LANG_F77_CONFIG - available_tags="$available_tags _LT_TAG" - fi], - [GCJ], [ - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - AC_LIBTOOL_LANG_GCJ_CONFIG - available_tags="$available_tags _LT_TAG" - fi], - [RC], [ - if test -n "$RC" && test "X$RC" != "Xno"; then - AC_LIBTOOL_LANG_RC_CONFIG - available_tags="$available_tags _LT_TAG" - fi], - [m4_errprintn(m4_location[: error: invalid tag name: ]"_LT_TAG") - m4_exit(1)]) - ]) - echo THOMAS: available tags: $available_tags - fi - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - AC_MSG_NOTICE([updated available libtool tags with $available_tags.]) - else - rm -f "${ofile}T" - AC_MSG_ERROR([unable to update list of available tagged configurations.]) - - fi - -])dnl _LT_AC_TAG_CONFIG -]) diff --git a/mobile/common/m4/as-libtool.m4 b/mobile/common/m4/as-libtool.m4 deleted file mode 100755 index 73dec1f..0000000 --- a/mobile/common/m4/as-libtool.m4 +++ /dev/null @@ -1,45 +0,0 @@ -dnl as-libtool.m4 0.1.4 - -dnl autostars m4 macro for libtool versioning - -dnl Thomas Vander Stichele - -dnl $Id: as-libtool.m4,v 1.6 2004/06/01 10:04:44 thomasvs Exp $ - -dnl AS_LIBTOOL(PREFIX, CURRENT, REVISION, AGE, [RELEASE]) - -dnl example -dnl AS_LIBTOOL(GST, 2, 0, 0) - -dnl this macro -dnl - defines [$PREFIX]_CURRENT, REVISION and AGE -dnl - defines [$PREFIX]_LIBVERSION -dnl - defines [$PREFIX]_LT_LDFLAGS to set versioning -dnl - AC_SUBST's them all - -dnl if RELEASE is given, then add a -release option to the LDFLAGS -dnl with the given release version -dnl then use [$PREFIX]_LT_LDFLAGS in the relevant Makefile.am's - -dnl call AM_PROG_LIBTOOL after this call - -AC_DEFUN([AS_LIBTOOL], -[ - [$1]_CURRENT=[$2] - [$1]_REVISION=[$3] - [$1]_AGE=[$4] - [$1]_LIBVERSION=[$2]:[$3]:[$4] - AC_SUBST([$1]_CURRENT) - AC_SUBST([$1]_REVISION) - AC_SUBST([$1]_AGE) - AC_SUBST([$1]_LIBVERSION) - - [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -version-info $[$1]_LIBVERSION" - if test ! -z "[$5]" - then - [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -release [$5]" - fi - AC_SUBST([$1]_LT_LDFLAGS) - - AC_LIBTOOL_DLOPEN -]) diff --git a/mobile/common/m4/as-python.m4 b/mobile/common/m4/as-python.m4 deleted file mode 100755 index eb9b175..0000000 --- a/mobile/common/m4/as-python.m4 +++ /dev/null @@ -1,152 +0,0 @@ -## ------------------------ -## Python file handling -## From Andrew Dalke -## Updated by James Henstridge -## Updated by Andy Wingo to loop through possible pythons -## ------------------------ - -# AS_PATH_PYTHON([MINIMUM-VERSION]) - -# Adds support for distributing Python modules and packages. To -# install modules, copy them to $(pythondir), using the python_PYTHON -# automake variable. To install a package with the same name as the -# automake package, install to $(pkgpythondir), or use the -# pkgpython_PYTHON automake variable. - -# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as -# locations to install python extension modules (shared libraries). -# Another macro is required to find the appropriate flags to compile -# extension modules. - -# If your package is configured with a different prefix to python, -# users will have to add the install directory to the PYTHONPATH -# environment variable, or create a .pth file (see the python -# documentation for details). - -# If the MINIMUM-VERSION argument is passed, AS_PATH_PYTHON will -# cause an error if the version of python installed on the system -# doesn't meet the requirement. MINIMUM-VERSION should consist of -# numbers and dots only. - -# Updated to loop over all possible python binaries by Andy Wingo -# -# Updated to only warn and unset PYTHON if no good one is found - -AC_DEFUN([AS_PATH_PYTHON], - [ - dnl Find a version of Python. I could check for python versions 1.4 - dnl or earlier, but the default installation locations changed from - dnl $prefix/lib/site-python in 1.4 to $prefix/lib/python1.5/site-packages - dnl in 1.5, and I don't want to maintain that logic. - - dnl should we do the version check? - PYTHON_CANDIDATES="python python2.2 python2.1 python2.0 python2 \ - python1.6 python1.5" - ifelse([$1],[], - [AC_PATH_PROG(PYTHON, $PYTHON_CANDIDATES)], - [ - AC_MSG_NOTICE(Looking for Python version >= $1) - changequote(<<, >>)dnl - prog=" -import sys, string -minver = '$1' -# split string by '.' and convert to numeric -minver_info = map(string.atoi, string.split(minver, '.')) -# we can now do comparisons on the two lists: -if sys.version_info >= tuple(minver_info): - sys.exit(0) -else: - sys.exit(1)" - changequote([, ])dnl - - python_good=false - for python_candidate in $PYTHON_CANDIDATES; do - unset PYTHON - AC_PATH_PROG(PYTHON, $python_candidate) 1> /dev/null 2> /dev/null - - if test "x$PYTHON" = "x"; then continue; fi - - if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC; then - AC_MSG_CHECKING(["$PYTHON":]) - AC_MSG_RESULT([okay]) - python_good=true - break; - else - dnl clear the cache val - unset ac_cv_path_PYTHON - fi - done - ]) - - if test "$python_good" != "true"; then - AC_MSG_WARN([No suitable version of python found]) - PYTHON= - else - - AC_MSG_CHECKING([local Python configuration]) - - dnl Query Python for its version number. Getting [:3] seems to be - dnl the best way to do this; it's what "site.py" does in the standard - dnl library. Need to change quote character because of [:3] - - AC_SUBST(PYTHON_VERSION) - changequote(<<, >>)dnl - PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[:3]"` - changequote([, ])dnl - - - dnl Use the values of $prefix and $exec_prefix for the corresponding - dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made - dnl distinct variables so they can be overridden if need be. However, - dnl general consensus is that you shouldn't need this ability. - - AC_SUBST(PYTHON_PREFIX) - PYTHON_PREFIX='${prefix}' - - AC_SUBST(PYTHON_EXEC_PREFIX) - PYTHON_EXEC_PREFIX='${exec_prefix}' - - dnl At times (like when building shared libraries) you may want - dnl to know which OS platform Python thinks this is. - - AC_SUBST(PYTHON_PLATFORM) - PYTHON_PLATFORM=`$PYTHON -c "import sys; print sys.platform"` - - - dnl Set up 4 directories: - - dnl pythondir -- where to install python scripts. This is the - dnl site-packages directory, not the python standard library - dnl directory like in previous automake betas. This behaviour - dnl is more consistent with lispdir.m4 for example. - dnl - dnl Also, if the package prefix isn't the same as python's prefix, - dnl then the old $(pythondir) was pretty useless. - - AC_SUBST(pythondir) - pythondir=$PYTHON_PREFIX"/lib/python"$PYTHON_VERSION/site-packages - - dnl pkgpythondir -- $PACKAGE directory under pythondir. Was - dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is - dnl more consistent with the rest of automake. - dnl Maybe this should be put in python.am? - - AC_SUBST(pkgpythondir) - pkgpythondir=\${pythondir}/$PACKAGE - - dnl pyexecdir -- directory for installing python extension modules - dnl (shared libraries) Was PYTHON_SITE_EXEC in previous betas. - - AC_SUBST(pyexecdir) - pyexecdir=$PYTHON_EXEC_PREFIX"/lib/python"$PYTHON_VERSION/site-packages - - dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) - dnl Maybe this should be put in python.am? - - AC_SUBST(pkgpyexecdir) - pkgpyexecdir=\${pyexecdir}/$PACKAGE - - AC_MSG_RESULT([looks good]) - - fi -]) diff --git a/mobile/common/m4/as-scrub-include.m4 b/mobile/common/m4/as-scrub-include.m4 deleted file mode 100755 index 96dfb8f..0000000 --- a/mobile/common/m4/as-scrub-include.m4 +++ /dev/null @@ -1,36 +0,0 @@ -dnl as-scrub-include.m4 0.0.4 - -dnl autostars m4 macro for scrubbing CFLAGS of system include dirs -dnl because gcc 3.x complains about including system including dirs - -dnl Thomas Vander Stichele - -dnl $Id: as-scrub-include.m4,v 1.5 2004/06/12 08:19:09 thomasvs Exp $ - -dnl This macro uses output of cpp -v and expects it to contain text that -dnl looks a little bit like this: -dnl #include <...> search starts here: -dnl /usr/local/include -dnl /usr/lib/gcc-lib/i386-redhat-linux/3.2/include -dnl /usr/include -dnl End of search list. - -dnl AS_SCRUB_INCLUDE(VAR) -dnl example -dnl AS_SCRUB_INCLUDE(CFLAGS) -dnl will remove all system include dirs from the given CFLAGS - -AC_DEFUN([AS_SCRUB_INCLUDE], -[ - GIVEN_CFLAGS=$[$1] - INCLUDE_DIRS=`echo | cpp -v 2>&1` - - dnl remove everything from this output between the "starts here" and "End of" - dnl line - INCLUDE_DIRS=`echo $INCLUDE_DIRS | sed -e 's/.*<...> search starts here://' | sed -e 's/End of search list.*//'` - for dir in $INCLUDE_DIRS; do - dnl use "" as the sed script so $dir gets expanded - GIVEN_CFLAGS=`echo $GIVEN_CFLAGS | sed -e "s#-I$dir ##"` - done - [$1]=$GIVEN_CFLAGS -]) diff --git a/mobile/common/m4/as-version.m4 b/mobile/common/m4/as-version.m4 deleted file mode 100755 index a5b4399..0000000 --- a/mobile/common/m4/as-version.m4 +++ /dev/null @@ -1,71 +0,0 @@ -dnl as-version.m4 0.2.0 - -dnl autostars m4 macro for versioning - -dnl Thomas Vander Stichele - -dnl $Id: as-version.m4,v 1.4 2004/06/01 09:40:05 thomasvs Exp $ - -dnl AS_VERSION - -dnl example -dnl AS_VERSION - -dnl this macro -dnl - AC_SUBST's PACKAGE_VERSION_MAJOR, _MINOR, _MICRO -dnl - AC_SUBST's PACKAGE_VERSION_RELEASE, -dnl which can be used for rpm release fields -dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents -dnl maintainer mode from running correctly -dnl -dnl don't forget to put #undef PACKAGE_VERSION_RELEASE in acconfig.h -dnl if you use acconfig.h - -AC_DEFUN([AS_VERSION], -[ - PACKAGE_VERSION_MAJOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f1) - PACKAGE_VERSION_MINOR=$(echo AC_PACKAGE_VERSION | cut -d'.' -f2) - PACKAGE_VERSION_MICRO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f3) - - AC_SUBST(PACKAGE_VERSION_MAJOR) - AC_SUBST(PACKAGE_VERSION_MINOR) - AC_SUBST(PACKAGE_VERSION_MICRO) -]) - -dnl AS_NANO(ACTION-IF-NO-NANO, [ACTION-IF-NANO]) - -dnl requires AC_INIT to be called before -dnl For projects using a fourth or nano number in your versioning to indicate -dnl development or prerelease snapshots, this macro allows the build to be -dnl set up differently accordingly. - -dnl this macro: -dnl - parses AC_PACKAGE_VERSION, set by AC_INIT, and extracts the nano number -dnl - sets the variable PACKAGE_VERSION_NANO -dnl - sets the variable PACKAGE_VERSION_RELEASE, which can be used -dnl for rpm release fields -dnl - executes ACTION-IF-NO-NANO or ACTION-IF-NANO - -dnl example: -dnl AS_NANO(RELEASE="yes", RELEASE="no") - -AC_DEFUN([AS_NANO], -[ - AC_MSG_CHECKING(nano version) - - NANO=$(echo AC_PACKAGE_VERSION | cut -d'.' -f4) - - if test x"$NANO" = x || test "x$NANO" = "x0" ; then - AC_MSG_RESULT([0 (release)]) - NANO=0 - PACKAGE_VERSION_RELEASE=1 - ifelse([$1], , :, [$1]) - else - AC_MSG_RESULT($NANO) - PACKAGE_VERSION_RELEASE=0.`date +%Y%m%d.%H%M%S` - ifelse([$2], , :, [$2]) - fi - PACKAGE_VERSION_NANO=$NANO - AC_SUBST(PACKAGE_VERSION_NANO) - AC_SUBST(PACKAGE_VERSION_RELEASE) -]) diff --git a/mobile/common/m4/ax_create_stdint_h.m4 b/mobile/common/m4/ax_create_stdint_h.m4 deleted file mode 100755 index 13bf699..0000000 --- a/mobile/common/m4/ax_create_stdint_h.m4 +++ /dev/null @@ -1,734 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_create_stdint_h.html -# -# SYNOPSIS -# -# AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] -# -# DESCRIPTION -# -# the "ISO C9X: 7.18 Integer types " section requires the -# existence of an include file that defines a set of -# typedefs, especially uint8_t,int32_t,uintptr_t. Many older -# installations will not provide this file, but some will have the -# very same definitions in . In other enviroments we can -# use the inet-types in which would define the typedefs -# int8_t and u_int8_t respectivly. -# -# This macros will create a local "_stdint.h" or the headerfile given -# as an argument. In many cases that file will just "#include -# " or "#include ", while in other environments -# it will provide the set of basic 'stdint's definitions/typedefs: -# -# int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t -# int_least32_t.. int_fast32_t.. intmax_t -# -# which may or may not rely on the definitions of other files, or -# using the AC_CHECK_SIZEOF macro to determine the actual sizeof each -# type. -# -# if your header files require the stdint-types you will want to -# create an installable file mylib-int.h that all your other -# installable header may include. So if you have a library package -# named "mylib", just use -# -# AX_CREATE_STDINT_H(mylib-int.h) -# -# in configure.ac and go to install that very header file in -# Makefile.am along with the other headers (mylib.h) - and the -# mylib-specific headers can simply use "#include " to -# obtain the stdint-types. -# -# Remember, if the system already had a valid , the -# generated file will include it directly. No need for fuzzy -# HAVE_STDINT_H things... (oops, GCC 4.2.x has deliberatly disabled -# its stdint.h for non-c99 compilation and the c99-mode is not the -# default. Therefore this macro will not use the compiler's stdint.h -# - please complain to the GCC developers). -# -# LAST MODIFICATION -# -# 2007-06-27 -# -# COPYLEFT -# -# Copyright (c) 2007 Guido U. Draheim -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program 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 -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# -# As a special exception, the respective Autoconf Macro's copyright -# owner gives unlimited permission to copy, distribute and modify the -# configure scripts that are the output of Autoconf when processing -# the Macro. You need not follow the terms of the GNU General Public -# License when using or distributing such scripts, even though -# portions of the text of the Macro appear in them. The GNU General -# Public License (GPL) does govern all other use of the material that -# constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the -# Autoconf Macro released by the Autoconf Macro Archive. When you -# make and distribute a modified version of the Autoconf Macro, you -# may extend this special exception to the GPL to apply to your -# modified version as well. - -AC_DEFUN([AX_CHECK_DATA_MODEL],[ - AC_CHECK_SIZEOF(char) - AC_CHECK_SIZEOF(short) - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(void*) - ac_cv_char_data_model="" - ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char" - ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short" - ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int" - ac_cv_long_data_model="" - ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int" - ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long" - ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp" - AC_MSG_CHECKING([data model]) - case "$ac_cv_char_data_model/$ac_cv_long_data_model" in - 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;; - 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;; - 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;; - 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;; - 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;; - 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;; - 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;; - 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;; - 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;; - 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;; - 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;; - 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;; - 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;; - 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;; - 222/*|333/*|444/*|666/*|888/*) : - ac_cv_data_model="iDSP" ; n="unusual dsptype" ;; - *) ac_cv_data_model="none" ; n="very unusual model" ;; - esac - AC_MSG_RESULT([$ac_cv_data_model ($ac_cv_long_data_model, $n)]) -]) - -dnl AX_CHECK_HEADER_STDINT_X([HEADERLIST][,ACTION-IF]) -AC_DEFUN([AX_CHECK_HEADER_STDINT_X],[ -AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ - ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) - AC_MSG_RESULT([(..)]) - for i in m4_ifval([$1],[$1],[stdint.h inttypes.h sys/inttypes.h sys/types.h]) - do - unset ac_cv_type_uintptr_t - unset ac_cv_type_uint64_t - AC_CHECK_TYPE(uintptr_t,[ac_cv_header_stdint_x=$i],continue,[#include <$i>]) - AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) - m4_ifvaln([$2],[$2]) break - done - AC_MSG_CHECKING([for stdint uintptr_t]) - ]) -]) - -AC_DEFUN([AX_CHECK_HEADER_STDINT_O],[ -AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ - ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) - AC_MSG_RESULT([(..)]) - for i in m4_ifval([$1],[$1],[inttypes.h sys/inttypes.h sys/types.h stdint.h]) - do - unset ac_cv_type_uint32_t - unset ac_cv_type_uint64_t - AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],continue,[#include <$i>]) - AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) - m4_ifvaln([$2],[$2]) break - break; - done - AC_MSG_CHECKING([for stdint uint32_t]) - ]) -]) - -AC_DEFUN([AX_CHECK_HEADER_STDINT_U],[ -AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ - ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) - AC_MSG_RESULT([(..)]) - for i in m4_ifval([$1],[$1],[sys/types.h inttypes.h sys/inttypes.h]) ; do - unset ac_cv_type_u_int32_t - unset ac_cv_type_u_int64_t - AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],continue,[#include <$i>]) - AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) - m4_ifvaln([$2],[$2]) break - break; - done - AC_MSG_CHECKING([for stdint u_int32_t]) - ]) -]) - -AC_DEFUN([AX_CREATE_STDINT_H], -[# ------ AX CREATE STDINT H ------------------------------------- -AC_MSG_CHECKING([for stdint types]) -ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` -# try to shortcircuit - if the default include path of the compiler -# can find a "stdint.h" header then we assume that all compilers can. -AC_CACHE_VAL([ac_cv_header_stdint_t],[ -old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" -old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" -old_CFLAGS="$CFLAGS" ; CFLAGS="" -AC_TRY_COMPILE([#include ],[int_least32_t v = 0;], -[ac_cv_stdint_result="(assuming C99 compatible system)" - ac_cv_header_stdint_t="stdint.h"; ], -[ac_cv_header_stdint_t=""]) -if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then -CFLAGS="-std=c99" -AC_TRY_COMPILE([#include ],[int_least32_t v = 0;], -[AC_MSG_WARN(your GCC compiler has a defunct stdint.h for its default-mode)]) -fi -CXXFLAGS="$old_CXXFLAGS" -CPPFLAGS="$old_CPPFLAGS" -CFLAGS="$old_CFLAGS" ]) - -v="... $ac_cv_header_stdint_h" -if test "$ac_stdint_h" = "stdint.h" ; then - AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) -elif test "$ac_stdint_h" = "inttypes.h" ; then - AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) -elif test "_$ac_cv_header_stdint_t" = "_" ; then - AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) -else - ac_cv_header_stdint="$ac_cv_header_stdint_t" - AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) -fi - -if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. - -dnl .....intro message done, now do a few system checks..... -dnl btw, all old CHECK_TYPE macros do automatically "DEFINE" a type, -dnl therefore we use the autoconf implementation detail CHECK_TYPE_NEW -dnl instead that is triggered with 3 or more arguments (see types.m4) - -inttype_headers=`echo $2 | sed -e 's/,/ /g'` - -ac_cv_stdint_result="(no helpful system typedefs seen)" -AX_CHECK_HEADER_STDINT_X(dnl - stdint.h inttypes.h sys/inttypes.h $inttype_headers, - ac_cv_stdint_result="(seen uintptr_t$and64 in $i)") - -if test "_$ac_cv_header_stdint_x" = "_" ; then -AX_CHECK_HEADER_STDINT_O(dnl, - inttypes.h sys/inttypes.h stdint.h $inttype_headers, - ac_cv_stdint_result="(seen uint32_t$and64 in $i)") -fi - -if test "_$ac_cv_header_stdint_x" = "_" ; then -if test "_$ac_cv_header_stdint_o" = "_" ; then -AX_CHECK_HEADER_STDINT_U(dnl, - sys/types.h inttypes.h sys/inttypes.h $inttype_headers, - ac_cv_stdint_result="(seen u_int32_t$and64 in $i)") -fi fi - -dnl if there was no good C99 header file, do some typedef checks... -if test "_$ac_cv_header_stdint_x" = "_" ; then - AC_MSG_CHECKING([for stdint datatype model]) - AC_MSG_RESULT([(..)]) - AX_CHECK_DATA_MODEL -fi - -if test "_$ac_cv_header_stdint_x" != "_" ; then - ac_cv_header_stdint="$ac_cv_header_stdint_x" -elif test "_$ac_cv_header_stdint_o" != "_" ; then - ac_cv_header_stdint="$ac_cv_header_stdint_o" -elif test "_$ac_cv_header_stdint_u" != "_" ; then - ac_cv_header_stdint="$ac_cv_header_stdint_u" -else - ac_cv_header_stdint="stddef.h" -fi - -AC_MSG_CHECKING([for extra inttypes in chosen header]) -AC_MSG_RESULT([($ac_cv_header_stdint)]) -dnl see if int_least and int_fast types are present in _this_ header. -unset ac_cv_type_int_least32_t -unset ac_cv_type_int_fast32_t -AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) -AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) -AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) - -fi # shortcircut to system "stdint.h" -# ------------------ PREPARE VARIABLES ------------------------------ -if test "$GCC" = "yes" ; then -ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` -else -ac_cv_stdint_message="using $CC" -fi - -AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl -$ac_cv_stdint_result]) - -dnl ----------------------------------------------------------------- -# ----------------- DONE inttypes.h checks START header ------------- -AC_CONFIG_COMMANDS([$ac_stdint_h],[ -AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) -ac_stdint=$tmp/_stdint.h - -echo "#ifndef" $_ac_stdint_h >$ac_stdint -echo "#define" $_ac_stdint_h "1" >>$ac_stdint -echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint -echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint -echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint -if test "_$ac_cv_header_stdint_t" != "_" ; then -echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint -echo "#include " >>$ac_stdint -echo "#endif" >>$ac_stdint -echo "#endif" >>$ac_stdint -else - -cat >>$ac_stdint < -#else -#include - -/* .................... configured part ............................ */ - -STDINT_EOF - -echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint -if test "_$ac_cv_header_stdint_x" != "_" ; then - ac_header="$ac_cv_header_stdint_x" - echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint -else - echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint -fi - -echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint -if test "_$ac_cv_header_stdint_o" != "_" ; then - ac_header="$ac_cv_header_stdint_o" - echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint -else - echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint -fi - -echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint -if test "_$ac_cv_header_stdint_u" != "_" ; then - ac_header="$ac_cv_header_stdint_u" - echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint -else - echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint -fi - -echo "" >>$ac_stdint - -if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then - echo "#include <$ac_header>" >>$ac_stdint - echo "" >>$ac_stdint -fi fi - -echo "/* which 64bit typedef has been found */" >>$ac_stdint -if test "$ac_cv_type_uint64_t" = "yes" ; then -echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint -else -echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint -fi -if test "$ac_cv_type_u_int64_t" = "yes" ; then -echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint -else -echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint -fi -echo "" >>$ac_stdint - -echo "/* which type model has been detected */" >>$ac_stdint -if test "_$ac_cv_char_data_model" != "_" ; then -echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint -echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint -else -echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint -echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint -fi -echo "" >>$ac_stdint - -echo "/* whether int_least types were detected */" >>$ac_stdint -if test "$ac_cv_type_int_least32_t" = "yes"; then -echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint -else -echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint -fi -echo "/* whether int_fast types were detected */" >>$ac_stdint -if test "$ac_cv_type_int_fast32_t" = "yes"; then -echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint -else -echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint -fi -echo "/* whether intmax_t type was detected */" >>$ac_stdint -if test "$ac_cv_type_intmax_t" = "yes"; then -echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint -else -echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint -fi -echo "" >>$ac_stdint - - cat >>$ac_stdint <= 199901L -#define _HAVE_UINT64_T -#define _HAVE_LONGLONG_UINT64_T -typedef long long int64_t; -typedef unsigned long long uint64_t; - -#elif !defined __STRICT_ANSI__ -#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ -#define _HAVE_UINT64_T -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; - -#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ -/* note: all ELF-systems seem to have loff-support which needs 64-bit */ -#if !defined _NO_LONGLONG -#define _HAVE_UINT64_T -#define _HAVE_LONGLONG_UINT64_T -typedef long long int64_t; -typedef unsigned long long uint64_t; -#endif - -#elif defined __alpha || (defined __mips && defined _ABIN32) -#if !defined _NO_LONGLONG -typedef long int64_t; -typedef unsigned long uint64_t; -#endif - /* compiler/cpu type to define int64_t */ -#endif -#endif -#endif - -#if defined _STDINT_HAVE_U_INT_TYPES -/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ -typedef u_int8_t uint8_t; -typedef u_int16_t uint16_t; -typedef u_int32_t uint32_t; - -/* glibc compatibility */ -#ifndef __int8_t_defined -#define __int8_t_defined -#endif -#endif - -#ifdef _STDINT_NEED_INT_MODEL_T -/* we must guess all the basic types. Apart from byte-adressable system, */ -/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ -/* (btw, those nibble-addressable systems are way off, or so we assume) */ - -dnl /* have a look at "64bit and data size neutrality" at */ -dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ -dnl /* (the shorthand "ILP" types always have a "P" part) */ - -#if defined _STDINT_BYTE_MODEL -#if _STDINT_LONG_MODEL+0 == 242 -/* 2:4:2 = IP16 = a normal 16-bit system */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -#ifndef __int8_t_defined -#define __int8_t_defined -typedef char int8_t; -typedef short int16_t; -typedef long int32_t; -#endif -#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 -/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ -/* 4:4:4 = ILP32 = a normal 32-bit system */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -#ifndef __int8_t_defined -#define __int8_t_defined -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -#endif -#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 -/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ -/* 4:8:8 = LP64 = a normal 64-bit system */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -#ifndef __int8_t_defined -#define __int8_t_defined -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -#endif -/* this system has a "long" of 64bit */ -#ifndef _HAVE_UINT64_T -#define _HAVE_UINT64_T -typedef unsigned long uint64_t; -typedef long int64_t; -#endif -#elif _STDINT_LONG_MODEL+0 == 448 -/* LLP64 a 64-bit system derived from a 32-bit system */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -#ifndef __int8_t_defined -#define __int8_t_defined -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -#endif -/* assuming the system has a "long long" */ -#ifndef _HAVE_UINT64_T -#define _HAVE_UINT64_T -#define _HAVE_LONGLONG_UINT64_T -typedef unsigned long long uint64_t; -typedef long long int64_t; -#endif -#else -#define _STDINT_NO_INT32_T -#endif -#else -#define _STDINT_NO_INT8_T -#define _STDINT_NO_INT32_T -#endif -#endif - -/* - * quote from SunOS-5.8 sys/inttypes.h: - * Use at your own risk. As of February 1996, the committee is squarely - * behind the fixed sized types; the "least" and "fast" types are still being - * discussed. The probability that the "fast" types may be removed before - * the standard is finalized is high enough that they are not currently - * implemented. - */ - -#if defined _STDINT_NEED_INT_LEAST_T -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -#ifdef _HAVE_UINT64_T -typedef int64_t int_least64_t; -#endif - -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -#ifdef _HAVE_UINT64_T -typedef uint64_t uint_least64_t; -#endif - /* least types */ -#endif - -#if defined _STDINT_NEED_INT_FAST_T -typedef int8_t int_fast8_t; -typedef int int_fast16_t; -typedef int32_t int_fast32_t; -#ifdef _HAVE_UINT64_T -typedef int64_t int_fast64_t; -#endif - -typedef uint8_t uint_fast8_t; -typedef unsigned uint_fast16_t; -typedef uint32_t uint_fast32_t; -#ifdef _HAVE_UINT64_T -typedef uint64_t uint_fast64_t; -#endif - /* fast types */ -#endif - -#ifdef _STDINT_NEED_INTMAX_T -#ifdef _HAVE_UINT64_T -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; -#else -typedef long intmax_t; -typedef unsigned long uintmax_t; -#endif -#endif - -#ifdef _STDINT_NEED_INTPTR_T -#ifndef __intptr_t_defined -#define __intptr_t_defined -/* we encourage using "long" to store pointer values, never use "int" ! */ -#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 -typedef unsigned int uintptr_t; -typedef int intptr_t; -#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 -typedef unsigned long uintptr_t; -typedef long intptr_t; -#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T -typedef uint64_t uintptr_t; -typedef int64_t intptr_t; -#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ -typedef unsigned long uintptr_t; -typedef long intptr_t; -#endif -#endif -#endif - -/* The ISO C99 standard specifies that in C++ implementations these - should only be defined if explicitly requested. */ -#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS -#ifndef UINT32_C - -/* Signed. */ -# define INT8_C(c) c -# define INT16_C(c) c -# define INT32_C(c) c -# ifdef _HAVE_LONGLONG_UINT64_T -# define INT64_C(c) c ## L -# else -# define INT64_C(c) c ## LL -# endif - -/* Unsigned. */ -# define UINT8_C(c) c ## U -# define UINT16_C(c) c ## U -# define UINT32_C(c) c ## U -# ifdef _HAVE_LONGLONG_UINT64_T -# define UINT64_C(c) c ## UL -# else -# define UINT64_C(c) c ## ULL -# endif - -/* Maximal type. */ -# ifdef _HAVE_LONGLONG_UINT64_T -# define INTMAX_C(c) c ## L -# define UINTMAX_C(c) c ## UL -# else -# define INTMAX_C(c) c ## LL -# define UINTMAX_C(c) c ## ULL -# endif - - /* literalnumbers */ -#endif -#endif - -/* These limits are merily those of a two complement byte-oriented system */ - -/* Minimum of signed integral types. */ -# define INT8_MIN (-128) -# define INT16_MIN (-32767-1) -# define INT32_MIN (-2147483647-1) -# define INT64_MIN (-__INT64_C(9223372036854775807)-1) -/* Maximum of signed integral types. */ -# define INT8_MAX (127) -# define INT16_MAX (32767) -# define INT32_MAX (2147483647) -# define INT64_MAX (__INT64_C(9223372036854775807)) - -/* Maximum of unsigned integral types. */ -# define UINT8_MAX (255) -# define UINT16_MAX (65535) -# define UINT32_MAX (4294967295U) -# define UINT64_MAX (__UINT64_C(18446744073709551615)) - -/* Minimum of signed integral types having a minimum size. */ -# define INT_LEAST8_MIN INT8_MIN -# define INT_LEAST16_MIN INT16_MIN -# define INT_LEAST32_MIN INT32_MIN -# define INT_LEAST64_MIN INT64_MIN -/* Maximum of signed integral types having a minimum size. */ -# define INT_LEAST8_MAX INT8_MAX -# define INT_LEAST16_MAX INT16_MAX -# define INT_LEAST32_MAX INT32_MAX -# define INT_LEAST64_MAX INT64_MAX - -/* Maximum of unsigned integral types having a minimum size. */ -# define UINT_LEAST8_MAX UINT8_MAX -# define UINT_LEAST16_MAX UINT16_MAX -# define UINT_LEAST32_MAX UINT32_MAX -# define UINT_LEAST64_MAX UINT64_MAX - - /* shortcircuit*/ -#endif - /* once */ -#endif -#endif -STDINT_EOF -fi - if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then - AC_MSG_NOTICE([$ac_stdint_h is unchanged]) - else - ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` - AS_MKDIR_P(["$ac_dir"]) - rm -f $ac_stdint_h - mv $ac_stdint $ac_stdint_h - fi -],[# variables for create stdint.h replacement -PACKAGE="$PACKAGE" -VERSION="$VERSION" -ac_stdint_h="$ac_stdint_h" -_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) -ac_cv_stdint_message="$ac_cv_stdint_message" -ac_cv_header_stdint_t="$ac_cv_header_stdint_t" -ac_cv_header_stdint_x="$ac_cv_header_stdint_x" -ac_cv_header_stdint_o="$ac_cv_header_stdint_o" -ac_cv_header_stdint_u="$ac_cv_header_stdint_u" -ac_cv_type_uint64_t="$ac_cv_type_uint64_t" -ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" -ac_cv_char_data_model="$ac_cv_char_data_model" -ac_cv_long_data_model="$ac_cv_long_data_model" -ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" -ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" -ac_cv_type_intmax_t="$ac_cv_type_intmax_t" -]) -]) diff --git a/mobile/common/m4/check.m4 b/mobile/common/m4/check.m4 deleted file mode 100755 index 19784ae..0000000 --- a/mobile/common/m4/check.m4 +++ /dev/null @@ -1,181 +0,0 @@ -dnl _AM_TRY_CHECK(MINIMUM-VERSION, EXTRA-CFLAGS, EXTRA-LIBS, CHECK-LIB-NAME -dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS -dnl Done this way because of the brokenness that is -dnl https://launchpad.net/distros/ubuntu/+source/check/+bug/5840 -dnl - -AC_DEFUN([_AM_TRY_CHECK], -[ - min_check_version=$1 - extra_cflags=$2 - extra_libs=$3 - check_lib_name=$4 - - CHECK_CFLAGS="$extra_cflags" - CHECK_LIBS="$extra_libs -l$check_lib_name" - - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - - CFLAGS="$CFLAGS $CHECK_CFLAGS" - LIBS="$CHECK_LIBS $LIBS" - - AC_MSG_CHECKING(for check named $check_lib_name - version >= $min_check_version) - - rm -f conf.check-test - dnl unset no_check, since in our second run it would have been set to yes - dnl before - no_check= - AC_TRY_RUN([ -#include -#include - -#include - -int main () -{ - int major, minor, micro; - char *tmp_version; - - system ("touch conf.check-test"); - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = strdup("$min_check_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_check_version"); - return 1; - } - - if ((CHECK_MAJOR_VERSION != check_major_version) || - (CHECK_MINOR_VERSION != check_minor_version) || - (CHECK_MICRO_VERSION != check_micro_version)) - { - printf("\n*** The check header file (version %d.%d.%d) does not match\n", - CHECK_MAJOR_VERSION, CHECK_MINOR_VERSION, CHECK_MICRO_VERSION); - printf("*** the check library (version %d.%d.%d).\n", - check_major_version, check_minor_version, check_micro_version); - return 1; - } - - if ((check_major_version > major) || - ((check_major_version == major) && (check_minor_version > minor)) || - ((check_major_version == major) && (check_minor_version == minor) && (check_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** An old version of check (%d.%d.%d) was found.\n", - check_major_version, check_minor_version, check_micro_version); - printf("*** You need a version of check being at least %d.%d.%d.\n", major, minor, micro); - printf("***\n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the check library and header\n"); - printf("*** file is being found. Rerun configure with the --with-check=PATH option\n"); - printf("*** to specify the prefix where the correct version was installed.\n"); - } - - return 1; -} -],, no_check=yes, [echo $ac_n "cross compiling; assumed OK... $ac_c"]) - - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - - if test "x$no_check" = x ; then - AC_MSG_RESULT(yes) - ifelse([$5], , :, [$5]) - else - AC_MSG_RESULT(no) - if test -f conf.check-test ; then - : - else - echo "*** Could not run check test program, checking why..." - CFLAGS="$CFLAGS $CHECK_CFLAGS" - LIBS="$CHECK_LIBS $LIBS" - AC_TRY_LINK([ -#include -#include - -#include -], , [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding check. You'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for" - echo "*** the exact error that occured." ]) - - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - - CHECK_CFLAGS="" - CHECK_LIBS="" - - rm -f conf.check-test - ifelse([$6], , AC_MSG_ERROR([check not found]), [$6]) - fi -]) - - -dnl AM_PATH_CHECK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for check, and define CHECK_CFLAGS and CHECK_LIBS -dnl - -AC_DEFUN([AM_PATH_CHECK], -[ - AC_ARG_WITH(check, - [ --with-check=PATH prefix where check is installed [default=auto]]) - - AC_ARG_WITH(checklibname, - AC_HELP_STRING([--with-check-lib-name=NAME], - [name of the PIC check library (default=check)])) - - min_check_version=ifelse([$1], ,0.8.2,$1) - - if test x$with_check = xno; then - AC_MSG_RESULT(disabled) - ifelse([$3], , AC_MSG_ERROR([disabling check is not supported]), [$3]) - else - if test "x$with_check" != x; then - CHECK_EXTRA_CFLAGS="-I$with_check/include" - CHECK_EXTRA_LIBS="-L$with_check/lib" - else - CHECK_EXTRA_CFLAGS="" - CHECK_EXTRA_LIBS="" - fi - - if test x$with_checklibname = x; then - _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, - check_pic, [have_check=true], [have_check=false]) - if test x$have_check = xtrue; then - ifelse([$2], , :, [$2]) - else - _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, - check, [have_check=true], [have_check=false]) - if test x$have_check = xtrue; then - ifelse([$2], , :, [$2]) - else - ifelse([$3], , AC_MSG_ERROR([check not found]), [$3]) - fi - fi - else - _AM_TRY_CHECK($min_check_version, $CHECK_EXTRA_CFLAGS, $CHECK_EXTRA_LIBS, - $with_checklibname, [have_check=true], [have_check=false]) - if test x$have_check = xtrue; then - ifelse([$2], , :, [$2]) - else - ifelse([$3], , AC_MSG_ERROR([check not found]), [$3]) - fi - fi - - AC_SUBST(CHECK_CFLAGS) - AC_SUBST(CHECK_LIBS) - rm -f conf.check-test - fi -]) diff --git a/mobile/common/m4/gettext.m4 b/mobile/common/m4/gettext.m4 deleted file mode 100755 index 45cad85..0000000 --- a/mobile/common/m4/gettext.m4 +++ /dev/null @@ -1,587 +0,0 @@ -# gettext.m4 serial 17 (gettext-0.11.5) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2002. - -dnl Macro to add for using GNU gettext. - -dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. -dnl If INTLSYMBOL is 'use-libtool', then a libtool library -dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, -dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. -dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext -dnl implementations (in libc or libintl) without the ngettext() function -dnl will be ignored. If NEEDSYMBOL is specified and is -dnl 'need-formatstring-macros', then GNU gettext implementations that don't -dnl support the ISO C 99 formatstring macros will be ignored. -dnl INTLDIR is used to find the intl libraries. If empty, -dnl the value `$(top_builddir)/intl/' is used. -dnl -dnl The result of the configuration is one of three cases: -dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled -dnl and used. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 2) GNU gettext has been found in the system's C library. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 3) No internationalization, always use English msgid. -dnl Catalog format: none -dnl Catalog extension: none -dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. -dnl The use of .gmo is historical (it was needed to avoid overwriting the -dnl GNU format catalogs when building on a platform with an X/Open gettext), -dnl but we keep it in order not to force irrelevant filename changes on the -dnl maintainers. -dnl -AC_DEFUN([AM_GNU_GETTEXT], -[ - dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , - [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) - ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , - [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT -])])])]) - define(gt_included_intl, ifelse([$1], [external], [no], [yes])) - define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) - - AC_REQUIRE([AM_PO_SUBDIRS])dnl - ifelse(gt_included_intl, yes, [ - AC_REQUIRE([AM_INTL_SUBDIR])dnl - ]) - - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Sometimes libintl requires libiconv, so first search for libiconv. - dnl Ideally we would do this search only after the - dnl if test "$USE_NLS" = "yes"; then - dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT - dnl the configure script would need to contain the same shell code - dnl again, outside any 'if'. There are two solutions: - dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. - dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. - ifelse(gt_included_intl, yes, , [ - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - ]) - - AC_MSG_CHECKING([whether NLS is requested]) - dnl Default is enabled NLS - AC_ARG_ENABLE(nls, - [ --disable-nls do not use Native Language Support], - USE_NLS=$enableval, USE_NLS=yes) - AC_MSG_RESULT($USE_NLS) - AC_SUBST(USE_NLS) - - ifelse(gt_included_intl, yes, [ - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - ]) - LIBINTL= - LTLIBINTL= - POSUB= - - dnl If we use NLS figure out what method - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - ifelse(gt_included_intl, yes, [ - AC_MSG_CHECKING([whether included gettext is requested]) - AC_ARG_WITH(included-gettext, - [ --with-included-gettext use the GNU gettext library included here], - nls_cv_force_use_gnu_gettext=$withval, - nls_cv_force_use_gnu_gettext=no) - AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) - - nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" - if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - ]) - dnl User does not insist on using GNU NLS library. Figure out what - dnl to use. If GNU gettext is available we use this. Else we have - dnl to fall back to GNU NLS library. - - dnl Add a version number to the cache macros. - define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) - define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) - define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) - - AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, - [AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings;], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], - gt_cv_func_gnugettext_libc=yes, - gt_cv_func_gnugettext_libc=no)]) - - if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl Sometimes libintl requires libiconv, so first search for libiconv. - ifelse(gt_included_intl, yes, , [ - AM_ICONV_LINK - ]) - dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL - dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) - dnl because that would add "-liconv" to LIBINTL and LTLIBINTL - dnl even if libiconv doesn't exist. - AC_LIB_LINKFLAGS_BODY([intl]) - AC_CACHE_CHECK([for GNU gettext in libintl], - gt_cv_func_gnugettext_libintl, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - dnl Now see whether libintl exists and does not depend on libiconv. - AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - gt_cv_func_gnugettext_libintl=yes, - gt_cv_func_gnugettext_libintl=no) - dnl Now see whether libintl exists and depends on libiconv. - if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - [LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - gt_cv_func_gnugettext_libintl=yes - ]) - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - fi - - dnl If an already present or preinstalled GNU gettext() is found, - dnl use it. But if this macro is used in GNU gettext, and GNU - dnl gettext is already preinstalled in libintl, we update this - dnl libintl. (Cf. the install rule in intl/Makefile.in.) - if test "$gt_cv_func_gnugettext_libc" = "yes" \ - || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ - && test "$PACKAGE" != gettext; }; then - gt_use_preinstalled_gnugettext=yes - else - dnl Reset the values set by searching for libintl. - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - ifelse(gt_included_intl, yes, [ - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - dnl GNU gettext is not found in the C library. - dnl Fall back on included GNU gettext library. - nls_cv_use_gnu_gettext=yes - fi - fi - - if test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions used to generate GNU NLS library. - INTLOBJS="\$(GETTOBJS)" - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions to use GNU gettext tools. - CATOBJEXT=.gmo - fi - ]) - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - AC_DEFINE(ENABLE_NLS, 1, - [Define to 1 if translation of program messages to the user's native language - is requested.]) - else - USE_NLS=no - fi - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - AC_MSG_CHECKING([how to link with libintl]) - AC_MSG_RESULT([$LIBINTL]) - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) - fi - - dnl For backward compatibility. Some packages may be using this. - AC_DEFINE(HAVE_GETTEXT, 1, - [Define if the GNU gettext() function is already present or preinstalled.]) - AC_DEFINE(HAVE_DCGETTEXT, 1, - [Define if the GNU dcgettext() function is already present or preinstalled.]) - fi - - dnl We need to process the po/ directory. - POSUB=po - fi - - ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext; then - BUILD_INCLUDED_LIBINTL=yes - fi - - dnl Make all variables we use known to autoconf. - AC_SUBST(BUILD_INCLUDED_LIBINTL) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(CATOBJEXT) - AC_SUBST(INTLOBJS) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST(DATADIRNAME) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST(INSTOBJEXT) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST(GENCAT) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) - ]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLLIBS="$LIBINTL" - AC_SUBST(INTLLIBS) - - dnl Make all documented variables known to autoconf. - AC_SUBST(LIBINTL) - AC_SUBST(LTLIBINTL) - AC_SUBST(POSUB) -]) - - -dnl Checks for all prerequisites of the po subdirectory, -dnl except for USE_NLS. -AC_DEFUN([AM_PO_SUBDIRS], -[ - AC_REQUIRE([AC_PROG_MAKE_SET])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - - dnl Perform the following tests also if --disable-nls has been given, - dnl because they are needed for "make dist" to work. - - dnl Search for GNU msgfmt in the PATH. - dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. - dnl The second test excludes FreeBSD msgfmt. - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - - dnl Search for GNU xgettext 0.11 or newer in the PATH. - dnl The first test excludes Solaris xgettext and early GNU xgettext versions. - dnl The second test excludes FreeBSD xgettext. - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - - dnl Search for GNU msgmerge 0.11 or newer in the PATH. - AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, - [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU msgfmt. - if test "$GMSGFMT" != ":"; then - dnl If it is no GNU msgfmt we define it as : so that the - dnl Makefiles still can work. - if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && - (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` - AC_MSG_RESULT( - [found $GMSGFMT program is not GNU msgfmt; ignore it]) - GMSGFMT=":" - fi - fi - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU xgettext. - if test "$XGETTEXT" != ":"; then - dnl If it is no GNU xgettext we define it as : so that the - dnl Makefiles still can work. - if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && - (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - AC_MSG_RESULT( - [found xgettext program is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - fi - - AC_OUTPUT_COMMANDS([ - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assigment from automake. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - fi - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - GMOFILES= - UPDATEPOFILES= - DUMMYPOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done], - [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it - # from automake. - eval 'ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - ]) -]) - - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([AC_ISC_POSIX])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_C_CONST])dnl - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_OFF_T])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([jm_GLIBC21])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - - AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ -stdlib.h string.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ -geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ -strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) - - AM_ICONV - AM_LANGINFO_CODESET - if test $ac_cv_header_locale_h = yes; then - AM_LC_MESSAGES - fi - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) - - -AC_DEFUN([AM_MKINSTALLDIRS], -[ - dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly - dnl find the mkinstalldirs script in another subdir but $(top_srcdir). - dnl Try to locate is. - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - AC_SUBST(MKINSTALLDIRS) -]) - - -dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) -AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/mobile/common/m4/glib-gettext.m4 b/mobile/common/m4/glib-gettext.m4 deleted file mode 100755 index 5a4ef28..0000000 --- a/mobile/common/m4/glib-gettext.m4 +++ /dev/null @@ -1,380 +0,0 @@ -# Copyright (C) 1995-2002 Free Software Foundation, Inc. -# Copyright (C) 2001-2003 Red Hat, Inc. -# -# This file is free software, distributed under the terms of the GNU -# General Public License. As a special exception to the GNU General -# Public License, this file may be distributed as part of a program -# that contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# This file can be copied and used freely without restrictions. It can -# be used in projects which are not available under the GNU Public License -# but which still want to provide support for the GNU gettext functionality. -# -# Macro to add for using GNU gettext. -# Ulrich Drepper , 1995, 1996 -# -# Modified to never use included libintl. -# Owen Taylor , 12/15/1998 -# -# Major rework to remove unused code -# Owen Taylor , 12/11/2002 -# -# Added better handling of ALL_LINGUAS from GNU gettext version -# written by Bruno Haible, Owen Taylor 5/30/3002 - -# -# We need this here as well, since someone might use autoconf-2.5x -# to configure GLib then an older version to configure a package -# using AM_GLIB_GNU_GETTEXT -AC_PREREQ(2.53) - -dnl -dnl We go to great lengths to make sure that aclocal won't -dnl try to pull in the installed version of these macros -dnl when running aclocal in the glib directory. -dnl -m4_copy([AC_DEFUN],[glib_DEFUN]) -m4_copy([AC_REQUIRE],[glib_REQUIRE]) -dnl -dnl At the end, if we're not within glib, we'll define the public -dnl definitions in terms of our private definitions. -dnl - -# GLIB_LC_MESSAGES -#-------------------- -glib_DEFUN([GLIB_LC_MESSAGES], - [AC_CHECK_HEADERS([locale.h]) - if test $ac_cv_header_locale_h = yes; then - AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, - [AC_TRY_LINK([#include ], [return LC_MESSAGES], - am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) - if test $am_cv_val_LC_MESSAGES = yes; then - AC_DEFINE(HAVE_LC_MESSAGES, 1, - [Define if your file defines LC_MESSAGES.]) - fi - fi]) - -# GLIB_PATH_PROG_WITH_TEST -#---------------------------- -dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], -[# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, -[case "[$]$1" in - /*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in ifelse([$5], , $PATH, [$5]); do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word" - break - fi - fi - done - IFS="$ac_save_ifs" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) -else - AC_MSG_RESULT(no) -fi -AC_SUBST($1)dnl -]) - -# GLIB_WITH_NLS -#----------------- -glib_DEFUN([GLIB_WITH_NLS], - dnl NLS is obligatory - [USE_NLS=yes - AC_SUBST(USE_NLS) - - gt_cv_have_gettext=no - - CATOBJEXT=NONE - XGETTEXT=: - INTLLIBS= - - AC_CHECK_HEADER(libintl.h, - [gt_cv_func_dgettext_libintl="no" - libintl_extra_libs="" - - # - # First check in libc - # - AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, - [AC_TRY_LINK([ -#include -], - [return (int) dgettext ("","")], - gt_cv_func_dgettext_libc=yes, - gt_cv_func_dgettext_libc=no) - ]) - - if test "$gt_cv_func_dgettext_libc" = "yes" ; then - AC_CHECK_FUNCS(bind_textdomain_codeset) - fi - - # - # If we don't have everything we want, check in libintl - # - if test "$gt_cv_func_dgettext_libc" != "yes" \ - || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then - - AC_CHECK_LIB(intl, bindtextdomain, - [AC_CHECK_LIB(intl, dgettext, - gt_cv_func_dgettext_libintl=yes)]) - - if test "$gt_cv_func_dgettext_libintl" != "yes" ; then - AC_MSG_CHECKING([if -liconv is needed to use gettext]) - AC_MSG_RESULT([]) - AC_CHECK_LIB(intl, dcgettext, - [gt_cv_func_dgettext_libintl=yes - libintl_extra_libs=-liconv], - :,-liconv) - fi - - # - # If we found libintl, then check in it for bind_textdomain_codeset(); - # we'll prefer libc if neither have bind_textdomain_codeset(), - # and both have dgettext - # - if test "$gt_cv_func_dgettext_libintl" = "yes" ; then - glib_save_LIBS="$LIBS" - LIBS="$LIBS -lintl $libintl_extra_libs" - unset ac_cv_func_bind_textdomain_codeset - AC_CHECK_FUNCS(bind_textdomain_codeset) - LIBS="$glib_save_LIBS" - - if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then - gt_cv_func_dgettext_libc=no - else - if test "$gt_cv_func_dgettext_libc" = "yes"; then - gt_cv_func_dgettext_libintl=no - fi - fi - fi - fi - - if test "$gt_cv_func_dgettext_libc" = "yes" \ - || test "$gt_cv_func_dgettext_libintl" = "yes"; then - gt_cv_have_gettext=yes - fi - - if test "$gt_cv_func_dgettext_libintl" = "yes"; then - INTLLIBS="-lintl $libintl_extra_libs" - fi - - if test "$gt_cv_have_gettext" = "yes"; then - AC_DEFINE(HAVE_GETTEXT,1, - [Define if the GNU gettext() function is already present or preinstalled.]) - GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl - if test "$MSGFMT" != "no"; then - glib_save_LIBS="$LIBS" - LIBS="$LIBS $INTLLIBS" - AC_CHECK_FUNCS(dcgettext) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) - AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; - return _nl_msg_cat_cntr], - [CATOBJEXT=.gmo - DATADIRNAME=share], - [case $host in - *-*-solaris*) - dnl On Solaris, if bind_textdomain_codeset is in libc, - dnl GNU format message catalog is always supported, - dnl since both are added to the libc all together. - dnl Hence, we'd like to go with DATADIRNAME=share and - dnl and CATOBJEXT=.gmo in this case. - AC_CHECK_FUNC(bind_textdomain_codeset, - [CATOBJEXT=.gmo - DATADIRNAME=share], - [CATOBJEXT=.mo - DATADIRNAME=lib]) - ;; - *) - CATOBJEXT=.mo - DATADIRNAME=lib - ;; - esac]) - LIBS="$glib_save_LIBS" - INSTOBJEXT=.mo - else - gt_cv_have_gettext=no - fi - fi - ]) - - if test "$gt_cv_have_gettext" = "yes" ; then - AC_DEFINE(ENABLE_NLS, 1, - [always defined to indicate that i18n is enabled]) - fi - - dnl Test whether we really found GNU xgettext. - if test "$XGETTEXT" != ":"; then - dnl If it is not GNU xgettext we define it as : so that the - dnl Makefiles still can work. - if $XGETTEXT --omit-header /dev/null 2> /dev/null; then - : ; - else - AC_MSG_RESULT( - [found xgettext program is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi - fi - - # We need to process the po/ directory. - POSUB=po - - AC_OUTPUT_COMMANDS( - [case "$CONFIG_FILES" in *po/Makefile.in*) - sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile - esac]) - - dnl These rules are solely for the distribution goal. While doing this - dnl we only have to keep exactly one list of the available catalogs - dnl in configure.in. - for lang in $ALL_LINGUAS; do - GMOFILES="$GMOFILES $lang.gmo" - POFILES="$POFILES $lang.po" - done - - dnl Make all variables we use known to autoconf. - AC_SUBST(CATALOGS) - AC_SUBST(CATOBJEXT) - AC_SUBST(DATADIRNAME) - AC_SUBST(GMOFILES) - AC_SUBST(INSTOBJEXT) - AC_SUBST(INTLLIBS) - AC_SUBST(PO_IN_DATADIR_TRUE) - AC_SUBST(PO_IN_DATADIR_FALSE) - AC_SUBST(POFILES) - AC_SUBST(POSUB) - ]) - -# AM_GLIB_GNU_GETTEXT -# ------------------- -# Do checks necessary for use of gettext. If a suitable implementation -# of gettext is found in either in libintl or in the C library, -# it will set INTLLIBS to the libraries needed for use of gettext -# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable -# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() -# on various variables needed by the Makefile.in.in installed by -# glib-gettextize. -dnl -glib_DEFUN([GLIB_GNU_GETTEXT], - [AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl - - GLIB_LC_MESSAGES - GLIB_WITH_NLS - - if test "$gt_cv_have_gettext" = "yes"; then - if test "x$ALL_LINGUAS" = "x"; then - LINGUAS= - else - AC_MSG_CHECKING(for catalogs to be installed) - NEW_LINGUAS= - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - NEW_LINGUAS="$NEW_LINGUAS $presentlang" - fi - done - LINGUAS=$NEW_LINGUAS - AC_MSG_RESULT($LINGUAS) - fi - - dnl Construct list of names of catalog files to be constructed. - if test -n "$LINGUAS"; then - for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done - fi - fi - - dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly - dnl find the mkinstalldirs script in another subdir but ($top_srcdir). - dnl Try to locate is. - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - AC_SUBST(MKINSTALLDIRS) - - dnl Generate list of files to be processed by xgettext which will - dnl be included in po/Makefile. - test -d po || mkdir po - if test "x$srcdir" != "x."; then - if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then - posrcprefix="$srcdir/" - else - posrcprefix="../$srcdir/" - fi - else - posrcprefix="../" - fi - rm -f po/POTFILES - sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ - < $srcdir/po/POTFILES.in > po/POTFILES - ]) - -# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) -# ------------------------------- -# Define VARIABLE to the location where catalog files will -# be installed by po/Makefile. -glib_DEFUN([GLIB_DEFINE_LOCALEDIR], -[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl -glib_save_prefix="$prefix" -glib_save_exec_prefix="$exec_prefix" -test "x$prefix" = xNONE && prefix=$ac_default_prefix -test "x$exec_prefix" = xNONE && exec_prefix=$prefix -if test "x$CATOBJEXT" = "x.mo" ; then - localedir=`eval echo "${libdir}/locale"` -else - localedir=`eval echo "${datadir}/locale"` -fi -prefix="$glib_save_prefix" -exec_prefix="$glib_save_exec_prefix" -AC_DEFINE_UNQUOTED($1, "$localedir", - [Define the location where the catalogs will be installed]) -]) - -dnl -dnl Now the definitions that aclocal will find -dnl -ifdef(glib_configure_in,[],[ -AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) -AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) -])dnl diff --git a/mobile/common/m4/gst-arch.m4 b/mobile/common/m4/gst-arch.m4 deleted file mode 100755 index 8a32bd2..0000000 --- a/mobile/common/m4/gst-arch.m4 +++ /dev/null @@ -1,123 +0,0 @@ -dnl AG_GST_ARCH -dnl sets up defines and automake conditionals for host architecture -dnl checks endianness -dnl defines HOST_CPU - -AC_DEFUN([AG_GST_ARCH], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use host_ variables - - dnl Determine CPU - case "x${host_cpu}" in - xi?86 | xk? | xi?86_64) - HAVE_CPU_I386=yes - AC_DEFINE(HAVE_CPU_I386, 1, [Define if the host CPU is an x86]) - - dnl FIXME could use some better detection - dnl (ie CPUID) - case "x${host_cpu}" in - xi386 | xi486) ;; - *) - AC_DEFINE(HAVE_RDTSC, 1, [Define if RDTSC is available]) ;; - esac ;; - xpowerpc) - HAVE_CPU_PPC=yes - AC_DEFINE(HAVE_CPU_PPC, 1, [Define if the host CPU is a PowerPC]) ;; - xpowerpc64) - HAVE_CPU_PPC64=yes - AC_DEFINE(HAVE_CPU_PPC64, 1, [Define if the host CPU is a 64 bit PowerPC]) ;; - xalpha*) - HAVE_CPU_ALPHA=yes - AC_DEFINE(HAVE_CPU_ALPHA, 1, [Define if the host CPU is an Alpha]) ;; - xarm*) - HAVE_CPU_ARM=yes - AC_DEFINE(HAVE_CPU_ARM, 1, [Define if the host CPU is an ARM]) ;; - xsparc*) - HAVE_CPU_SPARC=yes - AC_DEFINE(HAVE_CPU_SPARC, 1, [Define if the host CPU is a SPARC]) ;; - xmips*) - HAVE_CPU_MIPS=yes - AC_DEFINE(HAVE_CPU_MIPS, 1, [Define if the host CPU is a MIPS]) ;; - xhppa*) - HAVE_CPU_HPPA=yes - AC_DEFINE(HAVE_CPU_HPPA, 1, [Define if the host CPU is a HPPA]) ;; - xs390*) - HAVE_CPU_S390=yes - AC_DEFINE(HAVE_CPU_S390, 1, [Define if the host CPU is a S390]) ;; - xia64*) - HAVE_CPU_IA64=yes - AC_DEFINE(HAVE_CPU_IA64, 1, [Define if the host CPU is a IA64]) ;; - xm68k*) - HAVE_CPU_M68K=yes - AC_DEFINE(HAVE_CPU_M68K, 1, [Define if the host CPU is a M68K]) ;; - xx86_64) - HAVE_CPU_X86_64=yes - AC_DEFINE(HAVE_CPU_X86_64, 1, [Define if the host CPU is a x86_64]) ;; - xcris) - HAVE_CPU_CRIS=yes - AC_DEFINE(HAVE_CPU_CRIS, 1, [Define if the host CPU is a CRIS]) ;; - xcrisv32) - HAVE_CPU_CRISV32=yes - AC_DEFINE(HAVE_CPU_CRISV32, 1, [Define if the host CPU is a CRISv32]) ;; - esac - - dnl Determine endianness - AC_C_BIGENDIAN - - AM_CONDITIONAL(HAVE_CPU_I386, test "x$HAVE_CPU_I386" = "xyes") - AM_CONDITIONAL(HAVE_CPU_PPC, test "x$HAVE_CPU_PPC" = "xyes") - AM_CONDITIONAL(HAVE_CPU_PPC64, test "x$HAVE_CPU_PPC64" = "xyes") - AM_CONDITIONAL(HAVE_CPU_ALPHA, test "x$HAVE_CPU_ALPHA" = "xyes") - AM_CONDITIONAL(HAVE_CPU_ARM, test "x$HAVE_CPU_ARM" = "xyes") - AM_CONDITIONAL(HAVE_CPU_SPARC, test "x$HAVE_CPU_SPARC" = "xyes") - AM_CONDITIONAL(HAVE_CPU_HPPA, test "x$HAVE_CPU_HPPA" = "xyes") - AM_CONDITIONAL(HAVE_CPU_MIPS, test "x$HAVE_CPU_MIPS" = "xyes") - AM_CONDITIONAL(HAVE_CPU_S390, test "x$HAVE_CPU_S390" = "xyes") - AM_CONDITIONAL(HAVE_CPU_IA64, test "x$HAVE_CPU_IA64" = "xyes") - AM_CONDITIONAL(HAVE_CPU_M68K, test "x$HAVE_CPU_M68K" = "xyes") - AM_CONDITIONAL(HAVE_CPU_X86_64, test "x$HAVE_CPU_X86_64" = "xyes") - AM_CONDITIONAL(HAVE_CPU_CRIS, test "x$HAVE_CPU_CRIS" = "xyes") - AM_CONDITIONAL(HAVE_CPU_CRISV32, test "x$HAVE_CPU_CRISV32" = "xyes") - - AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu", [the host CPU]) -]) - -dnl check if unaligned memory access works correctly -AC_DEFUN([AG_GST_UNALIGNED_ACCESS], [ - AC_MSG_CHECKING([if unaligned memory access works correctly]) - if test x"$as_cv_unaligned_access" = x ; then - case $host in - alpha*|arm*|hp*|mips*|sh*|sparc*|ia64*) - _AS_ECHO_N([(blacklisted) ]) - as_cv_unaligned_access=no - ;; - i?86*|powerpc*|m68k*|cris*) - _AS_ECHO_N([(whitelisted) ]) - as_cv_unaligned_access=yes - ;; - esac - else - _AS_ECHO_N([(cached) ]) - fi - if test x"$as_cv_unaligned_access" = x ; then - AC_TRY_RUN([ -int main(int argc, char **argv) -{ - char array[] = "ABCDEFGH"; - unsigned int iarray[2]; - memcpy(iarray,array,8); -#define GET(x) (*(unsigned int *)((char *)iarray + (x))) - if(GET(0) != 0x41424344 && GET(0) != 0x44434241) return 1; - if(GET(1) != 0x42434445 && GET(1) != 0x45444342) return 1; - if(GET(2) != 0x43444546 && GET(2) != 0x46454443) return 1; - if(GET(3) != 0x44454647 && GET(3) != 0x47464544) return 1; - return 0; -} - ], as_cv_unaligned_access="yes", as_cv_unaligned_access="no") - fi - AC_MSG_RESULT($as_cv_unaligned_access) - if test "$as_cv_unaligned_access" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_UNALIGNED_ACCESS, 1, - [defined if unaligned memory access works correctly]) - fi -]) diff --git a/mobile/common/m4/gst-args.m4 b/mobile/common/m4/gst-args.m4 deleted file mode 100755 index 1781af4..0000000 --- a/mobile/common/m4/gst-args.m4 +++ /dev/null @@ -1,302 +0,0 @@ -dnl configure-time options shared among gstreamer modules - -dnl AG_GST_ARG_DEBUG -dnl AG_GST_ARG_PROFILING -dnl AG_GST_ARG_VALGRIND -dnl AG_GST_ARG_GCOV - -dnl AG_GST_ARG_EXAMPLES - -dnl AG_GST_ARG_WITH_PKG_CONFIG_PATH -dnl AG_GST_ARG_WITH_PACKAGE_NAME -dnl AG_GST_ARG_WITH_PACKAGE_ORIGIN - -dnl AG_GST_ARG_WITH_PLUGINS -dnl AG_GST_CHECK_PLUGIN -dnl AG_GST_DISABLE_PLUGIN - -dnl AG_GST_ARG_ENABLE_EXTERNAL -dnl AG_GST_ARG_ENABLE_EXPERIMENTAL -dnl AG_GST_ARG_ENABLE_BROKEN - -AC_DEFUN([AG_GST_ARG_DEBUG], -[ - dnl debugging stuff - AC_ARG_ENABLE(debug, - AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]), - [ - case "${enableval}" in - yes) USE_DEBUG=yes ;; - no) USE_DEBUG=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; - esac - ], - [USE_DEBUG=yes]) dnl Default value -]) - -AC_DEFUN([AG_GST_ARG_PROFILING], -[ - AC_ARG_ENABLE(profiling, - AC_HELP_STRING([--enable-profiling], - [adds -pg to compiler commandline, for profiling]), - [ - case "${enableval}" in - yes) USE_PROFILING=yes ;; - no) USE_PROFILING=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-profiling) ;; - esac - ], - [USE_PROFILING=no]) dnl Default value -]) - -AC_DEFUN([AG_GST_ARG_VALGRIND], -[ - dnl valgrind inclusion - AC_ARG_ENABLE(valgrind, - AC_HELP_STRING([--disable-valgrind],[disable run-time valgrind detection]), - [ - case "${enableval}" in - yes) USE_VALGRIND="$USE_DEBUG" ;; - no) USE_VALGRIND=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-valgrind) ;; - esac - ], - [USE_VALGRIND="$USE_DEBUG"]) dnl Default value - VALGRIND_REQ="2.1" - if test "x$USE_VALGRIND" = xyes; then - PKG_CHECK_MODULES(VALGRIND, valgrind > $VALGRIND_REQ, - USE_VALGRIND="yes", - [ - USE_VALGRIND="no" - AC_MSG_RESULT([no]) - ]) - fi - if test "x$USE_VALGRIND" = xyes; then - AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used]) - AC_MSG_NOTICE(Using extra code paths for valgrind) - fi -]) - -AC_DEFUN([AG_GST_ARG_GCOV], -[ - AC_ARG_ENABLE(gcov, - AC_HELP_STRING([--enable-gcov], - [compile with coverage profiling instrumentation (gcc only)]), - enable_gcov=$enableval, - enable_gcov=no) - if test x$enable_gcov = xyes ; then - if test "x$GCC" != "xyes" - then - AC_MSG_ERROR([gcov only works if gcc is used]) - fi - - AS_COMPILER_FLAG(["-fprofile-arcs"], - [GCOV_CFLAGS="$GCOV_CFLAGS -fprofile-arcs"], - true) - AS_COMPILER_FLAG(["-ftest-coverage"], - [GCOV_CFLAGS="$GCOV_CFLAGS -ftest-coverage"], - true) - dnl remove any -O flags - FIXME: is this needed ? - GCOV_CFLAGS=`echo "$GCOV_CFLAGS" | sed -e 's/-O[[0-9]]*//g'` - dnl libtool 1.5.22 and lower strip -fprofile-arcs from the flags - dnl passed to the linker, which is a bug; -fprofile-arcs implicitly - dnl links in -lgcov, so we do it explicitly here for the same effect - GCOV_LIBS=-lgcov - AC_SUBST(GCOV_CFLAGS) - AC_SUBST(GCOV_LIBS) - GCOV=`echo $CC | sed s/gcc/gcov/g` - AC_SUBST(GCOV) - - GST_GCOV_ENABLED=yes - AC_DEFINE_UNQUOTED(GST_GCOV_ENABLED, 1, - [Defined if gcov is enabled to force a rebuild due to config.h changing]) - dnl if gcov is used, we do not want default -O2 CFLAGS - if test "x$GST_GCOV_ENABLED" = "xyes" - then - CFLAGS="-O0" - AC_SUBST(CFLAGS) - CXXFLAGS="-O0" - AC_SUBST(CXXFLAGS) - FFLAGS="-O0" - AC_SUBST(FFLAGS) - CCASFLAGS="-O0" - AC_SUBST(CCASFLAGS) - AC_MSG_NOTICE([gcov enabled, setting CFLAGS and friends to $CFLAGS]) - fi - fi - AM_CONDITIONAL(GST_GCOV_ENABLED, test x$enable_gcov = xyes) -]) - -AC_DEFUN([AG_GST_ARG_EXAMPLES], -[ - AC_ARG_ENABLE(examples, - AC_HELP_STRING([--disable-examples], [disable building examples]), - [ - case "${enableval}" in - yes) BUILD_EXAMPLES=yes ;; - no) BUILD_EXAMPLES=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --disable-examples) ;; - esac - ], - [BUILD_EXAMPLES=yes]) dnl Default value - AM_CONDITIONAL(BUILD_EXAMPLES, test "x$BUILD_EXAMPLES" = "xyes") -]) - -AC_DEFUN([AG_GST_ARG_WITH_PKG_CONFIG_PATH], -[ - dnl possibly modify pkg-config path - AC_ARG_WITH(pkg-config-path, - AC_HELP_STRING([--with-pkg-config-path], - [colon-separated list of pkg-config(1) dirs]), - [ - export PKG_CONFIG_PATH=${withval} - AC_MSG_NOTICE(Set PKG_CONFIG_PATH to $PKG_CONFIG_PATH) - ]) -]) - - -dnl This macro requires that GST_CVS is set to yes or no (release) -AC_DEFUN([AG_GST_ARG_WITH_PACKAGE_NAME], -[ - dnl package name in plugins - AC_ARG_WITH(package-name, - AC_HELP_STRING([--with-package-name], - [specify package name to use in plugins]), - [ - case "${withval}" in - yes) AC_MSG_ERROR(bad value ${withval} for --with-package-name) ;; - no) AC_MSG_ERROR(bad value ${withval} for --with-package-name) ;; - *) GST_PACKAGE_NAME="${withval}" ;; - esac - ], - [ - P=$1 - if test "x$P" = "x" - then - P=$PACKAGE_NAME - fi - - dnl default value - if test "x$GST_CVS" = "xyes" - then - dnl nano >= 1 - GST_PACKAGE_NAME="$P CVS/prerelease" - else - GST_PACKAGE_NAME="$P source release" - fi - ] - ) - AC_MSG_NOTICE(Using $GST_PACKAGE_NAME as package name) - AC_DEFINE_UNQUOTED(GST_PACKAGE_NAME, "$GST_PACKAGE_NAME", - [package name in plugins]) - AC_SUBST(GST_PACKAGE_NAME) -]) - -AC_DEFUN([AG_GST_ARG_WITH_PACKAGE_ORIGIN], -[ - dnl package origin URL - AC_ARG_WITH(package-origin, - AC_HELP_STRING([--with-package-origin], - [specify package origin URL to use in plugins]), - [ - case "${withval}" in - yes) AC_MSG_ERROR(bad value ${withval} for --with-package-origin) ;; - no) AC_MSG_ERROR(bad value ${withval} for --with-package-origin) ;; - *) GST_PACKAGE_ORIGIN="${withval}" ;; - esac - ], - [GST_PACKAGE_ORIGIN="[Unknown package origin]"] dnl Default value - ) - AC_MSG_NOTICE(Using $GST_PACKAGE_ORIGIN as package origin) - AC_DEFINE_UNQUOTED(GST_PACKAGE_ORIGIN, "$GST_PACKAGE_ORIGIN", - [package origin]) - AC_SUBST(GST_PACKAGE_ORIGIN) -]) - -dnl sets WITH_PLUGINS to the list of plug-ins given as an argument -dnl also clears GST_PLUGINS_ALL and GST_PLUGINS_SELECTED -AC_DEFUN([AG_GST_ARG_WITH_PLUGINS], -[ - AC_ARG_WITH(plugins, - AC_HELP_STRING([--with-plugins], - [comma-separated list of dependencyless plug-ins to compile]), - [WITH_PLUGINS=$withval], - [WITH_PLUGINS=]) - - GST_PLUGINS_ALL="" - GST_PLUGINS_SELECTED="" - - AC_SUBST(GST_PLUGINS_ALL) - AC_SUBST(GST_PLUGINS_SELECTED) -]) - -dnl AG_GST_CHECK_PLUGIN(PLUGIN-NAME) -dnl -dnl This macro adds the plug-in to GST_PLUGINS_ALL. Then it -dnl checks if the plug-in is present in WITH_PLUGINS, and if so adds it to -dnl GST_PLUGINS_SELECTED. -dnl -dnl The macro will call AM_CONDITIONAL(USE_PLUGIN_, ...) to allow -dnl control of what is built in Makefile.ams. -AC_DEFUN([AG_GST_CHECK_PLUGIN], -[ - GST_PLUGINS_ALL="$GST_PLUGINS_ALL [$1]" - if [[ -z "$WITH_PLUGINS" ]] || echo " [$WITH_PLUGINS] " | tr , ' ' | grep -i " [$1] " > /dev/null; then - GST_PLUGINS_SELECTED="$GST_PLUGINS_SELECTED [$1]" - fi - AM_CONDITIONAL([USE_PLUGIN_]translit([$1], a-z, A-Z), echo " $GST_PLUGINS_SELECTED " | grep -i " [$1] " > /dev/null) -]) - -dnl AG_GST_DISABLE_PLUGIN(PLUGIN-NAME) -dnl -dnl This macro disables the plug-in by removing it from -dnl GST_PLUGINS_SELECTED. -AC_DEFUN([AG_GST_DISABLE_PLUGIN], -[ - GST_PLUGINS_SELECTED=`echo " $GST_PLUGINS_SELECTED " | $SED -e 's/ [$1] / /'` - AM_CONDITIONAL([USE_PLUGIN_]translit([$1], a-z, A-Z), false) -]) - -AC_DEFUN([AG_GST_ARG_ENABLE_EXTERNAL], -[ - AG_GST_CHECK_FEATURE(EXTERNAL, [building of plug-ins with external deps],, - HAVE_EXTERNAL=yes, enabled, - [ - AC_MSG_NOTICE(building external plug-ins) - BUILD_EXTERNAL="yes" - ],[ - AC_MSG_WARN(all plug-ins with external dependencies will not be built) - BUILD_EXTERNAL="no" - ]) - # make BUILD_EXTERNAL available to Makefile.am - AM_CONDITIONAL(BUILD_EXTERNAL, test "x$BUILD_EXTERNAL" = "xyes") -]) - -dnl experimental plug-ins; stuff that hasn't had the dust settle yet -dnl read 'builds, but might not work' -AC_DEFUN([AG_GST_ARG_ENABLE_EXPERIMENTAL], -[ - AG_GST_CHECK_FEATURE(EXPERIMENTAL, [building of experimental plug-ins],, - HAVE_EXPERIMENTAL=yes, disabled, - [ - AC_MSG_WARN(building experimental plug-ins) - BUILD_EXPERIMENTAL="yes" - ],[ - AC_MSG_NOTICE(not building experimental plug-ins) - BUILD_EXPERIMENTAL="no" - ]) - # make BUILD_EXPERIMENTAL available to Makefile.am - AM_CONDITIONAL(BUILD_EXPERIMENTAL, test "x$BUILD_EXPERIMENTAL" = "xyes") -]) - -dnl broken plug-ins; stuff that doesn't seem to build at the moment -AC_DEFUN([AG_GST_ARG_ENABLE_BROKEN], -[ - AG_GST_CHECK_FEATURE(BROKEN, [building of broken plug-ins],, - HAVE_BROKEN=yes, disabled, - [ - AC_MSG_WARN([building broken plug-ins -- no bug reports on these, only patches ...]) - ],[ - AC_MSG_NOTICE([not building broken plug-ins]) - ]) -]) diff --git a/mobile/common/m4/gst-check.m4 b/mobile/common/m4/gst-check.m4 deleted file mode 100755 index 3f6b8ff..0000000 --- a/mobile/common/m4/gst-check.m4 +++ /dev/null @@ -1,138 +0,0 @@ -dnl pkg-config-based checks for GStreamer modules and dependency modules - -dnl generic: -dnl AG_GST_PKG_CHECK_MODULES([PREFIX], [WHICH], [REQUIRED]) -dnl sets HAVE_[$PREFIX], [$PREFIX]_* -dnl AG_GST_CHECK_MODULES([PREFIX], [MODULE], [MINVER], [NAME], [REQUIRED]) -dnl sets HAVE_[$PREFIX], [$PREFIX]_* - -dnl specific: -dnl AG_GST_CHECK_GST([MAJMIN], [MINVER], [REQUIRED]) -dnl also sets/ACSUBSTs GST_TOOLS_DIR and GST_PLUGINS_DIR -dnl AG_GST_CHECK_GST_BASE([MAJMIN], [MINVER], [REQUIRED]) -dnl AG_GST_CHECK_GST_GDP([MAJMIN], [MINVER], [REQUIRED]) -dnl AG_GST_CHECK_GST_CONTROLLER([MAJMIN], [MINVER], [REQUIRED]) -dnl AG_GST_CHECK_GST_CHECK([MAJMIN], [MINVER], [REQUIRED]) -dnl AG_GST_CHECK_GST_PLUGINS_BASE([MAJMIN], [MINVER], [REQUIRED]) -dnl also sets/ACSUBSTs GSTPB_PLUGINS_DIR - -AC_DEFUN([AG_GST_PKG_CHECK_MODULES], -[ - which="[$2]" - dnl not required by default, since we use this mostly for plugin deps - required=ifelse([$3], , "no", [$3]) - - PKG_CHECK_MODULES([$1], $which, - [ - HAVE_[$1]="yes" - ], - [ - HAVE_[$1]="no" - AC_MSG_RESULT(no) - if test "x$required" = "xyes"; then - AC_MSG_ERROR($[$1]_PKG_ERRORS) - else - AC_MSG_NOTICE($[$1]_PKG_ERRORS) - fi - ]) - - dnl AC_SUBST of CFLAGS and LIBS was not done before automake 1.7 - dnl It gets done automatically in automake >= 1.7, which we now require -])) - -AC_DEFUN([AG_GST_CHECK_MODULES], -[ - module=[$2] - minver=[$3] - name="[$4]" - required=ifelse([$5], , "yes", [$5]) dnl required by default - - PKG_CHECK_MODULES([$1], $module >= $minver, - [ - HAVE_[$1]="yes" - ], - [ - HAVE_[$1]="no" - AC_MSG_RESULT(no) - AC_MSG_NOTICE($[$1]_PKG_ERRORS) - if test "x$required" = "xyes"; then - AC_MSG_ERROR([no $module >= $minver ($name) found]) - else - AC_MSG_NOTICE([no $module >= $minver ($name) found]) - fi - ]) - - dnl AC_SUBST of CFLAGS and LIBS was not done before automake 1.7 - dnl It gets done automatically in automake >= 1.7, which we now require -])) - -AC_DEFUN([AG_GST_CHECK_GST], -[ - AG_GST_CHECK_MODULES(GST, gstreamer-[$1], [$2], [GStreamer], [$3]) - dnl allow setting before calling this macro to override - if test -z $GST_TOOLS_DIR; then - GST_TOOLS_DIR=`$PKG_CONFIG --variable=toolsdir gstreamer-[$1]` - if test -z $GST_TOOLS_DIR; then - AC_MSG_ERROR( - [no tools dir set in GStreamer pkg-config file, core upgrade needed.]) - fi - fi - AC_MSG_NOTICE([using GStreamer tools in $GST_TOOLS_DIR]) - AC_SUBST(GST_TOOLS_DIR) - - dnl check for where core plug-ins got installed - dnl this is used for unit tests - dnl allow setting before calling this macro to override - if test -z $GST_PLUGINS_DIR; then - GST_PLUGINS_DIR=`$PKG_CONFIG --variable=pluginsdir gstreamer-[$1]` - if test -z $GST_PLUGINS_DIR; then - AC_MSG_ERROR( - [no pluginsdir set in GStreamer pkg-config file, core upgrade needed.]) - fi - fi - AC_MSG_NOTICE([using GStreamer plug-ins in $GST_PLUGINS_DIR]) - AC_SUBST(GST_PLUGINS_DIR) -]) - -AC_DEFUN([AG_GST_CHECK_GST_BASE], -[ - AG_GST_CHECK_MODULES(GST_BASE, gstreamer-base-[$1], [$2], - [GStreamer Base Libraries], [$3]) -]) - -AC_DEFUN([AG_GST_CHECK_GST_GDP], -[ - AG_GST_CHECK_MODULES(GST_GDP, gstreamer-dataprotocol-[$1], [$2], - [GStreamer Data Protocol Library], [$3]) -]) - -AC_DEFUN([AG_GST_CHECK_GST_CONTROLLER], -[ - AG_GST_CHECK_MODULES(GST_CONTROLLER, gstreamer-controller-[$1], [$2], - [GStreamer Controller Library], [$3]) -]) - -AC_DEFUN([AG_GST_CHECK_GST_CHECK], -[ - AG_GST_CHECK_MODULES(GST_CHECK, gstreamer-check-[$1], [$2], - [GStreamer Check unittest Library], [$3]) -]) - -AC_DEFUN([AG_GST_CHECK_GST_PLUGINS_BASE], -[ - AG_GST_CHECK_MODULES(GST_PLUGINS_BASE, gstreamer-plugins-base-[$1], [$2], - [GStreamer Base Plug-ins Library], [$3]) - - dnl check for where base plug-ins got installed - dnl this is used for unit tests - dnl allow setting before calling this macro to override - if test -z $GSTPB_PLUGINS_DIR; then - GSTPB_PLUGINS_DIR=`$PKG_CONFIG --variable=pluginsdir gstreamer-plugins-base-[$1]` - if test -z $GSTPB_PLUGINS_DIR; then - AC_MSG_ERROR( - [no pluginsdir set in GStreamer Base Plug-ins pkg-config file]) - fi - fi - AC_MSG_NOTICE([using GStreamer Base Plug-ins in $GSTPB_PLUGINS_DIR]) - AC_SUBST(GSTPB_PLUGINS_DIR) -]) diff --git a/mobile/common/m4/gst-debuginfo.m4 b/mobile/common/m4/gst-debuginfo.m4 deleted file mode 100755 index b48854d..0000000 --- a/mobile/common/m4/gst-debuginfo.m4 +++ /dev/null @@ -1,46 +0,0 @@ -AC_DEFUN([AG_GST_DEBUGINFO], [ -AC_ARG_ENABLE(debug, -AC_HELP_STRING([--disable-debug],[disable addition of -g debugging info]), -[case "${enableval}" in - yes) USE_DEBUG=yes ;; - no) USE_DEBUG=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; -esac], -[USE_DEBUG=yes]) dnl Default value - -AC_ARG_ENABLE(DEBUG, -AC_HELP_STRING([--disable-DEBUG],[disables compilation of debugging messages]), -[case "${enableval}" in - yes) ENABLE_DEBUG=yes ;; - no) ENABLE_DEBUG=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-DEBUG) ;; -esac], -[ENABLE_DEBUG=yes]) dnl Default value -if test x$ENABLE_DEBUG = xyes; then - AC_DEFINE(GST_DEBUG_ENABLED, 1, [Define if DEBUG statements should be compiled in]) -fi - -AC_ARG_ENABLE(INFO, -AC_HELP_STRING([--disable-INFO],[disables compilation of informational messages]), -[case "${enableval}" in - yes) ENABLE_INFO=yes ;; - no) ENABLE_INFO=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-INFO) ;; -esac], -[ENABLE_INFO=yes]) dnl Default value -if test x$ENABLE_INFO = xyes; then - AC_DEFINE(GST_INFO_ENABLED, 1, [Define if INFO statements should be compiled in]) -fi - -AC_ARG_ENABLE(debug-color, -AC_HELP_STRING([--disable-debug-color],[disables color output of DEBUG and INFO output]), -[case "${enableval}" in - yes) ENABLE_DEBUG_COLOR=yes ;; - no) ENABLE_DEBUG_COLOR=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug-color) ;; -esac], -[ENABLE_DEBUG_COLOR=yes]) dnl Default value -if test "x$ENABLE_DEBUG_COLOR" = xyes; then - AC_DEFINE(GST_DEBUG_COLOR, 1, [Define if debugging messages should be colorized]) -fi -]) diff --git a/mobile/common/m4/gst-default.m4 b/mobile/common/m4/gst-default.m4 deleted file mode 100755 index da1a81c..0000000 --- a/mobile/common/m4/gst-default.m4 +++ /dev/null @@ -1,45 +0,0 @@ -dnl default elements used for tests and such - -dnl AG_GST_DEFAULT_ELEMENTS - -AC_DEFUN([AG_GST_DEFAULT_ELEMENTS], -[ - dnl decide on default elements - dnl FIXME: provide configure-time options for this - dnl FIXME: describe where exactly this gets used - dnl FIXME: decide if it's a problem that this could point to sinks from - dnl depending plugin modules - DEFAULT_AUDIOSINK="autoaudiosink" - DEFAULT_VIDEOSINK="autovideosink" - DEFAULT_AUDIOSRC="alsasrc" - DEFAULT_VIDEOSRC="v4lsrc" - DEFAULT_VISUALIZER="goom" - case "$host" in - *-sun-* | *pc-solaris* ) - DEFAULT_AUDIOSINK="sunaudiosink" - DEFAULT_VIDEOSINK="ximagesink" - DEFAULT_AUDIOSRC="sunaudiosrc" - ;; - *-darwin* ) - DEFAULT_AUDIOSINK="osxaudiosink" - DEFAULT_AUDIOSRC="osxaudiosrc" - DEFAULT_VIDEOSINK="osxvideosink" - ;; - esac - - AC_SUBST(DEFAULT_AUDIOSINK) - AC_DEFINE_UNQUOTED(DEFAULT_AUDIOSINK, "$DEFAULT_AUDIOSINK", - [Default audio sink]) - AC_SUBST(DEFAULT_AUDIOSRC) - AC_DEFINE_UNQUOTED(DEFAULT_AUDIOSRC, "$DEFAULT_AUDIOSRC", - [Default audio source]) - AC_SUBST(DEFAULT_VIDEOSINK) - AC_DEFINE_UNQUOTED(DEFAULT_VIDEOSINK, "$DEFAULT_VIDEOSINK", - [Default video sink]) - AC_SUBST(DEFAULT_VIDEOSRC) - AC_DEFINE_UNQUOTED(DEFAULT_VIDEOSRC, "$DEFAULT_VIDEOSRC", - [Default video source]) - AC_SUBST(DEFAULT_VISUALIZER) - AC_DEFINE_UNQUOTED(DEFAULT_VISUALIZER, "$DEFAULT_VISUALIZER", - [Default visualizer]) -]) diff --git a/mobile/common/m4/gst-doc.m4 b/mobile/common/m4/gst-doc.m4 deleted file mode 100755 index 7000c17..0000000 --- a/mobile/common/m4/gst-doc.m4 +++ /dev/null @@ -1,148 +0,0 @@ -AC_DEFUN([AG_GST_DOCBOOK_CHECK], -[ - dnl choose a location to install docbook docs in - if test "x$PACKAGE_TARNAME" = "x" - then - AC_MSG_ERROR([Internal error - PACKAGE_TARNAME not set]) - fi - docdir="\$(datadir)/doc/$PACKAGE_TARNAME-$GST_MAJORMINOR" - - dnl enable/disable docbook documentation building - AC_ARG_ENABLE(docbook, - AC_HELP_STRING([--enable-docbook], - [use docbook to build documentation [default=no]]),, - enable_docbook=no) - - have_docbook=no - - if test x$enable_docbook = xyes; then - dnl check if we actually have everything we need - - dnl check for docbook tools - AC_CHECK_PROG(HAVE_DOCBOOK2PS, docbook2ps, yes, no) - AC_CHECK_PROG(HAVE_DOCBOOK2HTML, docbook2html, yes, no) - AC_CHECK_PROG(HAVE_JADETEX, jadetex, yes, no) - AC_CHECK_PROG(HAVE_PS2PDF, ps2pdf, yes, no) - - # -V option appeared in 0.6.10 - docbook2html_min_version=0.6.10 - if test "x$HAVE_DOCBOOK2HTML" != "xno"; then - docbook2html_version=`docbook2html --version` - AC_MSG_CHECKING([docbook2html version ($docbook2html_version) >= $docbook2html_min_version]) - if perl -w < \$min_version_major) || - ((\$docbook2html_version_major == \$min_version_major) && - (\$docbook2html_version_minor >= \$min_version_minor)) || - ((\$docbook2html_version_major == \$min_version_major) && - (\$docbook2html_version_minor >= \$min_version_minor) && - (\$docbook2html_version_micro >= \$min_version_micro))) - ? 0 : 1); -EOF - then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - HAVE_DOCBOOK2HTML=no - fi - fi - - dnl check if we can process docbook stuff - AS_DOCBOOK(have_docbook=yes, have_docbook=no) - - dnl check for extra tools - AC_CHECK_PROG(HAVE_DVIPS, dvips, yes, no) - AC_CHECK_PROG(HAVE_XMLLINT, xmllint, yes, no) - - dnl check for image conversion tools - AC_CHECK_PROG(HAVE_FIG2DEV, fig2dev, yes, no) - if test "x$HAVE_FIG2DEV" = "xno" ; then - AC_MSG_WARN([Did not find fig2dev (from xfig), images will not be generated.]) - fi - - dnl The following is a hack: if fig2dev doesn't display an error message - dnl for the desired type, we assume it supports it. - HAVE_FIG2DEV_EPS=no - if test "x$HAVE_FIG2DEV" = "xyes" ; then - fig2dev_quiet=`fig2dev -L eps &1 >/dev/null` - if test "x$fig2dev_quiet" = "x" ; then - HAVE_FIG2DEV_EPS=yes - fi - fi - HAVE_FIG2DEV_PNG=no - if test "x$HAVE_FIG2DEV" = "xyes" ; then - fig2dev_quiet=`fig2dev -L png &1 >/dev/null` - if test "x$fig2dev_quiet" = "x" ; then - HAVE_FIG2DEV_PNG=yes - fi - fi - HAVE_FIG2DEV_PDF=no - if test "x$HAVE_FIG2DEV" = "xyes" ; then - fig2dev_quiet=`fig2dev -L pdf &1 >/dev/null` - if test "x$fig2dev_quiet" = "x" ; then - HAVE_FIG2DEV_PDF=yes - fi - fi - - AC_CHECK_PROG(HAVE_PNGTOPNM, pngtopnm, yes, no) - AC_CHECK_PROG(HAVE_PNMTOPS, pnmtops, yes, no) - AC_CHECK_PROG(HAVE_EPSTOPDF, epstopdf, yes, no) - - dnl check if we can generate HTML - if test "x$HAVE_DOCBOOK2HTML" = "xyes" && \ - test "x$enable_docbook" = "xyes" && \ - test "x$HAVE_XMLLINT" = "xyes" && \ - test "x$HAVE_FIG2DEV_PNG" = "xyes"; then - DOC_HTML=yes - AC_MSG_NOTICE(Will output HTML documentation) - else - DOC_HTML=no - AC_MSG_NOTICE(Will not output HTML documentation) - fi - - dnl check if we can generate PS - if test "x$HAVE_DOCBOOK2PS" = "xyes" && \ - test "x$enable_docbook" = "xyes" && \ - test "x$HAVE_XMLLINT" = "xyes" && \ - test "x$HAVE_JADETEX" = "xyes" && \ - test "x$HAVE_FIG2DEV_EPS" = "xyes" && \ - test "x$HAVE_DVIPS" = "xyes" && \ - test "x$HAVE_PNGTOPNM" = "xyes" && \ - test "x$HAVE_PNMTOPS" = "xyes"; then - DOC_PS=yes - AC_MSG_NOTICE(Will output PS documentation) - else - DOC_PS=no - AC_MSG_NOTICE(Will not output PS documentation) - fi - - dnl check if we can generate PDF - using only ps2pdf - if test "x$DOC_PS" = "xyes" && \ - test "x$enable_docbook" = "xyes" && \ - test "x$HAVE_XMLLINT" = "xyes" && \ - test "x$HAVE_PS2PDF" = "xyes"; then - DOC_PDF=yes - AC_MSG_NOTICE(Will output PDF documentation) - else - DOC_PDF=no - AC_MSG_NOTICE(Will not output PDF documentation) - fi - - dnl if we don't have everything, we should disable - if test "x$have_docbook" != "xyes"; then - enable_docbook=no - fi - fi - - dnl if we're going to install documentation, tell us where - if test "x$have_docbook" = "xyes"; then - AC_MSG_NOTICE(Installing documentation in $docdir) - AC_SUBST(docdir) - fi - - AM_CONDITIONAL(ENABLE_DOCBOOK, test x$enable_docbook = xyes) - AM_CONDITIONAL(DOC_HTML, test x$DOC_HTML = xyes) - AM_CONDITIONAL(DOC_PDF, test x$DOC_PDF = xyes) - AM_CONDITIONAL(DOC_PS, test x$DOC_PS = xyes) -]) diff --git a/mobile/common/m4/gst-error.m4 b/mobile/common/m4/gst-error.m4 deleted file mode 100755 index f97f9a6..0000000 --- a/mobile/common/m4/gst-error.m4 +++ /dev/null @@ -1,145 +0,0 @@ -Dnl handle various error-related things - -dnl Thomas Vander Stichele -dnl Tim-Philipp Müller - -dnl Last modification: 2008-02-18 - -dnl AG_GST_SET_ERROR_CFLAGS([ADD-WERROR]) -dnl AG_GST_SET_ERROR_CXXFLAGS([ADD-WERROR]) -dnl AG_GST_SET_LEVEL_DEFAULT([IS-CVS-VERSION]) - - -dnl Sets ERROR_CFLAGS to something the compiler will accept. -dnl AC_SUBST them so they are available in Makefile - -dnl -Wall is added if it is supported -dnl -Werror is added if ADD-WERROR is not "no" - -dnl These flags can be overridden at make time: -dnl make ERROR_CFLAGS= -AC_DEFUN([AG_GST_SET_ERROR_CFLAGS], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AS_COMPILER_FLAG]) - - - dnl if we support -Wall, set it unconditionally - AS_COMPILER_FLAG(-Wall, - ERROR_CFLAGS="-Wall", - ERROR_CFLAGS="") - - dnl if asked for, add -Werror if supported - if test "x$1" != "xno" - then - AS_COMPILER_FLAG(-Werror, ERROR_CFLAGS="$ERROR_CFLAGS -Werror") - - dnl if -Werror isn't suported, try -errwarn=%all (Sun Forte case) - if test "x$ERROR_CFLAGS" == "x" - then - AS_COMPILER_FLAG([-errwarn=%all], [ - ERROR_CFLAGS="-errwarn=%all" - dnl try -errwarn=%all,no%E_EMPTY_DECLARATION, - dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH, - dnl no%E_MACRO_REDEFINED (Sun Forte case) - dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon - dnl "statement not reached" disabled because there is g_assert_not_reached () in some places - dnl "macro redefined" because of gst/gettext.h - dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'? - for f in 'no%E_EMPTY_DECLARATION' \ - 'no%E_STATEMENT_NOT_REACHED' \ - 'no%E_ARGUEMENT_MISMATCH' \ - 'no%E_MACRO_REDEFINED' - do - AS_COMPILER_FLAG([-errwarn=%all,$f], [ - ERROR_CFLAGS="$ERROR_CFLAGS,$f" - ]) - done - ]) - fi - fi - - AC_SUBST(ERROR_CFLAGS) - AC_MSG_NOTICE([set ERROR_CFLAGS to $ERROR_CFLAGS]) -]) - -dnl Sets ERROR_CXXFLAGS to something the compiler will accept. -dnl AC_SUBST them so they are available in Makefile - -dnl -Wall is added if it is supported -dnl -Werror is added if ADD-WERROR is not "no" - -dnl These flags can be overridden at make time: -dnl make ERROR_CXXFLAGS= -AC_DEFUN([AG_GST_SET_ERROR_CXXFLAGS], -[ - AC_REQUIRE([AC_PROG_CXX]) - AC_REQUIRE([AS_CXX_COMPILER_FLAG]) - - - dnl if we support -Wall, set it unconditionally - AS_CXX_COMPILER_FLAG(-Wall, [ - ERROR_CXXFLAGS="-Wall" - ], [ - ERROR_CXXFLAGS="" - ]) - - dnl if asked for, add -Werror if supported - if test "x$1" != "xno" - then - AS_CXX_COMPILER_FLAG(-Werror, werror_supported=yes, werror_supported=no) - - if test "x$werror_supported" = "xyes"; then - ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror" - - dnl add exceptions - for f in '-Wno-non-virtual-dtor' - do - AS_CXX_COMPILER_FLAG([$f], ERROR_CXXFLAGS="$ERROR_CXXFLAGS $f") - done - else - dnl if -Werror isn't suported, try -errwarn=%all - AS_CXX_COMPILER_FLAG([-errwarn=%all], errwarnall=yes, errwarnall=no) - if test "x$errwarnall" = "xyes"; then - ERROR_CXXFLAGS="-errwarn=%all" - dnl try -errwarn=%all,no%E_EMPTY_DECLARATION, - dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH, - dnl no%E_MACRO_REDEFINED (Sun Forte case) - dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon - dnl "statement not reached" disabled because there is g_assert_not_reached () in some places - dnl "macro redefined" because of gst/gettext.h - dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'? - dnl FIXME: do any of these work with the c++ compiler? if not, why - dnl do we check at all? - for f in 'no%E_EMPTY_DECLARATION' \ - 'no%E_STATEMENT_NOT_REACHED' \ - 'no%E_ARGUEMENT_MISMATCH' \ - 'no%E_MACRO_REDEFINED' - do - AS_CXX_COMPILER_FLAG([-errwarn=%all,$f], [ - ERROR_CXXFLAGS="$ERROR_CXXFLAGS,$f" - ]) - done - fi - fi - fi - - AC_SUBST(ERROR_CXXFLAGS) - AC_MSG_NOTICE([set ERROR_CXXFLAGS to $ERROR_CXXFLAGS]) -]) - -dnl Sets the default error level for debugging messages -AC_DEFUN([AG_GST_SET_LEVEL_DEFAULT], -[ - dnl define correct errorlevel for debugging messages. We want to have - dnl GST_ERROR messages printed when running cvs builds - if test "x[$1]" = "xyes"; then - GST_LEVEL_DEFAULT=GST_LEVEL_ERROR - else - GST_LEVEL_DEFAULT=GST_LEVEL_NONE - fi - AC_DEFINE_UNQUOTED(GST_LEVEL_DEFAULT, $GST_LEVEL_DEFAULT, - [Default errorlevel to use]) - dnl AC_SUBST so we can use it for win32/common/config.h - AC_SUBST(GST_LEVEL_DEFAULT) -]) diff --git a/mobile/common/m4/gst-feature.m4 b/mobile/common/m4/gst-feature.m4 deleted file mode 100755 index 6777029..0000000 --- a/mobile/common/m4/gst-feature.m4 +++ /dev/null @@ -1,286 +0,0 @@ -dnl Perform a check for a feature for GStreamer -dnl Richard Boulton -dnl Thomas Vander Stichele added useful stuff -dnl Last modification: 25/06/2001 -dnl -dnl AG_GST_CHECK_FEATURE(FEATURE-NAME, FEATURE-DESCRIPTION, -dnl DEPENDENT-PLUGINS, TEST-FOR-FEATURE, -dnl DISABLE-BY-DEFAULT, ACTION-IF-USE, ACTION-IF-NOTUSE) -dnl -dnl This macro adds a command line argument to allow the user to enable -dnl or disable a feature, and if the feature is enabled, performs a supplied -dnl test to check if the feature is available. -dnl -dnl The test should define HAVE_ to "yes" or "no" depending -dnl on whether the feature is available. -dnl -dnl The macro will set USE_ to "yes" or "no" depending on -dnl whether the feature is to be used. -dnl Thomas changed this, so that when USE_ was already set -dnl to no, then it stays that way. -dnl -dnl The macro will call AM_CONDITIONAL(USE_, ...) to allow -dnl the feature to control what is built in Makefile.ams. If you want -dnl additional actions resulting from the test, you can add them with the -dnl ACTION-IF-USE and ACTION-IF-NOTUSE parameters. -dnl -dnl FEATURE-NAME is the name of the feature, and should be in -dnl purely upper case characters. -dnl FEATURE-DESCRIPTION is used to describe the feature in help text for -dnl the command line argument. -dnl DEPENDENT-PLUGINS lists any plug-ins which depend on this feature. -dnl TEST-FOR-FEATURE is a test which sets HAVE_ to "yes" -dnl or "no" depending on whether the feature is -dnl available. -dnl DISABLE-BY-DEFAULT if "disabled", the feature is disabled by default, -dnl if any other value, the feature is enabled by default. -dnl ACTION-IF-USE any extra actions to perform if the feature is to be -dnl used. -dnl ACTION-IF-NOTUSE any extra actions to perform if the feature is not to -dnl be used. -dnl -dnl -dnl thomas : -dnl we also added a history. -dnl GST_PLUGINS_YES will contain all plugins to be built -dnl that were checked through AG_GST_CHECK_FEATURE -dnl GST_PLUGINS_NO will contain those that won't be built - -AC_DEFUN([AG_GST_CHECK_FEATURE], -[echo -AC_MSG_NOTICE(*** checking feature: [$2] ***) -if test "x[$3]" != "x" -then - AC_MSG_NOTICE(*** for plug-ins: [$3] ***) -fi -dnl -builtin(define, [gst_endisable], ifelse($5, [disabled], [enable], [disable]))dnl -dnl if it is set to NO, then don't even consider it for building -NOUSE= -if test "x$USE_[$1]" = "xno"; then - NOUSE="yes" -fi -AC_ARG_ENABLE(translit([$1], A-Z, a-z), - [ ]builtin(format, --%-26s gst_endisable %s, gst_endisable-translit([$1], A-Z, a-z), [$2]ifelse([$3],,,: [$3])), - [ case "${enableval}" in - yes) USE_[$1]=yes;; - no) USE_[$1]=no;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-translit([$1], A-Z, a-z)) ;; - esac], - [ USE_$1=]ifelse($5, [disabled], [no], [yes])) dnl DEFAULT - -dnl *** set it back to no if it was preset to no -if test "x$NOUSE" = "xyes"; then - USE_[$1]="no" - AC_MSG_WARN(*** $3 pre-configured not to be built) -fi -NOUSE= - -dnl *** If it's enabled - -if test x$USE_[$1] = xyes; then - dnl save compile variables before the test - - gst_check_save_LIBS=$LIBS - gst_check_save_LDFLAGS=$LDFLAGS - gst_check_save_CFLAGS=$CFLAGS - gst_check_save_CPPFLAGS=$CPPFLAGS - gst_check_save_CXXFLAGS=$CXXFLAGS - - HAVE_[$1]=no - dnl TEST_FOR_FEATURE - $4 - - LIBS=$gst_check_save_LIBS - LDFLAGS=$gst_check_save_LDFLAGS - CFLAGS=$gst_check_save_CFLAGS - CPPFLAGS=$gst_check_save_CPPFLAGS - CXXFLAGS=$gst_check_save_CXXFLAGS - - dnl If it isn't found, unset USE_[$1] - if test x$HAVE_[$1] = xno; then - USE_[$1]=no - else - ifelse([$3], , :, [AC_MSG_NOTICE(*** These plugins will be built: [$3])]) - fi -fi -dnl *** Warn if it's disabled or not found -if test x$USE_[$1] = xyes; then - ifelse([$6], , :, [$6]) - if test "x$3" != "x"; then - GST_PLUGINS_YES="\t[$3]\n$GST_PLUGINS_YES" - fi - AC_DEFINE(HAVE_[$1], , [Define to enable $2]ifelse($3,,, [ (used by $3)]).) -else - ifelse([$3], , :, [AC_MSG_NOTICE(*** These plugins will not be built: [$3])]) - if test "x$3" != "x"; then - GST_PLUGINS_NO="\t[$3]\n$GST_PLUGINS_NO" - fi - ifelse([$7], , :, [$7]) -fi -dnl *** Define the conditional as appropriate -AM_CONDITIONAL(USE_[$1], test x$USE_[$1] = xyes) -]) - -dnl Use a -config program which accepts --cflags and --libs parameters -dnl to set *_CFLAGS and *_LIBS and check existence of a feature. -dnl Richard Boulton -dnl Last modification: 26/06/2001 -dnl AG_GST_CHECK_CONFIGPROG(FEATURE-NAME, CONFIG-PROG-FILENAME, MODULES) -dnl -dnl This check was written for GStreamer: it should be renamed and checked -dnl for portability if you decide to use it elsewhere. -dnl -AC_DEFUN([AG_GST_CHECK_CONFIGPROG], -[ - AC_PATH_PROG([$1]_CONFIG, [$2], no) - if test x$[$1]_CONFIG = xno; then - [$1]_LIBS= - [$1]_CFLAGS= - HAVE_[$1]=no - else - if [$2] --plugin-libs [$3] &> /dev/null; then - [$1]_LIBS=`[$2] --plugin-libs [$3]` - else - [$1]_LIBS=`[$2] --libs [$3]` - fi - [$1]_CFLAGS=`[$2] --cflags [$3]` - HAVE_[$1]=yes - fi - AC_SUBST([$1]_LIBS) - AC_SUBST([$1]_CFLAGS) -]) - -dnl Use AC_CHECK_LIB and AC_CHECK_HEADER to do both tests at once -dnl sets HAVE_module if we have it -dnl Richard Boulton -dnl Last modification: 26/06/2001 -dnl AG_GST_CHECK_LIBHEADER(FEATURE-NAME, LIB NAME, LIB FUNCTION, EXTRA LD FLAGS, -dnl HEADER NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND) -dnl -dnl This check was written for GStreamer: it should be renamed and checked -dnl for portability if you decide to use it elsewhere. -dnl -AC_DEFUN([AG_GST_CHECK_LIBHEADER], -[ - AC_CHECK_LIB([$2], [$3], HAVE_[$1]=yes, HAVE_[$1]=no,[$4]) - if test "x$HAVE_[$1]" = "xyes"; then - AC_CHECK_HEADER([$5], :, HAVE_[$1]=no) - if test "x$HAVE_[$1]" = "xyes"; then - dnl execute what needs to be - ifelse([$6], , :, [$6]) - else - ifelse([$7], , :, [$7]) - fi - else - ifelse([$7], , :, [$7]) - fi - AC_SUBST(HAVE_[$1]) -] -) - -dnl 2004-02-14 Thomas - changed to get set properly and use proper output -dnl 2003-06-27 Benjamin Otte - changed to make this work with gstconfig.h -dnl -dnl Add a subsystem --disable flag and all the necessary symbols and substitions -dnl -dnl AG_GST_CHECK_SUBSYSTEM_DISABLE(SYSNAME, [subsystem name]) -dnl -AC_DEFUN([AG_GST_CHECK_SUBSYSTEM_DISABLE], -[ - dnl this define will replace each literal subsys_def occurrence with - dnl the lowercase hyphen-separated subsystem - dnl e.g. if $1 is GST_DEBUG then subsys_def will be a macro with gst-debug - define([subsys_def],translit([$1], _A-Z, -a-z)) - - AC_ARG_ENABLE(subsys_def, - AC_HELP_STRING(--disable-subsys_def, [disable $2]), - [ - case "${enableval}" in - yes) GST_DISABLE_[$1]=no ;; - no) GST_DISABLE_[$1]=yes ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-subsys_def]) ;; - esac - ], - [GST_DISABLE_[$1]=no]) dnl Default value - - if test x$GST_DISABLE_[$1] = xyes; then - AC_MSG_NOTICE([disabled subsystem [$2]]) - GST_DISABLE_[$1]_DEFINE="#define GST_DISABLE_$1 1" - else - GST_DISABLE_[$1]_DEFINE="/* #undef GST_DISABLE_$1 */" - fi - AC_SUBST(GST_DISABLE_[$1]_DEFINE) - undefine([subsys_def]) -]) - - -dnl Parse gstconfig.h for feature and defines add the symbols and substitions -dnl -dnl AG_GST_PARSE_SUBSYSTEM_DISABLE(GST_CONFIGPATH, FEATURE) -dnl -AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLE], -[ - grep >/dev/null "#undef GST_DISABLE_$2" $1 - if test $? = 0; then - GST_DISABLE_[$2]=0 - else - GST_DISABLE_[$2]=1 - fi - AC_SUBST(GST_DISABLE_[$2]) -]) - -dnl Parse gstconfig.h and defines add the symbols and substitions -dnl -dnl GST_CONFIGPATH=`$PKG_CONFIG --variable=includedir gstreamer-0.10`"/gst/gstconfig.h" -dnl AG_GST_PARSE_SUBSYSTEM_DISABLES(GST_CONFIGPATH) -dnl -AC_DEFUN([AG_GST_PARSE_SUBSYSTEM_DISABLES], -[ - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,GST_DEBUG) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,LOADSAVE) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PARSE) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,TRACE) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ALLOC_TRACE) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,REGISTRY) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,ENUMTYPES) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,INDEX) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,PLUGIN) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,URI) - AG_GST_PARSE_SUBSYSTEM_DISABLE($1,XML) -]) - - - -dnl relies on GST_PLUGINS_ALL, GST_PLUGINS_SELECTED, GST_PLUGINS_YES, -dnl GST_PLUGINS_NO, and BUILD_EXTERNAL -AC_DEFUN([AG_GST_OUTPUT_PLUGINS], [ - -printf "configure: *** Plug-ins without external dependencies that will be built:\n" -( for i in $GST_PLUGINS_SELECTED; do printf '\t'$i'\n'; done ) | sort -printf "\n" - -printf "configure: *** Plug-ins without external dependencies that will NOT be built:\n" -( for i in $GST_PLUGINS_ALL; do - case $GST_PLUGINS_SELECTED in - *$i*) - ;; - *) - printf '\t'$i'\n' - ;; - esac - done ) | sort -printf "\n" - -if test "x$BUILD_EXTERNAL" = "xno"; then - printf "configure: *** No plug-ins with external dependencies will be built\n" -else - printf "configure: *** Plug-ins with dependencies that will be built:" - printf "$GST_PLUGINS_YES\n" | sort - printf "\n" - printf "configure: *** Plug-ins with dependencies that will NOT be built:" - printf "$GST_PLUGINS_NO\n" | sort - printf "\n" -fi -]) - diff --git a/mobile/common/m4/gst-function.m4 b/mobile/common/m4/gst-function.m4 deleted file mode 100755 index 1216621..0000000 --- a/mobile/common/m4/gst-function.m4 +++ /dev/null @@ -1,63 +0,0 @@ -dnl -dnl Check for compiler mechanism to show functions in debugging -dnl copied from an Ali patch floating on the internet -dnl -AC_DEFUN([AG_GST_CHECK_FUNCTION],[ - dnl #1: __PRETTY_FUNCTION__ - AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__) - AC_CACHE_VAL(have_pretty_function,[ - AC_TRY_LINK([#include ], - [printf("%s", __PRETTY_FUNCTION__);], - have_pretty_function=yes, - have_pretty_function=no) - ]) - AC_MSG_RESULT($have_pretty_function) - if test "$have_pretty_function" = yes; then - AC_DEFINE(HAVE_PRETTY_FUNCTION, 1, - [defined if the compiler implements __PRETTY_FUNCTION__]) - fi - -dnl #2: __FUNCTION__ - AC_MSG_CHECKING(whether $CC implements __FUNCTION__) - AC_CACHE_VAL(have_function,[ - AC_TRY_LINK([#include ], - [printf("%s", __FUNCTION__);], - have_function=yes, - have_function=no) - ]) - AC_MSG_RESULT($have_function) - if test "$have_function" = yes; then - AC_DEFINE(HAVE_FUNCTION, 1, - [defined if the compiler implements __FUNCTION__]) - fi - -dnl #3: __func__ - AC_MSG_CHECKING(whether $CC implements __func__) - AC_CACHE_VAL(have_func,[ - AC_TRY_LINK([#include ], - [printf("%s", __func__);], - have_func=yes, - have_func=no) - ]) - AC_MSG_RESULT($have_func) - if test "$have_func" = yes; then - AC_DEFINE(HAVE_FUNC, 1, - [defined if the compiler implements __func__]) - fi - -dnl now define FUNCTION to whatever works, and fallback to "" - if test "$have_pretty_function" = yes; then - function=__PRETTY_FUNCTION__ - else - if test "$have_function" = yes; then - function=__FUNCTION__ - else - if test "$have_func" = yes; then - function=__func__ - else - function=\"\" - fi - fi - fi - AC_DEFINE_UNQUOTED(GST_FUNCTION, $function, [macro to use to show function name]) -]) diff --git a/mobile/common/m4/gst-gettext.m4 b/mobile/common/m4/gst-gettext.m4 deleted file mode 100755 index a63651b..0000000 --- a/mobile/common/m4/gst-gettext.m4 +++ /dev/null @@ -1,21 +0,0 @@ -dnl gettext setup - -dnl AG_GST_GETTEXT([gettext-package]) -dnl defines GETTEXT_PACKAGE and LOCALEDIR - -AC_DEFUN([AG_GST_GETTEXT], -[ - if test "$USE_NLS" = "yes"; then - GETTEXT_PACKAGE=[$1] - else - GETTEXT_PACKAGE=[NULL] - fi - AC_SUBST(GETTEXT_PACKAGE) - AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], "$GETTEXT_PACKAGE", - [gettext package name]) - - dnl define LOCALEDIR in config.h - AS_AC_EXPAND(LOCALEDIR, $datadir/locale) - AC_DEFINE_UNQUOTED([LOCALEDIR], "$LOCALEDIR", - [gettext locale dir]) -]) diff --git a/mobile/common/m4/gst-glib2.m4 b/mobile/common/m4/gst-glib2.m4 deleted file mode 100755 index 3060e5e..0000000 --- a/mobile/common/m4/gst-glib2.m4 +++ /dev/null @@ -1,25 +0,0 @@ -dnl check for a minimum version of GLib - -dnl AG_GST_GLIB_CHECK([minimum-version-required]) - -AC_DEFUN([AG_GST_GLIB_CHECK], -[ - dnl Minimum required version of GLib - GLIB_REQ=[$1] - if test "x$GLIB_REQ" = "x" - then - AC_MSG_ERROR([Please specify a required version for GLib 2.0]) - fi - AC_SUBST(GLIB_REQ) - - dnl Check for glib with everything - AG_GST_PKG_CHECK_MODULES(GLIB, - glib-2.0 >= $GLIB_REQ gobject-2.0 gthread-2.0 gmodule-no-export-2.0) - - if test "x$HAVE_GLIB" = "xno"; then - AC_MSG_ERROR([This package requires GLib >= $GLIB_REQ to compile.]) - fi - - dnl for the poor souls who for example have glib in /usr/local - AS_SCRUB_INCLUDE(GLIB_CFLAGS) -]) diff --git a/mobile/common/m4/gst-libxml2.m4 b/mobile/common/m4/gst-libxml2.m4 deleted file mode 100755 index 7d978d3..0000000 --- a/mobile/common/m4/gst-libxml2.m4 +++ /dev/null @@ -1,46 +0,0 @@ -dnl call this macro with the minimum required version as an argument -dnl this macro sets and AC_SUBSTs XML_CFLAGS and XML_LIBS -dnl it also sets LIBXML_PKG, used for the pkg-config file - -AC_DEFUN([AG_GST_LIBXML2_CHECK], -[ - dnl Minimum required version of libxml2 - dnl default to 2.4.9 if not specified - LIBXML2_REQ=ifelse([$1],,2.4.9,[$1]) - AC_SUBST(LIBXML2_REQ) - - dnl check for libxml2 - PKG_CHECK_MODULES(XML, libxml-2.0 >= $LIBXML2_REQ, - HAVE_LIBXML2=yes, [ - AC_MSG_RESULT(no) - HAVE_LIBXML2=no - ]) - if test "x$HAVE_LIBXML2" = "xyes"; then - AC_DEFINE(HAVE_LIBXML2, 1, [Define if libxml2 is available]) - else - AC_MSG_ERROR([Need libxml2 for glib2 builds -- you should be able to do without it -- this needs fixing]) - fi - dnl this is for the .pc file - LIBXML_PKG=', libxml-2.0' - AC_SUBST(LIBXML_PKG) - AC_SUBST(XML_LIBS) - AC_SUBST(XML_CFLAGS) - - dnl XML_LIBS might pull in -lz without zlib actually being on the system, so - dnl try linking with these LIBS and CFLAGS - ac_save_CFLAGS=$CFLAGS - ac_save_LIBS=$LIBS - CFLAGS="$CFLAGS $XML_CFLAGS" - LIBS="$LIBS $XML_LIBS" - AC_TRY_LINK([ -#include -#include -],[ -/* function body */ -], - AC_MSG_NOTICE([Test xml2 program linked]), - AC_MSG_ERROR([Could not link libxml2 test program. Check if you have the necessary dependencies.]) - ) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" -]) diff --git a/mobile/common/m4/gst-parser.m4 b/mobile/common/m4/gst-parser.m4 deleted file mode 100755 index 9cc0981..0000000 --- a/mobile/common/m4/gst-parser.m4 +++ /dev/null @@ -1,63 +0,0 @@ -AC_DEFUN([AG_GST_BISON_CHECK], -[ - dnl FIXME: check if AC_PROG_YACC is suitable here - dnl FIXME: make precious - AC_PATH_PROG(BISON_PATH, bison, no) - if test x$BISON_PATH = xno; then - AC_MSG_ERROR(Could not find bison) - fi - - dnl check bison version - dnl FIXME 0.11: we need version >= 1.875 for the reentrancy support - dnl in the parser. If an older version is installed pre-generated - dnl sources are used. This should become a hard dependency for 0.11! - bison_min_version=1.875 - bison_version=`$BISON_PATH --version | head -n 1 | sed 's/^.*) //' | sed 's/[[a-zA-Z]]*$//' | cut -d' ' -f1` - AC_MSG_CHECKING([bison version $bison_version >= $bison_min_version]) - - if perl -w <= 2.5.31 for the reentrancy support - dnl in the parser. If an older version is installed pre-generated - dnl sources are used. This should become a hard dependency for 0.11! - flex_min_version=2.5.31 - flex_version=`$FLEX_PATH --version | head -n 1 | sed 's/^.* //' | sed 's/[[a-zA-Z]]*$//' | cut -d' ' -f1` - AC_MSG_CHECKING([flex version $flex_version >= $flex_min_version]) - if perl -w < \$min_version_major) || - ((\$flex_version_major == \$min_version_major) && - (\$flex_version_minor > \$min_version_minor)) || - ((\$flex_version_major == \$min_version_major) && - (\$flex_version_minor == \$min_version_minor) && - (\$flex_version_micro >= \$min_version_micro))) - ? 0 : 1); -EOF - then - AC_MSG_RESULT(yes) - AM_CONDITIONAL(GENERATE_PARSER, test -z $GENERATE_PARSER_TRUE) - else - AC_MSG_RESULT([no, using pre-generated parser sources]) - AM_CONDITIONAL(GENERATE_PARSER, false) - fi -]) diff --git a/mobile/common/m4/gst-plugin-docs.m4 b/mobile/common/m4/gst-plugin-docs.m4 deleted file mode 100755 index 29ebbd6..0000000 --- a/mobile/common/m4/gst-plugin-docs.m4 +++ /dev/null @@ -1,47 +0,0 @@ -dnl AG_GST_PYXML_CHECK([MINIMUM-PYTHON-VERSION]) - -AC_DEFUN([AG_GST_PYXML_CHECK], -[ - AC_BEFORE([AS_PATH_PYTHON],[$0])dnl find python first - - have_pyxml=no - if test "x$PYTHON" != x; then - AC_MSG_CHECKING([pyxml]) - if $PYTHON -c "from xml.dom.ext.reader import Sax2" 2>/dev/null \ - && $PYTHON -c "from xml.dom.NodeFilter import NodeFilter" 2>/dev/null; then - AC_MSG_RESULT(yes) - have_pyxml=yes - else - AC_MSG_RESULT(no) - fi - fi -]) - -dnl AG_GST_PLUGIN_DOCS([MINIMUM-GTK-DOC-VERSION],[MINIMUM-PYTHON-VERSION]) -dnl -dnl checks for prerequisites for the common/mangle-tmpl.py script -dnl used when building the plugin documentation - -AC_DEFUN([AG_GST_PLUGIN_DOCS], -[ - AC_BEFORE([GTK_DOC_CHECK],[$0])dnl check for gtk-doc first - - if test x$enable_gtk_doc = xyes -a x$have_gtk_doc = xyes; then - AG_GST_PYXML_CHECK([$1]) - fi - - build_plugin_docs=no - AC_MSG_CHECKING([whether to build plugin documentation]) - if test x$enable_gtk_doc = xyes -a x$have_gtk_doc = xyes; then - if test "x$have_pyxml" != xyes; then - AC_MSG_RESULT([no (pyxml not installed)]) - else - build_plugin_docs=yes - AC_MSG_RESULT([yes]) - fi - else - AC_MSG_RESULT([no (gtk-doc disabled or not available)]) - fi - - AM_CONDITIONAL(ENABLE_PLUGIN_DOCS, test x$build_plugin_docs = xyes) -]) diff --git a/mobile/common/m4/gst-plugindir.m4 b/mobile/common/m4/gst-plugindir.m4 deleted file mode 100755 index 09989d0..0000000 --- a/mobile/common/m4/gst-plugindir.m4 +++ /dev/null @@ -1,17 +0,0 @@ -dnl AG_GST_SET_PLUGINDIR - -dnl AC_DEFINE PLUGINDIR to the full location where plug-ins will be installed -dnl AC_SUBST plugindir, to be used in Makefile.am's - -AC_DEFUN([AG_GST_SET_PLUGINDIR], -[ - dnl define location of plugin directory - AS_AC_EXPAND(PLUGINDIR, ${libdir}/gstreamer-$GST_MAJORMINOR) - AC_DEFINE_UNQUOTED(PLUGINDIR, "$PLUGINDIR", - [directory where plugins are located]) - AC_MSG_NOTICE([Using $PLUGINDIR as the plugin install location]) - - dnl plugin directory configure-time variable for use in Makefile.am - plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" - AC_SUBST(plugindir) -]) diff --git a/mobile/common/m4/gst-valgrind.m4 b/mobile/common/m4/gst-valgrind.m4 deleted file mode 100755 index 93c2635..0000000 --- a/mobile/common/m4/gst-valgrind.m4 +++ /dev/null @@ -1,35 +0,0 @@ -AC_DEFUN([AG_GST_VALGRIND_CHECK], -[ - dnl valgrind inclusion - AC_ARG_ENABLE(valgrind, - AC_HELP_STRING([--disable-valgrind], [disable run-time valgrind detection]), - [ - case "${enableval}" in - yes) USE_VALGRIND="$USE_DEBUG" ;; - no) USE_VALGRIND=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-valgrind) ;; - esac], - [ - USE_VALGRIND="$USE_DEBUG" - ]) dnl Default value - - VALGRIND_REQ="2.1" - if test "x$USE_VALGRIND" = xyes; then - PKG_CHECK_MODULES(VALGRIND, valgrind > $VALGRIND_REQ, - USE_VALGRIND="yes", - [ - USE_VALGRIND="no" - AC_MSG_RESULT([no]) - ]) - fi - - if test "x$USE_VALGRIND" = xyes; then - AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used]) - AC_MSG_NOTICE(Using extra code paths for valgrind) - fi - AC_SUBST(VALGRIND_CFLAGS) - AC_SUBST(VALGRIND_LIBS) - - AC_PATH_PROG(VALGRIND_PATH, valgrind, no) - AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno") -]) diff --git a/mobile/common/m4/gst-x11.m4 b/mobile/common/m4/gst-x11.m4 deleted file mode 100644 index d3baf2d..0000000 --- a/mobile/common/m4/gst-x11.m4 +++ /dev/null @@ -1,70 +0,0 @@ -dnl macros for X-related detections -dnl AC_SUBST's HAVE_X, X_CFLAGS, X_LIBS -AC_DEFUN([AG_GST_CHECK_X], -[ - AC_PATH_XTRA - ac_cflags_save="$CFLAGS" - ac_cppflags_save="$CPPFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" - CPPFLAGS="$CPPFLAGS $X_CFLAGS" - - dnl now try to find the HEADER - AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no") - - if test "x$HAVE_X" = "xno" - then - AC_MSG_NOTICE([cannot find X11 development files]) - else - dnl this is much more than we want - X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS" - dnl AC_PATH_XTRA only defines the path needed to find the X libs, - dnl it does not add the libs; therefore we add them here - X_LIBS="$X_LIBS -lX11" - AC_SUBST(X_CFLAGS) - AC_SUBST(X_LIBS) - fi - AC_SUBST(HAVE_X) - - CFLAGS="$ac_cflags_save" - CPPFLAGS="$ac_cppflags_save" -]) - -dnl *** XVideo *** -dnl Look for the PIC library first, Debian requires it. -dnl Check debian-devel archives for gory details. -dnl 20020110: -dnl At the moment XFree86 doesn't distribute shared libXv due -dnl to unstable API. On many platforms you CAN NOT link a shared -dnl lib to a static non-PIC lib. This is what the xvideo GStreamer -dnl plug-in wants to do. So Debian distributes a PIC compiled -dnl version of the static lib for plug-ins to link to when it is -dnl inappropriate to link the main application to libXv directly. -dnl FIXME: add check if this platform can support linking to a -dnl non-PIC libXv, if not then don not use Xv. -dnl FIXME: perhaps warn user if they have a shared libXv since -dnl this is an error until XFree86 starts shipping one -AC_DEFUN([AG_GST_CHECK_XV], -[ - if test x$HAVE_X = xyes; then - AC_CHECK_LIB(Xv_pic, XvQueryExtension, - HAVE_XVIDEO="yes", HAVE_XVIDEO="no", - $X_LIBS -lXext) - - if test x$HAVE_XVIDEO = xyes; then - XVIDEO_LIBS="-lXv_pic -lXext" - AC_SUBST(XVIDEO_LIBS) - else - dnl try again using something else if we didn't find it first - if test x$HAVE_XVIDEO = xno; then - AC_CHECK_LIB(Xv, XvQueryExtension, - HAVE_XVIDEO="yes", HAVE_XVIDEO="no", - $X_LIBS -lXext) - - if test x$HAVE_XVIDEO = xyes; then - XVIDEO_LIBS="-lXv -lXext" - AC_SUBST(XVIDEO_LIBS) - fi - fi - fi - fi -]) diff --git a/mobile/common/m4/gst.m4 b/mobile/common/m4/gst.m4 deleted file mode 100755 index 04b466f..0000000 --- a/mobile/common/m4/gst.m4 +++ /dev/null @@ -1,10 +0,0 @@ -dnl AG_GST_INIT -dnl sets up use of GStreamer configure.ac macros -dnl all GStreamer autoconf macros are prefixed -dnl with AG_GST_ for public macros -dnl with _AG_GST_ for private macros - -AC_DEFUN([AG_GST_INIT], -[ - m4_pattern_forbid(^_?AG_GST_) -]) diff --git a/mobile/common/m4/gtk-doc.m4 b/mobile/common/m4/gtk-doc.m4 deleted file mode 100755 index 57040aa..0000000 --- a/mobile/common/m4/gtk-doc.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl -*- mode: autoconf -*- - -# serial 1 - -dnl Usage: -dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) -AC_DEFUN([GTK_DOC_CHECK], -[ - AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first - dnl for overriding the documentation installation directory - AC_ARG_WITH(html-dir, - AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, - [with_html_dir='${datadir}/gtk-doc/html']) - HTML_DIR="$with_html_dir" - AC_SUBST(HTML_DIR) - - dnl enable/disable documentation building - AC_ARG_ENABLE(gtk-doc, - AC_HELP_STRING([--enable-gtk-doc], - [use gtk-doc to build documentation [default=no]]),, - enable_gtk_doc=no) - - have_gtk_doc=no - if test x$enable_gtk_doc = xyes; then - if test -z "$PKG_CONFIG"; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - fi - if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then - have_gtk_doc=yes - fi - if test -z "$SED"; then - AC_PROG_SED - fi - -dnl do we want to do a version check? -ifelse([$1],[],, - [gtk_doc_min_version=$1 - if test "$have_gtk_doc" = yes; then - AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version]) - if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - have_gtk_doc=no - fi - fi -]) - if test "$have_gtk_doc" != yes; then - enable_gtk_doc=no - fi - fi - - AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) - AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL") -]) diff --git a/mobile/common/m4/iconv.m4 b/mobile/common/m4/iconv.m4 deleted file mode 100755 index c5f3579..0000000 --- a/mobile/common/m4/iconv.m4 +++ /dev/null @@ -1,103 +0,0 @@ -# iconv.m4 serial AM4 (gettext-0.11.3) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_func_iconv=yes) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include -#include ], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_lib_iconv=yes - am_cv_func_iconv=yes) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST(LIBICONV) - AC_SUBST(LTLIBICONV) -]) - -AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(am_cv_proto_iconv, [ - AC_TRY_COMPILE([ -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif -], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([$]{ac_t:- - }[$]am_cv_proto_iconv) - AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, - [Define as const if the declaration of iconv() needs const.]) - fi -]) diff --git a/mobile/common/m4/isc-posix.m4 b/mobile/common/m4/isc-posix.m4 deleted file mode 100755 index 1319dd1..0000000 --- a/mobile/common/m4/isc-posix.m4 +++ /dev/null @@ -1,26 +0,0 @@ -# isc-posix.m4 serial 2 (gettext-0.11.2) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. - -# This test replaces the one in autoconf. -# Currently this macro should have the same name as the autoconf macro -# because gettext's gettext.m4 (distributed in the automake package) -# still uses it. Otherwise, the use in gettext.m4 makes autoheader -# give these diagnostics: -# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX -# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX - -undefine([AC_ISC_POSIX]) - -AC_DEFUN([AC_ISC_POSIX], - [ - dnl This test replaces the obsolescent AC_ISC_POSIX kludge. - AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) - ] -) diff --git a/mobile/common/m4/lib-ld.m4 b/mobile/common/m4/lib-ld.m4 deleted file mode 100755 index ddb5732..0000000 --- a/mobile/common/m4/lib-ld.m4 +++ /dev/null @@ -1,97 +0,0 @@ -# lib-ld.m4 serial 1 (gettext-0.11) -dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - acl_cv_prog_gnu_ld=yes -else - acl_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$acl_cv_prog_gnu_ld -]) - -dnl From libtool-1.4. Sets the variable LD. -AC_DEFUN([AC_LIB_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(acl_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU -]) diff --git a/mobile/common/m4/lib-link.m4 b/mobile/common/m4/lib-link.m4 deleted file mode 100755 index 6b94251..0000000 --- a/mobile/common/m4/lib-link.m4 +++ /dev/null @@ -1,554 +0,0 @@ -# lib-link.m4 serial 3 (gettext-0.11.3) -dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - undefine([Name]) - undefine([NAME]) -]) - -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. If found, it -dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and -dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIB[]NAME" - AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - undefine([Name]) - undefine([NAME]) -]) - -dnl Determine the platform dependent parameters needed to use rpath: -dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, -dnl hardcode_direct, hardcode_minus_L, -dnl sys_lib_search_path_spec, sys_lib_dlsearch_path_spec. -AC_DEFUN([AC_LIB_RPATH], -[ - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" - sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE(rpath, - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_ARG_WITH([lib$1-prefix], -[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib - --without-lib$1-prefix don't search for lib$1 in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) diff --git a/mobile/common/m4/lib-prefix.m4 b/mobile/common/m4/lib-prefix.m4 deleted file mode 100755 index b8b79ab..0000000 --- a/mobile/common/m4/lib-prefix.m4 +++ /dev/null @@ -1,148 +0,0 @@ -# lib-prefix.m4 serial 1 (gettext-0.11) -dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) diff --git a/mobile/common/m4/libtool.m4 b/mobile/common/m4/libtool.m4 deleted file mode 100644 index a3fee53..0000000 --- a/mobile/common/m4/libtool.m4 +++ /dev/null @@ -1,7377 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 56 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl -_LT_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\[$]0 --fallback-echo"')dnl " - lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` - ;; -esac - -_LT_OUTPUT_LIBTOOL_INIT -]) - - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -cat >"$CONFIG_LT" <<_LTEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. - -lt_cl_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AS_SHELL_SANITIZE -_AS_PREPARE - -exec AS_MESSAGE_FD>&1 -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2008 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -if test "$no_create" != yes; then - lt_cl_success=: - test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" - exec AS_MESSAGE_LOG_FD>/dev/null - $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false - exec AS_MESSAGE_LOG_FD>>config.log - $lt_cl_success || AS_EXIT(1) -fi -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_XSI_SHELLFNS - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX -# ----------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_SHELL_INIT - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[_LT_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -[$]* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(lt_ECHO) -]) -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], - [An echo program that does not interpret backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[AC_CHECK_TOOL(AR, ar, false) -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1]) - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line __oline__ "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method == "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC*) - # IBM XL 8.0 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac -AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; - linux* | k*bsd*-gnu) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - _LT_TAGVAR(link_all_deplibs, $1)=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE(int foo(void) {}, - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - ) - LDFLAGS="$save_LDFLAGS" - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [fix_srcfile_path], [1], - [Fix the shell variable $srcfile for the compiler]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_PROG_CXX -# ------------ -# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ -# compiler, we have our own version here. -m4_defun([_LT_PROG_CXX], -[ -pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) -AC_PROG_CXX -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_CXX - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_CXX], []) - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[AC_REQUIRE([_LT_PROG_CXX])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 will use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - xl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=echo - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_PROG_F77 -# ------------ -# Since AC_PROG_F77 is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_F77], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) -AC_PROG_F77 -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_F77 - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_F77], []) - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_REQUIRE([_LT_PROG_F77])dnl -AC_LANG_PUSH(Fortran 77) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${F77-"f77"} - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_PROG_FC -# ----------- -# Since AC_PROG_FC is broken, in that it returns the empty string -# if there is no fortran compiler, we have our own version here. -m4_defun([_LT_PROG_FC], -[ -pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) -AC_PROG_FC -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi -popdef([AC_MSG_ERROR]) -])# _LT_PROG_FC - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([_LT_PROG_FC], []) - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_REQUIRE([_LT_PROG_FC])dnl -AC_LANG_PUSH(Fortran) - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - CC=${FC-"f95"} - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC="$lt_save_CC" -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC="$lt_save_CC" -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_XSI_SHELLFNS -# --------------------- -# Bourne and XSI compatible variants of some useful shell functions. -m4_defun([_LT_PROG_XSI_SHELLFNS], -[case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $[*] )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - -dnl func_dirname_and_basename -dnl A portable version of this function is already defined in general.m4sh -dnl so there is no need for it here. - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[[^=]]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$[@]"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]+=\$[2]" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]=\$$[1]\$[2]" -} - -_LT_EOF - ;; - esac -]) diff --git a/mobile/common/m4/ltoptions.m4 b/mobile/common/m4/ltoptions.m4 deleted file mode 100644 index 34151a3..0000000 --- a/mobile/common/m4/ltoptions.m4 +++ /dev/null @@ -1,368 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [0], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/mobile/common/m4/ltsugar.m4 b/mobile/common/m4/ltsugar.m4 deleted file mode 100644 index 9000a05..0000000 --- a/mobile/common/m4/ltsugar.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/mobile/common/m4/ltversion.m4 b/mobile/common/m4/ltversion.m4 deleted file mode 100644 index f3c5309..0000000 --- a/mobile/common/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# Generated from ltversion.in. - -# serial 3017 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.2.6b]) -m4_define([LT_PACKAGE_REVISION], [1.3017]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.6b' -macro_revision='1.3017' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/mobile/common/m4/lt~obsolete.m4 b/mobile/common/m4/lt~obsolete.m4 deleted file mode 100644 index 637bb20..0000000 --- a/mobile/common/m4/lt~obsolete.m4 +++ /dev/null @@ -1,92 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 4 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/mobile/common/m4/pkg.m4 b/mobile/common/m4/pkg.m4 deleted file mode 100755 index 3c20213..0000000 --- a/mobile/common/m4/pkg.m4 +++ /dev/null @@ -1,135 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_ifval([$1], [$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi - -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# -# Similar to PKG_CHECK_MODULES, make sure that the first instance of -# this or PKG_CHECK_MODULES is called, or make sure to call -# PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_ifval([$2], [$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$PKG_CONFIG"; then - if test -n "$$1"; then - pkg_cv_[]$1="$$1" - else - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - fi -else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -if test $pkg_failed = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" 1>&AS_MESSAGE_LOG_FD - - ifelse([$4], , [AC_MSG_ERROR(dnl -[Package requirements ($2) were not met. -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables -to avoid the need to call pkg-config. See the pkg-config man page for -more details.])], - [$4]) -elif test $pkg_failed = untried; then - ifelse([$4], , [AC_MSG_FAILURE(dnl -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively you may set the $1_CFLAGS and $1_LIBS environment variables -to avoid the need to call pkg-config. See the pkg-config man page for -more details. - -To get pkg-config, see .])], - [$4]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - ifelse([$3], , :, [$3]) -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/mobile/common/m4/progtest.m4 b/mobile/common/m4/progtest.m4 deleted file mode 100755 index 443c8e3..0000000 --- a/mobile/common/m4/progtest.m4 +++ /dev/null @@ -1,59 +0,0 @@ -# progtest.m4 serial 2 (gettext-0.10.40) -dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1996. - -# Search path for a program which passes the given test. - -dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN([AM_PATH_PROG_WITH_TEST], -[# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, -[case "[$]$1" in - /*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in ifelse([$5], , $PATH, [$5]); do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word" - break - fi - fi - done - IFS="$ac_save_ifs" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) -else - AC_MSG_RESULT(no) -fi -AC_SUBST($1)dnl -]) diff --git a/mobile/common/mangle-tmpl.py b/mobile/common/mangle-tmpl.py deleted file mode 100755 index d319040..0000000 --- a/mobile/common/mangle-tmpl.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- Mode: Python -*- -# vi:si:et:sw=4:sts=4:ts=4 - -""" -use the output from gst-xmlinspect.py to mangle tmpl/*.sgml and -insert/overwrite Short Description and Long Description -""" - -# FIXME: right now it uses pygst and scans on its own; -# we really should use inspect/*.xml instead since the result of -# gst-xmlinspect.py is commited by the docs maintainer, who can be -# expected to have pygst, but this step should be done for every docs build, -# so no pygst allowed - -# read in inspect/*.xml -# for every tmpl/element-(name).xml: mangle with details from element - -import glob -import re -import sys -import os - -class Tmpl: - def __init__(self, filename): - self.filename = filename - self._sectionids = [] - self._sections = {} - - def read(self): - """ - Read and parse the sections from the given file. - """ - lines = open(self.filename).readlines() - matcher = re.compile("\n") - id = None - - for line in lines: - match = matcher.search(line) - if match: - id = match.expand("\\1") - self._sectionids.append(id) - self._sections[id] = [] - else: - if not id: - sys.stderr.write( - "WARNING: line before a SECTION header: %s" % line) - else: - self._sections[id].append(line) - - def get_section(self, id): - """ - Get the content from the given section. - """ - return self._sections[id] - - def set_section(self, id, content): - """ - Replace the given section id with the given content. - """ - self._sections[id] = content - - def output(self): - """ - Return the output of the current template in the tmpl/*.sgml format. - """ - lines = [] - for id in self._sectionids: - lines.append("\n" % id) - for line in self._sections[id]: - lines.append(line) - - return "".join(lines) - - def write(self, backup=False): - """ - Write out the template file again, backing up the previous one. - """ - if backup: - target = self.filename + ".mangle.bak" - os.rename(self.filename, target) - - handle = open(self.filename, "w") - handle.write(self.output()) - handle.close() - -from xml.dom.ext.reader import Sax2 -from xml.dom.NodeFilter import NodeFilter - -def get_elements(file): - elements = {} - handle = open(file) - reader = Sax2.Reader() - doc = reader.fromStream(handle) - handle.close() - - walker = doc.createTreeWalker(doc.documentElement, - NodeFilter.SHOW_ELEMENT, None, 0) - while walker.currentNode and walker.currentNode.tagName != 'elements': - walker.nextNode() - - # we're at elements now - el = walker.firstChild() - while walker.currentNode: - element = walker.firstChild() - # loop over children of - name = None - description = None - while walker.currentNode: - if walker.currentNode.tagName == 'name': - name = walker.currentNode.firstChild.data.encode('UTF-8') - if walker.currentNode.tagName == 'description': - description = walker.currentNode.firstChild.data.encode('UTF-8') - if not walker.nextSibling(): break - # back up to - walker.parentNode() - elements[name] = {'description': description} - - if not walker.nextSibling(): break - - return elements - - -def main(): - if not len(sys.argv) == 3: - sys.stderr.write('Please specify the inspect/ dir and the tmpl/ dir') - sys.exit(1) - - inspectdir = sys.argv[1] - tmpldir = sys.argv[2] - - # parse all .xml files; build map of element name -> short desc - #for file in glob.glob("inspect/plugin-*.xml"): - elements = {} - for file in glob.glob("%s/plugin-*.xml" % inspectdir): - elements.update(get_elements(file)) - - for file in glob.glob("%s/element-*.sgml" % tmpldir): - base = os.path.basename(file) - element = base[len("element-"):-len(".sgml")] - tmpl = Tmpl(file) - tmpl.read() - if element in elements.keys(): - description = elements[element]['description'] - tmpl.set_section("Short_Description", "%s\n\n" % description) - - # put in an include if not yet there - line = '\n' - section = tmpl.get_section("Long_Description") - if not section[0] == line: - section.insert(0, line) - tmpl.set_section("Long_Description", section) - tmpl.write() - -main() diff --git a/mobile/common/plugins.xsl b/mobile/common/plugins.xsl deleted file mode 100755 index 150087f..0000000 --- a/mobile/common/plugins.xsl +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - -plugins- - - - - - - - - - - - - - Element Information - - - - - plugin - - - - plugin- - - - - - - - - author - - - - - - - class - - - - - - - - Element Pads - - - - - name - - - - - - - direction - - - - - - - presence - - - - - - - details - - - - - - - - - - - - - - - - - - -plugins-plugin- - - - - - - 3 - FIXME Library - - - - - - plugin- - - - - - - - - - - - Plugin Information - - - - filename - - - - - - - version - - - - - - - run-time license - - - - - - - package - - - - - - - origin - - - - - - - - - - - - - - - - - - - - - - - Elements - - - - - - - - - - - - - - diff --git a/mobile/common/po.mak b/mobile/common/po.mak deleted file mode 100755 index e019fac..0000000 --- a/mobile/common/po.mak +++ /dev/null @@ -1,4 +0,0 @@ -# rule to download the latest .po files -download-po: $(top_srcdir)/common/download-translations - $(top_srcdir)/common/download-translations $(PACKAGE) - diff --git a/mobile/common/release.mak b/mobile/common/release.mak deleted file mode 100755 index afb0c8c..0000000 --- a/mobile/common/release.mak +++ /dev/null @@ -1,25 +0,0 @@ -# include this snippet to add a common release: target by using -# include $(top_srcdir)/common/release.mak - -# make bz2 as well -AUTOMAKE_OPTIONS = dist-bzip2 - -release: dist - $(MAKE) $(PACKAGE)-$(VERSION).tar.gz.md5 - $(MAKE) $(PACKAGE)-$(VERSION).tar.bz2.md5 - -# generate md5 sum files -%.md5: % - md5sum $< > $@ - -# check that no marshal or enumtypes files are included -# this in turn ensures that distcheck fails for missing .list files which is currently -# shadowed when the corresponding .c and .h files are included. -distcheck-hook: - @test "x" = "x`find $(distdir) -name \*-enumtypes.[ch] | grep -v win32`" && \ - test "x" = "x`find $(distdir) -name \*-marshal.[ch]`" || \ - ( $(ECHO) "*** Leftover enumtypes or marshal files in the tarball." && \ - $(ECHO) "*** Make sure the following files are not disted:" && \ - find $(distdir) -name \*-enumtypes.[ch] | grep -v win32 && \ - find $(distdir) -name \*-marshal.[ch] && \ - false ) diff --git a/mobile/common/scangobj-merge.py b/mobile/common/scangobj-merge.py deleted file mode 100755 index 4917255..0000000 --- a/mobile/common/scangobj-merge.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/python -# -*- Mode: Python -*- -# vi:si:et:sw=4:sts=4:ts=4 - -""" -parse, update and write .signals and .args files -""" - -from twisted.python import util - -import sys -import os - -def debug(*args): - pass - -class Object: - def __init__(self, name): - self._signals = util.OrderedDict() - self._args = util.OrderedDict() - self.name = name - - def __repr__(self): - return "" % self.name - - def add_signal(self, signal, overwrite=True): - if not overwrite and self._signals.has_key(signal.name): - raise IndexError, "signal %s already in %r" % (signal.name, self) - self._signals[signal.name] = signal - - def add_arg(self, arg, overwrite=True): - if not overwrite and self._args.has_key(arg.name): - raise IndexError, "arg %s already in %r" % (arg.name, self) - self._args[arg.name] = arg - -class Docable: - def __init__(self, **kwargs): - for key in self.attrs: - setattr(self, key, kwargs[key]) - self.dict = kwargs - - def __repr__(self): - return "<%r %s>" % (str(self.__class__), self.name) - -class Signal(Docable): - attrs = ['name', 'returns', 'args'] - -class Arg(Docable): - attrs = ['name', 'type', 'range', 'flags', 'nick', 'blurb', 'default'] - -class GDoc: - def load_file(self, filename): - try: - lines = open(filename).readlines() - self.load_data("".join(lines)) - except IOError: - print "WARNING - could not read from %s" % filename - - def save_file(self, filename, backup=False): - """ - Save the signals information to the given .signals file if the - file content changed. - """ - olddata = None - try: - lines = open(filename).readlines() - olddata = "".join(lines) - except IOError: - print "WARNING - could not read from %s" % filename - newdata = self.get_data() - if olddata and olddata == newdata: - return - - if olddata: - if backup: - os.rename(filename, filename + '.bak') - - handle = open(filename, "w") - handle.write(newdata) - handle.close() - -class Signals(GDoc): - def __init__(self): - self._objects = util.OrderedDict() - - def load_data(self, data): - """ - Load the .signals lines, creating our list of objects and signals. - """ - import re - smatcher = re.compile( - '(?s)' # make . match \n - '\n(.*?)\n' - ) - nmatcher = re.compile( - '' - '(?P\S*)' # store object - '::' - '(?P\S*)' # store signal - '' - ) - rmatcher = re.compile( - '(?s)' # make . match \n - '(?P\S*)\n' # store returns - '(?P.*)' # store args - ) - for block in smatcher.findall(data): - nmatch = nmatcher.search(block) - if nmatch: - o = nmatch.group('object') - debug("Found object", o) - debug("Found signal", nmatch.group('signal')) - if not self._objects.has_key(o): - object = Object(o) - self._objects[o] = object - - rmatch = rmatcher.search(block) - if rmatch: - dict = rmatch.groupdict().copy() - dict['name'] = nmatch.group('signal') - signal = Signal(**dict) - self._objects[o].add_signal(signal) - - def get_data(self): - lines = [] - for o in self._objects.values(): - for s in o._signals.values(): - block = """ -%(object)s::%(name)s -%(returns)s -%(args)s -""" - d = s.dict.copy() - d['object'] = o.name - lines.append(block % d) - - return "\n".join(lines) + '\n' - -class Args(GDoc): - def __init__(self): - self._objects = util.OrderedDict() - - def load_data(self, data): - """ - Load the .args lines, creating our list of objects and args. - """ - import re - amatcher = re.compile( - '(?s)' # make . match \n - '\n(.*?)\n' - ) - nmatcher = re.compile( - '' - '(?P\S*)' # store object - '::' - '(?P\S*)' # store arg - '' - ) - rmatcher = re.compile( - '(?s)' # make . match \n - '(?P\S*)\n' # store type - '(?P.*?)\n' # store range - '(?P\S*)\n' # store flags - '(?P.*?)\n' # store nick - '(?P.*?)\n' # store blurb - '(?P.*?)\n' # store default - ) - for block in amatcher.findall(data): - nmatch = nmatcher.search(block) - if nmatch: - o = nmatch.group('object') - debug("Found object", o) - debug("Found arg", nmatch.group('arg')) - if not self._objects.has_key(o): - object = Object(o) - self._objects[o] = object - - rmatch = rmatcher.search(block) - if rmatch: - dict = rmatch.groupdict().copy() - dict['name'] = nmatch.group('arg') - arg = Arg(**dict) - self._objects[o].add_arg(arg) - else: - print "ERROR: could not match arg from block %s" % block - - def get_data(self): - lines = [] - for o in self._objects.values(): - for a in o._args.values(): - block = """ -%(object)s::%(name)s -%(type)s -%(range)s -%(flags)s -%(nick)s -%(blurb)s -%(default)s - -""" - d = a.dict.copy() - d['object'] = o.name - lines.append(block % d) - - return "\n".join(lines) + '\n' - -def main(argv): - modulename = None - try: - modulename = argv[1] - except IndexError: - sys.stderr.write('Pleae provide a documentation module name\n') - sys.exit(1) - - print "Merging scangobj output for %s" % modulename - signals = Signals() - signals.load_file(modulename + '.signals') - signals.load_file(modulename + '.signals.new') - signals.save_file(modulename + '.signals', backup=True) - - args = Args() - args.load_file(modulename + '.args') - args.load_file(modulename + '.args.new') - args.save_file(modulename + '.args', backup=True) - -main(sys.argv) diff --git a/mobile/common/upload.mak b/mobile/common/upload.mak deleted file mode 100755 index 60731e5..0000000 --- a/mobile/common/upload.mak +++ /dev/null @@ -1,33 +0,0 @@ -# this snippet is to be included by both our docbook manuals -# and gtk-doc API references - -# it adds an upload target to each of these dir's Makefiles - -# each Makefile.am should define the following variables: -# - DOC: the base name of the documentation -# (faq, manual, pwg, gstreamer, gstreamer-libs) -# - FORMATS: the formats in which DOC is output -# (html ps pdf) - -# if you want to use it, make sure your $HOME/.ssh/config file contains the -# correct User entry for the Host entry for the DOC_SERVER - -# these variables define the location of the online docs -DOC_SERVER = gstreamer.freedesktop.org -DOC_BASE = /srv/gstreamer.freedesktop.org/www/data/doc -DOC_URL = $(DOC_SERVER):$(DOC_BASE) - -upload: $(FORMATS) - @if test "x$(PACKAGE_VERSION_NANO)" = x0; then \ - export DOCVERSION=$(VERSION); \ - else export DOCVERSION=head; \ - fi; \ - export DIR=$(DOC_BASE)/gstreamer/$$DOCVERSION/$(DOC); \ - ssh $(DOC_SERVER) mkdir -p $$DIR; \ - if echo $(FORMATS) | grep html > /dev/null; then export SRC="$$SRC html"; fi; \ - if echo $(FORMATS) | grep ps > /dev/null; then export SRC="$$SRC $(DOC).ps"; fi; \ - if echo $(FORMATS) | grep pdf > /dev/null; then export SRC="$$SRC $(DOC).pdf"; fi; \ - echo Uploading $$SRC to $(DOC_SERVER):$$DIR; \ - rsync -rv -e ssh --delete $$SRC $(DOC_SERVER):$$DIR; \ - ssh $(DOC_SERVER) chmod -R g+w $$DIR; \ - echo Done diff --git a/mobile/common/win32.mak b/mobile/common/win32.mak deleted file mode 100755 index 63b1310..0000000 --- a/mobile/common/win32.mak +++ /dev/null @@ -1,54 +0,0 @@ -# various tests to make sure we dist the win32 stuff (for MSVC builds) right - -# the MANIFEST contains all win32 related files that should be disted -win32 = $(shell cat $(top_srcdir)/win32/MANIFEST) - -# wildcard is apparently not portable to other makes, hence the use of find -# these are library .def files with the symbols to export -win32defs = $(shell find $(top_srcdir)/win32/common -name '*.def') - -# wildcard is apparently not portable to other makes, hence the use of find -# these are files that need to be disted with CRLF line endings: -win32crlf = $(shell find $(top_srcdir)/win32 -name '*.dsw' -o -name '*.dsp') - -win32-debug: - @echo; \ - echo win32 = $(win32); \ - echo; \ - echo win32defs = $(win32defs); \ - echo; \ - echo win32crlf = $(win32crlf); \ - echo - -win32-check-crlf: - @echo Checking win32 files for CR LF line endings ...; \ - fail=0 ; \ - for each in $(win32crlf) ; do \ - if ! (file $$each | grep CRLF >/dev/null) ; then \ - echo $$each must be fixed to have CRLF line endings ; \ - fail=1; \ - fi ; \ - done ; \ - exit $$fail - -# make sure all symbols we export on linux are defined in the win32 .def too -# (don't care about other unixes for now, it's enough if it works on one of -# the linux build bots; we assume .so ) -check-exports: - fail=0 ; \ - for l in $(win32defs); do \ - libbase=`basename "$$l" ".def"`; \ - libso=`find "$(top_builddir)" -name "$$libbase-@GST_MAJORMINOR@.so"`; \ - libdef="$(top_srcdir)/win32/common/$$libbase.def"; \ - if test "x$$libso" != "x"; then \ - echo Checking symbols in $$libso; \ - if ! ($(top_srcdir)/common/check-exports $$libdef $$libso) ; then \ - fail=1; \ - fi; \ - fi; \ - done - - -dist-hook: check-exports win32-check-crlf - - diff --git a/mobile/drmsrc/src/gstdrmsrc.c b/mobile/drmsrc/src/gstdrmsrc.c deleted file mode 100644 index 92916f2..0000000 --- a/mobile/drmsrc/src/gstdrmsrc.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * drmsrc - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "gstdrmsrc.h" - -#define LOG_TRACE(message) //g_print("DRM_SRC: %s: %d: %s - %s \n", __FILE__, __LINE__, __FUNCTION__, message); - -#define GST_TAG_PLAYREADY "playready_file_path" - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,GST_STATIC_CAPS_ANY); - - -GST_DEBUG_CATEGORY_STATIC (gst_drm_src_debug); -#define GST_CAT_DEFAULT gst_drm_src_debug - -enum -{ - ARG_0, - ARG_LOCATION, - ARG_FD -}; -static void gst_drm_src_finalize (GObject * object); -static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static gboolean gst_drm_src_start (GstBaseSrc * basesrc); -static gboolean gst_drm_src_stop (GstBaseSrc * basesrc); -static gboolean gst_drm_src_is_seekable (GstBaseSrc * src); -static gboolean gst_drm_src_get_size (GstBaseSrc * src, guint64 * size); -static GstFlowReturn gst_drm_src_create (GstBaseSrc * src, guint64 offset, guint length, GstBuffer ** buffer); -static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data); - -/** - * This function does the following: - * 1. Initializes GstDrmSrc ( defines gst_drm_get_type) - * - * @param drmsrc_type [out] GType - * - * @return void - */ -static void _do_init (GType drmsrc_type) -{ - // 1. Initializes GstDrmSrc ( defines gst_drm_get_type) - static const GInterfaceInfo urihandler_info = { - gst_drm_src_uri_handler_init, - NULL, - NULL - }; - - g_type_add_interface_static (drmsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info); - GST_DEBUG_CATEGORY_INIT (gst_drm_src_debug, "drmsrc", 0, "drmsrc element"); -} -GST_BOILERPLATE_FULL (GstDrmSrc, gst_drm_src, GstBaseSrc, GST_TYPE_BASE_SRC, _do_init); -/** - * This function does the following: - * 1. Sets the class details - * 2. Adds the source pad template - * - * @param g_class [out] gpointer - * - * @return void - */ -static void gst_drm_src_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - // 1. Sets the class details - gst_element_class_set_details_simple (gstelement_class, - "DRM Source", - "Source/File", - "Read from arbitrary point in a standard/DRM file", - "Kishore Arepalli and Sadanand Dodawadakar "); - // 2. Adds the source pad template - gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate)); -} -/** - * This function does the following: - * 1. Installs the properties - * 2. Assigns the function pointers GObject class attributes - * - * @param klass [out] GstDrmSrcClass Structure - * - * @return void - */ -static void gst_drm_src_class_init (GstDrmSrcClass * klass) -{ - GObjectClass *gobject_class; - GstBaseSrcClass *gstbasesrc_class; - gobject_class = G_OBJECT_CLASS (klass); - gstbasesrc_class = GST_BASE_SRC_CLASS (klass); - // Assigns the function pointers GObject class attributes - gobject_class->set_property = gst_drm_src_set_property; - gobject_class->get_property = gst_drm_src_get_property; - // 1. Installs the properties - g_object_class_install_property (gobject_class, ARG_FD, - g_param_spec_int ("fd", "File-descriptor", - "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0, - G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, ARG_LOCATION, - g_param_spec_string ("location", "File Location", - "Location of the file to read", NULL, G_PARAM_READWRITE)); - - // 2. Assigns the function pointers GObject class attributes - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_drm_src_finalize); - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_drm_src_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_drm_src_stop); - gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_drm_src_is_seekable); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_drm_src_get_size); - gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_drm_src_create); - - - gst_tag_register (GST_TAG_PLAYREADY, GST_TAG_FLAG_META, - G_TYPE_STRING, - "PlayReady File Path", - "a tag that is specific to PlayReady File", - NULL); -} -/** - * This function does the following: - * 1. Initilizes the parameters of GstDrmSrc - * - * @param src [out] GstDrmSrc structure - * @param g_class [in] GstDrmSrcClass structure - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static void gst_drm_src_init (GstDrmSrc * src, GstDrmSrcClass * g_class) -{ - // 1. Initilizes the parameters of GstDrmSrc - src->filename = NULL; - src->fd = 0; - src->uri = NULL; - src->is_regular = FALSE; - src->seekable = FALSE; - PROFILE_INIT; -} -/** - * This function does the following: - * 1. deallocates the filename and uri - * 2. calls the parent class->finalize - * - * @param object [in] GObject Structure - * - * @return void - */ -static void gst_drm_src_finalize (GObject * object) -{ - GstDrmSrc *src; - - src = GST_DRM_SRC (object); - // 1. deallocates the filename and uri - g_free (src->filename); - g_free (src->uri); - // 2. calls the parent class->finalize - G_OBJECT_CLASS (parent_class)->finalize (object); -} -/** - * This function does the following: - * 1. Checks the state - * 2. Checks the filename - * 3. Sets the filename - * - * @param src [in] GstDrmSrc Structure - * @param location [in] location of the file - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static gboolean gst_drm_src_set_location (GstDrmSrc * src, const gchar * location) -{ - GstState state; - - GST_OBJECT_LOCK (src); - // 1. Checks the state - state = GST_STATE (src); - if (state != GST_STATE_READY && state != GST_STATE_NULL) - { - GST_DEBUG_OBJECT (src, "setting location in wrong state"); - GST_OBJECT_UNLOCK (src); - return FALSE; - } - GST_OBJECT_UNLOCK (src); - g_free (src->filename); - g_free (src->uri); - // 2. Checks the filename - if (location == NULL) - { - src->filename = NULL; - src->uri = NULL; - } - else - { - // 3. Sets the filename - src->filename = g_strdup (location); - src->uri = gst_uri_construct ("file", src->filename); - } - g_object_notify (G_OBJECT (src), "location"); - gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri); - return TRUE; -} -/** - * This function does the following: - * 1. Sets the location of the file. - * - * @param object [in] GObject Structure - * @param prop_id [in] id of the property - * @param value [in] property value - * @param pspec [in] GParamSpec Structure - * - * @return void - */ -static void gst_drm_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstDrmSrc *src; - - g_return_if_fail (GST_IS_DRM_SRC (object)); - src = GST_DRM_SRC (object); - switch (prop_id) - { - // 1. Sets the location of the file. - case ARG_LOCATION: - gst_drm_src_set_location (src, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} -/** - * This function does the following: - * 1. Provides the location of the file. - * 2. Provides the file descriptor. - * - * @param object [in] GObject Structure - * @param prop_id [in] id of the property - * @param value [out] property value - * @param pspec [in] GParamSpec Structure - * - * @return void - */ -static void gst_drm_src_get_property (GObject * object, guint prop_id, GValue * value,GParamSpec * pspec) -{ - GstDrmSrc *src; - - g_return_if_fail (GST_IS_DRM_SRC (object)); - src = GST_DRM_SRC (object); - switch (prop_id) - { - // 1. Provides the location of the file. - case ARG_LOCATION: - g_value_set_string (value, src->filename); - break; - // 2. Provides the file descriptor. - case ARG_FD: - g_value_set_int (value, src->fd); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * This function does the following: - * 1. Seeks to the specified position. - * 2. Allocates a buffer to push the data - * 3. Reads from the file and sets the related params - * - * @param src [in] GstDrmSrc Structure - * @param offset [in] offset of the file to seek - * @param length [in] size of the data in bytes - * @param buffer [out] GstBuffer to hold the contents - * - * @return GstFlowReturn Returns GST_FLOW_OK on success and ERROR on failure - */ -static GstFlowReturn gst_drm_src_create_read (GstDrmSrc * src, guint64 offset, guint length, GstBuffer ** buffer) -{ - int ret; - GstBuffer *buf; - // 1. Seeks to the specified position. - if (G_UNLIKELY (src->read_position != offset)) - { - off_t res; - res = lseek (src->fd, offset, SEEK_SET); - if (G_UNLIKELY (res < 0 || res != offset)) - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - return GST_FLOW_ERROR; - } - src->read_position = offset; - } - // 2. Allocates a buffer to push the data - buf = gst_buffer_new_and_alloc (length); - GST_LOG_OBJECT (src, "Reading %d bytes", length); - // 3. Reads from the file and sets the related params - ret = read (src->fd, GST_BUFFER_DATA (buf), length); - if (G_UNLIKELY (ret < 0)) - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } - if (G_UNLIKELY ((guint) ret < length && src->seekable)) - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),("unexpected end of file.")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } - if (G_UNLIKELY (ret == 0 && length > 0)) - { - GST_DEBUG ("non-regular file hits EOS"); - gst_buffer_unref (buf); - return GST_FLOW_UNEXPECTED; - } - length = ret; - GST_BUFFER_SIZE (buf) = length; - GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_OFFSET_END (buf) = offset + length; - *buffer = buf; - src->read_position += length; - return GST_FLOW_OK; -} -/** - * This function does the following: - * 1. Calls DRM file read chain method for drm files. - * 2. Calls normal file read chain method for standard files. - * - * @param basesrc [in] BaseSrc Structure - * @param size [out] Size of the file - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static GstFlowReturn gst_drm_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) -{ - GstDrmSrc *src = GST_DRM_SRC (basesrc); - - // 1. Calls DRM file read chain method for drm files. - - // 2. Calls normal file read chain method for standard files. - return gst_drm_src_create_read (src, offset, length, buffer); -} -/** - * - * @param basesrc [in] BaseSrc Structure - * - * @return gboolean Returns TRUE if the file is seekable and FALSE if the file is not seekable - */ -static gboolean gst_drm_src_is_seekable (GstBaseSrc * basesrc) -{ - GstDrmSrc *src = GST_DRM_SRC (basesrc); - return src->seekable; -} -/** - * This function does the following: - * 1. Gets the filesize for drm file by using seek oprations - * 2. Gets the file size for standard file by using statistics - * - * @param basesrc [in] BaseSrc Structure - * @param size [in] Size of the file - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static gboolean gst_drm_src_get_size (GstBaseSrc * basesrc, guint64 * size) -{ - struct stat stat_results; - GstDrmSrc *src = GST_DRM_SRC (basesrc); - unsigned int offset; - - // 1. Gets the filesize for drm file by using seek oprations - - // 2. Gets the file size for standard file by using statistics - if (fstat (src->fd, &stat_results) < 0) - return FALSE; - *size = stat_results.st_size; - return TRUE; -} -/** - * This function does the following: - * 1. Checks the filename - * 2. Opens the file and check statistics of the file - * 7. Checks the seeking for standard files - * - * @param basesrc [in] BaseSrc Structure - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static gboolean gst_drm_src_start (GstBaseSrc * basesrc) -{ - GstDrmSrc *src = GST_DRM_SRC (basesrc); - struct stat stat_results; - off_t ret; -PROFILE_FUNC_BEGIN; - // 1. Checks the filename - if (src->filename == NULL || src->filename[0] == '\0') - { - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,("No file name specified for reading."), (NULL)); - return FALSE; - } - // 2. Opens the file and check statistics of the file - GST_INFO_OBJECT (src, "opening file %s", src->filename); - src->fd = open (src->filename, O_RDONLY | O_BINARY); - if (src->fd < 0) - { - if(errno == ENOENT) - { - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),("No such file \"%s\"", src->filename)); - return FALSE; - } - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not open file \"%s\" for reading.", src->filename), GST_ERROR_SYSTEM); - return FALSE; - } - if (fstat (src->fd, &stat_results) < 0) - { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"%s\".", src->filename), (NULL)); - close (src->fd); - return FALSE; - } - if (S_ISDIR (stat_results.st_mode)) - { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("\"%s\" is a directory.", src->filename), (NULL)); - close (src->fd); - return FALSE; - } - if (S_ISSOCK (stat_results.st_mode)) - { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"%s\" is a socket.", src->filename), (NULL)); - close (src->fd); - return FALSE; - } - src->read_position = 0; - - // 7. Checks the seeking for standard files - if (S_ISREG (stat_results.st_mode)) - src->is_regular = TRUE; - ret = lseek (src->fd, 0, SEEK_END); - if (ret < 0) - { - GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek " - "failed: %s", g_strerror (errno)); - src->seekable = FALSE; - } - else - { - src->seekable = TRUE; - } - lseek (src->fd, 0, SEEK_SET); - src->seekable = src->seekable && src->is_regular; - PROFILE_FUNC_END; - return TRUE; -} -/** - * This function does the following: - * 1. Closes the file desciptor and resets the flags - * - * @param basesrc [in] BaseSrc Structure - * - * @return gboolean Returns TRUE on success and FALSE on ERROR - */ -static gboolean gst_drm_src_stop (GstBaseSrc * basesrc) -{ - GstDrmSrc *src = GST_DRM_SRC (basesrc); - - // 1. Closes the file desciptor and resets the flags - if(src->fd > 0) - close (src->fd); - src->fd = 0; - src->is_regular = FALSE; -// PROFILE_SHOW_RESULT; - return TRUE; -} -/** - * - * @param void - * - * @return GstURIType Returns GST_URI_SRC - */ - -static GstURIType gst_drm_src_uri_get_type (void) -{ - return GST_URI_SRC; -} - -/** - * This function does the following: - * 1. Defines the list of protocols - * - * @param void - * - * @return gchar ** Returns the protocol list - */ - -static gchar ** gst_drm_src_uri_get_protocols (void) -{ - static gchar *protocols[] = { "file", NULL }; - return protocols; -} -/** - * - * @param handler [in] GstURIHandler structure - * - * @return gchar* Returns the uri - */ -static const gchar * gst_drm_src_uri_get_uri (GstURIHandler *handler) -{ - GstDrmSrc *src = GST_DRM_SRC (handler); - return src->uri; -} -/** - * This function does the following: - * 1. Checks the protocol - * 2. Checks the whether it is absolute or not - * 3 sets the location - * - * @param handler [in] GstURIHandler structure - * @param uri [in] uri string - * - * @return gboolean Returns TRUE on success and FALSE on Error - */ -static gboolean gst_drm_src_uri_set_uri (GstURIHandler *handler, const gchar * uri) -{ - gchar *protocol, *location; - gboolean ret; - GstDrmSrc *src = GST_DRM_SRC (handler); - // 1. Checks the protocol - protocol = gst_uri_get_protocol (uri); - if (strcmp (protocol, "file") != 0) - { - g_free (protocol); - return FALSE; - } - g_free (protocol); - if (g_str_has_prefix (uri, "file://localhost/")) - { - char *tmp; - tmp = g_strconcat ("file://", uri + 16, NULL); - location = gst_uri_get_location (tmp); - g_free (tmp); - } - else if (strcmp (uri, "file://") == 0) - { - gst_drm_src_set_location (src, NULL); - return TRUE; - } - else - { - location = gst_uri_get_location (uri); - } - if (!location) - return FALSE; - // 2. Checks the whether it is absolute or not - if (!g_path_is_absolute (location)) - { - g_free (location); - return FALSE; - } - // 3 sets the location - ret = gst_drm_src_set_location (src, location); - g_free (location); - return ret; -} -/** - * This function does the following: - * 1. Assignes the function pointer for URI related stuff - * - * @param g_iface [in] an interface to URI handler - * @param iface_data [in] a gpointer - * - * @return void - */ -static void gst_drm_src_uri_handler_init (gpointer g_iface, gpointer iface_data) -{ - GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; - // 1. Assigning the function pointer for URI related stuff - iface->get_type = gst_drm_src_uri_get_type; - iface->get_protocols = gst_drm_src_uri_get_protocols; - iface->get_uri = gst_drm_src_uri_get_uri; - iface->set_uri = gst_drm_src_uri_set_uri; -} -/** - * This function does the following: - * 1. Registers an element as drmsrc - * - * @param i_pPlugin [in] a plug-in structure - * - * @return gboolean TRUE on SUCCESS and FALSE on Error - */ -static gboolean plugin_init(GstPlugin* i_pPlugin) -{ - return gst_element_register(i_pPlugin, "drmsrc", GST_RANK_NONE, GST_TYPE_DRM_SRC);; -} -/** - * This function does the following: - * 1. plugin defination - * - */ -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "drmsrc", - "Plugin to read data from standad/DRM File", - plugin_init, - VERSION, - "LGPL", - "Samsung Electronics Co", - "http://www.samsung.com/") - diff --git a/mobile/encodebin/src/Makefile.am b/mobile/encodebin/src/Makefile.am deleted file mode 100644 index c855890..0000000 --- a/mobile/encodebin/src/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -glib_enum_define=GST_RECORD -glib_enum_prefix=gst_record - -plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ - -plugin_LTLIBRARIES = libgstencodebin.la -libgstencodebin_la_SOURCES = gstencodebin.c -nodist_libgstencodebin_la_SOURCES = $(built_sources) -libgstencodebin_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) -libgstencodebin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstencodebin_la_LIBADD = \ - $(GST_LIBS)\ - $(GST_BASE_LIBS) \ - $(GST_LIBS) -if ISPROTECTOR_TARGET -libgstencodebin_la_CFLAGS += -DUSE_ENCODER_QUEUE_SET -libgstencodebin_la_CFLAGS += -DVIDEO_ENC_QUE_TIME=4 -DAUDIO_ENC_QUE_TIME=4 -endif - -if ISVOLANS_TARGET -libgstencodebin_la_CFLAGS += -DUSE_ENCODER_QUEUE_SET -libgstencodebin_la_CFLAGS += -DVIDEO_ENC_QUE_TIME=4 -DAUDIO_ENC_QUE_TIME=4 -endif - -BUILT_SOURCES = $(built_headers) $(built_sources) - -CLEANFILES = $(BUILT_SOURCES) - -include $(top_srcdir)/common/glib-gen.mak - diff --git a/mobile/encodebin/src/gstencodebin.c b/mobile/encodebin/src/gstencodebin.c deleted file mode 100644 index 5ee9617..0000000 --- a/mobile/encodebin/src/gstencodebin.c +++ /dev/null @@ -1,3352 +0,0 @@ -/* - * GStreamer encodebin - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "gstencodebin.h" - -#ifdef GST_EXT_PAD_LINK_UNCHECKED -#define _GST_ELEMENT_LINK_MANY gst_element_link_many_unchecked -#define _GST_ELEMENT_LINK gst_element_link_unchecked -#define _GST_PAD_LINK gst_pad_link_unchecked -#else -#define _GST_ELEMENT_LINK_MANY gst_element_link_many -#define _GST_ELEMENT_LINK gst_element_link -#define _GST_PAD_LINK gst_pad_link -#endif - -#ifndef VIDEO_ENC_QUE_TIME -#define VIDEO_ENC_QUE_TIME 1 -#endif -#ifndef AUDIO_ENC_QUE_TIME -#define AUDIO_ENC_QUE_TIME 1 -#endif - -//define USE_ENCODER_QUEUE_SET -#ifdef USE_ENCODER_QUEUE_SET -#define ENCODER_QUEUE_SET(x_queue, x_byte, x_buffer, x_time /*sec*/) \ -{\ -g_object_set(G_OBJECT(x_queue), \ - "max-size-bytes", (guint)x_byte, \ - "max-size-buffers", (guint)x_buffer, \ - "max-size-time", (guint64)(x_time*GST_SECOND), \ - NULL); \ - GST_INFO("Set to [%s], max [%d] byte, max [%d] buffer, max [%d] time(sec) ", GST_OBJECT_NAME(x_queue), x_byte, x_buffer, x_time);\ -} -#else -#define ENCODER_QUEUE_SET(x_queue, x_byte, x_buffer, x_time) -#endif - -#define _GST_PAD_LINK_UNREF( srcpad, sinkpad, if_fail_goto )\ -{\ - GstPadLinkReturn ret = _GST_PAD_LINK( srcpad, sinkpad );\ - gst_object_unref( srcpad ); srcpad = NULL;\ - gst_object_unref( sinkpad ); sinkpad = NULL;\ - if( ret != GST_PAD_LINK_OK) goto if_fail_goto;\ -} - -#define _GST_PAD_UNLINK_UNREF( srcpad, sinkpad)\ -{\ - gst_pad_unlink( srcpad, sinkpad );\ - gst_object_unref( srcpad ); srcpad = NULL;\ - gst_object_unref( sinkpad ); sinkpad = NULL;\ -} - -#define DEFAULT_PROP_PROFILE 0 -#define DEFAULT_PROP_HIGH_SPEED 0 -#define DEFAULT_PROP_VENC_NAME "ffenc_h263" -#define DEFAULT_PROP_AENC_NAME "secenc_amr" -#define DEFAULT_PROP_IENC_NAME "jpegenc" -#define DEFAULT_PROP_MUX_NAME "ffmux_3gp" -#define DEFAULT_PROP_VCONV_NAME "ffmpegcolorspace" - -/* props */ -enum -{ - PROP_0, - // encodebin mode : a/v, audio only, stillshot - PROP_PROFILE, - //support slow motion capture - PROP_HIGH_SPEED, - //elements name - PROP_VENC_NAME, - PROP_AENC_NAME, - PROP_IENC_NAME, - PROP_MUX_NAME, - PROP_VCONV_NAME, - //caps - PROP_VCAPS, - PROP_ACAPS, - PROP_ICAPS, - //functions - PROP_AUTO_AUDIO_CONVERT, - PROP_AUTO_AUDIO_RESAMPLE, - PROP_AUTO_COLORSPACE, - PROP_BLOCK, - PROP_PAUSE, - PROP_VENC_QUEUE, - PROP_AENC_QUEUE, - //elements pointer - PROP_VIDEO_ENC, - PROP_AUDIO_ENC, - PROP_IMAGE_ENC, - PROP_MUX, - PROP_VIDEO_CONV, - //options - PROP_USE_VIDEO_TOGGLE, -}; - -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE -/* signals */ -enum -{ - SIGNAL_STREAM_BLOCK, - SIGNAL_STREAM_UNBLOCK, - SIGNAL_STREAM_PAUSE, - SIGNAL_STREAM_RESUME, - LAST_SIGNAL -}; -#endif - -typedef enum { - ENCODEBIN_ELEMENT_VENC, - ENCODEBIN_ELEMENT_AENC, - ENCODEBIN_ELEMENT_IENC, - ENCODEBIN_ELEMENT_MUX, - ENCODEBIN_ELEMENT_VIDEO_CONV -}GstEncodeBinElement; - -typedef enum { - ENCODEBIN_MUX_AUDIO_SINK, - ENCODEBIN_MUX_VIDEO_SINK, -}GstEncodeBinMuxSinkPad; - - -/* FIX ME */ - -#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) -# define ENDIANNESS "LITTLE_ENDIAN, BIG_ENDIAN" -#else -# define ENDIANNESS "BIG_ENDIAN, LITTLE_ENDIAN" -#endif - -/* generic templates */ -#define STATIC_AUDIO_CAPS \ -GST_STATIC_CAPS ( \ - "audio/x-raw-float, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 64;" \ - "audio/x-raw-float, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 32;" \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 32, " \ - "depth = (int) [ 1, 32 ], " \ - "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 24, " \ - "depth = (int) [ 1, 24 ], " "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 16, " \ - "depth = (int) [ 1, 16 ], " \ - "signed = (boolean) { true, false }; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 8 ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 8, " \ - "depth = (int) [ 1, 8 ], " \ - "signed = (boolean) { true, false } " \ -) - -#define STATIC_VIDEO_CAPS \ -GST_STATIC_CAPS ( \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) I420;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) YV12;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) YUY2;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 24," \ - "depth = (int) 24," \ - "red_mask = (int) 16711680," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 255," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 24," \ - "depth = (int) 24," \ - "red_mask = (int) 255," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 16711680," \ - "endianness = (int) 4321;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) Y42B;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) Y444;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 32," \ - "red_mask = (int) 65280," \ - "green_mask = (int) 16711680," \ - "blue_mask = (int) -16777216," \ - "alpha_mask = (int) 255," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 32," \ - "red_mask = (int) 16711680," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 255," \ - "alpha_mask = (int) -16777216," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 32," \ - "red_mask = (int) 255," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 16711680," \ - "alpha_mask = (int) -16777216," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 32," \ - "red_mask = (int) -16777216," \ - "green_mask = (int) 16711680," \ - "blue_mask = (int) 65280," \ - "alpha_mask = (int) 255," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 24," \ - "red_mask = (int) 65280," \ - "green_mask = (int) 16711680," \ - "blue_mask = (int) -16777216," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 24," \ - "red_mask = (int) 255," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 16711680," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 24," \ - "red_mask = (int) 16711680," \ - "green_mask = (int) 65280," \ - "blue_mask = (int) 255," \ - "endianness = (int) 4321;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 32," \ - "depth = (int) 24," \ - "red_mask = (int) -16777216," \ - "green_mask = (int) 16711680," \ - "blue_mask = (int) 65280," \ - "endianness = (int) 4321;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) YUV9;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) YVU9;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) Y41B;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 16," \ - "depth = (int) 16," \ - "red_mask = (int) 63488," \ - "green_mask = (int) 2016," \ - "blue_mask = (int) 31," \ - "endianness = (int) 1234;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 16," \ - "depth = (int) 15," \ - "red_mask = (int) 31744," \ - "green_mask = (int) 992," \ - "blue_mask = (int) 31," \ - "endianness = (int) 1234;" \ - "video/x-raw-gray," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 8," \ - "depth = (int) 8;" \ - "video/x-raw-rgb," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "bpp = (int) 8," \ - "depth = (int) 8," \ - "endianness = (int) 1234;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) UYVY;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) IYU1;" \ - "video/x-raw-yuv," \ - "width = (int) [ 1, 2147483647 ]," \ - "height = (int) [ 1, 2147483647 ]," \ - "framerate = (fraction) [ 0/1, 2147483647/1 ]," \ - "format = (fourcc) AYUV " \ -) - - -static GstStaticPadTemplate encoder_bin_src_template = -GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate encoder_bin_video_sink_template = -GST_STATIC_PAD_TEMPLATE ("video", - GST_PAD_SINK, - GST_PAD_REQUEST, - STATIC_VIDEO_CAPS - ); - -static GstStaticPadTemplate encoder_bin_audio_sink_template = -GST_STATIC_PAD_TEMPLATE ("audio", - GST_PAD_SINK, - GST_PAD_REQUEST, - STATIC_AUDIO_CAPS - ); - -static GstStaticPadTemplate encoder_bin_image_sink_template = -GST_STATIC_PAD_TEMPLATE ("image", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) - ); - -GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug); -#define GST_CAT_DEFAULT gst_encode_bin_debug - -static void gst_encode_bin_class_init (GstEncodeBinClass *klass); -static void gst_encode_bin_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_encode_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_encode_bin_init (GstEncodeBin * encodebin); -static void gst_encode_bin_dispose (GObject * object); -static void gst_encode_bin_finalize (GObject * object); -static GstPad *gst_encode_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name); - -static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element, GstStateChange transition); -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad); -static gint pad_compare_name (GstPad * pad1, const gchar * name); -static gboolean gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name); -#if 0 //disable unused function -static gboolean gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean profile); -static void gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement); -static gboolean gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name); -static gboolean gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element); -#endif //disable unused function -static gboolean gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element); -static gboolean gst_encode_bin_link_elements (GstEncodeBin *encodebin); -static gboolean gst_encode_bin_unlink_elements (GstEncodeBin *encodebin); -static gboolean gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data); -static gboolean gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data); -static gboolean gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data); -static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value); -static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value); -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static gboolean gst_encode_bin_release_pipeline (GstElement *element, gpointer user_data); -static gboolean gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps); -static gboolean gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps); -static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps); -static GstPad* gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type); - -//Data probe -static gboolean gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin); -static gboolean gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin); -static gboolean gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin); - -static GstElementClass *parent_class; - -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE -static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 }; -#endif - -static const GstElementDetails gst_encode_bin_details = -GST_ELEMENT_DETAILS ("Samsung Electronics Co. Encoder Bin", - "Generic/Bin/Encoder", - "Autoplug and encode to muxed media", - "Jeonghoon Park , Wonhyung Cho , Sangho Park "); - -typedef enum { - GST_ENCODE_BIN_PROFILE_AV, - GST_ENCODE_BIN_PROFILE_AUDIO, - GST_ENCODE_BIN_PROFILE_IMAGE, -} GstEncodeBinProfile; - -GType -gst_encode_bin_profile_get_type (void) -{ - static GType encode_bin_profile_type = 0; - static const GEnumValue profile_types[] = { - {GST_ENCODE_BIN_PROFILE_AV, "Audio and Video Recording", "A/V"}, - {GST_ENCODE_BIN_PROFILE_AUDIO, "Audio Only Recording", "Audio"}, - {GST_ENCODE_BIN_PROFILE_IMAGE, "Image Stillshot", "Image"}, - {0, NULL, NULL} - }; - - if (!encode_bin_profile_type) { - encode_bin_profile_type = - g_enum_register_static ("GstEncodeBinProfile",profile_types); - } - return encode_bin_profile_type; -} - -GType -gst_encode_bin_get_type (void) -{ - static GType gst_encode_bin_type = 0; - - if (!gst_encode_bin_type) { - static const GTypeInfo gst_encode_bin_info = { - sizeof (GstEncodeBinClass), - NULL, - NULL, - (GClassInitFunc) gst_encode_bin_class_init, - NULL, - NULL, - sizeof (GstEncodeBin), - 0, - (GInstanceInitFunc) gst_encode_bin_init, - NULL - }; - - gst_encode_bin_type = - g_type_register_static (GST_TYPE_BIN, "GstEncodeBin", - &gst_encode_bin_info, 0); - } - - return gst_encode_bin_type; -} - -static void -queue_overun_cb (GstElement * queue, GstEncodeBin *encodebin) -{ -#if 0 - guint queue_size = 0; - guint queue_bufnum = 0; -// guint64 queue_time= (guint64)0; - - GstClockTime now = gst_util_get_timestamp (); - - g_object_get(G_OBJECT(queue), "current-level-bytes", &queue_size, - "current-level-buffers", &queue_bufnum, - // "current-level-time", &queue_time, - NULL); - GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY, - ("[%" GST_TIME_FORMAT "][%s], [%u b], [%u]", - GST_TIME_ARGS(now), GST_OBJECT_NAME(queue), queue_size, queue_bufnum), (NULL)); -#else - GST_ELEMENT_WARNING (encodebin, STREAM, TOO_LAZY, - ("%s overrun", GST_OBJECT_NAME(queue)), (NULL)); -#endif -} - -static void -gst_encode_bin_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstEncodeBin *encodebin; - - encodebin = GST_ENCODE_BIN (object); - - switch (prop_id) { - case PROP_PROFILE: - g_value_set_enum (value, encodebin->profile); - break; - case PROP_HIGH_SPEED: - g_value_set_int (value, encodebin->high_speed_fps); - break; - //elements name - case PROP_VENC_NAME: - g_value_set_string (value, encodebin->venc_name); - break; - case PROP_AENC_NAME: - g_value_set_string (value, encodebin->aenc_name); - break; - case PROP_IENC_NAME: - g_value_set_string (value, encodebin->ienc_name); - break; - case PROP_MUX_NAME: - g_value_set_string (value, encodebin->mux_name); - break; - case PROP_VCONV_NAME: - g_value_set_string (value, encodebin->vconv_name); - break; - //caps - case PROP_VCAPS: - gst_value_set_caps (value, encodebin->vcaps); - break; - case PROP_ACAPS: - gst_value_set_caps (value, encodebin->acaps); - break; - case PROP_ICAPS: - gst_value_set_caps (value, encodebin->icaps); - break; - //functions - case PROP_AUTO_AUDIO_CONVERT: - g_value_set_boolean (value, encodebin->auto_audio_convert); - break; - case PROP_AUTO_AUDIO_RESAMPLE: - g_value_set_boolean (value, encodebin->auto_audio_resample); - break; - case PROP_AUTO_COLORSPACE: - g_value_set_boolean (value, encodebin->auto_color_space); - break; - case PROP_BLOCK: - g_value_set_boolean (value, encodebin->block); - break; - case PROP_PAUSE: - g_value_set_boolean (value, encodebin->pause); - break; - case PROP_VENC_QUEUE: -// g_value_set_boolean (value, encodebin->use_venc_queue); - if((encodebin->video_encode_queue == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) { - encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue"); - if(encodebin->video_encode_queue != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue); - } - g_value_set_object (value, encodebin->video_encode_queue); - break; - case PROP_AENC_QUEUE: -// g_value_set_boolean (value, encodebin->use_aenc_queue); - if((encodebin->audio_encode_queue == NULL) && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) { - encodebin->audio_encode_queue = gst_element_factory_make ("queue", "audio_encode_queue"); - if(encodebin->audio_encode_queue != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue); - } - g_value_set_object (value, encodebin->audio_encode_queue); - break; - //elements pointer - case PROP_VIDEO_ENC: - if((encodebin->video_encode == NULL) && (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV)) { - encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode"); - if(encodebin->video_encode != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - } - g_value_set_object (value, encodebin->video_encode); - break; - case PROP_AUDIO_ENC: - if(encodebin->audio_encode == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) { - encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode"); - if(encodebin->audio_encode != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode); - } - g_value_set_object (value, encodebin->audio_encode); - break; - case PROP_IMAGE_ENC: - if(encodebin->image_encode == NULL && (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE)) { - encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode"); - if(encodebin->image_encode != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->image_encode); - } - g_value_set_object (value, encodebin->image_encode); - break; - case PROP_MUX: - if(encodebin->mux == NULL && (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO)) { - encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux"); - if(encodebin->mux != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->mux); - } - g_value_set_object (value, encodebin->mux); - break; - case PROP_VIDEO_CONV: - if(encodebin->color_space == NULL && (encodebin->profile != GST_ENCODE_BIN_PROFILE_AUDIO)) { - encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert"); - if(encodebin->color_space != NULL) - gst_bin_add(GST_BIN(encodebin), encodebin->color_space); - } - g_value_set_object (value, encodebin->color_space); - break; - case PROP_USE_VIDEO_TOGGLE: - g_value_set_boolean( value, encodebin->use_video_toggle ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_encode_bin_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstEncodeBin *encodebin; - - encodebin = GST_ENCODE_BIN (object); - - switch (prop_id) { - case PROP_PROFILE: - encodebin->profile = g_value_get_enum (value); - /* - gboolean newprofile = g_value_get_enum (value); - if(encodebin->profile != newprofile) { - gst_encode_bin_change_profile(encodebin, newprofile); - encodebin->profile = newprofile; - } - */ - break; - case PROP_HIGH_SPEED: - encodebin->high_speed_fps = g_value_get_int (value); - break; - case PROP_VENC_NAME: { - const gchar *new_name; - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - new_name = g_value_get_string (value); - - if(encodebin->video_encode == NULL) { - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name)) - encodebin->venc_name = g_strdup (new_name); - } else { - if(strcmp (encodebin->venc_name, new_name)) { - gst_encode_bin_remove_element(encodebin, encodebin->video_encode); - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VENC, new_name)) - encodebin->venc_name = g_strdup (new_name); - } - } - break; - } - case PROP_AENC_NAME: { - const gchar *new_name; - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - new_name = g_value_get_string (value); - - if(encodebin->audio_encode == NULL) { - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name)) - encodebin->aenc_name = g_strdup (new_name); - } else { - if(strcmp (encodebin->aenc_name, new_name)) { - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode); - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_AENC, new_name)) - encodebin->aenc_name = g_strdup (new_name); - } - } - break; - } - case PROP_IENC_NAME: { - const gchar *new_name; - if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - new_name = g_value_get_string (value); - - if(encodebin->image_encode == NULL) { - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name)) - encodebin->ienc_name = g_strdup (new_name); - } else { - if(strcmp (encodebin->ienc_name, new_name)) { - gst_encode_bin_remove_element(encodebin, encodebin->image_encode); - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_IENC, new_name)) - encodebin->ienc_name = g_strdup (new_name); - } - } - break; - } - case PROP_MUX_NAME: { - const gchar *new_name; - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match"); - break; - } - new_name = g_value_get_string (value); - - if(encodebin->mux == NULL) { - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name)) - encodebin->mux_name = g_strdup (new_name); - } else { - if(strcmp (encodebin->mux_name, new_name)) { - gst_encode_bin_remove_element(encodebin, encodebin->mux); - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_MUX, new_name)) - encodebin->mux_name = g_strdup (new_name); - } - } - break; - } - case PROP_VCONV_NAME: { - const gchar *new_name; - if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match"); - break; - } - new_name = g_value_get_string(value); - - if (encodebin->color_space == NULL) { - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name)) - encodebin->vconv_name = g_strdup (new_name); - } else { - if(strcmp (encodebin->vconv_name, new_name)) { - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - if(gst_encode_bin_add_element_by_name(encodebin, ENCODEBIN_ELEMENT_VIDEO_CONV, new_name)) - encodebin->vconv_name = g_strdup (new_name); - } - } - break; - } - //caps - case PROP_VCAPS: { - GstCaps *new_caps; - GstCaps *old_caps; - const GstCaps *new_caps_val = gst_value_get_caps (value); - - if (new_caps_val == NULL) { - new_caps = gst_caps_new_any (); - } else { - new_caps = (GstCaps *) new_caps_val; - gst_caps_ref (new_caps); - } - - old_caps = encodebin->vcaps; - encodebin->vcaps = new_caps; - gst_caps_unref (old_caps); - break; - } - case PROP_ACAPS: { - GstCaps *new_caps; - GstCaps *old_caps; - const GstCaps *new_caps_val = gst_value_get_caps (value); - - if (new_caps_val == NULL) { - new_caps = gst_caps_new_any (); - } else { - new_caps = (GstCaps *) new_caps_val; - gst_caps_ref (new_caps); - } - - old_caps = encodebin->acaps; - encodebin->acaps = new_caps; - gst_caps_unref (old_caps); - break; - } - case PROP_ICAPS: { - GstCaps *new_caps; - GstCaps *old_caps; - const GstCaps *new_caps_val = gst_value_get_caps (value); - - if (new_caps_val == NULL) { - new_caps = gst_caps_new_any (); - } else { - new_caps = (GstCaps *) new_caps_val; - gst_caps_ref (new_caps); - } - - old_caps = encodebin->icaps; - encodebin->icaps = new_caps; - gst_caps_unref (old_caps); - break; - } - //functions - case PROP_AUTO_AUDIO_CONVERT: - encodebin->auto_audio_convert = g_value_get_boolean (value); - break; - case PROP_AUTO_AUDIO_RESAMPLE: - encodebin->auto_audio_resample = g_value_get_boolean (value); - break; - case PROP_AUTO_COLORSPACE: - encodebin->auto_color_space = g_value_get_boolean (value); - break; - case PROP_BLOCK: { - gboolean newval = g_value_get_boolean (value); - if(encodebin->block != newval) { - if(!gst_encode_bin_block(encodebin, newval)) { -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - if(newval) { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, FALSE); - } else { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, FALSE); - } -#endif - break; - } - } -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - if(newval) { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_BLOCK], 0, TRUE); - } else { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK], 0, TRUE); - } -#endif - break; - } - case PROP_PAUSE: { - gboolean newval = g_value_get_boolean (value); - if(encodebin->pause != newval) { - if(!gst_encode_bin_pause(encodebin, newval)) - break; - } -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - if(newval) { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE); - } else { - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE); - } -#endif - break; - } - case PROP_VENC_QUEUE: -// encodebin->use_venc_queue = g_value_get_boolean (value); - { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue); - encodebin->video_encode_queue = newelement; - gst_object_ref (encodebin->video_encode_queue); - gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode_queue)); // take ownership ?? - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode_queue); - } - break; - } - break; - case PROP_AENC_QUEUE: -// encodebin->use_aenc_queue = g_value_get_boolean (value); - { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue); - encodebin->audio_encode_queue = newelement; - gst_object_ref (encodebin->audio_encode_queue); - gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode_queue)); - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode_queue); - } - break; - } - break; - case PROP_VIDEO_ENC: - { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AV) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->video_encode); - encodebin->video_encode = newelement; - gst_object_ref (encodebin->video_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ?? - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - } - break; - } - case PROP_AUDIO_ENC: - { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode); - encodebin->audio_encode = newelement; - gst_object_ref (encodebin->audio_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode)); - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode); - } - break; - } - case PROP_IMAGE_ENC: { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->image_encode); - encodebin->image_encode = newelement; - gst_object_ref (encodebin->image_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode)); - gst_bin_add(GST_BIN(encodebin), encodebin->image_encode); - } - break; - } - case PROP_MUX: { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->mux); - encodebin->mux = newelement; - gst_object_ref (encodebin->mux); - gst_object_sink (GST_OBJECT_CAST (encodebin->mux)); - gst_bin_add(GST_BIN(encodebin), encodebin->mux); - } - break; - } - case PROP_VIDEO_CONV: { - GstElement *newelement = g_value_get_object (value); - if(encodebin->profile == GST_ENCODE_BIN_PROFILE_AUDIO) { - GST_WARNING_OBJECT(encodebin, "Profile isn't match, change profile first!"); - break; - } - if(newelement != NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - encodebin->color_space = newelement; - gst_object_ref (encodebin->color_space); - gst_object_sink (GST_OBJECT_CAST (encodebin->color_space)); - gst_bin_add(GST_BIN(encodebin), encodebin->color_space); - } - break; - } - case PROP_USE_VIDEO_TOGGLE: - encodebin->use_video_toggle = g_value_get_boolean( value ); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstPad * -gst_encode_bin_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * req_name) -{ - GstEncodeBin *encodebin = NULL; - GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); - GstPad *pad = NULL; - - g_return_val_if_fail (templ != NULL, NULL); - - if (templ->direction != GST_PAD_SINK) { - GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: request pad that is not a SINK pad\n"); - return NULL; - } - - g_return_val_if_fail (GST_IS_ENCODE_BIN (element), NULL); - - encodebin = GST_ENCODE_BIN (element); - - /* FIXME */ - if (templ == gst_element_class_get_pad_template (klass, "audio")) { - if (encodebin->profile <= GST_ENCODE_BIN_PROFILE_AUDIO) { - gst_encode_bin_init_audio_elements(element, NULL); //?? - - if(encodebin->audio_sinkpad == NULL) - { - pad = gst_element_get_static_pad (encodebin->audio_queue, "sink"); - encodebin->audio_sinkpad = gst_ghost_pad_new ("audio", pad); - gst_object_unref(pad); - pad = NULL; - } - else - { - GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: audio pad is aleady existed, return existing audio pad\n"); - return encodebin->audio_sinkpad; - } - - gst_element_add_pad (element, encodebin->audio_sinkpad); - gst_pad_set_setcaps_function (encodebin->audio_sinkpad, - GST_DEBUG_FUNCPTR (gst_encode_bin_audsink_set_caps)); - return encodebin->audio_sinkpad; - } else - return NULL; - } else if (templ == gst_element_class_get_pad_template (klass, "video")) { - if (encodebin->profile == GST_ENCODE_BIN_PROFILE_AV) { - gst_encode_bin_init_video_elements(element, NULL); //?? - - if(encodebin->video_sinkpad == NULL) - { - pad = gst_element_get_static_pad (encodebin->video_queue, "sink"); - encodebin->video_sinkpad = gst_ghost_pad_new ("video", pad); - gst_object_unref(pad); - pad = NULL; - } - else - { - GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: video pad is aleady existed, return existing video pad\n"); - return encodebin->video_sinkpad; - } - - gst_element_add_pad (element, encodebin->video_sinkpad); - gst_pad_set_setcaps_function (encodebin->video_sinkpad, - GST_DEBUG_FUNCPTR (gst_encode_bin_vidsink_set_caps)); - return encodebin->video_sinkpad; - } else if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) { - gst_encode_bin_init_image_elements(element, NULL); //?? - - if(encodebin->image_sinkpad == NULL) - { - pad = gst_element_get_static_pad (encodebin->image_queue, "sink"); - encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad); - gst_object_unref(pad); - pad = NULL; - } - else - { - GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n"); - return encodebin->image_sinkpad; - } - - gst_element_add_pad (element, encodebin->image_sinkpad); - gst_pad_set_setcaps_function (encodebin->image_sinkpad, - GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps)); - return encodebin->image_sinkpad; - } else - return NULL; - } else { - if (encodebin->profile == GST_ENCODE_BIN_PROFILE_IMAGE) { - gst_encode_bin_init_image_elements(element, NULL); //?? - - if(encodebin->image_sinkpad == NULL) - { - pad = gst_element_get_static_pad (encodebin->image_queue, "sink"); - encodebin->image_sinkpad = gst_ghost_pad_new ("image", pad); - gst_object_unref(pad); - pad = NULL; - } - else - { - GST_WARNING_OBJECT (GST_IS_ENCODE_BIN (element), "encodebin: image pad is aleady existed, return existing image pad\n"); - return encodebin->image_sinkpad; - } - - gst_element_add_pad (element, encodebin->image_sinkpad); - gst_pad_set_setcaps_function (encodebin->image_sinkpad, - GST_DEBUG_FUNCPTR (gst_encode_bin_imgsink_set_caps)); - return encodebin->image_sinkpad; - } else - return NULL; - } -} - -static void -gst_encode_bin_class_init (GstEncodeBinClass *klass) -{ - GObjectClass *gobject_klass; - GstElementClass *gstelement_klass; - GstBinClass *gstbin_klass; - - gobject_klass = (GObjectClass *) klass; - gstelement_klass = (GstElementClass *) klass; - gstbin_klass = (GstBinClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_klass->get_property = gst_encode_bin_get_property; - gobject_klass->set_property = gst_encode_bin_set_property; - gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_encode_bin_dispose); - gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_encode_bin_finalize); - - - g_object_class_install_property (gobject_klass, PROP_PROFILE, - g_param_spec_enum ("profile", "PROFILE", "Profile of the media to record", - GST_TYPE_ENCODE_BIN_PROFILE, DEFAULT_PROP_PROFILE, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_HIGH_SPEED, - g_param_spec_int ("high-speed-fps", "high speed rec. fps", "framerate for high speed recording", 0, G_MAXINT, - DEFAULT_PROP_HIGH_SPEED, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_VENC_NAME, - g_param_spec_string ("venc-name", "video encoder name", "the name of video encoder to use", - DEFAULT_PROP_VENC_NAME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AENC_NAME, - g_param_spec_string ("aenc-name", "audio encoder name", "the name of audio encoder to use", - DEFAULT_PROP_AENC_NAME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_IENC_NAME, - g_param_spec_string ("ienc-name", "image encoder name", "the name of image encoder to use", - DEFAULT_PROP_IENC_NAME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_MUX_NAME, - g_param_spec_string ("mux-name", "muxer name", "the name of muxer to use", - DEFAULT_PROP_MUX_NAME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_VCONV_NAME, - g_param_spec_string ("vconv-name", "Video converter name", "the name of video color converter to use", - DEFAULT_PROP_VCONV_NAME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_VCAPS, - g_param_spec_boxed ("vcaps", "caps for video","caps for video recording", - GST_TYPE_CAPS, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_ACAPS, - g_param_spec_boxed ("acaps", "caps for audio","caps for audio recording", - GST_TYPE_CAPS, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_ICAPS, - g_param_spec_boxed ("icaps", "caps for image","caps for image stillshot", - GST_TYPE_CAPS, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_CONVERT, - g_param_spec_boolean ("auto-audio-convert", "auto audio convert", - "Support for auto audio convert", TRUE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AUTO_AUDIO_RESAMPLE, - g_param_spec_boolean ("auto-audio-resample", "auto audio resample", - "Support for auto audio resample", TRUE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AUTO_COLORSPACE, - g_param_spec_boolean ("auto-colorspace", "auto colorspace", - "Support for auto colorspace", TRUE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_BLOCK, - g_param_spec_boolean ("block", "stream block", - "Support for stream block", FALSE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_PAUSE, - g_param_spec_boolean ("runtime-pause", "recording pause", - "Support for recording pause/resume", FALSE, G_PARAM_READWRITE)); - -#if 0 - g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE, - g_param_spec_boolean ("use-venc-queue", "use queue between venc and mux", - "add queue between venc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE, - g_param_spec_boolean ("use-aenc-queue", "use queue between aenc and mux", - "add queue between aenc and mux(only for custom optimization)", FALSE, G_PARAM_READWRITE)); -#else - g_object_class_install_property (gobject_klass, PROP_VENC_QUEUE, - g_param_spec_object ("use-venc-queue", "Video Encoder queue", - "add queue between venc and mux(only for custom optimization)", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AENC_QUEUE, - g_param_spec_object ("use-aenc-queue", "Audio Encoder queue", - "add queue between aenc and mux(only for custom optimization)", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); -#endif - - g_object_class_install_property (gobject_klass, PROP_VIDEO_ENC, - g_param_spec_object ("video-encode", "Video Encoder", - "the video encoder element to use", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_AUDIO_ENC, - g_param_spec_object ("audio-encode", "Audio Encoder", - "the audio encoder element to use", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_IMAGE_ENC, - g_param_spec_object ("image-encode", "Image Encoder", - "the Image encoder element to use", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_MUX, - g_param_spec_object ("mux", "Muxer", - "the muxer element to use", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_VIDEO_CONV, - g_param_spec_object ("video-convert", "Video converter", - "the video converter element to use", - GST_TYPE_ELEMENT, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_klass, PROP_USE_VIDEO_TOGGLE, - g_param_spec_boolean ("use-video-toggle", "Use video toggle", - "Use video toggle while AV recording", TRUE, G_PARAM_READWRITE)); - -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - gst_encode_bin_signals[SIGNAL_STREAM_BLOCK] = - g_signal_new ("stream-block", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_block), - NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - gst_encode_bin_signals[SIGNAL_STREAM_UNBLOCK] = - g_signal_new ("stream-unblock", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_unblock), - NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - gst_encode_bin_signals[SIGNAL_STREAM_PAUSE] = - g_signal_new ("stream-pause", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_pause), - NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - gst_encode_bin_signals[SIGNAL_STREAM_RESUME] = - g_signal_new ("stream-resume", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstEncodeBinClass, stream_resume), - NULL, NULL, gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); -#endif - - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&encoder_bin_src_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&encoder_bin_audio_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&encoder_bin_video_sink_template)); - gst_element_class_add_pad_template (gstelement_klass, - gst_static_pad_template_get (&encoder_bin_image_sink_template)); - - gst_element_class_set_details (gstelement_klass, &gst_encode_bin_details); - - gstelement_klass->request_new_pad = - GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad); - gstelement_klass->release_pad = - GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad); - gstelement_klass->change_state = - GST_DEBUG_FUNCPTR (gst_encode_bin_change_state); -} - -static void -gst_encode_bin_init (GstEncodeBin *encodebin) -{ - encodebin->mutex = g_mutex_new(); - - if (encodebin->srcpad == NULL) { - encodebin->srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC); - gst_element_add_pad (GST_ELEMENT(encodebin), encodebin->srcpad); - } - - encodebin->video_sinkpad = NULL; - encodebin->audio_sinkpad = NULL; - encodebin->image_sinkpad = NULL; - encodebin->mux_audio_sinkpad = NULL; - encodebin->mux_video_sinkpad = NULL; - - encodebin->profile = DEFAULT_PROP_PROFILE; - encodebin->fps = 0; - encodebin->high_speed_fps = DEFAULT_PROP_HIGH_SPEED; - encodebin->multiple = 1; - - encodebin->auto_audio_convert = TRUE; - encodebin->auto_audio_resample = TRUE; - encodebin->auto_color_space = TRUE; - encodebin->block = FALSE; - encodebin->pause= FALSE; - encodebin->use_video_toggle = TRUE; - encodebin->use_venc_queue= FALSE; - encodebin->use_aenc_queue= FALSE; - - encodebin->venc_name = g_strdup(DEFAULT_PROP_VENC_NAME); - encodebin->aenc_name = g_strdup(DEFAULT_PROP_AENC_NAME); - encodebin->ienc_name = g_strdup(DEFAULT_PROP_IENC_NAME); - encodebin->mux_name = g_strdup(DEFAULT_PROP_MUX_NAME); - encodebin->vconv_name = g_strdup(DEFAULT_PROP_VCONV_NAME); - - encodebin->vcaps = gst_caps_new_any (); - encodebin->acaps = gst_caps_new_any (); - encodebin->icaps = gst_caps_new_any (); - - encodebin->audio_queue = NULL; - encodebin->video_queue = NULL; - encodebin->video_encode_queue = NULL; - encodebin->image_queue = NULL; - - encodebin->audio_encode = NULL; - encodebin->video_encode = NULL; - encodebin->image_encode = NULL; - - encodebin->vcapsfilter = NULL; - encodebin->acapsfilter = NULL; - encodebin->icapsfilter = NULL; - - encodebin->video_toggle = NULL; - encodebin->image_toggle = NULL; - encodebin->color_space = NULL; - encodebin->audio_conv = NULL; - encodebin->audio_sample = NULL; - - encodebin->mux = NULL; - - encodebin->paused_time = 0; - encodebin->total_offset_time = 0; - - encodebin->vsink_probeid = 0; - encodebin->vsink_hs_probeid = 0; - encodebin->asink_probeid = 0; - encodebin->veque_sig_id = 0; - encodebin->aeque_sig_id = 0; -} - -static void -gst_encode_bin_dispose (GObject * object) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (object); - - g_free(encodebin->venc_name); - encodebin->venc_name = NULL; - - g_free(encodebin->aenc_name); - encodebin->aenc_name = NULL; - - g_free(encodebin->ienc_name); - encodebin->ienc_name = NULL; - - g_free(encodebin->mux_name); - encodebin->mux_name = NULL; - - g_free(encodebin->vconv_name); - encodebin->vconv_name = NULL; - - gst_caps_replace (&encodebin->vcaps, NULL); - gst_caps_replace (&encodebin->acaps, NULL); - gst_caps_replace (&encodebin->icaps, NULL); - - if (encodebin->srcpad != NULL) { - gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->srcpad); - encodebin->srcpad = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); - - encodebin->video_sinkpad = NULL; - encodebin->audio_sinkpad = NULL; - encodebin->image_sinkpad = NULL; - encodebin->mux_audio_sinkpad = NULL; - encodebin->mux_video_sinkpad = NULL; - - encodebin->audio_queue = NULL; - encodebin->video_queue = NULL; - encodebin->image_queue = NULL; - - encodebin->audio_encode = NULL; - encodebin->video_encode = NULL; - encodebin->video_encode_queue = NULL; - encodebin->image_encode = NULL; - - encodebin->vcapsfilter = NULL; - encodebin->acapsfilter = NULL; - encodebin->icapsfilter = NULL; - - encodebin->video_toggle = NULL; - encodebin->image_toggle = NULL; - encodebin->color_space = NULL; - encodebin->audio_conv = NULL; - encodebin->audio_sample = NULL; - - if (encodebin->mux && GST_IS_ELEMENT(encodebin->mux)) { - int remain_count= 0; - remain_count = GST_OBJECT_REFCOUNT_VALUE(encodebin->mux); - while (remain_count) { - gst_object_unref(encodebin->mux); - remain_count--; - } - } - - encodebin->mux = NULL; -} - -static void -gst_encode_bin_finalize (GObject * object) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (object); - - g_mutex_free (encodebin->mutex); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static GstStateChangeReturn -gst_encode_bin_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret; - GstEncodeBin *encode_bin; - - encode_bin = GST_ENCODE_BIN (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - gst_encode_bin_link_elements(encode_bin); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - /* reset time related values */ - encode_bin->paused_time = 0; - encode_bin->total_offset_time = 0; - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - gst_encode_bin_unlink_elements(encode_bin); - break; - default: - break; - } - -// if (ret == GST_STATE_CHANGE_FAILURE) -// goto done; -//done: - return ret; -} - -static void -gst_encode_bin_release_all_pads (GstEncodeBin *encodebin) -{ - gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->video_sinkpad); - gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->audio_sinkpad); - gst_element_remove_pad(GST_ELEMENT(encodebin), encodebin->image_sinkpad); -} - -static void -gst_encode_bin_release_pad (GstElement * element, GstPad * pad) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (element); - GstPad *muxpad = NULL; - - if(!pad_compare_name(pad, "video")) { -#if 0 - gst_encode_bin_remove_element(encodebin, encodebin->video_queue); - encodebin->video_queue = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->video_toggle); - encodebin->video_toggle = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - encodebin->color_space = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->vcapsfilter); - encodebin->vcapsfilter = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->video_encode_queue); - encodebin->video_encode_queue = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->video_encode); - encodebin->video_encode = NULL; - - gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad); - encodebin->mux_video_sinkpad = NULL; - - if(encodebin->mux_audio_sinkpad == NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->mux); - encodebin->mux = NULL; - } - else - { - encodebin->mux_audio_sinkpad = NULL; - } -#endif - - if(encodebin->mux_video_sinkpad != NULL) - { - gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad); - encodebin->mux_video_sinkpad = NULL; - } - - gst_pad_set_active (pad, FALSE); //?? - gst_element_remove_pad(element, pad); - encodebin->video_sinkpad = NULL; - } else if(!pad_compare_name(pad, "audio")) { -#if 0 - gst_encode_bin_remove_element(encodebin, encodebin->audio_queue); - encodebin->audio_queue = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->audio_sample); - encodebin->audio_sample = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->audio_conv); - encodebin->audio_conv = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->acapsfilter); - encodebin->acapsfilter = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode_queue); - encodebin->audio_encode_queue = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode); - encodebin->audio_encode = NULL; - - encodebin->mux_audio_sinkpad; - gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad); - muxpad = NULL; - - if(encodebin->mux_video_sinkpad == NULL) { - gst_encode_bin_remove_element(encodebin, encodebin->mux); - encodebin->mux = NULL; - } - else - { - encodebin->mux_video_sinkpad = NULL; - } -#endif - if(encodebin->mux_audio_sinkpad != NULL) - { - gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad); -// gst_object_unref(encodebin->mux_audio_sinkpad); //*** - encodebin->mux_audio_sinkpad = NULL; - } - - gst_pad_set_active (pad, FALSE); //?? - gst_element_remove_pad(element, pad); - encodebin->audio_sinkpad = NULL; - } else { -#if 0 - gst_encode_bin_remove_element(encodebin, encodebin->image_queue); - encodebin->image_queue = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->image_toggle); - encodebin->image_toggle = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - encodebin->color_space = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->icapsfilter); - encodebin->icapsfilter = NULL; - gst_encode_bin_remove_element(encodebin, encodebin->image_encode); - encodebin->image_encode = NULL; -#endif - gst_pad_set_active (pad, FALSE); //?? - gst_element_remove_pad(element, pad); - encodebin->image_sinkpad = NULL; - } -} - -static gint -pad_compare_name (GstPad * pad1, const gchar * name) -{ - gint result; - - GST_OBJECT_LOCK (pad1); - result = strcmp (GST_PAD_NAME (pad1), name); - GST_OBJECT_UNLOCK (pad1); - - return result; -} - -static gboolean -gst_encode_bin_add_element_by_name (GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name) -{ - switch(type) { - case ENCODEBIN_ELEMENT_VENC: - encodebin->video_encode = gst_element_factory_make (name, "video_encode"); - if(encodebin->video_encode != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - g_free(encodebin->venc_name); - encodebin->venc_name = NULL; - } else { - goto element_make_fail; - } - break; - case ENCODEBIN_ELEMENT_AENC: - encodebin->audio_encode = gst_element_factory_make (name, "audio_encode"); - if(encodebin->audio_encode != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode); - g_free(encodebin->aenc_name); - encodebin->aenc_name = NULL; - } else { - goto element_make_fail; - } - break; - case ENCODEBIN_ELEMENT_IENC: - encodebin->image_encode = gst_element_factory_make (name, "image_encode"); - if(encodebin->image_encode != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->image_encode); - g_free(encodebin->ienc_name); - encodebin->ienc_name = NULL; - } else { - goto element_make_fail; - } - break; - case ENCODEBIN_ELEMENT_MUX: - encodebin->mux = gst_element_factory_make (name, "mux"); - if(encodebin->mux != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->mux); - g_free(encodebin->mux_name); - encodebin->mux_name = NULL; - } else { - goto element_make_fail; - } - break; - case ENCODEBIN_ELEMENT_VIDEO_CONV: - encodebin->color_space = gst_element_factory_make(name, "video_convert"); - if (encodebin->color_space != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->color_space); - g_free(encodebin->vconv_name); - encodebin->vconv_name = NULL; - } else { - goto element_make_fail; - } - break; - default: - GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type); - break; - } - - return TRUE; - -element_make_fail: - GST_WARNING_OBJECT(encodebin, "no such element factory \"%s\"!", name); - return FALSE; -} - -#if 0 //disable unused function -static gboolean -gst_encode_bin_change_profile(GstEncodeBin *encodebin, gboolean newprofile) -{ - - gst_encode_bin_remove_element(encodebin, encodebin->video_encode); - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode); - gst_encode_bin_remove_element(encodebin, encodebin->image_encode); - gst_encode_bin_remove_element(encodebin, encodebin->mux); - - switch (newprofile) { - case GST_ENCODE_BIN_PROFILE_AV : - encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode"); - encodebin->video_encode = gst_element_factory_make (encodebin->venc_name,"video_encode"); - encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux"); - - gst_bin_add_many (GST_BIN (encodebin), - encodebin->audio_encode, - encodebin->video_encode, - encodebin->mux, - NULL); - break; - case GST_ENCODE_BIN_PROFILE_AUDIO : - encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode"); - encodebin->mux = gst_element_factory_make (encodebin->mux_name,"mux"); - - gst_bin_add_many (GST_BIN (encodebin), - encodebin->audio_encode, - encodebin->mux, - NULL); - break; - case GST_ENCODE_BIN_PROFILE_IMAGE : - encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name,"image_encode"); - - gst_bin_add_many (GST_BIN (encodebin), - encodebin->image_encode, - NULL); - break; - default: - GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile); - return FALSE; - break; - } - return TRUE; - -} - -static void -gst_encode_bin_replace_element (GstEncodeBin *encodebin, gint type, GstElement * newelement) -{ - if(newelement == NULL) { - GST_ERROR_OBJECT(encodebin, "some elements are null\n"); - return; - } - switch(type) { - case PROP_VIDEO_ENC: - gst_encode_bin_remove_element(encodebin, encodebin->video_encode); - encodebin->video_encode = newelement; - gst_object_ref (encodebin->video_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->video_encode)); // take ownership ?? - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - break; - case PROP_AUDIO_ENC: - gst_encode_bin_remove_element(encodebin, encodebin->audio_encode); - encodebin->audio_encode = newelement; - gst_object_ref (encodebin->audio_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->audio_encode)); - gst_bin_add(GST_BIN(encodebin), encodebin->audio_encode); - break; - case PROP_IMAGE_ENC: - gst_encode_bin_remove_element(encodebin, encodebin->image_encode); - encodebin->image_encode = newelement; - gst_object_ref (encodebin->image_encode); - gst_object_sink (GST_OBJECT_CAST (encodebin->image_encode)); - gst_bin_add(GST_BIN(encodebin), encodebin->image_encode); - break; - case PROP_MUX: - gst_encode_bin_remove_element(encodebin, encodebin->mux); - encodebin->mux = newelement; - gst_object_ref (encodebin->mux); - gst_object_sink (GST_OBJECT_CAST (encodebin->mux)); - gst_bin_add(GST_BIN(encodebin), encodebin->mux); - break; - default: - GST_WARNING_OBJECT(encodebin, "Invalid type = %d", type); - return; - break; - } -} - -static gboolean -gst_encode_bin_replace_element_by_name(GstEncodeBin *encodebin, GstEncodeBinElement type, const gchar *name) -{ - GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc; - - switch(type) { - case ENCODEBIN_ELEMENT_VENC: - if(encodebin->video_encode == NULL) { - encodebin->video_encode = gst_element_factory_make (name, "video_encode"); - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - } else { - sink1 = gst_element_get_static_pad(encodebin->video_encode, "sink"); - src = gst_element_get_static_pad(encodebin->video_encode, "src"); - if(sink1 != NULL) { - peersink1 = gst_pad_get_peer(sink1); - if(peersink1 != NULL) { - if(!gst_pad_unlink(peersink1, sink1)) { - goto unlink_fail; - } - } - } - - if(src !=NULL) { - peersrc = gst_pad_get_peer(src); - if(peersrc != NULL) { - if(!gst_pad_unlink(src, peersrc)) { - goto unlink_fail; - } - } - } - - if(gst_encode_bin_remove_element(encodebin, encodebin->video_encode)) { - if(encodebin->video_encode = gst_element_factory_make (name, "video_encode") != NULL) { - gst_bin_add(GST_BIN(encodebin), encodebin->video_encode); - if(peersink1 != NULL) { - if(!gst_pad_link(peersink1, gst_element_get_pad(encodebin->video_encode, "sink"))) { - goto link_fail; - } - } - - if(peersrc != NULL) { - if(!gst_pad_link(gst_element_get_pad(encodebin->video_encode, "src"), peersrc)) { - goto link_fail; - } - } - } else { - GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] make fail\n", type); - return FALSE; - } - } else { - GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] remove fail\n", type); - return FALSE; - } - } - break; - case ENCODEBIN_ELEMENT_AENC: - break; - case ENCODEBIN_ELEMENT_IENC: - break; - case ENCODEBIN_ELEMENT_MUX: - break; - default : - GST_WARNING_OBJECT(encodebin, "Invalid element type = %d", type); - break; - } - gst_object_unref(sink1); - gst_object_unref(sink2); - gst_object_unref(src); - gst_object_unref(peersink1); - gst_object_unref(peersink2); - gst_object_unref(peersrc); - return TRUE; - -unlink_fail: - gst_object_unref(sink1); - gst_object_unref(sink2); - gst_object_unref(src); - gst_object_unref(peersink1); - gst_object_unref(peersink2); - gst_object_unref(peersrc); - GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() old element[%d] unlink fail\n", type); - return FALSE; - - -link_fail: - gst_object_unref(sink1); - gst_object_unref(sink2); - gst_object_unref(src); - gst_object_unref(peersink1); - gst_object_unref(peersink2); - gst_object_unref(peersrc); - GST_ERROR_OBJECT(encodebin, "gst_encode_bin_replace_element_by_name() new element[%d] link fail\n", type); - return FALSE; -} - -static gboolean -gst_encode_bin_replace_element_by_object(GstEncodeBin *encodebin, GstEncodeBinElement type, GstElement * element) -{ - GstPad *sink1, *sink2, *src, *peersink1, *peersink2, *peersrc; - - switch(type) - case ENCODEBIN_ELEMENT_VENC: - if(encodebin->video_encode == NULL) { - encodebin->video_encode = element - } - break; - case ENCODEBIN_ELEMENT_AENC: - break; - case ENCODEBIN_ELEMENT_IENC: - break; - case ENCODEBIN_ELEMENT_MUX: - break; - default : - GST_WARNING_OBJECT (encodebin,"Invalid element type = %d", type); - break; -} -#endif //disable unused function - -static gboolean -gst_encode_bin_remove_element (GstEncodeBin *encodebin, GstElement * element) -{ - GstObject *parent; - gchar *ename = NULL; - GST_INFO_OBJECT (encodebin, "gst_encode_bin_remove_element"); - - if (element == NULL) { - GST_INFO_OBJECT (encodebin, "element is already NULL"); - return TRUE; - } - - gst_element_set_state (element, GST_STATE_NULL); - parent = gst_element_get_parent (element); - - if (parent != NULL) { - if(!gst_bin_remove (GST_BIN_CAST (parent), element)) { - gst_object_unref (parent); - ename = gst_element_get_name (element); - GST_ERROR_OBJECT (encodebin, "gst_encode_bin_remove_element() [%s] remove fail", ename); - g_free (ename); - return FALSE; - } else { - gst_object_unref(parent); - } - } else { - gst_object_unref(element); - } - - return TRUE; - } - -static gboolean -gst_encode_bin_link_elements (GstEncodeBin *encodebin) // need to return ???? -{ - GstPad *srcpad = NULL, *sinkpad = NULL; - switch(encodebin->profile) { - case GST_ENCODE_BIN_PROFILE_AV : - if (!gst_caps_is_any(encodebin->vcaps)) { - gchar *caps_str = NULL; - caps_str = gst_caps_to_string(encodebin->vcaps); - if (caps_str) { - GST_INFO_OBJECT(encodebin, "vconv caps [%s]", caps_str); - g_free(caps_str); - caps_str = NULL; - } - - g_object_set(encodebin->vcapsfilter, "caps", encodebin->vcaps, NULL); - } - - if (encodebin->auto_color_space) { - if(encodebin->color_space == NULL) { - encodebin->color_space = gst_element_factory_make (encodebin->vconv_name, "video_convert"); - gst_bin_add (GST_BIN (encodebin), encodebin->color_space); - } - - srcpad = gst_element_get_static_pad(encodebin->video_queue, "src"); - if( encodebin->video_toggle ) - { - sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src"); - } - sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->color_space, "src"); - sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); -#if 0 - if(encodebin->use_venc_queue) - { - if(encodebin->video_encode_queue == NULL) { - encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue); - - ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME); - encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - - } - - srcpad = gst_element_get_static_pad(encodebin->video_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } -#else - if(encodebin->video_encode_queue) - { - ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME); - encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); -#if 0 - g_object_set(G_OBJECT(encodebin->video_queue), - "max-size-bytes", (guint)0, - "max-size-buffers", (guint)1, - "max-size-time", (guint64)0, - NULL); -#endif - srcpad = gst_element_get_static_pad(encodebin->video_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } -#endif - - } - else { - srcpad = gst_element_get_static_pad(encodebin->video_queue, "src"); - if( encodebin->video_toggle ) - { - sinkpad = gst_element_get_static_pad(encodebin->video_toggle, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->video_toggle, "src"); - } - sinkpad = gst_element_get_static_pad(encodebin->vcapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->vcapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - #if 0 - if(encodebin->use_venc_queue) - { - if(encodebin->video_encode_queue == NULL) { - encodebin->video_encode_queue = gst_element_factory_make ("queue","video_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->video_encode_queue); - - ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME); - encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - } - - srcpad = gst_element_get_static_pad(encodebin->video_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - - } -#else - if(encodebin->video_encode_queue) - { - ENCODER_QUEUE_SET(encodebin->video_encode_queue, 0, 0, VIDEO_ENC_QUE_TIME); - encodebin->veque_sig_id = g_signal_connect( G_OBJECT(encodebin->video_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); -#if 0 - g_object_set(G_OBJECT(encodebin->video_queue), - "max-size-bytes", (guint)0, - "max-size-buffers", (guint)1, - "max-size-time", (guint64)0, - NULL); -#endif - - srcpad = gst_element_get_static_pad(encodebin->video_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->video_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } -#endif - - } - -// gst_element_get_request_pad (encodebin->mux, "video_%d"); -#if 0 - if(encodebin->use_venc_queue) - { - srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src"); - sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } -#else - if(encodebin->video_encode_queue) - { - srcpad = gst_element_get_static_pad(encodebin->video_encode_queue, "src"); - sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } -#endif - else - { - srcpad = gst_element_get_static_pad(encodebin->video_encode, "src"); - sinkpad = encodebin->mux_video_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_VIDEO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, video_link_fail); - } - - srcpad = gst_element_get_static_pad(encodebin->mux, "src"); - if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad) - gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad); - gst_object_unref(srcpad); - srcpad = NULL; - - /* For pause/resume control */ -// encodebin->vsink_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_queue, "sink"), - sinkpad = gst_element_get_static_pad (encodebin->video_queue, "sink"); - encodebin->vsink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe), encodebin); - gst_object_unref(sinkpad); - sinkpad = NULL; - - if(encodebin->high_speed_fps > DEFAULT_PROP_HIGH_SPEED) - { -// encodebin->vsink_hs_probeid = gst_pad_add_data_probe (gst_element_get_static_pad (encodebin->video_encode, "sink"), - sinkpad = gst_element_get_static_pad (encodebin->video_encode, "sink"); - encodebin->vsink_hs_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_video_probe_hs), encodebin); - gst_object_unref(sinkpad); - sinkpad = NULL; - } - - if(encodebin->audio_queue == NULL) - { - GST_WARNING_OBJECT(encodebin, "Audio pad isn't requested, recording video only mode"); - break; - } - case GST_ENCODE_BIN_PROFILE_AUDIO : - if(!gst_caps_is_any(encodebin->acaps)) - { - g_object_set(encodebin->acapsfilter, "caps", encodebin->acaps, NULL); - } - if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) { - if (!encodebin->auto_audio_convert) { - if(encodebin->audio_sample == NULL) { - encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample); - } - srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src"); - sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); -#if 0 - if(encodebin->use_aenc_queue) - { - if(encodebin->audio_encode_queue == NULL) { - encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue); - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#else - if(encodebin->audio_encode_queue) - { - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#endif - - } else if (!encodebin->auto_audio_resample) { - if (encodebin->audio_conv == NULL) { - encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src"); - sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); -#if 0 - if(encodebin->use_aenc_queue) - { - if(encodebin->audio_encode_queue == NULL) { - encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue); - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - } -#else - if(encodebin->audio_encode_queue) - { - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#endif - - } else { - if(encodebin->audio_sample == NULL) { - encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_sample); - } - if (encodebin->audio_conv == NULL) { - encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_conv); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_conv, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->audio_conv, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_sample, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->audio_sample, "src"); - sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); -#if 0 - if(encodebin->use_aenc_queue) - { - if(encodebin->audio_encode_queue == NULL) { - encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue); - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - } -#else - if(encodebin->audio_encode_queue) - { - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#endif - - } - }else { - - srcpad = gst_element_get_static_pad(encodebin->audio_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->acapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->acapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); -#if 0 - if(encodebin->use_aenc_queue) - { - if(encodebin->audio_encode_queue == NULL) { - encodebin->audio_encode_queue = gst_element_factory_make ("queue","audio_encode_queue"); - gst_bin_add (GST_BIN (encodebin), encodebin->audio_encode_queue); - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - } - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#else - if(encodebin->audio_encode_queue) - { - - ENCODER_QUEUE_SET(encodebin->audio_encode_queue, 0, 0, AUDIO_ENC_QUE_TIME); - encodebin->aeque_sig_id = g_signal_connect( G_OBJECT(encodebin->audio_encode_queue), "overrun", - G_CALLBACK(queue_overun_cb), encodebin); - - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - } -#endif - - } -#if 0 - if(encodebin->use_aenc_queue) - { - srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src"); - sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - } -#else - - if(encodebin->audio_encode_queue) - { - srcpad = gst_element_get_static_pad(encodebin->audio_encode_queue, "src"); - sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - } -#endif - else - { - srcpad = gst_element_get_static_pad(encodebin->audio_encode, "src"); - sinkpad = encodebin->mux_audio_sinkpad = gst_encode_bin_get_mux_sink_pad(encodebin->mux, ENCODEBIN_MUX_AUDIO_SINK); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, audio_link_fail); - - } - - srcpad = gst_element_get_static_pad(encodebin->mux, "src"); - if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad) - gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad); - gst_object_unref(srcpad); - srcpad = NULL; - - /* For pause/resume control */ - sinkpad = gst_element_get_static_pad (encodebin->audio_queue, "sink"); - encodebin->asink_probeid = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (gst_encode_bin_audio_probe), encodebin); - gst_object_unref(sinkpad); - sinkpad = NULL; - - break; - case GST_ENCODE_BIN_PROFILE_IMAGE : - if(!gst_caps_is_any(encodebin->icaps)) - { - g_object_set(encodebin->icapsfilter, "caps", encodebin->icaps, NULL); - } - - if (encodebin->auto_color_space) { - if(encodebin->color_space == NULL) { - encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space"); - gst_bin_add (GST_BIN (encodebin), encodebin->color_space); - } - - srcpad = gst_element_get_static_pad(encodebin->image_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src"); - sinkpad = gst_element_get_static_pad(encodebin->color_space, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->color_space, "src"); - sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - } - else { - - srcpad = gst_element_get_static_pad(encodebin->image_queue, "src"); - sinkpad = gst_element_get_static_pad(encodebin->image_toggle, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->image_toggle, "src"); - sinkpad = gst_element_get_static_pad(encodebin->icapsfilter, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - srcpad = gst_element_get_static_pad(encodebin->icapsfilter, "src"); - sinkpad = gst_element_get_static_pad(encodebin->image_encode, "sink"); - _GST_PAD_LINK_UNREF(srcpad, sinkpad, image_link_fail); - - } - srcpad = gst_element_get_static_pad (encodebin->image_encode, "src"); - if(gst_ghost_pad_get_target(GST_GHOST_PAD (encodebin->srcpad)) != srcpad) - gst_ghost_pad_set_target(GST_GHOST_PAD (encodebin->srcpad), srcpad); - gst_object_unref(srcpad); - srcpad = NULL; - break; - default: - GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile); - return FALSE; - break; - } -// gst_pad_set_active(encodebin->srcpad, TRUE); - return TRUE; - -video_link_fail: - // remove elements - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - GST_WARNING_OBJECT(encodebin, "encodebin link video elements fail"); - return FALSE; - -audio_link_fail: - // remove element - gst_encode_bin_remove_element(encodebin, encodebin->audio_conv); - gst_encode_bin_remove_element(encodebin, encodebin->audio_sample); - GST_WARNING_OBJECT(encodebin, "encodebin link audio elements fail"); - return FALSE; - -image_link_fail: - // remove element - gst_encode_bin_remove_element(encodebin, encodebin->color_space); - GST_WARNING_OBJECT(encodebin, "encodebin link image elements fail"); - return FALSE; - - -} - -static gboolean -gst_encode_bin_unlink_elements (GstEncodeBin *encodebin) -{ - GstPad *pad = NULL, *muxpad = NULL; - - switch(encodebin->profile) { - case GST_ENCODE_BIN_PROFILE_AV : - if (encodebin->auto_color_space) { - if (encodebin->video_toggle) { - gst_element_unlink_many( - encodebin->video_queue, - encodebin->video_toggle, - encodebin->color_space, - encodebin->vcapsfilter, - encodebin->video_encode, - //encodebin->video_encode_queue, - NULL); - } else { - gst_element_unlink_many( - encodebin->video_queue, - encodebin->color_space, - encodebin->vcapsfilter, - encodebin->video_encode, - //encodebin->video_encode_queue, - NULL); - } - } else { - if (encodebin->video_toggle) { - gst_element_unlink_many( - encodebin->video_queue, - encodebin->video_toggle, - encodebin->vcapsfilter, - encodebin->video_encode, - //encodebin->video_encode_queue, - NULL); - } else { - gst_element_unlink_many( - encodebin->video_queue, - encodebin->vcapsfilter, - encodebin->video_encode, - //encodebin->video_encode_queue, - NULL); - } - } - - if(encodebin->mux_video_sinkpad != NULL) - { -#if 0 - if(encodebin->use_venc_queue) - { - gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue); - - pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src"); - gst_pad_unlink(pad, muxpad); - gst_object_unref(pad); - pad = NULL; - - if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) ) - { - g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id ); - } - } -#else - if(encodebin->video_encode_queue) - { - gst_element_unlink(encodebin->video_encode, encodebin->video_encode_queue); - - pad = gst_element_get_static_pad (encodebin->video_encode_queue, "src"); - gst_pad_unlink(pad, encodebin->mux_video_sinkpad); - gst_object_unref(pad); - pad = NULL; - - if ( g_signal_handler_is_connected ( encodebin->video_encode_queue, encodebin->veque_sig_id) ) - { - g_signal_handler_disconnect ( encodebin->video_encode_queue, encodebin->veque_sig_id ); - } - } -#endif - else - { - pad = gst_element_get_static_pad (encodebin->video_encode, "src"); - gst_pad_unlink(pad, encodebin->mux_video_sinkpad); - gst_object_unref(pad); - pad = NULL; - } - - gst_element_release_request_pad(encodebin->mux, encodebin->mux_video_sinkpad); -// gst_object_unref(encodebin->mux_video_sinkpad); //*** - encodebin->mux_video_sinkpad = NULL; - } - - if(encodebin->vsink_probeid) - { - pad = gst_element_get_static_pad (encodebin->video_queue, "sink"); - gst_pad_remove_buffer_probe(pad, encodebin->vsink_probeid); - encodebin->vsink_probeid = 0; - gst_object_unref(pad); - pad = NULL; - } - - - if(encodebin->vsink_hs_probeid) - { - pad = gst_element_get_static_pad (encodebin->video_encode, "sink"); - gst_pad_remove_buffer_probe(pad, encodebin->vsink_hs_probeid); - encodebin->vsink_hs_probeid = 0; - gst_object_unref(pad); - pad = NULL; - } - - if(encodebin->audio_queue == NULL) - { - break; - } - case GST_ENCODE_BIN_PROFILE_AUDIO : - if (encodebin->auto_audio_convert ||encodebin->auto_audio_resample) { - if (!encodebin->auto_audio_convert) { - gst_element_unlink_many ( - encodebin->audio_queue, - encodebin->audio_sample, - encodebin->acapsfilter, - encodebin->audio_encode, - NULL); - } else if (!encodebin->auto_audio_resample) { - gst_element_unlink_many ( - encodebin->audio_queue, - encodebin->audio_conv, - encodebin->acapsfilter, - encodebin->audio_encode, - NULL); - } else { - gst_element_unlink_many ( - encodebin->audio_queue, - encodebin->audio_conv, - encodebin->audio_sample, - encodebin->acapsfilter, - encodebin->audio_encode, - NULL); - } - } - else { - gst_element_unlink_many ( - encodebin->audio_queue, - encodebin->acapsfilter, - encodebin->audio_encode, - NULL); - } - - if(encodebin->mux_audio_sinkpad != NULL) - { -#if 0 - if(encodebin->use_aenc_queue) - { - gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue); - - pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src"); - gst_pad_unlink(pad, muxpad); - gst_object_unref(pad); - pad = NULL; - - if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) ) - { - g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id ); - } - } -#else - if(encodebin->audio_encode_queue) - { - gst_element_unlink(encodebin->audio_encode, encodebin->audio_encode_queue); - - pad = gst_element_get_static_pad (encodebin->audio_encode_queue, "src"); - gst_pad_unlink(pad, encodebin->mux_audio_sinkpad); - gst_object_unref(pad); - pad = NULL; - - if ( g_signal_handler_is_connected ( encodebin->audio_encode_queue, encodebin->veque_sig_id) ) - { - g_signal_handler_disconnect ( encodebin->audio_encode_queue, encodebin->veque_sig_id ); - } - } -#endif - else - { - pad = gst_element_get_static_pad (encodebin->audio_encode, "src"); - gst_pad_unlink(pad, encodebin->mux_audio_sinkpad); - gst_object_unref(pad); - pad = NULL; - } - - gst_element_release_request_pad(encodebin->mux, encodebin->mux_audio_sinkpad); -// gst_object_unref(encodebin->mux_audio_sinkpad); //*** - encodebin->mux_audio_sinkpad = NULL; - } - - if(encodebin->asink_probeid) - { - pad = gst_element_get_static_pad (encodebin->audio_queue, "sink"); - gst_pad_remove_buffer_probe(pad, encodebin->asink_probeid); - encodebin->asink_probeid =0; - gst_object_unref(pad); - pad = NULL; - } - - break; - case GST_ENCODE_BIN_PROFILE_IMAGE : - if (encodebin->auto_color_space) { - gst_element_unlink_many ( - encodebin->image_queue, - encodebin->image_toggle, - encodebin->color_space, - encodebin->icapsfilter, - encodebin->image_encode, - NULL); - } - else { - gst_element_unlink_many ( - encodebin->image_queue, - encodebin->image_toggle, - encodebin->icapsfilter, - encodebin->image_encode, - NULL); - } - break; - default: - GST_WARNING_OBJECT(encodebin, "Invalid profile number = %d", encodebin->profile); - return FALSE; - break; - } - // gst_pad_set_active(encodebin->srcpad, TRUE); - return TRUE; - -} - -static gboolean -gst_encode_bin_init_video_elements (GstElement *element, gpointer user_data) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (element); - - if(encodebin->profile != GST_ENCODE_BIN_PROFILE_AV) - return FALSE; - - if(encodebin->video_queue == NULL) { - encodebin->video_queue = gst_element_factory_make ("queue","video_queue"); - gst_bin_add (GST_BIN (element), encodebin->video_queue); - } - - if( encodebin->use_video_toggle ) - { - if( encodebin->video_toggle == NULL ) - { - encodebin->video_toggle = gst_element_factory_make ("toggle","video_toggle"); - gst_bin_add (GST_BIN (element), encodebin->video_toggle); - } - GST_INFO_OBJECT( encodebin, "Video toggle is Enabled" ); - } - else - { - GST_INFO_OBJECT( encodebin, "Video toggle is Disabled" ); - } - - if(encodebin->vcapsfilter == NULL) { - encodebin->vcapsfilter = gst_element_factory_make ("capsfilter","vcapsfilter"); - gst_bin_add (GST_BIN (element), encodebin->vcapsfilter); - } -#if 0 - encodebin->vcaps = gst_caps_new_simple("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), - "width", G_TYPE_INT, 320, - "height", G_TYPE_INT, 240, - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); - -#endif - if(encodebin->video_encode == NULL) { - encodebin->video_encode = gst_element_factory_make (encodebin->venc_name, "video_encode"); - gst_bin_add (GST_BIN (element), encodebin->video_encode); - } - -#if 0 - if(encodebin->video_encode_queue == NULL) { - encodebin->video_encode_queue = gst_element_factory_make ("queue", "video_encode_queue"); - gst_bin_add (GST_BIN (element), encodebin->video_encode_queue); - } - - g_object_set(G_OBJECT(encodebin->video_encode_queue), "max-size-bytes", (unsigned int)0, NULL); -#endif - - if(encodebin->mux == NULL) { - encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux"); - gst_bin_add (GST_BIN (element), encodebin->mux); - } - - if (!encodebin->video_encode -// || !encodebin->video_encode_queue - || !encodebin->mux - || !encodebin->video_queue - || !encodebin->vcapsfilter - || !encodebin->srcpad ) - { - GST_ERROR_OBJECT(encodebin, "Faild create element \n"); - return FALSE; - } - - if( encodebin->use_video_toggle && !encodebin->video_toggle ) - { - GST_ERROR_OBJECT(encodebin, "Faild create video toggle element \n"); - return FALSE; - } - -#if 0 - if (encodebin->auto_color_space && (encodebin->color_space == NULL)) { - encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space"); - gst_bin_add (GST_BIN (element), encodebin->color_space); - } -#endif - return TRUE; -} - -static gboolean -gst_encode_bin_init_audio_elements (GstElement *element, gpointer user_data) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (element); - - if(encodebin->profile > GST_ENCODE_BIN_PROFILE_AUDIO) - return FALSE; - - if(encodebin->audio_queue == NULL) { - encodebin->audio_queue = gst_element_factory_make ("queue","audio_queue"); - gst_bin_add (GST_BIN (element), encodebin->audio_queue); - } - - if(encodebin->acapsfilter == NULL) { - encodebin->acapsfilter = gst_element_factory_make ("capsfilter","acapsfilter"); - gst_bin_add (GST_BIN (element), encodebin->acapsfilter); - } -#if 0 -encodebin->acaps = gst_caps_new_simple("audio/x-raw-int", - "rate", G_TYPE_INT, 8000, - "channels", G_TYPE_INT, 2, - "depth", G_TYPE_INT, 16, - NULL); -#endif - - if(encodebin->audio_encode == NULL) { - encodebin->audio_encode = gst_element_factory_make (encodebin->aenc_name, "audio_encode"); - gst_bin_add (GST_BIN (element), encodebin->audio_encode); - } - - if(encodebin->mux == NULL) { - encodebin->mux = gst_element_factory_make (encodebin->mux_name, "mux"); - gst_bin_add (GST_BIN (element), encodebin->mux); - } - - if (!encodebin->audio_encode - || !encodebin->audio_queue - || !encodebin->mux - || !encodebin->acapsfilter - || !encodebin->srcpad ) - { - GST_ERROR_OBJECT(encodebin, "Faild create element \n"); - return FALSE; - } -#if 0 - if (encodebin->auto_audio_convert && (encodebin->audio_conv == NULL)) { - encodebin->audio_conv = gst_element_factory_make ("audioconvert","audio_conv"); - gst_bin_add (GST_BIN (element), encodebin->audio_conv); - } - - if (encodebin->auto_audio_resample && (encodebin->audio_sample == NULL)) { - encodebin->audio_sample = gst_element_factory_make ("audioresample","audio_sample"); - gst_bin_add (GST_BIN (element), encodebin->audio_sample); - } -#endif - return TRUE; -} - - -static gboolean -gst_encode_bin_init_image_elements (GstElement *element, gpointer user_data) -{ - GstEncodeBin *encodebin = GST_ENCODE_BIN (element); - - if(encodebin->profile < GST_ENCODE_BIN_PROFILE_IMAGE) - return FALSE; - - if(encodebin->image_queue == NULL) { - encodebin->image_queue = gst_element_factory_make ("queue","image_queue"); - gst_bin_add (GST_BIN (element), encodebin->image_queue); - } - - if(encodebin->image_toggle == NULL) { - encodebin->image_toggle = gst_element_factory_make ("toggle","image_toggle"); - gst_bin_add (GST_BIN (element), encodebin->image_toggle); - } - - if(encodebin->icapsfilter == NULL) { - encodebin->icapsfilter = gst_element_factory_make ("capsfilter","icapsfilter"); - gst_bin_add (GST_BIN (element), encodebin->icapsfilter); - } - - if(encodebin->image_encode == NULL) { - encodebin->image_encode = gst_element_factory_make (encodebin->ienc_name, "image_encode"); - gst_bin_add (GST_BIN (element), encodebin->image_encode); - } - - if (!encodebin->image_encode - || !encodebin->image_queue - || !encodebin->image_toggle - || !encodebin->icapsfilter - || !encodebin->srcpad ) - { - GST_ERROR_OBJECT(encodebin, "Faild create element \n"); - return FALSE; - } -#if 0 - if (encodebin->auto_color_space && (encodebin->color_space == NULL)) { - encodebin->color_space = gst_element_factory_make ("ffmpegcolorspace","color_space"); - gst_bin_add (GST_BIN (element), encodebin->color_space); - } -#endif - return TRUE; -} - -static gboolean gst_encode_bin_block(GstEncodeBin *encodebin, gboolean value) -{ - - if(value) { //block stream - switch(encodebin->profile) { - case GST_ENCODE_BIN_PROFILE_AV: - if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) { - goto block_fail; - } else { - if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)), - "empty-buffers") == NULL) { - GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property"); - goto block_fail; - } - if( encodebin->video_toggle ) - { - g_object_set(encodebin->video_toggle, "block-data", TRUE , NULL); - GST_INFO_OBJECT( encodebin, "video_toggle block-data TRUE" ); - } - - g_object_set(encodebin->video_queue, "empty-buffers", TRUE , NULL); - GST_INFO_OBJECT( encodebin, "video_queue empty-buffers TRUE" ); - if(encodebin->audio_queue != NULL) - { - g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL); - GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" ); - } - } - break; - case GST_ENCODE_BIN_PROFILE_AUDIO: - if(encodebin->audio_queue == NULL) { - goto block_fail; - } else { - if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)), - "empty-buffers") == NULL) { - GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property"); - goto block_fail; - } - g_object_set(encodebin->audio_queue, "empty-buffers", TRUE , NULL); - GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers TRUE" ); - } - break; - case GST_ENCODE_BIN_PROFILE_IMAGE: - if(encodebin->image_toggle == NULL) { - goto block_fail; - } else { - g_object_set(encodebin->image_toggle, "block_data", TRUE, NULL); - GST_INFO_OBJECT( encodebin, "image_toggle block_data TRUE" ); - } - break; - default: - GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile); - goto block_fail; - break; - } - } else { //release blocked-stream - switch(encodebin->profile) { - case GST_ENCODE_BIN_PROFILE_AV: - if(encodebin->audio_queue == NULL && encodebin->video_queue == NULL) { - goto unblock_fail; - } else { - if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->video_queue)), - "empty-buffers") == NULL) { - GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property"); - goto unblock_fail; - } - if( encodebin->video_toggle ) - { - g_object_set(encodebin->video_toggle, "block-data", FALSE , NULL); - GST_INFO_OBJECT( encodebin, "video_toggle block-data FALSE" ); - } - - if(encodebin->audio_queue != NULL) - { - g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL); - GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" ); - } - g_object_set(encodebin->video_queue, "empty-buffers", FALSE , NULL); - GST_INFO_OBJECT( encodebin, "video_queue empty-buffers FALSE" ); - } - break; - case GST_ENCODE_BIN_PROFILE_AUDIO: - if(encodebin->audio_queue == NULL) { - goto unblock_fail; - } else { - if(g_object_class_find_property(G_OBJECT_GET_CLASS(GST_OBJECT(encodebin->audio_queue)), - "empty-buffers") == NULL) { - GST_ERROR_OBJECT(encodebin, "The queue element doesn't support 'empty-buffers' property"); - goto unblock_fail; - } - g_object_set(encodebin->audio_queue, "empty-buffers", FALSE , NULL); - GST_INFO_OBJECT( encodebin, "audio_queue empty-buffers FALSE" ); - } - break; - case GST_ENCODE_BIN_PROFILE_IMAGE: - if(encodebin->image_toggle == NULL) { - goto unblock_fail; - } else { - g_object_set(encodebin->image_toggle, "block_data", FALSE, NULL); - GST_INFO_OBJECT( encodebin, "image_toggle block_data FALSE" ); - } - break; - default: - GST_WARNING_OBJECT (encodebin,"Invalid profile number = %d", encodebin->profile); - goto unblock_fail; - break; - } - } - encodebin->block = value; - return TRUE; - -block_fail: - GST_ERROR_OBJECT(encodebin, "encodebin block failed"); - return FALSE; - -unblock_fail: - GST_ERROR_OBJECT(encodebin, "encodebin unblock failed"); - return FALSE; -} - -static gboolean gst_encode_bin_pause(GstEncodeBin *encodebin, gboolean value) -{ - GstClock *clock = NULL; - - if(value) { - /* pause stream*/ - //Block src of encode bin - if (!gst_encode_bin_block(encodebin, TRUE)) - { - GST_WARNING_OBJECT (encodebin, "Fail to block Encodebin."); - goto pause_fail; - } - - if (encodebin->paused_time == 0) - { - //get steam time - if (clock = GST_ELEMENT_CLOCK(encodebin)) //before PLAYING, this would be NULL. Need to check. - { - GstClockTime current_time, base_time; - - current_time = gst_clock_get_time(clock); - base_time = gst_element_get_base_time(GST_ELEMENT(encodebin)); - - encodebin->paused_time = current_time - base_time; - - GST_INFO_OBJECT (encodebin, "Encodebin is in running-pause at [%"GST_TIME_FORMAT"]." - , GST_TIME_ARGS(encodebin->paused_time)); - } - else - { - encodebin->paused_time = 0; - encodebin->total_offset_time = 0; - - GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin."); - } - } -#if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, TRUE); -#endif - } - else { - /* release paused-stream*/ - if (encodebin->paused_time != 0) - { - if (clock = GST_ELEMENT_CLOCK(encodebin)) - { - GstClockTime current_time, base_time; - GstClockTime paused_gap; - - current_time = gst_clock_get_time(clock); - base_time = gst_element_get_base_time(GST_ELEMENT(encodebin)); - paused_gap = current_time - base_time - encodebin->paused_time; - - encodebin->total_offset_time += paused_gap; - encodebin->paused_time = 0; - - GST_INFO_OBJECT (encodebin, "Encodebin now resumes. Offset delay [%"GST_TIME_FORMAT"], Total offset delay [%"GST_TIME_FORMAT"]" - , GST_TIME_ARGS(paused_gap) , GST_TIME_ARGS(encodebin->total_offset_time)); - } - else - { - encodebin->paused_time = 0; - encodebin->total_offset_time = 0; - - GST_WARNING_OBJECT (encodebin, "There is no clock in Encodebin."); - } - } - - //TODO : How about qos? - - //Unblock src of encode bin - if (!gst_encode_bin_block(encodebin, FALSE)) - { - GST_WARNING_OBJECT (encodebin, "Fail to Unblock Encodebin."); - goto resume_fail; - } -#if 0 //def GST_ENCODE_BIN_SIGNAL_ENABLE - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, TRUE); -#endif - } - encodebin->pause = value; - return TRUE; - -pause_fail: - GST_WARNING_OBJECT (encodebin, "Fail to pause Encodebin"); -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_PAUSE], 0, FALSE); -#endif - return FALSE; - -resume_fail: - GST_WARNING_OBJECT (encodebin, "Fail to resume Encodebin"); -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - g_signal_emit (G_OBJECT (encodebin), gst_encode_bin_signals[SIGNAL_STREAM_RESUME], 0, FALSE); -#endif - return FALSE; -} - -static gboolean -gst_encode_bin_release_pipeline (GstElement *element, - gpointer user_data) -{ -#if 0 - GstEncodeBin *encodebin = GST_ENCODE_BIN (element); - - gst_element_set_state (encodebin->audio_queue, GST_STATE_NULL); - gst_element_set_state (encodebin->audio_encode, GST_STATE_NULL); - gst_element_set_state (encodebin->video_queue, GST_STATE_NULL); - gst_element_set_state (encodebin->video_encode, GST_STATE_NULL); - gst_element_set_state (encodebin->mux, GST_STATE_NULL); - - if (encodebin->auto_video_scale) { - gst_element_set_state (encodebin->video_scale, GST_STATE_NULL); - gst_element_unlink (encodebin->video_queue, encodebin->video_scale); - gst_element_unlink (encodebin->video_scale, encodebin->video_encode); - gst_bin_remove (GST_BIN (element), encodebin->video_scale); - - encodebin->video_scale = NULL; - } else { - gst_element_unlink (encodebin->video_queue, encodebin->video_encode); - } - - gst_pad_unlink (gst_element_get_pad (encodebin->audio_encode, "src"), - encodebin->mux_audio_sinkpad); - gst_pad_unlink (gst_element_get_pad (encodebin->video_encode, "src"), - encodebin->mux_video_sinkpad); - - gst_bin_remove_many (GST_BIN (element), - encodebin->audio_queue, - encodebin->audio_encode, - encodebin->video_queue, - encodebin->video_encode, - encodebin->mux, - NULL); - - encodebin->audio_queue = NULL; - encodebin->audio_encode = NULL; - encodebin->video_queue = NULL; - encodebin->video_encode = NULL; - encodebin->mux = NULL; -#endif - return TRUE; -} - -static gboolean -gst_encode_bin_audsink_set_caps (GstPad * pad, GstCaps * vscaps) -{ - GstEncodeBin *encodebin; - GstStructure *structure; -// const gchar *mimetype; -// const GValue *codec_data; - gint channels, rate; - - encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad)); - - structure = gst_caps_get_structure (vscaps, 0); -// mimetype = gst_structure_get_name (structure); - - /* we want these for all */ - if (!gst_structure_get_int (structure, "channels", &channels) || - !gst_structure_get_int (structure, "rate", &rate)) { - goto refuse_caps; - } - -// codec_data = gst_structure_get_value (structure, "codec_data"); - /* FIXME */ - // g_return_val_if_fail (!strcmp (mimetype, "audio/x-raw-int"), FALSE); - gst_object_unref (encodebin); - return TRUE; - -refuse_caps: - { - GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps); - gst_object_unref (encodebin); - return FALSE; - } -} - -static gboolean -gst_encode_bin_vidsink_set_caps (GstPad * pad, GstCaps * vscaps) -{ - GstEncodeBin *encodebin; - GstStructure *structure; -// const gchar *mimetype; - const GValue *fps; -// const GValue *codec_data; - gint width, height; - - encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad)); - - structure = gst_caps_get_structure (vscaps, 0); -// mimetype = gst_structure_get_name (structure); - - if (!gst_structure_get_int (structure, "width", &width) || - !gst_structure_get_int (structure, "height", &height)) { - goto refuse_caps; - } - -// codec_data = gst_structure_get_value (structure, "codec_data"); - - fps = gst_structure_get_value (structure, "framerate"); - if (fps == NULL) - goto refuse_caps; - - encodebin->fps = gst_value_get_fraction_numerator(fps); - - if(encodebin->high_speed_fps > 0) - { - encodebin->multiple =(encodebin->high_speed_fps)/(encodebin->fps); - } - - { - guint32 format; - - gst_structure_get_fourcc (structure, "format", &format); - - switch (format) { - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - break; - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - break; - } - } -/* FIXME */ -// g_return_val_if_fail (!strcmp (mimetype, "video/x-raw-yuv"), FALSE); - -#if 0 - switch (encodebin->profile) { - case GST_ENCODE_BIN_PROFILE_3GP: - // need_videoscale - break; - case GST_ENCODE_BIN_PROFILE_MP4: - break; - default : - break; - } -#endif - gst_object_unref (encodebin); - return TRUE; - -refuse_caps: - { - GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps); - gst_object_unref (encodebin); - return FALSE; - } -} - -static gboolean gst_encode_bin_imgsink_set_caps (GstPad * pad, GstCaps * vscaps) -{ - GstEncodeBin *encodebin; - GstStructure *structure; -// const gchar *mimetype; -// const GValue *codec_data; - gint width, height; - - encodebin = GST_ENCODE_BIN (gst_pad_get_parent (pad)); - - structure = gst_caps_get_structure (vscaps, 0); -// mimetype = gst_structure_get_name (structure); - - if (!gst_structure_get_int (structure, "width", &width) || - !gst_structure_get_int (structure, "height", &height)) { - goto refuse_caps; - } - -// codec_data = gst_structure_get_value (structure, "codec_data"); - - { - guint32 format; - - gst_structure_get_fourcc (structure, "format", &format); - - switch (format) { - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - break; - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - break; - } - } - gst_object_unref (encodebin); - return TRUE; - -refuse_caps: - { - GST_WARNING_OBJECT (encodebin, "refused caps %" GST_PTR_FORMAT, vscaps); - gst_object_unref (encodebin); - return FALSE; - } - -} - -static gboolean -gst_encode_bin_video_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin) -{ - if (!encodebin) - { - GST_WARNING_OBJECT (encodebin, "encodebin is Null."); - return TRUE; - } - - //Adjusting timestamp of video source - GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time; - - return TRUE; -} - -static gboolean -gst_encode_bin_video_probe_hs(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin) -{ - if (!encodebin) - { - GST_WARNING_OBJECT (encodebin, "encodebin is Null."); - return TRUE; - } - - GST_BUFFER_TIMESTAMP(buffer) *= encodebin->multiple; - return TRUE; -} - -static gboolean -gst_encode_bin_audio_probe(GstPad *pad, GstBuffer *buffer, GstEncodeBin *encodebin) -{ - if (!encodebin) - { - GST_WARNING_OBJECT (encodebin, "encodebin is Null."); - return TRUE; - } - - //Adjusting timestamp of video source - GST_BUFFER_TIMESTAMP(buffer) -= encodebin->total_offset_time; - - return TRUE; -} - -static GstPad* -gst_encode_bin_get_mux_sink_pad(GstElement *mux, GstEncodeBinMuxSinkPad type) -{ - GstElementClass *elemclass = NULL; - GList *walk = NULL; - GstPad *pad = NULL; - - elemclass = GST_ELEMENT_GET_CLASS (mux); - - walk = gst_element_class_get_pad_template_list (elemclass); - - while (walk) { - GstPadTemplate *templ; - - templ = (GstPadTemplate *) walk->data; - if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SINK) { - /* ENHANCE ME: Please add other specific mux's case */ - if (((type == ENCODEBIN_MUX_AUDIO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "audio")) || //audio, audio_%d,... ex)ffmux_3gp - ((type == ENCODEBIN_MUX_VIDEO_SINK) && strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "video")) || //video, video_%d,... ex)ffmux_3gp - strstr(GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "sink") //sink, sink_%d, wavparse_sink, ... ex)oggmux, wavparse - ) { - g_print("PRINT TEMPLATE(%s)\n", GST_PAD_TEMPLATE_NAME_TEMPLATE (templ)); - pad = gst_element_get_request_pad (mux, GST_PAD_TEMPLATE_NAME_TEMPLATE (templ)); - break; - } - } - walk = g_list_next (walk); - } - - return pad; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin"); - -#ifdef ENABLE_NLS - GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, - LOCALEDIR); - bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); -#endif /* ENABLE_NLS */ - - return gst_element_register (plugin, "encodebin", GST_RANK_NONE, - GST_TYPE_ENCODE_BIN); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "encodebin", - "EXT encoder bin", - plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/") diff --git a/mobile/encodebin/src/gstencodebin.h b/mobile/encodebin/src/gstencodebin.h deleted file mode 100644 index 136fc92..0000000 --- a/mobile/encodebin/src/gstencodebin.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * GStreamer encodebin - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_ENCODE_BIN_H__ -#define __GST_ENCODE_BIN_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_CAT_DEFAULT gst_encode_bin_debug - -#define GST_TYPE_ENCODE_BIN_PROFILE (gst_encode_bin_profile_get_type()) -GType gst_encode_bin_profile_get_type (void); - -#define GST_TYPE_ENCODE_BIN (gst_encode_bin_get_type()) -#define GST_ENCODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENCODE_BIN,GstEncodeBin)) -#define GST_ENCODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ENCODE_BIN,GstEncodeBinClass)) -#define GST_IS_ENCODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODE_BIN)) -#define GST_IS_ENCODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ENCODE_BIN)) - -#define GST_ENCODE_BIN_GET_LOCK(encodebin) (((GstEncodeBin*)encodebin)->mutex) -#define GST_ENCODE_BIN_LOCK(encodebin) g_mutex_lock (GST_ENCODE_BIN_GET_LOCK(encodebin)) -#define GST_ENCODE_BIN_UNLOCK(encodebin) g_mutex_unlock (GST_ENCODE_BIN_GET_LOCK(encodebin)) - -/* Signal enable */ -#define GST_ENCODE_BIN_SIGNAL_ENABLE - -typedef struct _GstEncodeBinPad { - GstCollectData *collect; - - gboolean is_video; - gboolean connected; - - gchar *tag; - - gst_riff_strh hdr; -} GstEncodeBinPad; - -typedef struct _GstEncodeBin GstEncodeBin; -typedef struct _GstEncodeBinClass GstEncodeBinClass; - -struct _GstEncodeBin -{ - GstBin bin; /* we extend GstBin */ - - GMutex *mutex; - - /* pads */ - GstPad *srcpad; - GstPad *video_sinkpad; - GstPad *audio_sinkpad; - GstPad *image_sinkpad; - GstPad *mux_audio_sinkpad; - GstPad *mux_video_sinkpad; - - /* sinkpads, video first */ - GSList *sinkpads; - - /* video restricted to 1 pad */ - guint video_pads, audio_pads; - - gint profile; - gint fps; - gint high_speed_fps; - gint multiple; - gchar *venc_name; - gchar *aenc_name; - gchar *ienc_name; - gchar *mux_name; - gchar *vconv_name; - - GstCaps *vcaps; - GstCaps *acaps; - GstCaps *icaps; - - gboolean auto_audio_convert; - gboolean auto_audio_resample; - gboolean auto_color_space; - gboolean block; - gboolean pause; - gboolean use_video_toggle; - gboolean use_venc_queue; - gboolean use_aenc_queue; - - GstElement *audio_queue; - GstElement *video_queue; - GstElement *video_encode_queue; - GstElement *audio_encode_queue; - GstElement *image_queue; - - GstElement *audio_encode; - GstElement *video_encode; - GstElement *image_encode; - - GstElement *vcapsfilter; - GstElement *acapsfilter; - GstElement *icapsfilter; - - GstElement *video_toggle; - GstElement *image_toggle; - GstElement *color_space; - GstElement *audio_conv; - GstElement *audio_sample; - - GstElement *mux; - - /* pause/resume variables */ - GstClockTime paused_time; /* pipeline time when pausing */ - GstClockTime total_offset_time; /* delayed time which is due to pause */ - gulong vsink_probeid; - gulong vsink_hs_probeid; - gulong asink_probeid; - gulong veque_sig_id; - gulong aeque_sig_id; -}; - -struct _GstEncodeBinClass -{ - GstBinClass parent_class; - -#ifdef GST_ENCODE_BIN_SIGNAL_ENABLE - /* signal we fire when stream block/pause function called */ - void (*stream_block) (GstElement * element, gboolean result); - void (*stream_unblock) (GstElement * element, gboolean result); - void (*stream_pause) (GstElement * element, gboolean result); - void (*stream_resume) (GstElement * element, gboolean result); -#endif - -}; - -GType gst_encode_bin_get_type (void); - -G_END_DECLS - - -#endif /* __GST_ENCODE_BIN_H__ */ diff --git a/mobile/evasimagesink/src/Makefile.am b/mobile/evasimagesink/src/Makefile.am deleted file mode 100644 index 8521916..0000000 --- a/mobile/evasimagesink/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Note: plugindir is set in configure - -############################################################################## -# TODO: change libgstevasimagesink.la to something else, e.g. libmysomething.la # -############################################################################## -plugin_LTLIBRARIES = libgstevasimagesink.la - -############################################################################## -# TODO: for the next set of variables, name the prefix if you named the .la, # -# e.g. libmysomething.la => libmysomething_la_SOURCES # -# libmysomething_la_CFLAGS # -# libmysomething_la_LIBADD # -# libmysomething_la_LDFLAGS # -############################################################################## - -# sources used to compile this plug-in -libgstevasimagesink_la_SOURCES = gstevasimagesink.c gstevasimagesink.h - -# compiler and linker flags used to compile this plugin, set in configure.ac -libgstevasimagesink_la_CFLAGS = $(GST_CFLAGS) $(GST_VIDEO_CFLAGS) $(EFL_CFLAGS) $(MMTA_CFLAGS) -libgstevasimagesink_la_LIBADD = $(GST_LIBS) $(GST_VIDEO_LIBS) $(EFL_LIBS) $(MMTA_LIBS) -libgstevasimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstevasimagesink_la_LIBTOOLFLAGS = --tag=disable-static - -# headers we need but don't want installed -noinst_HEADERS = gstevasimagesink.h diff --git a/mobile/evasimagesink/src/gstevasimagesink.c b/mobile/evasimagesink/src/gstevasimagesink.c deleted file mode 100644 index 0647bf6..0000000 --- a/mobile/evasimagesink/src/gstevasimagesink.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * evasimagesink - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * SECTION:element-evasimagesink - * Gstreamer Evas Video Sink - draw video on the given Evas Image Object - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "gstevasimagesink.h" - -#define CAP_WIDTH "width" -#define CAP_HEIGHT "height" - -GST_DEBUG_CATEGORY_STATIC (gst_evas_image_sink_debug); -#define GST_CAT_DEFAULT gst_evas_image_sink_debug - -/* Enumerations */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_EVAS_OBJECT, - PROP_EVAS_OBJECT_SHOW -}; - -enum -{ - UPDATE_FALSE, - UPDATE_TRUE -}; - -#define COLOR_DEPTH 4 -#define GL_X11_ENGINE "gl_x11" -#define DO_RENDER_FROM_FIMC 1 -#define SIZE_FOR_UPDATE_VISIBILITY sizeof(gchar) - -#define EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \ -do \ -{ \ - if (x_evas_image_object) { \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event, x_usr_data); \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, x_usr_data); \ - } \ -}while(0) - -#define EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \ -do \ -{ \ - if (x_evas_image_object) { \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event); \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event); \ - } \ -}while(0) - -GMutex *instance_lock; -guint instance_lock_count; - -static inline gboolean -is_evas_image_object (Evas_Object *obj) -{ - const char *type; - if (!obj) { - return FALSE; - } - type = evas_object_type_get (obj); - if (!type) { - return FALSE; - } - if (strcmp (type, "image") == 0) { - return TRUE; - } - return FALSE; -} - -/* the capabilities of the inputs. - * - * BGRx format - */ -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)); - -GST_BOILERPLATE (GstEvasImageSink, gst_evas_image_sink, GstVideoSink, GST_TYPE_VIDEO_SINK); - -static void gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static gboolean gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps); -static GstFlowReturn gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf); -static gboolean gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event); -static GstStateChangeReturn gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition); -static void evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info); -static void evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info); - -static void -gst_evas_image_sink_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "EvasImageSink", - "VideoSink", - "Video sink element for evas image object", - "Samsung Electronics "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); -} - -static void -gst_evas_image_sink_class_init (GstEvasImageSinkClass *klass) -{ - GObjectClass *gobject_class; - GstBaseSinkClass *gstbasesink_class; - GstVideoSinkClass *gstvideosink_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstbasesink_class = GST_BASE_SINK_CLASS (klass); - gstvideosink_class = GST_VIDEO_SINK_CLASS (klass); - gstelement_class = (GstElementClass *) klass; - - gobject_class->set_property = gst_evas_image_sink_set_property; - gobject_class->get_property = gst_evas_image_sink_get_property; - - g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT, - g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT_SHOW, - g_param_spec_boolean ("visible", "Show Evas Object", "When disabled, evas object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gstvideosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evas_image_sink_show_frame); - gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evas_image_sink_set_caps); - gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evas_image_sink_event); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_evas_image_sink_change_state); -} - -static void -gst_evas_image_sink_fini (gpointer data, GObject *obj) -{ - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = GST_EVASIMAGESINK (obj); - if (!esink) { - return; - } - if (esink->oldbuf) { - gst_buffer_unref (esink->oldbuf); - } - - if (esink->eo) { - evas_object_image_data_set(esink->eo, NULL); - } - - g_mutex_lock (instance_lock); - instance_lock_count--; - g_mutex_unlock (instance_lock); - if (instance_lock_count == 0) { - g_mutex_free (instance_lock); - instance_lock = NULL; - } - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_image_sink_cb_pipe (void *data, void *buffer, unsigned int nbyte) -{ - GstBuffer *buf; - GstEvasImageSink *esink = data; - void *img_data; - - GST_DEBUG ("[ENTER]"); - - if (!esink || !esink->eo) { - return; - } - if (nbyte == SIZE_FOR_UPDATE_VISIBILITY) { - if(!esink->object_show) { - evas_object_hide(esink->eo); - GST_INFO ("object hide.."); - } else { - evas_object_show(esink->eo); - GST_INFO ("object show.."); - } - GST_DEBUG ("[LEAVE]"); - return; - } - if (!buffer || nbyte != sizeof (GstBuffer *)) { - return; - } - - memcpy (&buf, buffer, sizeof (GstBuffer *)); - if (!buf) { - GST_ERROR ("There is no buffer"); - return; - } - if (esink->present_data_addr == -1) { - /* if present_data_addr is -1, we don't use this member variable */ - } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { - GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); - return; - } - - MMTA_ACUM_ITEM_BEGIN("eavsimagesink _cb_pipe total", FALSE); - - if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) { - evas_object_image_size_set (esink->eo, esink->w, esink->h); - GST_DEBUG("evas_object_image_size_set(), width(%d),height(%d)",esink->w,esink->h); - esink->is_evas_object_size_set = TRUE; - } - if (esink->gl_zerocopy) { - img_data = evas_object_image_data_get (esink->eo, EINA_TRUE); - if (!img_data || !GST_BUFFER_DATA(buf)) { - GST_WARNING ("Cannot get image data from evas object or cannot get gstbuffer data"); - evas_object_image_data_set(esink->eo, img_data); - } else { - GST_DEBUG ("img_data(%x), GST_BUFFER_DATA(buf):%x, esink->w(%d),esink->h(%d), esink->eo(%x)",img_data,GST_BUFFER_DATA(buf),esink->w,esink->h,esink->eo); - __ta__("evasimagesink memcpy in _cb_pipe", memcpy (img_data, GST_BUFFER_DATA (buf), esink->w * esink->h * COLOR_DEPTH);); - evas_object_image_pixels_dirty_set (esink->eo, 1); - evas_object_image_data_set(esink->eo, img_data); - } - gst_buffer_unref (buf); - } else { - GST_DEBUG ("GST_BUFFER_DATA(buf):%x, esink->eo(%x)",GST_BUFFER_DATA(buf),esink->eo); - evas_object_image_data_set (esink->eo, GST_BUFFER_DATA (buf)); - evas_object_image_pixels_dirty_set (esink->eo, 1); - if (esink->oldbuf) { - gst_buffer_unref(esink->oldbuf); - } - esink->oldbuf = buf; - } - - MMTA_ACUM_ITEM_END("eavsimagesink _cb_pipe total", FALSE); - - GST_DEBUG ("[LEAVE]"); -} - -static void -gst_evas_image_sink_init (GstEvasImageSink *esink, GstEvasImageSinkClass *gclass) -{ - GST_DEBUG ("[ENTER]"); - - esink->eo = NULL; - esink->epipe = NULL; - esink->object_show = FALSE; - esink->update_visibility = UPDATE_FALSE; - esink->gl_zerocopy = FALSE; - esink->is_evas_object_size_set = FALSE; - esink->present_data_addr = -1; - - if(!instance_lock) { - instance_lock = g_mutex_new(); - } - g_mutex_lock (instance_lock); - instance_lock_count++; - g_mutex_unlock (instance_lock); - - g_object_weak_ref (G_OBJECT (esink), gst_evas_image_sink_fini, NULL); - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = data; - if (!esink) { - return; - } - - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - if (esink->oldbuf) { - gst_buffer_unref (esink->oldbuf); - esink->oldbuf = NULL; - } - - if (esink->eo) { - evas_object_image_data_set(esink->eo, NULL); - esink->eo = NULL; - } - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - int w = 0; - int h = 0; - - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = data; - if (!esink) { - return; - } - - evas_object_geometry_get(esink->eo, NULL, NULL, &w, &h); - if (!w || !h) { - GST_WARNING ("evas object size (w:%d,h:%d) was not set",w,h); - } else { - evas_object_image_fill_set(esink->eo, 0, 0, w, h); - GST_DEBUG ("evas object fill set (w:%d,h:%d)",w,h); - } - - GST_DEBUG ("[LEAVE]"); -} - -static int -evas_image_sink_get_size_from_caps (GstCaps *caps, int *w, int *h) -{ - gboolean r; - int width, height; - GstStructure *s; - - if (!caps || !w || !h) { - return -1; - } - s = gst_caps_get_structure (caps, 0); - if (!s) { - return -1; - } - - r = gst_structure_get_int (s, CAP_WIDTH, &width); - if (r == FALSE) { - return -1; - } - - r = gst_structure_get_int (s, CAP_HEIGHT, &height); - if (r == FALSE) { - return -1; - } - - *w = width; - *h = height; - return 0; -} - -static gboolean -is_zerocopy_supported (Evas *e) -{ - Eina_List *engines, *l; - int cur_id; - int id; - char *name; - - if (!e) { - return FALSE; - } - - engines = evas_render_method_list (); - if (!engines) { - return FALSE; - } - - cur_id = evas_output_method_get (e); - - EINA_LIST_FOREACH (engines, l, name) { - id = evas_render_method_lookup (name); - if (name && id == cur_id) { - if (!strcmp (name, GL_X11_ENGINE)) { - return TRUE; - } - break; - } - } - return FALSE; -} - -static int -evas_image_sink_event_parse_data (GstEvasImageSink *esink, GstEvent *event) -{ - const GstStructure *st; - guint st_data_addr = 0; - gint st_data_width = 0; - gint st_data_height = 0; - - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (esink != NULL, FALSE); - - if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM_OOB) { - GST_WARNING ("it's not a custom downstream oob event"); - return -1; - } - st = gst_event_get_structure (event); - if (st == NULL || !gst_structure_has_name (st, "GstStructureForCustomEvent")) { - GST_WARNING ("structure in a given event is not proper"); - return -1; - } - if (!gst_structure_get_uint (st, "data-addr", &st_data_addr)) { - GST_WARNING ("parsing data-addr failed"); - return -1; - } - esink->present_data_addr = st_data_addr; - - return 0; -} - -static gboolean -gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (sink); - GstMessage *msg; - gchar *str; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - GST_DEBUG ("GST_EVENT_FLUSH_START"); - break; - case GST_EVENT_FLUSH_STOP: - GST_DEBUG ("GST_EVENT_FLUSH_STOP"); - break; - case GST_EVENT_EOS: - GST_DEBUG ("GST_EVENT_EOS"); - break; - case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: - if(!evas_image_sink_event_parse_data(esink, event)) { - GST_DEBUG ("GST_EVENT_CUSTOM_DOWNSTREAM_OOB, present_data_addr:%x",esink->present_data_addr); - } else { - GST_ERROR ("evas_image_sink_event_parse_data() failed"); - } - break; - default: - break; - } - if (GST_BASE_SINK_CLASS (parent_class)->event) { - return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); - } else { - return TRUE; - } -} - -static GstStateChangeReturn -gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret_state = GST_STATE_CHANGE_SUCCESS; - GstEvasImageSink *esink = NULL; - esink = GST_EVASIMAGESINK(element); - int ret = 0; - - if(!esink) { - GST_ERROR("can not get evasimagesink from element"); - return GST_STATE_CHANGE_FAILURE; - } - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - GST_INFO ("*** STATE_CHANGE_NULL_TO_READY ***"); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_INFO ("*** STATE_CHANGE_READY_TO_PAUSED ***"); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - GST_INFO ("*** STATE_CHANGE_PAUSED_TO_PLAYING ***"); - break; - default: - break; - } - - ret_state = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - GST_INFO ("*** STATE_CHANGE_PLAYING_TO_PAUSED ***"); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_INFO ("*** STATE_CHANGE_PAUSED_TO_READY ***"); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - GST_INFO ("*** STATE_CHANGE_READY_TO_NULL ***"); - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - if (esink->epipe) { - ecore_pipe_del (esink->epipe); - esink->epipe = NULL; - } - break; - default: - break; - } - - return ret_state; -} - -static void -gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (object); - Evas_Object *eo; - - g_mutex_lock (instance_lock); - - switch (prop_id) { - case PROP_EVAS_OBJECT: - eo = g_value_get_pointer (value); - if (is_evas_image_object (eo)) { - if (eo != esink->eo) { - Eina_Bool r; - - /* delete evas object callbacks registrated on a previous evas image object */ - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - esink->eo = eo; - /* add evas object callbacks on a new evas image object */ - EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo, esink); - - esink->gl_zerocopy = is_zerocopy_supported (evas_object_evas_get (eo)); - if (esink->gl_zerocopy) { - evas_object_image_content_hint_set (esink->eo, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - GST_DEBUG("Enable gl zerocopy"); - } - GST_DEBUG("Evas Image Object(%x) is set",esink->eo); - esink->is_evas_object_size_set = FALSE; - if (!esink->epipe) { - esink->epipe = ecore_pipe_add (evas_image_sink_cb_pipe, esink); - if (!esink->epipe) { - GST_ERROR ("ecore-pipe create failed"); - break; - } - } - } - } else { - GST_ERROR ("Cannot set evas-object property: value is not an evas image object"); - } - break; - - case PROP_EVAS_OBJECT_SHOW: - { - Eina_Bool r; - esink->object_show = g_value_get_boolean (value); - if( !is_evas_image_object(esink->eo) ) { - GST_WARNING ("Cannot apply visible(show-object) property: cannot get an evas object\n"); - break; - } - esink->update_visibility = UPDATE_TRUE; - if (!esink->epipe) { - esink->epipe = ecore_pipe_add (evas_image_sink_cb_pipe, esink); - if (!esink->epipe) { - GST_ERROR ("ecore-pipe create failed"); - break; - } - } - r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); - if (r == EINA_FALSE) { - GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n"); - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - g_mutex_unlock (instance_lock); -} - -static void -gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (object); - - switch (prop_id) { - case PROP_EVAS_OBJECT: - g_value_set_pointer (value, esink->eo); - break; - case PROP_EVAS_OBJECT_SHOW: - g_value_set_boolean (value, esink->object_show); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps) -{ - int r; - int w, h; - GstEvasImageSink *esink = GST_EVASIMAGESINK (base_sink); - - esink->is_evas_object_size_set = FALSE; - r = evas_image_sink_get_size_from_caps (caps, &w, &h); - if (!r) { - esink->w = w; - esink->h = h; - GST_DEBUG ("set size w(%d), h(%d)", w, h); - } - return TRUE; -} - -static GstFlowReturn -gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (video_sink); - Eina_Bool r; - - g_mutex_lock (instance_lock); - if (esink->present_data_addr == -1) { - /* if present_data_addr is -1, we don't use this member variable */ - } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { - GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); - g_mutex_unlock (instance_lock); - return GST_FLOW_OK; - } - if (!esink->epipe) { - esink->epipe = ecore_pipe_add (evas_image_sink_cb_pipe, esink); - if (!esink->epipe) { - GST_ERROR ("ecore-pipe create failed"); - g_mutex_unlock (instance_lock); - return GST_FLOW_ERROR; - } - } - - gst_buffer_ref (buf); - __ta__("evasimagesink ecore_pipe_write", r = ecore_pipe_write (esink->epipe, &buf, sizeof (GstBuffer *));); - if (r == EINA_FALSE) { - gst_buffer_unref (buf); - } - GST_DEBUG ("ecore_pipe_write() was called with GST_BUFFER_DATA(buf):%x", GST_BUFFER_DATA(buf)); - - g_mutex_unlock (instance_lock); - return GST_FLOW_OK; -} - -static gboolean -evas_image_sink_init (GstPlugin *evasimagesink) -{ - GST_DEBUG_CATEGORY_INIT (gst_evas_image_sink_debug, "evasimagesink", 0, "Evas image object based videosink"); - - return gst_element_register (evasimagesink, "evasimagesink", GST_RANK_NONE, GST_TYPE_EVASIMAGESINK); -} - -#ifndef PACKAGE -#define PACKAGE "gstevasimagesink-plugin-package" -#endif - -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "evasimagesink", - "Evas image object based videosink", - evas_image_sink_init, - VERSION, - "LGPL", - "Samsung Electronics Co", - "http://www.samsung.com/" -) diff --git a/mobile/evasimagesink/src/gstevasimagesink.h b/mobile/evasimagesink/src/gstevasimagesink.h deleted file mode 100644 index 09c8102..0000000 --- a/mobile/evasimagesink/src/gstevasimagesink.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * evasimagesink - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_EVASIMAGESINK_H__ -#define __GST_EVASIMAGESINK_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -/* #defines don't like whitespacey bits */ -#define GST_TYPE_EVASIMAGESINK \ - (gst_evas_image_sink_get_type()) -#define GST_EVASIMAGESINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EVASIMAGESINK,GstEvasImageSink)) -#define GST_EVASIMAGESINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EVASIMAGESINK,GstEvasImageSinkClass)) -#define GST_IS_EVASIMAGESINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EVASIMAGESINK)) -#define GST_IS_EVASIMAGESINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EVASIMAGESINK)) - -typedef struct _GstEvasImageSink GstEvasImageSink; -typedef struct _GstEvasImageSinkClass GstEvasImageSinkClass; - -struct _GstEvasImageSink -{ - GstVideoSink element; - - Evas_Object *eo; - Ecore_Pipe *epipe; - Evas_Coord w; - Evas_Coord h; - gboolean object_show; - gchar update_visibility; - gboolean gl_zerocopy; - - GstBuffer *oldbuf; - - gboolean is_evas_object_size_set; - guint present_data_addr; -}; - -struct _GstEvasImageSinkClass -{ - GstVideoSinkClass parent_class; -}; - -GType gst_evas_image_sink_get_type (void); - -G_END_DECLS - -#endif /* __GST_EVASIMAGESINK_H__ */ diff --git a/mobile/evaspixmapsink/xv_types.h b/mobile/evaspixmapsink/xv_types.h deleted file mode 100644 index 8266e34..0000000 --- a/mobile/evaspixmapsink/xv_types.h +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************************************** - -xserver-xorg-video-exynos - -Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: Boram Park - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* */ -/* File name : xv_types.h */ -/* Author : Boram Park (boram1288.park@samsung.com) */ -/* Protocol Version : 1.0.1 (Dec 16th 2009) */ -/* This file is for describing Xv APIs' buffer encoding method. */ -/* */ - -#ifndef __XV_TYPE_H__ -#define __XV_TYPE_H__ - -#define XV_DATA_HEADER 0xDEADCD01 -#define XV_DATA_VERSION 0x00010001 - -/* Return Values */ -#define XV_OK 0 -#define XV_HEADER_ERROR -1 -#define XV_VERSION_MISMATCH -2 - -/* Video Mode */ -#define DISPLAY_MODE_DEFAULT 0 -#define DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_FULL_SCREEN 1 -#define DISPLAY_MODE_PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN 2 - -/* Color space range */ -#define CSC_RANGE_NARROW 0 -#define CSC_RANGE_WIDE 1 - -/* Buffer Type */ -#define XV_BUF_TYPE_DMABUF 0 -#define XV_BUF_TYPE_LEGACY 1 -#define XV_BUF_PLANE_NUM 3 - -/* Data structure for XvPutImage / XvShmPutImage */ -typedef struct -{ - unsigned int _header; /* for internal use only */ - unsigned int _version; /* for internal use only */ - - unsigned int YBuf; - unsigned int CbBuf; - unsigned int CrBuf; - unsigned int BufType; - unsigned int dmabuf_fd[XV_BUF_PLANE_NUM]; - unsigned int gem_handle[XV_BUF_PLANE_NUM]; - void *bo[XV_BUF_PLANE_NUM]; -} XV_DATA, * XV_DATA_PTR; - -static void -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_INIT_DATA (XV_DATA_PTR data) -{ - data->_header = XV_DATA_HEADER; - data->_version = XV_DATA_VERSION; -} - -static int -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_VALIDATE_DATA (XV_DATA_PTR data) -{ - if (data->_header != XV_DATA_HEADER) - return XV_HEADER_ERROR; - if (data->_version != XV_DATA_VERSION) - return XV_VERSION_MISMATCH; - return XV_OK; -} - -#endif diff --git a/mobile/gst-autogen.sh b/mobile/gst-autogen.sh deleted file mode 100755 index 7b31212..0000000 --- a/mobile/gst-autogen.sh +++ /dev/null @@ -1,308 +0,0 @@ -# a silly hack that generates autoregen.sh but it's handy -# Remove the old autoregen.sh first to create a new file, -# as the current one may be being read by the shell executing -# this script. -if [ -f "autoregen.sh" ]; then - rm autoregen.sh -fi -echo "#!/bin/sh" > autoregen.sh -echo "./autogen.sh $@ \$@" >> autoregen.sh -chmod +x autoregen.sh - -# helper functions for autogen.sh - -debug () -# print out a debug message if DEBUG is a defined variable -{ - if test ! -z "$DEBUG" - then - echo "DEBUG: $1" - fi -} - -version_check () -# check the version of a package -# first argument : package name (executable) -# second argument : optional path where to look for it instead -# third argument : source download url -# rest of arguments : major, minor, micro version -# all consecutive ones : suggestions for binaries to use -# (if not specified in second argument) -{ - PACKAGE=$1 - PKG_PATH=$2 - URL=$3 - MAJOR=$4 - MINOR=$5 - MICRO=$6 - - # for backwards compatibility, we let PKG_PATH=PACKAGE when PKG_PATH null - if test -z "$PKG_PATH"; then PKG_PATH=$PACKAGE; fi - debug "major $MAJOR minor $MINOR micro $MICRO" - VERSION=$MAJOR - if test ! -z "$MINOR"; then VERSION=$VERSION.$MINOR; else MINOR=0; fi - if test ! -z "$MICRO"; then VERSION=$VERSION.$MICRO; else MICRO=0; fi - - debug "major $MAJOR minor $MINOR micro $MICRO" - - for SUGGESTION in $PKG_PATH; do - COMMAND="$SUGGESTION" - - # don't check if asked not to - test -z "$NOCHECK" && { - echo -n " checking for $COMMAND >= $VERSION ... " - } || { - # we set a var with the same name as the package, but stripped of - # unwanted chars - VAR=`echo $PACKAGE | sed 's/-//g'` - debug "setting $VAR" - eval $VAR="$COMMAND" - return 0 - } - - debug "checking version with $COMMAND" - ($COMMAND --version) < /dev/null > /dev/null 2>&1 || - { - echo "not found." - continue - } - # strip everything that's not a digit, then use cut to get the first field - pkg_version=`$COMMAND --version|head -n 1|sed 's/^.*)[^0-9]*//'|cut -d' ' -f1` - debug "pkg_version $pkg_version" - # remove any non-digit characters from the version numbers to permit numeric - # comparison - pkg_major=`echo $pkg_version | cut -d. -f1 | sed s/[a-zA-Z\-].*//g` - pkg_minor=`echo $pkg_version | cut -d. -f2 | sed s/[a-zA-Z\-].*//g` - pkg_micro=`echo $pkg_version | cut -d. -f3 | sed s/[a-zA-Z\-].*//g` - test -z "$pkg_major" && pkg_major=0 - test -z "$pkg_minor" && pkg_minor=0 - test -z "$pkg_micro" && pkg_micro=0 - debug "found major $pkg_major minor $pkg_minor micro $pkg_micro" - - #start checking the version - debug "version check" - - # reset check - WRONG= - - if [ ! "$pkg_major" -gt "$MAJOR" ]; then - debug "major: $pkg_major <= $MAJOR" - if [ "$pkg_major" -lt "$MAJOR" ]; then - debug "major: $pkg_major < $MAJOR" - WRONG=1 - elif [ ! "$pkg_minor" -gt "$MINOR" ]; then - debug "minor: $pkg_minor <= $MINOR" - if [ "$pkg_minor" -lt "$MINOR" ]; then - debug "minor: $pkg_minor < $MINOR" - WRONG=1 - elif [ "$pkg_micro" -lt "$MICRO" ]; then - debug "micro: $pkg_micro < $MICRO" - WRONG=1 - fi - fi - fi - - if test ! -z "$WRONG"; then - echo "found $pkg_version, not ok !" - continue - else - echo "found $pkg_version, ok." - # we set a var with the same name as the package, but stripped of - # unwanted chars - VAR=`echo $PACKAGE | sed 's/-//g'` - debug "setting $VAR" - eval $VAR="$COMMAND" - return 0 - fi - done - - echo "not found !" - echo "You must have $PACKAGE installed to compile $package." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at $URL" - return 1; -} - -aclocal_check () -{ - # normally aclocal is part of automake - # so we expect it to be in the same place as automake - # so if a different automake is supplied, we need to adapt as well - # so how's about replacing automake with aclocal in the set var, - # and saving that in $aclocal ? - # note, this will fail if the actual automake isn't called automake* - # or if part of the path before it contains it - if [ -z "$automake" ]; then - echo "Error: no automake variable set !" - return 1 - else - aclocal=`echo $automake | sed s/automake/aclocal/` - debug "aclocal: $aclocal" - if [ "$aclocal" != "aclocal" ]; - then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal" - fi - if [ ! -x `which $aclocal` ]; then - echo "Error: cannot execute $aclocal !" - return 1 - fi - fi -} - -autoheader_check () -{ - # same here - autoheader is part of autoconf - # use the same voodoo - if [ -z "$autoconf" ]; then - echo "Error: no autoconf variable set !" - return 1 - else - autoheader=`echo $autoconf | sed s/autoconf/autoheader/` - debug "autoheader: $autoheader" - if [ "$autoheader" != "autoheader" ]; - then - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader" - fi - if [ ! -x `which $autoheader` ]; then - echo "Error: cannot execute $autoheader !" - return 1 - fi - fi - -} -autoconf_2_52d_check () -{ - # autoconf 2.52d has a weird issue involving a yes:no error - # so don't allow it's use - test -z "$NOCHECK" && { - ac_version=`$autoconf --version|head -n 1|sed 's/^[a-zA-Z\.\ ()]*//;s/ .*$//'` - if test "$ac_version" = "2.52d"; then - echo "autoconf 2.52d has an issue with our current build." - echo "We don't know who's to blame however. So until we do, get a" - echo "regular version. RPM's of a working version are on the gstreamer site." - exit 1 - fi - } - return 0 -} - -die_check () -{ - # call with $DIE - # if set to 1, we need to print something helpful then die - DIE=$1 - if test "x$DIE" = "x1"; - then - echo - echo "- Please get the right tools before proceeding." - echo "- Alternatively, if you're sure we're wrong, run with --nocheck." - exit 1 - fi -} - -autogen_options () -{ - if test "x$1" = "x"; then - return 0 - fi - - while test "x$1" != "x" ; do - optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - case "$1" in - --noconfigure) - NOCONFIGURE=defined - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --noconfigure" - echo "+ configure run disabled" - shift - ;; - --nocheck) - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --nocheck" - NOCHECK=defined - echo "+ autotools version check disabled" - shift - ;; - --debug) - DEBUG=defined - AUTOGEN_EXT_OPT="$AUTOGEN_EXT_OPT --debug" - echo "+ debug output enabled" - shift - ;; - --prefix=*) - CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$optarg" - echo "+ passing --prefix=$optarg to configure" - shift - ;; - --prefix) - shift - echo "DEBUG: $1" - CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT --prefix=$1" - echo "+ passing --prefix=$1 to configure" - shift - ;; - - -h|--help) - echo "autogen.sh (autogen options) -- (configure options)" - echo "autogen.sh help options: " - echo " --noconfigure don't run the configure script" - echo " --nocheck don't do version checks" - echo " --debug debug the autogen process" - echo " --prefix will be passed on to configure" - echo - echo " --with-autoconf PATH use autoconf in PATH" - echo " --with-automake PATH use automake in PATH" - echo - echo "to pass options to configure, put them as arguments after -- " - exit 1 - ;; - --with-automake=*) - AUTOMAKE=$optarg - echo "+ using alternate automake in $optarg" - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-automake=$AUTOMAKE" - shift - ;; - --with-autoconf=*) - AUTOCONF=$optarg - echo "+ using alternate autoconf in $optarg" - CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoconf=$AUTOCONF" - shift - ;; - --disable*|--enable*|--with*) - echo "+ passing option $1 to configure" - CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $1" - shift - ;; - --) shift ; break ;; - *) echo "- ignoring unknown autogen.sh argument $1"; shift ;; - esac - done - - for arg do CONFIGURE_EXT_OPT="$CONFIGURE_EXT_OPT $arg"; done - if test ! -z "$CONFIGURE_EXT_OPT" - then - echo "+ options passed to configure: $CONFIGURE_EXT_OPT" - fi -} - -toplevel_check () -{ - srcfile=$1 - test -f $srcfile || { - echo "You must run this script in the top-level $package directory" - exit 1 - } -} - - -tool_run () -{ - tool=$1 - options=$2 - run_if_fail=$3 - echo "+ running $tool $options..." - $tool $options || { - echo - echo $tool failed - eval $run_if_fail - exit 1 - } -} diff --git a/mobile/gst-plugins-ext0.10.manifest b/mobile/gst-plugins-ext0.10.manifest deleted file mode 100755 index a76fdba..0000000 --- a/mobile/gst-plugins-ext0.10.manifest +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/mobile/m4/Makefile.am b/mobile/m4/Makefile.am deleted file mode 100644 index 5fa63aa..0000000 --- a/mobile/m4/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = as-version.m4 as-compiler-flag.m4 diff --git a/mobile/m4/as-compiler-flag.m4 b/mobile/m4/as-compiler-flag.m4 deleted file mode 100755 index 4134857..0000000 --- a/mobile/m4/as-compiler-flag.m4 +++ /dev/null @@ -1,25 +0,0 @@ -dnl as-compiler-flag.m4 0.0.1 -dnl autostars m4 macro for detection of compiler flags -dnl -dnl ds@schleef.org - -AC_DEFUN([AS_COMPILER_FLAG], -[ - AC_MSG_CHECKING([to see if compiler understands $1]) - - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - $2 - true - else - $3 - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - diff --git a/mobile/m4/as-version.m4 b/mobile/m4/as-version.m4 deleted file mode 100755 index 249102b..0000000 --- a/mobile/m4/as-version.m4 +++ /dev/null @@ -1,66 +0,0 @@ -dnl as-version.m4 0.1.0 - -dnl autostars m4 macro for versioning - -dnl Thomas Vander Stichele - -dnl $Id: as-version.m4,v 1.2 2004-09-17 22:18:03 leroutier Exp $ - -dnl AS_VERSION(PACKAGE, PREFIX, MAJOR, MINOR, MICRO, NANO, -dnl ACTION-IF-NO-NANO, [ACTION-IF-NANO]) - -dnl example -dnl AS_VERSION(gstreamer, GST_VERSION, 0, 3, 2,) -dnl for a 0.3.2 release version - -dnl this macro -dnl - defines [$PREFIX]_MAJOR, MINOR and MICRO -dnl - if NANO is empty, then we're in release mode, else in cvs/dev mode -dnl - defines [$PREFIX], VERSION, and [$PREFIX]_RELEASE -dnl - executes the relevant action -dnl - AC_SUBST's PACKAGE, VERSION, [$PREFIX] and [$PREFIX]_RELEASE -dnl as well as the little ones -dnl - doesn't call AM_INIT_AUTOMAKE anymore because it prevents -dnl maintainer mode from running ok -dnl -dnl don't forget to put #undef [$2] and [$2]_RELEASE in acconfig.h -dnl if you use acconfig.h - -AC_DEFUN([AS_VERSION], -[ - PACKAGE=[$1] - [$2]_MAJOR=[$3] - [$2]_MINOR=[$4] - [$2]_MICRO=[$5] - NANO=[$6] - [$2]_NANO=$NANO - if test "x$NANO" = "x" || test "x$NANO" = "x0"; - then - AC_MSG_NOTICE(configuring [$1] for release) - VERSION=[$3].[$4].[$5] - [$2]_RELEASE=1 - dnl execute action - ifelse([$7], , :, [$7]) - else - AC_MSG_NOTICE(configuring [$1] for development with nano $NANO) - VERSION=[$3].[$4].[$5].$NANO - [$2]_RELEASE=0.`date +%Y%m%d.%H%M%S` - dnl execute action - ifelse([$8], , :, [$8]) - fi - - [$2]=$VERSION - AC_DEFINE_UNQUOTED([$2], "$[$2]", [Define the version]) - AC_SUBST([$2]) - AC_DEFINE_UNQUOTED([$2]_RELEASE, "$[$2]_RELEASE", [Define the release version]) - AC_SUBST([$2]_RELEASE) - - AC_SUBST([$2]_MAJOR) - AC_SUBST([$2]_MINOR) - AC_SUBST([$2]_MICRO) - AC_SUBST([$2]_NANO) - AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define the package name]) - AC_SUBST(PACKAGE) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Define the version]) - AC_SUBST(VERSION) -]) diff --git a/mobile/pdpushsrc/src/gstpdpushsrc.c b/mobile/pdpushsrc/src/gstpdpushsrc.c deleted file mode 100644 index fb56643..0000000 --- a/mobile/pdpushsrc/src/gstpdpushsrc.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - * pdpushsrc - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Seungbae Shin - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include "gstpdpushsrc.h" -#include -#include -#include -#ifdef G_OS_WIN32 -#include /* lseek, open, close, read */ -/* On win32, stat* default to 32 bit; we need the 64-bit - * variants, so explicitly define it that way. */ -#define stat __stat64 -#define fstat _fstat64 -#undef lseek -#define lseek _lseeki64 -#undef off_t -#define off_t guint64 -/* Prevent stat.h from defining the stat* functions as - * _stat*, since we're explicitly overriding that */ -#undef _INC_STAT_INL -#endif -#include -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#include -#include - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -/* FIXME we should be using glib for this */ -#ifndef S_ISREG -#define S_ISREG(mode) ((mode)&_S_IFREG) -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode)&_S_IFDIR) -#endif -#ifndef S_ISSOCK -#define S_ISSOCK(x) (0) -#endif -#ifndef O_BINARY -#define O_BINARY (0) -#endif - -static int -file_open (const gchar * filename, int flags, int mode) -{ - return open (filename, flags, mode); -} - -GST_DEBUG_CATEGORY_STATIC (gst_pd_pushsrc_debug); -#define GST_CAT_DEFAULT gst_pd_pushsrc_debug - -/* FileSrc signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -#define DEFAULT_BLOCKSIZE 4*1024 - -enum -{ - ARG_0, - ARG_LOCATION, - ARG_EOS, -}; - -static void gst_pd_pushsrc_finalize (GObject * object); - -static void gst_pd_pushsrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_pd_pushsrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); - -static gboolean gst_pd_pushsrc_start (GstBaseSrc * basesrc); -static gboolean gst_pd_pushsrc_stop (GstBaseSrc * basesrc); - -static gboolean gst_pd_pushsrc_is_seekable (GstBaseSrc * src); -static gboolean gst_pd_pushsrc_get_size (GstBaseSrc * src, guint64 * size); -static gboolean gst_pd_pushsrc_query (GstBaseSrc * src, GstQuery * query); -static void gst_pd_pushsrc_uri_handler_init (gpointer g_iface, gpointer iface_data); -static GstFlowReturn gst_pd_pushsrc_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer); -static gboolean gst_pd_pushsrc_checkgetrange (GstPad * pad); - -static void -_do_init (GType pd_pushsrc_type) -{ - static const GInterfaceInfo urihandler_info = { - gst_pd_pushsrc_uri_handler_init, - NULL, - NULL - }; - - g_type_add_interface_static (pd_pushsrc_type, GST_TYPE_URI_HANDLER, &urihandler_info); - GST_DEBUG_CATEGORY_INIT (gst_pd_pushsrc_debug, "pdpushsrc", 0, "PD push source element"); -} - -GST_BOILERPLATE_FULL (GstPDPushSrc, gst_pd_pushsrc, GstBaseSrc, GST_TYPE_BASE_SRC, _do_init); - -static void -gst_pd_pushsrc_base_init (gpointer g_class) -{ - GST_LOG ("IN"); - - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details_simple (gstelement_class, - "PD push source", - "Source/File", - "Read from arbitrary point in a file", - "Naveen Ch "); - gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate)); - - GST_LOG ("OUT"); -} - -static void -gst_pd_pushsrc_class_init (GstPDPushSrcClass * klass) -{ - GST_LOG ("IN"); - - GObjectClass *gobject_class; - GstBaseSrcClass *gstbasesrc_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstbasesrc_class = GST_BASE_SRC_CLASS (klass); - - gobject_class->set_property = gst_pd_pushsrc_set_property; - gobject_class->get_property = gst_pd_pushsrc_get_property; - gobject_class->finalize = gst_pd_pushsrc_finalize; - - g_object_class_install_property (gobject_class, ARG_LOCATION, - g_param_spec_string ("location", "File Location", - "Location of the file to read", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | - GST_PARAM_MUTABLE_READY)); - - g_object_class_install_property (gobject_class, ARG_EOS, - g_param_spec_boolean ("eos", - "EOS recived on downloading pipeline", - "download of clip is over", - 0, - G_PARAM_READWRITE)); - - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_stop); - gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_is_seekable); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_get_size); - gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_query); - gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_create); - - if (sizeof (off_t) < 8) { - GST_LOG ("No large file support, sizeof (off_t) = %" G_GSIZE_FORMAT "!", - sizeof (off_t)); - } - - GST_LOG ("OUT"); - -} - -static void -gst_pd_pushsrc_init (GstPDPushSrc * src, GstPDPushSrcClass * g_class) -{ - GST_LOG ("IN"); - GstBaseSrc *basesrc = GST_BASE_SRC (src); - - src->filename = NULL; - src->fd = 0; - src->uri = NULL; - src->is_regular = FALSE; - src->is_eos = FALSE; - - gst_pad_set_checkgetrange_function (basesrc->srcpad, GST_DEBUG_FUNCPTR (gst_pd_pushsrc_checkgetrange)); - - GST_LOG ("OUT"); -} - -static void -gst_pd_pushsrc_finalize (GObject * object) -{ - GST_LOG ("IN"); - - GstPDPushSrc *src; - - src = GST_PD_PUSHSRC (object); - - g_free (src->filename); - g_free (src->uri); - - G_OBJECT_CLASS (parent_class)->finalize (object); - - GST_LOG ("OUT"); -} - -static gboolean -gst_pd_pushsrc_set_location (GstPDPushSrc * src, const gchar * location) -{ - GST_LOG ("IN"); - - GstState state; - - /* the element must be stopped in order to do this */ - GST_OBJECT_LOCK (src); - state = GST_STATE (src); - if (state != GST_STATE_READY && state != GST_STATE_NULL) - goto wrong_state; - GST_OBJECT_UNLOCK (src); - - g_free (src->filename); - g_free (src->uri); - - /* clear the filename if we get a NULL (is that possible?) */ - if (location == NULL) { - src->filename = NULL; - src->uri = NULL; - } else { - /* we store the filename as received by the application. On Windows this - * should be UTF8 */ - src->filename = g_strdup (location); - src->uri = gst_filename_to_uri (location, NULL); - GST_INFO ("filename : %s", src->filename); - GST_INFO ("uri : %s", src->uri); - } - g_object_notify (G_OBJECT (src), "location"); - gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri); - - GST_LOG ("OUT"); - - return TRUE; - - /* ERROR */ -wrong_state: - { - g_warning ("Changing the `location' property on filesrc when a file is " - "open is not supported."); - GST_OBJECT_UNLOCK (src); - GST_LOG ("OUT :: wrong_state"); - return FALSE; - } -} - -static void -gst_pd_pushsrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GST_LOG ("IN"); - - GstPDPushSrc *src; - - g_return_if_fail (GST_IS_PD_PUSHSRC (object)); - - src = GST_PD_PUSHSRC (object); - - switch (prop_id) { - case ARG_LOCATION: - gst_pd_pushsrc_set_location (src, g_value_get_string (value)); - break; - case ARG_EOS: - src->is_eos = g_value_get_boolean (value); - g_print ("\n\n\nis_eos is becoming %d\n\n\n", src->is_eos); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - GST_LOG ("OUT"); -} - -static void -gst_pd_pushsrc_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GST_LOG ("IN"); - GstPDPushSrc *src; - - g_return_if_fail (GST_IS_PD_PUSHSRC (object)); - - src = GST_PD_PUSHSRC (object); - - switch (prop_id) { - case ARG_LOCATION: - g_value_set_string (value, src->filename); - break; - case ARG_EOS: - g_value_set_boolean (value, src->is_eos); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - GST_LOG ("OUT"); -} - -static GstFlowReturn -gst_pd_pushsrc_create_read (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) -{ - GST_LOG ("IN"); - - int ret; - GstBuffer *buf = NULL; - struct stat stat_results; - GstPDPushSrc *src; - - src = GST_PD_PUSHSRC_CAST (basesrc); - - GST_LOG_OBJECT (src, "read position = %"G_GUINT64_FORMAT ", offset = %"G_GUINT64_FORMAT", length = %d", - src->read_position, offset, length); - - memset (&stat_results, 0, sizeof (stat_results)); - - if (fstat (src->fd, &stat_results) < 0) - goto could_not_stat; - - GST_LOG_OBJECT (src, "offset + length = %"G_GUINT64_FORMAT " and filesize = %"G_GUINT64_FORMAT, offset + length, stat_results.st_size); - - while ((offset + length) > stat_results.st_size) - { - fd_set fds; - int ret; - struct timeval timeout = {0,}; - guint64 avail_size = 0; - - if (src->is_eos) - goto eos; - - FD_ZERO (&fds); - FD_SET (src->fd, &fds); - - timeout.tv_sec = 0; - timeout.tv_usec = ((basesrc->blocksize * 8 * 1000) / 64000); // wait_time = (blocksize * 8) / (min downloadratei.e. 64Kbps) - - GST_DEBUG_OBJECT (src, "Going to wait for %ld msec", timeout.tv_usec); - - ret = select (src->fd + 1, &fds, NULL, NULL, &timeout); - if (-1 == ret) - { - GST_ERROR_OBJECT (src, "ERROR in select () : reason - %s...\n", strerror(errno)); - return GST_FLOW_ERROR; - } - else if (0 == ret) - { - GST_WARNING_OBJECT (src, "select () timeout happened..."); - } - else - { - memset (&stat_results, 0, sizeof (stat_results)); - - if (fstat (src->fd, &stat_results) < 0) - goto could_not_stat; - - avail_size = stat_results.st_size; - - GST_LOG_OBJECT (src, "Available data size in file = %"G_GUINT64_FORMAT, avail_size); - - if ((offset + length) > avail_size) - { - GST_LOG_OBJECT (src, "Enough data is NOT available..."); - } - else - { - GST_LOG_OBJECT (src, "Enough data is available..."); - } - } - } - - if (G_UNLIKELY (src->read_position != offset)) { - off_t res; - - res = lseek (src->fd, offset, SEEK_SET); - if (G_UNLIKELY (res < 0 || res != offset)) - goto seek_failed; - src->read_position = offset; - } - - buf = gst_buffer_try_new_and_alloc (length); - if (G_UNLIKELY (buf == NULL && length > 0)) { - GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length); - return GST_FLOW_ERROR; - } - - /* No need to read anything if length is 0 */ - if (length > 0) { - GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", - length, offset); - ret = read (src->fd, GST_BUFFER_DATA (buf), length); - if (G_UNLIKELY (ret < 0)) - goto could_not_read; - - /* seekable regular files should have given us what we expected */ - if (G_UNLIKELY ((guint) ret < length && src->seekable)) - goto unexpected_eos; - - /* other files should eos if they read 0 and more was requested */ - if (G_UNLIKELY (ret == 0 && length > 0)) - goto eos; - - length = ret; - GST_BUFFER_SIZE (buf) = length; - GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_OFFSET_END (buf) = offset + length; - - src->read_position += length; - } - - *buffer = buf; - GST_LOG ("OUT"); - - return GST_FLOW_OK; - - /* ERROR */ -seek_failed: - { - GST_ERROR_OBJECT (src, "Seek failed..."); - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - return GST_FLOW_ERROR; - } -could_not_stat: - { - GST_ERROR_OBJECT (src, "Could not stat"); - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - return GST_FLOW_ERROR; - } -could_not_read: - { - GST_ERROR_OBJECT (src, "Could not read..."); - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - if (buf) - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -unexpected_eos: - { - GST_ERROR_OBJECT (src, "Unexpected EOS occured..."); - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), ("unexpected end of file.")); - if (buf) - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -eos: - { - GST_ERROR_OBJECT (src, "non-regular file hits EOS"); - if (buf) - gst_buffer_unref (buf); - return GST_FLOW_UNEXPECTED; - } -} - -static GstFlowReturn -gst_pd_pushsrc_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer) -{ - GST_LOG ("IN"); - - GstPDPushSrc *pdsrc; - GstFlowReturn ret; - - pdsrc = GST_PD_PUSHSRC_CAST (basesrc); - ret = gst_pd_pushsrc_create_read (basesrc, offset, length, buffer); - GST_LOG ("OUT"); - - return ret; -} - -static gboolean -gst_pd_pushsrc_query (GstBaseSrc * basesrc, GstQuery * query) -{ - GST_LOG ("IN"); - - gboolean ret = FALSE; - GstPDPushSrc *src = GST_PD_PUSHSRC (basesrc); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_URI: - gst_query_set_uri (query, src->uri); - ret = TRUE; - break; - default: - ret = FALSE; - break; - } - - if (!ret) - ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); - GST_LOG ("OUT"); - - return ret; -} - -static gboolean -gst_pd_pushsrc_checkgetrange (GstPad * pad) -{ - GST_LOG ("IN"); - - GST_LOG ("OUT"); - - return FALSE; -} - -static gboolean -gst_pd_pushsrc_is_seekable (GstBaseSrc * basesrc) -{ - GST_LOG ("IN"); - - GstPDPushSrc *src = GST_PD_PUSHSRC (basesrc); - - GST_DEBUG_OBJECT (src, "seekable = %d", src->seekable); - GST_LOG ("OUT"); - - return src->seekable; - -} - -static gboolean -gst_pd_pushsrc_get_size (GstBaseSrc * basesrc, guint64 * size) -{ - GST_LOG ("IN"); - - struct stat stat_results; - GstPDPushSrc *src; - - src = GST_PD_PUSHSRC (basesrc); - - if (!src->seekable) { - /* If it isn't seekable, we won't know the length (but fstat will still - * succeed, and wrongly say our length is zero. */ - return FALSE; - } - - if (fstat (src->fd, &stat_results) < 0) - goto could_not_stat; - - //*size = stat_results.st_size; - /* Naveen : Intentionally, doing this because we dont know the file size...because its keep on increasing in PD case */ - *size = G_MAXUINT64; - - GST_DEBUG ("size of the file = %"G_GUINT64_FORMAT, *size); - - GST_LOG ("OUT"); - - return TRUE; - - /* ERROR */ -could_not_stat: - { - GST_ERROR_OBJECT (src, "Could not stat"); - return FALSE; - } -} - -/* open the file, necessary to go to READY state */ -static gboolean -gst_pd_pushsrc_start (GstBaseSrc * basesrc) -{ - GST_LOG ("IN"); - - GstPDPushSrc *src = GST_PD_PUSHSRC (basesrc); - struct stat stat_results; - - if (src->filename == NULL || src->filename[0] == '\0') - goto no_filename; - - GST_INFO_OBJECT (src, "opening file %s", src->filename); - - /* open the file */ - src->fd = file_open (src->filename, O_RDONLY | O_BINARY, 0); - - if (src->fd < 0) - goto open_failed; - - /* check if it is a regular file, otherwise bail out */ - if (fstat (src->fd, &stat_results) < 0) - goto no_stat; - - if (S_ISDIR (stat_results.st_mode)) - goto was_directory; - - if (S_ISSOCK (stat_results.st_mode)) - goto was_socket; - - src->read_position = 0; - - /* record if it's a regular (hence seekable and lengthable) file */ - if (S_ISREG (stat_results.st_mode)) - src->is_regular = TRUE; - - { - /* we need to check if the underlying file is seekable. */ - off_t res = lseek (src->fd, 0, SEEK_END); - - if (res < 0) { - GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek " - "failed: %s", g_strerror (errno)); - src->seekable = FALSE; - } else { - src->seekable = TRUE; - } - lseek (src->fd, 0, SEEK_SET); - } - - /* We can only really do seeking on regular files - for other file types, we - * don't know their length, so seeking isn't useful/meaningful */ - src->seekable = src->seekable && src->is_regular; - GST_LOG ("OUT"); - - return TRUE; - - /* ERROR */ -no_filename: - { - GST_ERROR_OBJECT (src, "No file name specified for reading..."); - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, - ("No file name specified for reading."), (NULL)); - return FALSE; - } -open_failed: - { - switch (errno) { - case ENOENT: - GST_ERROR_OBJECT (src, "File could not be found"); - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), - ("No such file \"\"")); - break; - default: - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("Could not open file for reading."), - GST_ERROR_SYSTEM); - break; - } - return FALSE; - } -no_stat: - { - GST_ERROR_OBJECT (src, "Could not get stat info..."); - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("Could not get info on \"\"."), (NULL)); - close (src->fd); - return FALSE; - } -was_directory: - { - GST_ERROR_OBJECT (src, "Is a Directory"); - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("\"\" is a directory."), (NULL)); - close (src->fd); - return FALSE; - } -was_socket: - { - GST_ERROR_OBJECT (src, "Is a Socket"); - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("File \"\" is a socket."), (NULL)); - close (src->fd); - return FALSE; - } -} - -/* unmap and close the file */ -static gboolean -gst_pd_pushsrc_stop (GstBaseSrc * basesrc) -{ - GST_LOG ("IN"); - - GstPDPushSrc *src = GST_PD_PUSHSRC (basesrc); - - /* close the file */ - close (src->fd); - - /* zero out a lot of our state */ - src->fd = 0; - src->is_regular = FALSE; - - GST_LOG ("OUT"); - - return TRUE; -} - -/*** GSTURIHANDLER INTERFACE *************************************************/ - -static GstURIType -gst_pd_pushsrc_uri_get_type (void) -{ - GST_LOG ("IN"); - GST_LOG ("OUT"); - - return GST_URI_SRC; -} - -static gchar ** -gst_pd_pushsrc_uri_get_protocols (void) -{ - GST_LOG ("IN"); - static gchar *protocols[] = { (char *) "file", NULL }; - GST_LOG ("OUT"); - - return protocols; -} - -static const gchar * -gst_pd_pushsrc_uri_get_uri (GstURIHandler * handler) -{ - GST_LOG ("IN"); - GstPDPushSrc *src = GST_PD_PUSHSRC (handler); - GST_LOG ("OUT"); - - return src->uri; -} - -static gboolean -gst_pd_pushsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) -{ - GST_LOG ("IN"); - - gchar *location, *hostname = NULL; - gboolean ret = FALSE; - GstPDPushSrc *src = GST_PD_PUSHSRC (handler); - GError *error = NULL; - - if (strcmp (uri, "file://") == 0) { - /* Special case for "file://" as this is used by some applications - * to test with gst_element_make_from_uri if there's an element - * that supports the URI protocol. */ - gst_pd_pushsrc_set_location (src, NULL); - return TRUE; - } - - location = g_filename_from_uri (uri, &hostname, &error); - - if (!location || error) { - if (error) { - GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc: %s", uri, - error->message); - g_error_free (error); - } else { - GST_WARNING_OBJECT (src, "Invalid URI '%s' for filesrc", uri); - } - goto beach; - } - - if ((hostname) && (strcmp (hostname, "localhost"))) { - /* Only 'localhost' is permitted */ - GST_WARNING_OBJECT (src, "Invalid hostname '%s' for filesrc", hostname); - goto beach; - } -#ifdef G_OS_WIN32 - /* Unfortunately, g_filename_from_uri() doesn't handle some UNC paths - * correctly on windows, it leaves them with an extra backslash - * at the start if they're of the mozilla-style file://///host/path/file - * form. Correct this. - */ - if (location[0] == '\\' && location[1] == '\\' && location[2] == '\\') - g_memmove (location, location + 1, strlen (location + 1) + 1); -#endif - - ret = gst_pd_pushsrc_set_location (src, location); - - GST_LOG ("OUT"); - -beach: - if (location) - g_free (location); - if (hostname) - g_free (hostname); - - return ret; -} - -static void -gst_pd_pushsrc_uri_handler_init (gpointer g_iface, gpointer iface_data) -{ - GST_LOG ("IN"); - GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; - - iface->get_type = gst_pd_pushsrc_uri_get_type; - iface->get_protocols = gst_pd_pushsrc_uri_get_protocols; - iface->get_uri = gst_pd_pushsrc_uri_get_uri; - iface->set_uri = gst_pd_pushsrc_uri_set_uri; - GST_LOG ("OUT"); -} - -static gboolean -gst_pd_pushsrc_plugin_init (GstPlugin *plugin) -{ - if (!gst_element_register (plugin, "pdpushsrc", GST_RANK_NONE, gst_pd_pushsrc_get_type())) - { - return FALSE; - } - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "pdpushsrc", - "PD push source", - gst_pd_pushsrc_plugin_init, - VERSION, - "LGPL", - "Samsung Electronics Co", - "http://www.samsung.com") - - diff --git a/mobile/pdpushsrc/src/gstpdpushsrc.h b/mobile/pdpushsrc/src/gstpdpushsrc.h deleted file mode 100755 index 651efdb..0000000 --- a/mobile/pdpushsrc/src/gstpdpushsrc.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * pdpushsrc - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Seungbae Shin - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_PD_PUSHSRC_H__ -#define __GST_PD_PUSHSRC_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_PD_PUSHSRC (gst_pd_pushsrc_get_type()) -#define GST_PD_PUSHSRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PD_PUSHSRC,GstPDPushSrc)) -#define GST_PD_PUSHSRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PD_PUSHSRC,GstPDPushSrcClass)) -#define GST_IS_PD_PUSHSRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PD_PUSHSRC)) -#define GST_IS_PD_PUSHSRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PD_PUSHSRC)) -#define GST_PD_PUSHSRC_CAST(obj) ((GstPDPushSrc*) obj) - -typedef struct _GstPDPushSrc GstPDPushSrc; -typedef struct _GstPDPushSrcClass GstPDPushSrcClass; - -/** - * GstFileSrc: - * - * Opaque #GstPDPushSrc structure. - */ -struct _GstPDPushSrc { - GstBaseSrc element; - GstPad *srcpad; - - gchar *filename; /* filename */ - gchar *uri; /* caching the URI */ - gint fd; /* open file descriptor */ - guint64 read_position; /* position of fd */ - - gboolean seekable; /* whether the file is seekable */ - gboolean is_regular; /* whether it's a (symlink to a) regular file */ - - gboolean is_eos; - -}; - -struct _GstPDPushSrcClass { - GstBaseSrcClass parent_class; -}; - -GType gst_pd_pushsrc_get_type (void); - -G_END_DECLS - -#endif /* __GST_FILE_SRC_H__ */ diff --git a/mobile/toggle/src/gsttoggle.c b/mobile/toggle/src/gsttoggle.c deleted file mode 100755 index 1f8d831..0000000 --- a/mobile/toggle/src/gsttoggle.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * toggle - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "gsttoggle.h" -#include - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (gst_mytoggle_debug); -#define GST_CAT_DEFAULT gst_mytoggle_debug - -enum -{ - LAST_SIGNAL -}; - - -#define DEFAULT_BLOCK_DATA FALSE - -enum -{ - PROP_0, - PROP_BLOCK_DATA - -}; - - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_mytoggle_debug, "toggle", 0, "toggle element"); - -GST_BOILERPLATE_FULL (GstMytoggle, gst_mytoggle, GstBaseTransform, - GST_TYPE_BASE_TRANSFORM, _do_init); - -static void gst_mytoggle_finalize (GObject * object); -static void gst_mytoggle_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_mytoggle_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static gboolean gst_mytoggle_event (GstBaseTransform * trans, GstEvent * event); -static GstFlowReturn gst_mytoggle_transform_ip (GstBaseTransform * trans, - GstBuffer * buf); -static gboolean gst_mytoggle_start (GstBaseTransform * trans); -static gboolean gst_mytoggle_stop (GstBaseTransform * trans); - -static void -gst_mytoggle_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details_simple (gstelement_class, - "toggle", - "Generic", - "Pass data without modification", "Rahul Mittal "); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); -} - -static void -gst_mytoggle_finalize (GObject * object) -{ - GstMytoggle *mytoggle; - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_mytoggle_class_init (GstMytoggleClass * klass) -{ - GObjectClass *gobject_class; - GstBaseTransformClass *gstbasetrans_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass); - - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_mytoggle_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_mytoggle_get_property); - - g_object_class_install_property (gobject_class, - PROP_BLOCK_DATA, g_param_spec_boolean ("block_data", - "Data Block", - "Data Block", - DEFAULT_BLOCK_DATA, G_PARAM_READWRITE)); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_mytoggle_finalize); - - gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_mytoggle_event); - gstbasetrans_class->transform_ip = - GST_DEBUG_FUNCPTR (gst_mytoggle_transform_ip); - gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_mytoggle_start); - gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_mytoggle_stop); -} - -static void -gst_mytoggle_init (GstMytoggle * mytoggle, GstMytoggleClass * g_class) -{ - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (mytoggle), TRUE); - - mytoggle->block_data = DEFAULT_BLOCK_DATA; - -} - - -static gboolean -gst_mytoggle_event (GstBaseTransform * trans, GstEvent * event) -{ - return TRUE; -} - -static GstFlowReturn -gst_mytoggle_transform_ip (GstBaseTransform * trans, GstBuffer * buf) -{ - GstMytoggle *mytoggle = GST_MYTOGGLE (trans); - - if (mytoggle->block_data ==TRUE) - return GST_BASE_TRANSFORM_FLOW_DROPPED; - - return GST_FLOW_OK; -} - -static void -gst_mytoggle_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstMytoggle *mytoggle; - - mytoggle = GST_MYTOGGLE (object); - - switch (prop_id) { - - case PROP_BLOCK_DATA: - mytoggle->block_data = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_mytoggle_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstMytoggle *mytoggle; - - mytoggle = GST_MYTOGGLE (object); - - switch (prop_id) { - case PROP_BLOCK_DATA: - g_value_set_boolean (value, mytoggle->block_data); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -gst_mytoggle_start (GstBaseTransform * trans) -{ - return TRUE; -} - -static gboolean -gst_mytoggle_stop (GstBaseTransform * trans) -{ - return TRUE; -} - - -static gboolean plugin_init(GstPlugin *plugin) -{ - - GST_DEBUG_CATEGORY_INIT (gst_mytoggle_debug, "toggle",0, "toggle"); - return gst_element_register (plugin, "toggle", GST_RANK_NONE, GST_TYPE_MYTOGGLE); -} -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "toggle", - "Base transform plugin template", - plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com/") - - diff --git a/mobile/toggle/src/gsttoggle.h b/mobile/toggle/src/gsttoggle.h deleted file mode 100755 index 0090a6b..0000000 --- a/mobile/toggle/src/gsttoggle.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * toggle - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_MYTOGGLE_H__ -#define __GST_MYTOGGLE_H__ - - -#include -#include - -G_BEGIN_DECLS - - -#define GST_TYPE_MYTOGGLE \ - (gst_mytoggle_get_type()) -#define GST_MYTOGGLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MYTOGGLE,GstMytoggle)) -#define GST_MYTOGGLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MYTOGGLE,GstMytoggleClass)) -#define GST_IS_MYTOGGLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MYTOGGLE)) -#define GST_IS_MYTOGGLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MYTOGGLE)) - -typedef struct _GstMytoggle GstMytoggle; -typedef struct _GstMytoggleClass GstMytoggleClass; - -struct _GstMytoggle { - GstBaseTransform element; - gboolean block_data; -}; - -struct _GstMytoggleClass { - GstBaseTransformClass parent_class; -}; - -GType gst_mytoggle_get_type(void); - -G_END_DECLS - -#endif /* __GST_MYTOGGLE_H__ */ diff --git a/mobile/xvimagesrc/Makefile.am b/mobile/xvimagesrc/Makefile.am deleted file mode 100644 index af437a6..0000000 --- a/mobile/xvimagesrc/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/mobile/xvimagesrc/src/Makefile.am b/mobile/xvimagesrc/src/Makefile.am deleted file mode 100644 index 7fb9ec7..0000000 --- a/mobile/xvimagesrc/src/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# plugindir is set in configure - -############################################################################## -# change libgstplugin.la to something more suitable, e.g. libmysomething.la # -############################################################################## -plugin_LTLIBRARIES = libgstxvimagesrc.la - -############################################################################## -# for the next set of variables, rename the prefix if you renamed the .la, # -# e.g. libgstplugin_la_SOURCES => libmysomething_la_SOURCES # -# libgstplugin_la_CFLAGS => libmysomething_la_CFLAGS # -# libgstplugin_la_LIBADD => libmysomething_la_LIBADD # -# libgstplugin_la_LDFLAGS => libmysomething_la_LDFLAGS # -############################################################################## - -# sources used to compile this plug-in -libgstxvimagesrc_la_SOURCES = gstxvimagesrc.c - -# flags used to compile this plugin -# add other _CFLAGS and _LIBS as needed -libgstxvimagesrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(TBM_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS) $(XV_CFLAGS) $(XDAMAGE_CFLAGS) $(DRM_DEVEL_CFLAGS) $(DRM_CFLAGS) -libgstxvimagesrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(TBM_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(XV_LIBS) $(XDAMAGE_LIBS) $(DRM_LIBS) $(DRM_DEVEL_LIBS) -libgstxvimagesrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -# headers we need but don't want installed -noinst_HEADERS = gstxvimagesrc.h diff --git a/mobile/xvimagesrc/src/gstxvimagesrc.c b/mobile/xvimagesrc/src/gstxvimagesrc.c deleted file mode 100644 index 21688bf..0000000 --- a/mobile/xvimagesrc/src/gstxvimagesrc.c +++ /dev/null @@ -1,1527 +0,0 @@ -/* - * xvimagesrc - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Hyunil Park - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -/** -* SECTION:element-xvimagesrc -* -* xvimagesrc captures frame buffer which includes the application data along with video layer data -* from the XServer and pushes the data to the downstream element. -* -* -* -* Example launch line -* |[ -* gst-launch xvimagesrc ! "video/x-raw-yuv, width=720, height=1280, framerate=(fraction)30/1, format=(fourcc)ST12" ! fakesink -* ]| captures the frame buffer from the XServer and send the buffers to a fakesink. -* -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstxvimagesrc.h" - -/* headers for drm */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GST_DEBUG_CATEGORY_STATIC (xvimagesrc_debug); -#define GST_CAT_DEFAULT xvimagesrc_debug - - -#define GST_XV_IMAGE_SRC_CAPS \ - "video/x-raw-rgb, " \ - "bpp = (int) 32, " \ - "depth = (int) 24, " \ - "endianness = (int) BIG_ENDIAN, " \ - "red_mask = (int) 0xFF000000, " \ - "green_mask = (int) 0x00FF0000, " \ - "blue_mask = (int) 0x0000FF00, " \ - "width = (int) [ 16, 4096 ], " \ - "height = (int) [ 16, 4096 ], " \ - "framerate = (fraction) [0/1, 2147483647/1];" \ - "video/x-raw-yuv," \ - "format = (fourcc) { SN12, ST12 }, " \ - "width = (int) [ 1, 4096 ], " \ - "height = (int) [ 1, 4096 ], " \ - "framerate = (fraction) [0/1, 2147483647/1];" \ - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS(GST_XV_IMAGE_SRC_CAPS) -); - -enum -{ - PROP_0 -}; - -enum -{ - VIDEO_TYPE_VIDEO_WITH_UI, - VIDEO_TYPE_VIDEO_ONLY, -}; - -enum -{ - SIGNAL_VIDEO_WITH_UI = 0, - SIGNAL_VIDEO_ONLY, - SIGNAL_LAST -}; -#define GEM_NAME_MAX 10 - -#define SCMN_CS_YUV420 1 /* Y:U:V 4:2:0 */ -#define SCMN_CS_I420 SCMN_CS_YUV420 /* Y:U:V */ -#define SCMN_CS_NV12 6 -#define SCMN_CS_NV12_T64X32 11 /* 64x32 Tiled NV12 type */ -#define SCMN_CS_UYVY 100 -#define SCMN_CS_YUYV 101 -#define SCMN_CS_YUY2 SCMN_CS_YUYV - -/* max channel count *********************************************************/ -#define SCMN_IMGB_MAX_PLANE (4) - -/* image buffer definition *************************************************** - - +------------------------------------------+ --- - | | ^ - | a[], p[] | | - | +---------------------------+ --- | | - | | | ^ | | - | |<---------- w[] ---------->| | | | - | | | | | | - | | | | - | | | h[] | e[] - | | | | - | | | | | | - | | | | | | - | | | v | | - | +---------------------------+ --- | | - | | v - +------------------------------------------+ --- - - |<----------------- s[] ------------------>| -*/ - -typedef struct -{ - /* width of each image plane */ - int w[SCMN_IMGB_MAX_PLANE]; - /* height of each image plane */ - int h[SCMN_IMGB_MAX_PLANE]; - /* stride of each image plane */ - int s[SCMN_IMGB_MAX_PLANE]; - /* elevation of each image plane */ - int e[SCMN_IMGB_MAX_PLANE]; - /* user space address of each image plane */ - void *a[SCMN_IMGB_MAX_PLANE]; - /* physical address of each image plane, if needs */ - void *p[SCMN_IMGB_MAX_PLANE]; - /* color space type of image */ - int cs; - /* left postion, if needs */ - int x; - /* top position, if needs */ - int y; - /* to align memory */ - int __dummy2; - /* arbitrary data */ - int data[16]; - /* dmabuf fd */ - gint32 fd[SCMN_IMGB_MAX_PLANE]; - /* flag for buffer share */ - int buf_share_method; - /* Y plane size in case of ST12 */ - int y_size; - /* UV plane size in case of ST12 */ - int uv_size; - - /* Tizen buffer object of each image plane */ - void *bo[SCMN_IMGB_MAX_PLANE]; - - /* JPEG data */ - void *jpeg_data; - /* JPEG size */ - int jpeg_size; - - /* tzmem buffer */ - int tz_enable; -} SCMN_IMGB; - -typedef struct -{ - void *address[GEM_NAME_MAX]; - int buffer_size[GEM_NAME_MAX]; - int name[GEM_NAME_MAX]; - gint32 fd[GEM_NAME_MAX]; - gint32 handle[GEM_NAME_MAX]; -} GEM_MMAP; - -typedef enum { - BUF_SHARE_METHOD_PADDR = 0, - BUF_SHARE_METHOD_FD -} buf_share_method_t; - -typedef struct GstXvImageOutBuffer GstXvImageOutBuffer; - -struct GstXvImageOutBuffer { - GstBuffer buffer; - int fd_name; - int YBuf; - GstXVImageSrc * xvimagesrc; -}; - - - -#define DEFAULT_USER_AGENT "GStreamer xvimagesrc " - -static guint gst_xv_image_src_signals[SIGNAL_LAST] = { 0 }; - -#define BASE_TIME 33000 -#define LIMIT_TIME -33000 -//#define COUNT_FRAMES -#ifdef COUNT_FRAMES -gchar old_time[10] = {0, }; -#endif -static gboolean error_caught = FALSE; - -#define HANDLE_OUTBUF_UNREF - -#ifdef HANDLE_OUTBUF_UNREF -#define BUFFER_COND_WAIT_TIMEOUT 1000000 -#define GST_TYPE_GST_XV_IMAGE_OUT_BUFFER (gst_xv_image_out_buffer_get_type()) -#define GST_IS_GST_XV_IMAGE_OUT_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_GST_XV_IMAGE_OUT_BUFFER)) -static GstBufferClass *gst_xv_image_out_buffer_parent_class = NULL; -static void gst_xv_image_out_buffer_class_init(gpointer g_class, gpointer class_data); -static void gst_xv_image_out_buffer_finalize(GstXvImageOutBuffer *buffer); -static GstXvImageOutBuffer *gst_xv_image_out_buffer_new(GstXVImageSrc *src); -#endif -static GstStateChangeReturn gst_xv_image_src_change_state (GstElement * element, GstStateChange transition); -static void gst_xv_image_src_finalize (GObject * gobject); - -static void gst_xv_image_src_set_property (GObject *object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_xv_image_src_get_property (GObject *object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstFlowReturn gst_xv_image_src_create (GstPushSrc * psrc, GstBuffer ** outbuf); -static gboolean gst_xv_image_src_start (GstBaseSrc * bsrc); -static gboolean gst_xv_image_src_stop (GstBaseSrc * bsrc); -static gboolean gst_xv_image_src_get_size (GstBaseSrc * bsrc, guint64 * size); -static gboolean gst_xv_image_src_is_seekable (GstBaseSrc * bsrc); -static gboolean gst_xv_image_src_query (GstBaseSrc * bsrc, GstQuery * query); -static gboolean gst_xv_image_src_unlock (GstBaseSrc * bsrc); -static gboolean gst_xv_image_src_unlock_stop (GstBaseSrc * bsrc); -static gboolean gst_xv_image_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps); - -static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap); -static int port_get (GstXVImageSrc * src, unsigned int id); -static void pixmap_update (GstXVImageSrc * src,Display *dpy, tbm_bufmgr bufmgr, Pixmap pixmap, - int x, int y, int width, int height); -static Pixmap pixmap_create (GstXVImageSrc * src, Display *dpy, int width, int height); - -static void* gst_xv_image_src_update_thread (void * asrc); -static gboolean xvimagesrc_thread_start(GstXVImageSrc *src); -static void drm_init(GstXVImageSrc *src); -static void drm_finalize(GstXVImageSrc *src); -static gint32 drm_convert_gem_to_fd(int * gemname_cnt, int drm_fd, unsigned int name, void * data, void **virtual_address); -static void gst_xv_get_image_sleep(void *asrc, long duration); - -static void -_do_init (GType type) -{ - GST_DEBUG_CATEGORY_INIT (xvimagesrc_debug, "xvimagesrc", 0, "Xv image src"); -} - -GST_BOILERPLATE_FULL (GstXVImageSrc, gst_xv_image_src, GstPushSrc, GST_TYPE_PUSH_SRC, _do_init); - -#ifdef HANDLE_OUTBUF_UNREF -static void gst_xv_image_out_buffer_class_init(gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class); - gst_xv_image_out_buffer_parent_class = g_type_class_peek_parent(g_class); - mini_object_class->finalize = (GstMiniObjectFinalizeFunction)gst_xv_image_out_buffer_finalize; -} - -static GType gst_xv_image_out_buffer_get_type(void) -{ - static GType _gst_gst_xv_image_out_buffer_type; - - if (G_UNLIKELY(_gst_gst_xv_image_out_buffer_type == 0)) { - static const GTypeInfo gst_xv_image_out_buffer_info = { - sizeof (GstBufferClass), - NULL, - NULL, - gst_xv_image_out_buffer_class_init, - NULL, - NULL, - sizeof (GstXvImageOutBuffer), - 0, - NULL, - NULL - }; - _gst_gst_xv_image_out_buffer_type = g_type_register_static(GST_TYPE_BUFFER, - "GstOmxOutBuffer", - &gst_xv_image_out_buffer_info, 0); - } - return _gst_gst_xv_image_out_buffer_type; -} -#ifdef DEBUG_BUFFER - int value[5] ={0}; - static int value_count =0; -#endif - -static GstStateChangeReturn -gst_xv_image_src_change_state (GstElement * element, GstStateChange transition) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (element); - - GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE; - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - src->pause_cond_var = FALSE; - g_cond_signal(src->pause_cond); - break; - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - src->pause_cond_var = TRUE; - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - src->thread_return = TRUE; - g_cond_signal(src->pause_cond); - g_cond_signal(src->queue_cond); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default : - break; - } - result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return result; -} - - -static void gst_xv_image_out_buffer_finalize(GstXvImageOutBuffer *buffer) -{ - Atom atom_retbuf = 0; - g_mutex_lock (buffer->xvimagesrc->dpy_lock); - atom_retbuf = XInternAtom (buffer->xvimagesrc->dpy, "_USER_WM_PORT_ATTRIBUTE_RETURN_BUFFER", False); - XvSetPortAttribute (buffer->xvimagesrc->dpy, buffer->xvimagesrc->p, atom_retbuf, buffer->YBuf); //data->YBuf is gemname, refer to drm_convert_gem_to_fd - g_mutex_unlock (buffer->xvimagesrc->dpy_lock); - g_cond_signal(buffer->xvimagesrc->buffer_cond); - GST_INFO(" xvimagesrc = %p, gem_name =%d, fd_name =%d", buffer->xvimagesrc, buffer->YBuf, buffer->fd_name); -#ifdef DEBUG_BUFFER - int i = 0; - for(i=0 ; i<5; i++){ - if (value[i] == buffer->YBuf) { - value[i]=0; - GST_ERROR("value[%d]=%d", i, value[i]); - } - } -#endif - return; -} - - -static GstXvImageOutBuffer *gst_xv_image_out_buffer_new(GstXVImageSrc *src) -{ - GstXvImageOutBuffer *newbuf = NULL; - GST_LOG("gst_omx_out_buffer_new"); - - newbuf = (GstXvImageOutBuffer *)gst_mini_object_new(GST_TYPE_GST_XV_IMAGE_OUT_BUFFER); - if(!newbuf) - { - GST_ERROR("gst_omx_out_buffer_new out of memory"); - return NULL; - } - GST_LOG("creating buffer : %p", newbuf); - newbuf->xvimagesrc = gst_object_ref(GST_OBJECT(src)); - newbuf->fd_name = 0; - newbuf->YBuf =0; - return newbuf; -} -#endif - -static void -gst_xv_image_src_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&srctemplate)); - gst_element_class_set_details_simple (element_class, "XServer Display FB video source", - "Source/video", - "Receive frame buffer data from XServer and passes to next element", - ""); -} - -static void -gst_xv_image_src_class_init (GstXVImageSrcClass * klass) -{ - GObjectClass *gobject_class; - GstBaseSrcClass *gstbasesrc_class; - GstPushSrcClass *gstpushsrc_class; - GstElementClass *gstelement_class; - gobject_class = G_OBJECT_CLASS (klass); - gstelement_class = (GstElementClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; - gstpushsrc_class = (GstPushSrcClass *) klass; - gobject_class->set_property = gst_xv_image_src_set_property; - gobject_class->get_property = gst_xv_image_src_get_property; - gobject_class->finalize = gst_xv_image_src_finalize; - - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_xv_image_src_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_xv_image_src_stop); - gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_xv_image_src_unlock); - gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_xv_image_src_unlock_stop); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_xv_image_src_get_size); - gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_xv_image_src_is_seekable); - gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_xv_image_src_query); - gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_xv_image_src_setcaps); - gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_xv_image_src_create); - gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_xv_image_src_change_state); - - gst_xv_image_src_signals[SIGNAL_VIDEO_WITH_UI] = - g_signal_new ("video-with-ui", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstXVImageSrcClass, video_with_ui), NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - - gst_xv_image_src_signals[SIGNAL_VIDEO_ONLY] = - g_signal_new ("video-only", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstXVImageSrcClass, video_only), NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - -} - -static gboolean gst_xv_image_src_get_frame_size(int fourcc, int width, int height, unsigned int *outsize) -{ - switch (fourcc) { -/* case GST_MAKE_FOURCC('I','4','2','0'): // V4L2_PIX_FMT_YUV420 - *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); - *outsize += 2 * ((GST_ROUND_UP_8 (width) / 2) * (GST_ROUND_UP_2 (height) / 2)); - break;*/ - case GST_MAKE_FOURCC('S','N','1','2'): // V4L2_PIX_FMT_NV12 non-linear - GST_INFO("SN12"); - case GST_MAKE_FOURCC('S','T','1','2'): // V4L2_PIX_FMT_NV12 tiled non-linear - GST_INFO("ST12"); - *outsize = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height); - *outsize += (GST_ROUND_UP_4 (width) * height) / 2; - break; - case GST_MAKE_FOURCC('R','G','B','4'): - /* jpeg size can't be calculated here. */ - *outsize = width * height * 4; - break; - default: - /* unkown format!! */ - *outsize = 0; - return FALSE; - } - return TRUE; -} - -static gboolean -gst_xv_image_src_parse_caps (const GstCaps * caps, guint32 *fourcc, - gint * width, gint * height, gint * rate_numerator, gint * rate_denominator, unsigned int *framesize) -{ - const GstStructure *structure; - GstPadLinkReturn ret = TRUE; - const GValue *framerate; - const char *media_type = NULL; - GST_DEBUG ("parsing caps"); - if (gst_caps_get_size (caps) < 1) return FALSE; - GST_INFO("xvimagesrc src caps:%"GST_PTR_FORMAT, caps); - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", width); - if(!ret) { - GST_ERROR ("xvimagesrc width not specified in caps"); - goto error; - } - ret = gst_structure_get_int (structure, "height", height); - if(!ret) { - GST_ERROR ("xvimagesrc height not specified in caps"); - goto error; - } - media_type = gst_structure_get_name (structure); - if(media_type == NULL) { - GST_ERROR ("xvimagesrc media type not specified in caps"); - goto error; - } - framerate = gst_structure_get_value (structure, "framerate"); - if (framerate) { - *rate_numerator = gst_value_get_fraction_numerator (framerate); - *rate_denominator = gst_value_get_fraction_denominator (framerate); - } else { - GST_ERROR ("xvimagesrc frametype not specified in caps"); - goto error; - } - if (g_strcmp0 (media_type, "video/x-raw-rgb") == 0) { - gst_xv_image_src_get_frame_size(FOURCC_RGB32, *width, *height, framesize); - *fourcc = FOURCC_RGB32; - GST_DEBUG ("Caps set to RGB32"); - } else if(g_strcmp0 (media_type, "video/x-raw-yuv") == 0) { - - GST_INFO ("media_type is video/x-raw-yuv"); - guint32 format = FOURCC_SN12; - ret = gst_structure_get_fourcc (structure, "format", &format); - if (!ret) GST_DEBUG ("xvimagesrc format not specified in caps, SN12 selected as default"); - ret = gst_xv_image_src_get_frame_size(format, *width, *height, framesize); - if(!ret) { - GST_ERROR ("xvimagesrc unsupported format type specified in caps"); - goto error; - } - *fourcc = format; - } - return TRUE; -/* ERRORS */ -error: - return FALSE; -} - -static gboolean gst_xv_image_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps) -{ - gboolean res = TRUE; - gint width, height, rate_denominator, rate_numerator; - GstXVImageSrc *src; - src = GST_XV_IMAGE_SRC (bsrc); - res = gst_xv_image_src_parse_caps (caps, &src->format_id, &width, &height, - &rate_numerator, &rate_denominator, &src->framesize); - if (res) { - /* looks ok here */ - src->width = width; - src->height = height; - src->rate_numerator = rate_numerator; - src->rate_denominator = rate_denominator; - GST_DEBUG_OBJECT (src, "size %dx%d, %d/%d fps", - src->width, src->height, - src->rate_numerator, src->rate_denominator); - } - xvimagesrc_thread_start(src); - return res; -} -static void -gst_xv_image_src_reset (GstXVImageSrc * src) -{ -} - -static void -gst_xv_image_src_init (GstXVImageSrc * src, GstXVImageSrcClass * g_class) -{ - src->format_id = 0; - src->running_time = GST_CLOCK_TIME_NONE; - src->frame_duration = GST_CLOCK_TIME_NONE; - src->virtual = NULL; - src->bo = NULL; - src->dri2_buffers = NULL; - src->queue_lock = g_mutex_new (); - src->queue = g_queue_new (); - src->queue_cond = g_cond_new (); - src->cond_lock = g_mutex_new (); - src->buffer_cond = g_cond_new (); - src->buffer_cond_lock = g_mutex_new (); - src->pause_cond = g_cond_new (); - src->pause_cond_lock = g_mutex_new (); - src->dpy_lock = g_mutex_new (); - src->pause_cond_var = FALSE; - src->drm_fd = -1; - src->current_data_type = VIDEO_TYPE_VIDEO_WITH_UI; - src->new_data_type = VIDEO_TYPE_VIDEO_WITH_UI; - src->get_image_overtime = 0; - src->get_image_overtime_cnt = 0; - src->gemname_cnt = 0; - src->tz_enable = 0; - drm_init(src); - gst_base_src_set_live (GST_BASE_SRC (src), TRUE); -} - -static void -gst_xv_image_src_finalize (GObject * gobject) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (gobject); - GST_DEBUG_OBJECT (src, "finalize"); - g_mutex_free (src->queue_lock); - drm_finalize(src); - G_OBJECT_CLASS (parent_class)->finalize (gobject); -} -static void drm_init(GstXVImageSrc *src) -{ - Display *dpy; - int eventBase, errorBase; - int dri2Major, dri2Minor; - char *driverName, *deviceName; - struct drm_auth auth_arg = {0}; - - src->drm_fd = -1; - dpy = XOpenDisplay(0); - - /* DRI2 */ - if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) { - GST_ERROR("DRI2QueryExtension !!"); - return; - } - if (!DRI2QueryVersion(dpy, &dri2Major, &dri2Minor)) { - GST_ERROR("DRI2QueryVersion !!"); - return; - } - if (!DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), &driverName, &deviceName)) { - GST_ERROR("DRI2Connect !!"); - return; - } - GST_INFO("Open drm device : %s", deviceName); - - /* get the drm_fd though opening the deviceName */ - src->drm_fd = open(deviceName, O_RDWR); - if (src->drm_fd < 0) { - GST_ERROR("cannot open drm device (%s)", deviceName); - return; - } - - /* get magic from drm to authentication */ - if (ioctl(src->drm_fd, DRM_IOCTL_GET_MAGIC, &auth_arg)) { - GST_ERROR("cannot get drm auth magic"); - close(src->drm_fd); - src->drm_fd = -1; - return; - } - if (!DRI2Authenticate(dpy, RootWindow(dpy, DefaultScreen(dpy)), auth_arg.magic)) { - GST_ERROR("cannot get drm authentication from X"); - close(src->drm_fd); - src->drm_fd = -1; - return; - } -} -static void drm_finalize(GstXVImageSrc *src) -{ - if (src->drm_fd >= 0) { - close(src->drm_fd); - src->drm_fd = -1; - } -} -static gint32 drm_convert_gem_to_fd(int *gemname_cnt, int drm_fd, unsigned int name, void *data, void **virtual_address) -{ - g_return_val_if_fail((data != NULL),0); - int count=0; - gint32 fd = 0; - count = *gemname_cnt; - GST_DEBUG("gamname_cnt = %d", count); - GST_DEBUG("name = %u", name); - - - GEM_MMAP *xv_gem_mmap = NULL; - xv_gem_mmap = (GEM_MMAP *) data; - if(count >=GEM_NAME_MAX) - goto PASS; - - if (count < GEM_NAME_MAX ) { - int i =0; - for ( i =0 ; i < GEM_NAME_MAX ; i++) { - if (name == xv_gem_mmap->name[i]) - goto PASS; - } - - struct drm_prime_handle prime; - struct drm_gem_open gem_open; - struct drm_exynos_gem_mmap gem_mmap; //for virtual address - - memset (&gem_open, 0, sizeof (struct drm_gem_open)); - gem_open.name = name; - if (ioctl(drm_fd, DRM_IOCTL_GEM_OPEN, &gem_open)) { - GST_ERROR("Gem Open failed"); - return 0; - } - memset (&prime, 0, sizeof (struct drm_prime_handle)); - prime.handle = gem_open.handle; - prime.flags = DRM_CLOEXEC; - /*get gem_open handle*/ - xv_gem_mmap->handle[count] = gem_open.handle; - GST_DEBUG("gem_open.handle =%d, xv_gem_mmap->handle[count]=%d", gem_open.handle, xv_gem_mmap->handle[count]); - /*get virtual address */ - /*set name*/ - xv_gem_mmap->name[count] = name; - memset (&gem_mmap, 0, sizeof (struct drm_exynos_gem_mmap)); - gem_mmap.handle = prime.handle; - gem_mmap.size = gem_open.size; - /*set size*/ - xv_gem_mmap->buffer_size[count] = gem_mmap.size; - if (drmIoctl(drm_fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &gem_mmap) !=0) { - GST_ERROR("Gem mmap failed [handle %d, size %d]", gem_mmap.handle, gem_mmap.size); - return 0; - } - /*set virtual address*/ - xv_gem_mmap->address[count] = (void *)(gem_mmap.mapped); - GST_DEBUG ("%d - Virtual address[%d] = %p size=%d ", name, count, xv_gem_mmap->address[count], xv_gem_mmap->buffer_size[count] ); - - /*get fd*/ - if (ioctl(drm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime) < 0) { - GST_ERROR("Gem Handle to Fd failed"); - return 0; - } - xv_gem_mmap->fd[count] = prime.fd; - GST_DEBUG("fd = %d", xv_gem_mmap->fd[count]); - } - - if (count < GEM_NAME_MAX) { - count ++; - *gemname_cnt = count; - } - -PASS: - - if (name == xv_gem_mmap->name[0]) { - *virtual_address = xv_gem_mmap->address[0]; - fd = xv_gem_mmap->fd[0]; - } else if (name == xv_gem_mmap->name[1]) { - *virtual_address = xv_gem_mmap->address[1]; - fd = xv_gem_mmap->fd[1]; - } else if (name == xv_gem_mmap->name[2]) { - *virtual_address = xv_gem_mmap->address[2]; - fd = xv_gem_mmap->fd[2]; - } else if ( name == xv_gem_mmap->name[3]) { - *virtual_address = xv_gem_mmap->address[3]; - fd = xv_gem_mmap->fd[3]; - } else if (name == xv_gem_mmap->name[4]) { - *virtual_address = xv_gem_mmap->address[4]; - fd = xv_gem_mmap->fd[4]; - } else if ( name == xv_gem_mmap->name[5]) { - *virtual_address = xv_gem_mmap->address[5]; - fd = xv_gem_mmap->fd[5]; - } else if (name == xv_gem_mmap->name[6]) { - *virtual_address = xv_gem_mmap->address[6]; - fd = xv_gem_mmap->fd[6]; - } else if (name == xv_gem_mmap->name[7]) { - *virtual_address = xv_gem_mmap->address[7]; - fd = xv_gem_mmap->fd[7]; - } else if ( name == xv_gem_mmap->name[8]) { - *virtual_address = xv_gem_mmap->address[8]; - fd = xv_gem_mmap->fd[8]; - } else if (name == xv_gem_mmap->name[9]) { - *virtual_address = xv_gem_mmap->address[9]; - fd = xv_gem_mmap->fd[9]; - } - - GST_DEBUG("virtual_address = %p fd = %d", *virtual_address, fd); - return fd; -} -static void -gst_xv_image_src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (object); - GST_INFO ("set property function %x", src); - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - return; -} - -static void -gst_xv_image_src_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (object); - GST_INFO ("get property function %x", src); - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static inline GstClockTime xvimagesrc_clock (GstXVImageSrc *src) -{ - struct timeval tv; - gettimeofday (&tv, NULL); - if(!src->base_time) { - src->base_time = GST_TIMEVAL_TO_TIME(tv); - } - return (GstClockTime)(GST_TIMEVAL_TO_TIME(tv) - src->base_time); -} - -static gboolean gst_xv_image_src_get_timeinfo(GstXVImageSrc *src, GstBuffer *buffer) -{ - int fps_nu = 0; - int fps_de = 0; - GstClockTime timestamp = GST_CLOCK_TIME_NONE; - GstClockTime duration = GST_CLOCK_TIME_NONE; - GstClock *clock; - if (!src || !buffer) { - GST_WARNING("Invalid pointer [handle:%p, buffer:%p]", src, buffer); - return FALSE; - } - clock = gst_element_get_clock (GST_ELEMENT (src)); - if (clock) { - timestamp = gst_clock_get_time (clock); - timestamp -= gst_element_get_base_time (GST_ELEMENT (src)); - gst_object_unref (clock); - } else { - /* not an error not to have a clock */ - timestamp = GST_CLOCK_TIME_NONE; - } - - //timestamp = xvimagesrc_clock(src); - /* if we have a framerate adjust timestamp for frame latency */ - if ((int)((float)src->rate_numerator / (float)src->rate_denominator) <= 0) { - /*if fps is zero, auto fps mode*/ - fps_nu = 0; - fps_de = 1; - } else { - fps_nu = 1; - fps_de = (int)((float)src->rate_numerator / (float)src->rate_denominator); - } - if (fps_nu > 0 && fps_de > 0) { - GstClockTime latency; - latency = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de); - duration = latency; - } - GST_BUFFER_TIMESTAMP(buffer) = timestamp; - GST_BUFFER_DURATION(buffer) = duration; - return TRUE; -} -#ifdef COUNT_FRAMES -static int fps = 0; - -static gchar *get_current_system_time() -{ - gchar target[10]={0,}; - time_t t; - struct tm tm; - - t = time(NULL); - tzset(); - /*localtimer_r : available since libc 5.2.5*/ - if(localtime_r(&t, &tm) == NULL) { - return NULL; - } - snprintf(target, sizeof(target), "%02i:%02i:%02i", tm.tm_hour, tm.tm_min, tm.tm_sec); - return g_strdup(target); -} -#endif -static void gst_xv_get_image_sleep(void *asrc, long duration) -{ - GST_INFO("end_time duration=%d", duration); - if (duration < 0) return; - GstXVImageSrc *src = (GstXVImageSrc *)asrc; - g_return_if_fail(src != NULL); - long sleep_time = 0; - sleep_time = (long)BASE_TIME - duration; - if (sleep_time < 0) { - src->get_image_overtime_cnt ++; - src->get_image_overtime += sleep_time; - if (src->get_image_overtime_cnt > 2) - src->get_image_overtime = 0; - if (src->get_image_overtime <= (long)LIMIT_TIME) - src->get_image_overtime = 0; - } else if (sleep_time > 0) { - src->get_image_overtime_cnt = 0; - sleep_time = sleep_time + src->get_image_overtime; - src->get_image_overtime = (sleep_time < 0) ? sleep_time : 0; - if (sleep_time >0) { - GST_INFO("end_time : sleep_time = %d", sleep_time); - usleep(sleep_time); - } - } -} -static GstFlowReturn -gst_xv_image_src_create (GstPushSrc * psrc, GstBuffer ** buffer) -{ - GST_INFO("gst_xv_image_src_create"); - GstXVImageSrc *src; - GstXvImageOutBuffer *outbuf = NULL; - src = GST_XV_IMAGE_SRC (psrc); - g_mutex_lock (src->queue_lock); - if(g_queue_is_empty (src->queue)) { - GST_INFO("g_queue_is_empty"); - g_mutex_unlock (src->queue_lock); - GST_INFO("g_cond_wait"); - g_cond_wait(src->queue_cond, src->cond_lock); - if(src->pause_cond_var) return GST_FLOW_WRONG_STATE; - g_mutex_lock (src->queue_lock); - outbuf = (GstXvImageOutBuffer *)g_queue_pop_head(src->queue); - GST_INFO("g_queue_pop_head"); - g_mutex_unlock (src->queue_lock); - } - else { - GstXvImageOutBuffer *tempbuf = NULL; - while((tempbuf = (GstXvImageOutBuffer*)g_queue_pop_head(src->queue)) != NULL) - { - outbuf = tempbuf; // To reduce latency, skipping the old frames and submitting only latest frames - g_mutex_unlock (src->queue_lock); - } - GST_INFO("g_queue_pop_head end"); - } - if(outbuf == NULL) return GST_FLOW_ERROR; - GST_INFO("gem_name=%d, fd_name=%d, Time stamp of the buffer is %"GST_TIME_FORMAT, outbuf->YBuf, outbuf->fd_name, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(outbuf))); - *buffer = outbuf; -#ifdef COUNT_FRAMES - gchar *current_time = NULL; - current_time = get_current_system_time(); - if (strncmp(current_time, old_time, 10) == 0) { - fps ++; - strncpy(old_time, current_time, 10); - } else { - g_printf("xvimagesrc %s - fps : %d\n", old_time, fps); - fps = 1; - strncpy(old_time, current_time, 10); - } -#endif - GST_INFO("return ok"); - return GST_FLOW_OK; -} - -static gboolean xvimagesrc_thread_start(GstXVImageSrc *src) -{ - GError *error; - if(!src->updates_thread) src->updates_thread = g_thread_create ((GThreadFunc) gst_xv_image_src_update_thread, src, TRUE, &error); - else GST_LOG_OBJECT (src, "The thread function already running"); - return TRUE; -} - -static gboolean -gst_xv_image_src_start (GstBaseSrc * bsrc) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - if(src->format_id) xvimagesrc_thread_start(src); - return TRUE; -} - -gboolean signal_emit_func(void *asrc) -{ - GstXVImageSrc *src = (GstXVImageSrc *)asrc; - if (src->current_data_type == VIDEO_TYPE_VIDEO_ONLY) { - g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_VIDEO_ONLY] , 0, NULL); - } else if (src->current_data_type == VIDEO_TYPE_VIDEO_WITH_UI) { - g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_VIDEO_WITH_UI] , 0, NULL); - } - return FALSE; -} - -static int -gst_xvimagesrc_handle_xerror (Display * display, XErrorEvent * xevent) -{ - char error_msg[1024]; - - XGetErrorText (display, xevent->error_code, error_msg, 1024); - GST_DEBUG ("XError. error: %s", error_msg); - error_caught = TRUE; - return 0; -} - -//static gboolean first_frame=TRUE; -static void* gst_xv_image_src_update_thread (void * asrc) -{ - GstXVImageSrc *src = (GstXVImageSrc *)asrc; - Atom atom_data_type = 0; - Atom atom_secure = 0, atom_capture=0; - Atom atom_fps = 0; - g_return_val_if_fail((src != NULL),NULL); - - struct drm_gem_close gem_close; - int i=0; - GEM_MMAP *xv_gem_mmap = NULL; - xv_gem_mmap = (GEM_MMAP *)malloc(sizeof(GEM_MMAP)); - g_return_val_if_fail((xv_gem_mmap != NULL),NULL); - - memset(xv_gem_mmap, 0, sizeof(GEM_MMAP)); - - GST_LOG_OBJECT (src, "The thread function start"); - { - int damage_err_base = 0; - Atom atom_format = 0; - src->dpy = XOpenDisplay (NULL); - src->p = port_get (src, src->format_id); - if (src->p < 0) goto finish; - /*src->width and src->height is set by caps info */ - GST_DEBUG (" width and height of caps : %dx%d ", src->width, src->height); - if (src->width == 0 || src->height == 0) goto finish; - GST_DEBUG ("gst_xv_image_src_update_thread pixmap_create !!"); - src->pixmap = pixmap_create (src, src->dpy, src->width, src->height); - GST_DEBUG ("gst_xv_image_src_update_thread pixmap_create !!"); - src->gc = XCreateGC (src->dpy, src->pixmap, 0, 0); - GST_DEBUG ("gst_xv_image_src_update_thread XCreateGC !!"); - src->bufmgr = bufmgr_get (src->dpy, src->pixmap); - if (!src->bufmgr) goto finish; - GST_DEBUG ("gst_xv_image_src_update_thread bufmgr_get !!"); - if (!XDamageQueryExtension(src->dpy, &src->damage_base, &damage_err_base)) goto finish; - GST_DEBUG ("gst_xv_image_src_update_thread XDamageQueryExtension !!"); - src->damage = XDamageCreate (src->dpy, src->pixmap, XDamageReportNonEmpty); - atom_format = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_FORMAT", False); - atom_capture = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False); - atom_secure = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_SECURE", False); - src->atom_stream_off = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False); - XvSetPortAttribute (src->dpy, src->p, atom_format, src->format_id); - - /*get data type*/ - atom_data_type = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_DATA_TYPE", False); - XvSelectPortNotify (src->dpy, src->p, 1); - XvGetPortAttribute (src->dpy, src->p, atom_data_type, &(src->new_data_type)); -#if 0 - /*set Xorg write-back hz*/ - atom_fps = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_FPS", False); - GST_DEBUG("frame rate of caps %d", src->rate_numerator); - XvSetPortAttribute (src->dpy, src->p, atom_fps, src->rate_numerator); - GST_DEBUG ("gst_xv_image_src_update_thread XvSetPortAttribute !!"); -#endif - } - - struct timeval start_time, end_time; - long duration; - long starttime, endtime; - GTimeVal timeout; - XEvent ev; - int eventcount = 0; - void *virtual_address = NULL; - int (*handler) (Display *, XErrorEvent *); - GstXvImageOutBuffer *outbuf = NULL; - - while(!src->thread_return) { - if(src->pause_cond_var == TRUE) { - g_cond_wait(src->pause_cond,src->pause_cond_lock); - } - duration = 0; - starttime =0; - endtime = 0; - start_time.tv_sec = 0; - start_time.tv_usec = 0; - end_time.tv_sec = 0; - end_time.tv_usec = 0; - gettimeofday(&start_time, NULL); - - eventcount = 0; - virtual_address = NULL; - duration = 0; - outbuf = NULL; - g_mutex_lock (src->dpy_lock); - XSync(src->dpy, 0); - GST_INFO ("gst_xv_image_src_update_thread XSync@@ !!"); - g_mutex_unlock (src->dpy_lock); - error_caught = FALSE; - GST_DEBUG ("gst_xv_image_src_update_thread XSetErrorHandler in !!"); - handler = XSetErrorHandler (gst_xvimagesrc_handle_xerror); - GST_INFO ("gst_xv_image_src_update_thread XSetErrorHandler !!"); - GST_INFO ("gst_xv_image_src_update_thread XvPutStill in !!"); - g_mutex_lock (src->dpy_lock); - XvPutStill (src->dpy, src->p, src->pixmap, src->gc, 0, 0, src->width, src->height, 0, 0, src->width, src->height); - GST_INFO ("gst_xv_image_src_update_thread XvPutStill !!"); - XSync (src->dpy, 0); - g_mutex_unlock (src->dpy_lock); - if (error_caught) { - GST_ERROR("gst_xv_image_src_update_thread error_caught is TRUE, X is out of buffers"); - error_caught = FALSE; - XSetErrorHandler(handler); - g_get_current_time(&timeout); - g_time_val_add(&timeout, BUFFER_COND_WAIT_TIMEOUT); - if(!g_cond_timed_wait(src->buffer_cond, src->buffer_cond_lock, &timeout)) { - GST_ERROR("skip wating"); - } else { - GST_ERROR("Signal received"); - } - continue; - } - /*reset error handler*/ - error_caught = FALSE; - XSetErrorHandler(handler); - - GST_INFO ("gst_xv_image_src_update_thread XSync !!"); -next_event: - g_mutex_lock (src->dpy_lock); - GST_INFO("XNextEvent in"); - XNextEvent (src->dpy, &ev); /* wating for x event */ - GST_INFO("XNextEvent out"); - g_mutex_unlock (src->dpy_lock); - GST_INFO ("gst_xv_image_src_update_thread XNextEvent !!"); - if (ev.type == (src->damage_base + XDamageNotify)) { - XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev; - GST_INFO ("gst_xv_image_src_update_thread XDamageNotifyEvent"); - g_mutex_lock (src->dpy_lock); - if (damage_ev->drawable == src->pixmap) { - pixmap_update (src, src->dpy, src->bufmgr, src->pixmap, - damage_ev->area.x, - damage_ev->area.y, - damage_ev->area.width, - damage_ev->area.height); - GST_INFO("gst_xv_image_src_update_thread pixmap_update"); - } - XDamageSubtract (src->dpy, src->damage, None, None ); - g_mutex_unlock (src->dpy_lock); - GST_INFO ("gst_xv_image_src_update_thread XDamageSubtract"); - } - else if (ev.type == (src->evt_base + XvPortNotify)) { - XvPortNotifyEvent *notify_ev = (XvPortNotifyEvent*)&ev; - if (notify_ev->attribute == atom_secure) { - GST_WARNING ("secure attr changed : %s \n", ((int)notify_ev->value)?"Secure":"Normal"); - src->tz_enable = (int)notify_ev->value; - GST_ERROR("src->tz_enable = %d", src->tz_enable); - } - else if (notify_ev->attribute == atom_data_type) { - /* got a port notify, data_type */ - src->new_data_type = (int)notify_ev->value; - if (src->current_data_type != src->new_data_type) { - src->current_data_type = src->new_data_type; - GST_WARNING("current_data_type : %s \n", (src->current_data_type)?"Video":"UI+Video"); - g_timeout_add(1, signal_emit_func, src); - } - } - goto next_event; - } - - if(!src->virtual) continue; - if(src->format_id == FOURCC_RGB32) { - outbuf = gst_buffer_new_and_alloc (src->framesize); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src))); - memcpy(GST_BUFFER_DATA (outbuf), src->virtual, src->framesize); - } else if (src->format_id == FOURCC_SN12) { - XV_PUTSTILL_DATA_PTR data = (XV_PUTSTILL_DATA_PTR)src->virtual; - int error = XV_PUTSTILL_VALIDATE_DATA (data); - outbuf = gst_xv_image_out_buffer_new(src); - if(!outbuf) - { - GST_ERROR("Out of memory"); - continue; - } - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src))); - if (error == XV_HEADER_ERROR) - GST_ERROR ("XV_HEADER_ERROR\n"); - else if (error == XV_VERSION_MISMATCH) - GST_ERROR ("XV_VERSION_MISMATCH\n"); - else - { - SCMN_IMGB *psimgb = NULL; - psimgb = (SCMN_IMGB *)malloc(sizeof(SCMN_IMGB)); - if (psimgb == NULL) { - GST_ERROR_OBJECT(src, "failed to alloc SCMN_IMGB"); - return NULL; - } - memset(psimgb, 0x00, sizeof(SCMN_IMGB)); - if (data->BufType == XV_BUF_TYPE_LEGACY) { - psimgb->p[0] = (void *)data->YBuf; - psimgb->p[1] = (void *)data->CbBuf; - psimgb->buf_share_method = BUF_SHARE_METHOD_PADDR; - psimgb->a[0] = NULL; - psimgb->a[1] = NULL; - } else if (data->BufType == XV_BUF_TYPE_DMABUF) { - psimgb->fd[0] = drm_convert_gem_to_fd(&src->gemname_cnt, src->drm_fd, (void *)data->YBuf, xv_gem_mmap, &virtual_address); - if(!virtual_address) continue; - psimgb->a[0] = virtual_address; - GST_DEBUG("YBuf gem to fd[0]=%d virtual_address = %p", psimgb->fd[0], psimgb->a[0]); - psimgb->fd[1] = drm_convert_gem_to_fd(&src->gemname_cnt, src->drm_fd, (void *)data->CbBuf, xv_gem_mmap, &virtual_address); - if(!virtual_address) continue; - psimgb->a[1] = virtual_address; - GST_DEBUG("CbBuf gem to fd[1]=%d virtual_address = %p", psimgb->fd[1], psimgb->a[1]); - psimgb->buf_share_method = BUF_SHARE_METHOD_FD; - } - psimgb->w[0] = src->width; - psimgb->h[0] = src->height; - psimgb->cs = SCMN_CS_NV12; - psimgb->w[1] = src->width; - psimgb->h[1] = src->height >> 1; - psimgb->tz_enable = 0; - psimgb->s[0] = GST_ROUND_UP_16(psimgb->w[0]); - psimgb->e[0] = GST_ROUND_UP_16(psimgb->h[0]); - psimgb->s[1] = GST_ROUND_UP_16(psimgb->w[1]); - psimgb->e[1] = GST_ROUND_UP_16(psimgb->h[1]); - outbuf->fd_name = psimgb->fd[0]; - GST_BUFFER_MALLOCDATA(outbuf) = (unsigned char*)psimgb; - GST_BUFFER_DATA(outbuf) = src->virtual; - outbuf->YBuf = (void *)data->YBuf; - outbuf->fd_name = psimgb->fd[0]; -#ifdef DEBUG_BUFFER - for ( i=0; i<5 ; i++) { - if(value[value_count] == outbuf->YBuf ) { - GST_ERROR("ERROR: value[%d](%d)==YBUf(%d)", value_count, value[value_count], outbuf->YBuf); - } - } - value[value_count] = outbuf->YBuf ; - GST_ERROR("value[%d]=%d", value_count, value[value_count]); - if( value_count < 4){ - value_count ++; - } else { - value_count = 0; - } -#endif - } - } - if(!outbuf) continue; - GST_BUFFER_SIZE (outbuf) = src->framesize; - gst_xv_image_src_get_timeinfo(src,outbuf); - src->running_time = GST_BUFFER_TIMESTAMP(outbuf); - src->frame_duration = GST_BUFFER_DURATION(outbuf); - //first_frame = FALSE; - g_mutex_lock (src->queue_lock); - g_queue_push_tail(src->queue, outbuf); - GST_INFO("g_queue_push_tail"); - g_mutex_unlock (src->queue_lock); - g_cond_signal(src->queue_cond); - GST_INFO("g_cond_signal"); - - update_done: - if (src->virtual) tbm_bo_unmap(src->bo); - src->virtual = NULL; - GST_INFO("g_cond_signal"); - if (src->bo) tbm_bo_unref(src->bo); - src->bo = NULL; - if (src->dri2_buffers) free(src->dri2_buffers); - src->dri2_buffers = NULL; - gettimeofday(&end_time, NULL); - starttime = start_time.tv_usec; - endtime = end_time.tv_usec; - GST_INFO("star_time: %d, end_time:%d", starttime, endtime); - if (endtime > starttime) { - GST_INFO("end_time > start_time"); - duration = endtime - starttime; - } else { - GST_INFO("end_time.tv_usec < start_time.tv_usec"); - endtime=endtime+1000000; - GST_INFO("end_time =%d", endtime); - duration = endtime -starttime; - } - GST_INFO("end_time duration = %d", duration); - gst_xv_get_image_sleep (src, duration); - GST_INFO ("gst_xv_image_src_update_thread cleanup !!"); - } - for ( i=0 ; i < GEM_NAME_MAX ; i++) { - /*gem munmap*/ - if (xv_gem_mmap->address[i]) { - if (-1 == munmap(xv_gem_mmap->address[i],xv_gem_mmap->buffer_size[i])) { - GST_ERROR ("munmap failed"); - return NULL; - } - } - if (xv_gem_mmap->handle[i]) { - gem_close.handle = xv_gem_mmap->handle[i]; - if (ioctl(src->drm_fd, DRM_IOCTL_GEM_CLOSE, &gem_close)) { - GST_ERROR("Gem Close failed"); - } - } - if (xv_gem_mmap->fd[i]) { - close(xv_gem_mmap->fd[i]); - } - } - if (xv_gem_mmap) { - free(xv_gem_mmap); - xv_gem_mmap = NULL; - } - GST_LOG_OBJECT (src, "The thread function cleanup"); - if (src->atom_stream_off > 0) { - XvSetPortAttribute (src->dpy, src->p, src->atom_stream_off, 1); - src->atom_stream_off = 0; - } - if (src->bufmgr) { - tbm_bufmgr_deinit (src->bufmgr); - src->bufmgr = NULL; - } - if (src->p > 0) { - XvUngrabPort (src->dpy, src->p, 0); - src->p = 0; - } - if (src->gc) { - XFreeGC (src->dpy, src->gc); - src->gc = NULL; - } - if (src->pixmap > 0) { - XFreePixmap (src->dpy, src->pixmap); - src->pixmap = 0; - } - if (src->dpy) { - XCloseDisplay (src->dpy); - src->dpy = NULL; - } - GST_LOG_OBJECT (src, "The thread function stop"); - return NULL; -finish: - GST_LOG_OBJECT (src, "The thread function Error cleanup"); - if (src->atom_stream_off > 0) { - XvSetPortAttribute (src->dpy, src->p, src->atom_stream_off, 1); - src->atom_stream_off = 0; - } - if (src->bufmgr) tbm_bufmgr_deinit (src->bufmgr); - src->bufmgr = NULL; - if (src->p > 0) XvUngrabPort (src->dpy, src->p, 0); - src->p = 0; - if (src->gc) XFreeGC (src->dpy, src->gc); - src->gc = NULL; - if (src->pixmap > 0) XFreePixmap (src->dpy, src->pixmap); - src->pixmap = 0; - if (src->dpy) XCloseDisplay (src->dpy); - src->dpy = NULL; - GST_LOG_OBJECT (src, "The thread function Error stop"); - return NULL; -} - -static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap) -{ - int screen; - int drm_fd; - tbm_bufmgr bufmgr; - int eventBase, errorBase; - int dri2Major, dri2Minor; - char *driverName, *deviceName; - drm_magic_t magic; - - screen = DefaultScreen(dpy); - if (!DRI2QueryExtension (dpy, &eventBase, &errorBase)) { - GST_ERROR ("!!Error : DRI2QueryExtension !!"); - return NULL; - } - if (!DRI2QueryVersion (dpy, &dri2Major, &dri2Minor)) { - GST_ERROR ("!!Error : DRI2QueryVersion !!"); - return NULL; - } - if (!DRI2Connect (dpy, RootWindow(dpy, screen), &driverName, &deviceName)) { - GST_ERROR ( "!!Error : DRI2Connect !!"); - if(driverName) Xfree(driverName); - if(deviceName) Xfree(deviceName); - return NULL; - } - if(driverName) Xfree(driverName); - GST_DEBUG("Open drm device : %s", deviceName); - // get the drm_fd though opening the deviceName - drm_fd = open (deviceName, O_RDWR); - if (drm_fd < 0) { - GST_ERROR ("!!Error : cannot open drm device (%s)", deviceName); - if(deviceName) Xfree(deviceName); - return NULL; - } - if(deviceName) Xfree(deviceName); - /* get the drm magic */ - drmGetMagic(drm_fd, &magic); - fprintf(stderr, ">>> drm magic=%d \n", magic); - if (!DRI2Authenticate(dpy, RootWindow(dpy, screen), magic)) - { - fprintf(stderr, "!!Error : DRI2Authenticate !!\n"); - close (drm_fd); - return NULL; - } - // drm slp buffer manager init - bufmgr = tbm_bufmgr_init (drm_fd); - if (!bufmgr) { - GST_ERROR ("!!Error : fail to init buffer manager "); - close (drm_fd); - return NULL; - } - DRI2CreateDrawable (dpy, pixmap); - return bufmgr; -} - -static int port_get (GstXVImageSrc * src, unsigned int id) -{ - unsigned int ver, rev, req_base, err_base; - unsigned int adaptors; - XvAdaptorInfo *ai = NULL; - XvAttribute *at = NULL; - XvImageFormatValues *fo = NULL; - int attributes, formats; - int i, j, p; - - if (XvQueryExtension (src->dpy, &ver, &rev, &req_base, &src->evt_base, &err_base) != Success) return -1; - if (XvQueryAdaptors (src->dpy, DefaultRootWindow (src->dpy), &adaptors, &ai) != Success) return -1; - if (!ai) return -1; - for (i = 0; i < adaptors; i++) { - int support_format = False; - if (!(ai[i].type & XvInputMask) || !(ai[i].type & XvStillMask)) continue; - GST_LOG ("==========================================="); - GST_LOG (" name: %s" - " first port: %ld" - " ports: %ld", - ai[i].name, - ai[i].base_id, - ai[i].num_ports); - p = ai[i].base_id; - GST_LOG (" attribute list:"); - at = XvQueryPortAttributes (src->dpy, p, &attributes); - for (j = 0; j < attributes; j++) GST_LOG ("\t- name: %s\n" - "\t\t flags: %s%s\n" - "\t\t min_value: %i\n" - "\t\t max_value: %i\n", - at[j].name, - (at[j].flags & XvGettable) ? " get" : "", - (at[j].flags & XvSettable) ? " set" : "", - at[j].min_value, at[j].max_value); - if (at) XFree (at); - GST_LOG (" image format list:"); - fo = XvListImageFormats (src->dpy, p, &formats); - for (j = 0; j < formats; j++) { - GST_LOG ("\t- 0x%x (%4.4s) %s", fo[j].id, (char *)&fo[j].id, (fo[j].format == XvPacked) ? "packed" : "planar"); - if (fo[j].id == (int)id) support_format = True; - } - if (fo) XFree (fo); - if (!support_format) continue; - for (; p < ai[i].base_id + ai[i].num_ports; p++) { - if (XvGrabPort (src->dpy, p, 0) == Success) { - GST_LOG ("========================================"); - GST_DEBUG ("XvGrabPort success : %d", p); - GST_LOG ("========================================"); - XvFreeAdaptorInfo (ai); - return p; - } - } - } - XvFreeAdaptorInfo (ai); - return -1; -} - -static void pixmap_update (GstXVImageSrc * src, Display *dpy, tbm_bufmgr bufmgr, Pixmap pixmap, - int x, int y, int width, int height) -{ - unsigned int attachments[1]; - int dri2_count, dri2_out_count; - int dri2_width, dri2_height, dri2_stride; - int opt; - tbm_bo_handle temp_virtual; - attachments[0] = DRI2BufferFrontLeft; - dri2_count = 1; - src->dri2_buffers = DRI2GetBuffers (dpy, pixmap, &dri2_width, &dri2_height, attachments, dri2_count, &dri2_out_count); - if (!src->dri2_buffers) { - GST_ERROR ("[Error] : fail to get buffers"); - goto update_done; - } - if (!src->dri2_buffers[0].name) { - GST_ERROR ("[Error] : a handle of the dri2 buffer is null "); - goto update_done; - } - src->bo = tbm_bo_import(bufmgr, src->dri2_buffers[0].name); - if (!src->bo) { - GST_ERROR ("[Error] : cannot import bo (key:%d)", src->dri2_buffers[0].name); - goto update_done; - } - dri2_stride = src->dri2_buffers[0].pitch; - opt = TBM_OPTION_READ|TBM_OPTION_WRITE; - temp_virtual = tbm_bo_map (src->bo, TBM_DEVICE_CPU, opt); - src->virtual = temp_virtual.ptr; - if (!src->virtual) { - GST_ERROR ("[Error] : fail to map "); - goto update_done; - } - return; -update_done: - if (src->virtual) tbm_bo_unmap(src->bo); - src->virtual = NULL; - if (src->bo) tbm_bo_unref(src->bo); - src->bo = NULL; - if (src->dri2_buffers) free(src->dri2_buffers); - src->dri2_buffers = NULL; - return; -} - -static Pixmap pixmap_create (GstXVImageSrc * src, Display *dpy, int width, int height) -{ - src->pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, DefaultDepth(dpy, DefaultScreen(dpy))); - src->gc = XCreateGC (dpy, src->pixmap, 0, 0); - XSetForeground (dpy, src->gc, 0xFFFF0000); - XFillRectangle (dpy, src->pixmap, src->gc, 0, 0, width, height); - XSync(dpy, 0); - XFreeGC (dpy, src->gc); - return src->pixmap; -} - -static gboolean -gst_xv_image_src_stop (GstBaseSrc * bsrc) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_DEBUG_OBJECT (src, "stop()"); - - if(src->updates_thread) { - src->thread_return = TRUE; - g_thread_join ( src->updates_thread); - src->updates_thread = NULL; - } - GST_DEBUG_OBJECT (src, "stop end "); - return TRUE; -} - -/* Interrupt a blocking request. */ -static gboolean -gst_xv_image_src_unlock (GstBaseSrc * bsrc) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock()"); - g_cond_signal(src->queue_cond); - return TRUE; -} - -/* Interrupt interrupt. */ -static gboolean -gst_xv_image_src_unlock_stop (GstBaseSrc * bsrc) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock_stop()"); - return TRUE; -} - -static gboolean -gst_xv_image_src_get_size (GstBaseSrc * bsrc, guint64 * size) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_INFO ("Get size %x", src); - return FALSE; -} - -static gboolean -gst_xv_image_src_is_seekable (GstBaseSrc * bsrc) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_INFO ("Is seekable %x", src); - return FALSE; -} - -static gboolean -gst_xv_image_src_query (GstBaseSrc * bsrc, GstQuery * query) -{ - GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - gboolean ret; - GST_INFO ("src query %x", src); - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_URI: - ret = TRUE; - break; - default: - ret = FALSE; - break; - } - - if (!ret) - ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); - - return ret; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (xvimagesrc_debug, "xvimagesrc", 0, "XServer display FB video capture Source"); - return gst_element_register (plugin, "xvimagesrc", GST_RANK_PRIMARY, GST_TYPE_XV_IMAGE_SRC); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "xvimage", - "XServer display video src", - plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com") diff --git a/mobile/xvimagesrc/src/gstxvimagesrc.h b/mobile/xvimagesrc/src/gstxvimagesrc.h deleted file mode 100644 index 37519e3..0000000 --- a/mobile/xvimagesrc/src/gstxvimagesrc.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * xvimagesrc - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Hyunil Park - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#ifndef __GST_XV_IMAGE_SRC_H__ -#define __GST_XV_IMAGE_SRC_H__ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include //libdri2-dev, libdrm-dev -#include - -#include "xv_types.h" - -#define C(b,m) (((b) >> (m)) & 0xFF) -#define B(c,s) ((((unsigned int)(c)) & 0xff) << (s)) -#define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0)) -#define FOURCC_RGB32 FOURCC('R','G','B','4') -#define FOURCC_I420 FOURCC('I','4','2','0') -#define FOURCC_SN12 FOURCC('S','N','1','2') -#define FOURCC_ST12 FOURCC('S','T','1','2') - -G_BEGIN_DECLS - -#define GST_TYPE_XV_IMAGE_SRC \ - (gst_xv_image_src_get_type()) -#define GST_XV_IMAGE_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_XV_IMAGE_SRC,GstXVImageSrc)) -#define GST_XV_IMAGE_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_XV_IMAGE_SRC,GstXVImageSrcClass)) -#define GST_IS_XV_IMAGE_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_XV_IMAGE_SRC)) -#define GST_IS_XV_IMAGE_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_XV_IMAGE_SRC)) - -typedef struct _GstXVImageSrc GstXVImageSrc; -typedef struct _GstXVImageSrcClass GstXVImageSrcClass; - -struct _GstXVImageSrc { - GstPushSrc element; - Display *dpy; - int p; - Pixmap pixmap; - GC gc; - unsigned int width; - unsigned int height; - unsigned int framesize; - guint32 format_id; - Damage damage; - int damage_base; - unsigned int evt_base; - tbm_bufmgr bufmgr; - void *virtual; - tbm_bo bo; - DRI2Buffer* dri2_buffers; - guint64 running_time; - guint64 base_time; - guint64 frame_duration; - Atom atom_stream_off; - gint rate_numerator; - gint rate_denominator; - GThread *updates_thread; - gboolean thread_return; - GQueue *queue; - GMutex *queue_lock; - GCond *queue_cond; - GMutex *cond_lock; - GCond *buffer_cond; - gboolean pause_cond_var; - GCond *pause_cond; - GMutex *pause_cond_lock; - GMutex *buffer_cond_lock; - GMutex *dpy_lock; - gint drm_fd; - int current_data_type; - int new_data_type; - double get_image_overtime; - int get_image_overtime_cnt; - int gemname_cnt; - int tz_enable; - -}; - -struct _GstXVImageSrcClass { - GstPushSrcClass parent_class; - - /* signals */ - void (*video_with_ui) (void *data); - void (*video_only) (void *data); -}; - -GType gst_xv_image_src_get_type (void); - -G_END_DECLS - -#endif /* __GST_XV_IMAGE_SRC_H__ */ - diff --git a/mobile/xvimagesrc/src/xv_types.h b/mobile/xvimagesrc/src/xv_types.h deleted file mode 100755 index afeb389..0000000 --- a/mobile/xvimagesrc/src/xv_types.h +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************** - -xserver-xorg-video-exynos - -Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: Boram Park - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* */ -/* File name : xv_types.h */ -/* Author : Boram Park (boram1288.park@samsung.com) */ -/* Protocol Version : 1.0.1 (Dec 16th 2009) */ -/* This file is for describing Xv APIs' buffer encoding method. */ -/* */ - -#ifndef XV_TYPES_H_ -#define XV_TYPES_H_ - -G_BEGIN_DECLS - -#define XV_PUTIMAGE_HEADER 0xDEADCD01 -#define XV_PUTIMAGE_VERSION 0x00010001 - -#define XV_PUTSTILL_HEADER 0xDEADCD02 -#define XV_PUTSTILL_VERSION 0x00010001 - -/* Return Values */ -#define XV_OK 0 -#define XV_HEADER_ERROR -1 -#define XV_VERSION_MISMATCH -2 - -#define XV_BUF_TYPE_DMABUF 0 -#define XV_BUF_TYPE_LEGACY 1 - -/* Data structure for XvPutImage / XvShmPutImage */ -typedef struct -{ - unsigned int _header; /* for internal use only */ - unsigned int _version; /* for internal use only */ - - unsigned int YBuf; - unsigned int CbBuf; - unsigned int CrBuf; - - unsigned int BufType; -} XV_PUTIMAGE_DATA, * XV_PUTIMAGE_DATA_PTR; - -/* Data structure for XvPutImage / XvShmPutImage */ -typedef struct -{ - unsigned int _header; /* for internal use only */ - unsigned int _version; /* for internal use only */ - - unsigned int YBuf; - unsigned int CbBuf; - unsigned int CrBuf; - - unsigned int BufIndex; - unsigned int BufType; -} XV_PUTSTILL_DATA, * XV_PUTSTILL_DATA_PTR; - -static void -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_PUTIMAGE_INIT_DATA (XV_PUTIMAGE_DATA_PTR data) -{ - data->_header = XV_PUTIMAGE_HEADER; - data->_version = XV_PUTIMAGE_VERSION; -} - - -static int -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_PUTIMAGE_VALIDATE_DATA (XV_PUTIMAGE_DATA_PTR data) -{ - if (data->_header != XV_PUTIMAGE_HEADER) - return XV_HEADER_ERROR; - if (data->_version != XV_PUTIMAGE_VERSION) - return XV_VERSION_MISMATCH; - return XV_OK; -} - -static void -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_PUTSTILL_INIT_DATA (XV_PUTSTILL_DATA_PTR data) -{ - data->_header = XV_PUTSTILL_HEADER; - data->_version = XV_PUTSTILL_VERSION; -} - - -static int -#ifdef __GNUC__ -__attribute__ ((unused)) -#endif -XV_PUTSTILL_VALIDATE_DATA (XV_PUTSTILL_DATA_PTR data) -{ - if (data->_header != XV_PUTSTILL_HEADER) - return XV_HEADER_ERROR; - if (data->_version != XV_PUTSTILL_VERSION) - return XV_VERSION_MISMATCH; - return XV_OK; -} - -G_END_DECLS - -#endif diff --git a/packaging/gst-plugins-ext0.10-0.3.14.tar.gz b/packaging/gst-plugins-ext0.10-0.3.14.tar.gz deleted file mode 100755 index 0d4415b..0000000 Binary files a/packaging/gst-plugins-ext0.10-0.3.14.tar.gz and /dev/null differ diff --git a/packaging/gst-plugins-ext0.10.spec b/packaging/gst-plugins-ext0.10.spec index cb3d74a..8d89e5a 100644 --- a/packaging/gst-plugins-ext0.10.spec +++ b/packaging/gst-plugins-ext0.10.spec @@ -1,41 +1,34 @@ Name: gst-plugins-ext0.10 -%if 0%{?tizen_profile_mobile} -Version: 0.3.14 +Version: 0.4.87 Summary: GStreamer extra plugins (common) Release: 0 -%else -Version: 0.4.13 -Summary: GStreamer extra plugins (common) -Release: 0 -VCS: framework/multimedia/gst-plugins-ext0.10#gst-plugins-ext0.10_0.3.3-8-2-125-g8a01f7e8af22f9b5977ed9bbf6e0eff94afe837b -%endif Group: libs License: LGPLv2+ Source0: %{name}-%{version}.tar.gz -BuildRequires: pkgconfig(avsysaudio) BuildRequires: pkgconfig(camsrcjpegenc) +#BuildRequires: pkgconfig(drm-client) +#BuildRequires: pkgconfig(drm-trusted) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(ecore-x) BuildRequires: pkgconfig(evas) -BuildRequires: pkgconfig(mm-ta) +BuildRequires: gst-plugins-base-devel BuildRequires: pkgconfig(gstreamer-plugins-base-0.10) -BuildRequires: pkgconfig(gstreamer-0.10) +BuildRequires: pkgconfig(gstreamer-0.10) BuildRequires: pkgconfig(libexif) -%if "%{_repository}" == "mobile" -BuildRequires: pkgconfig(libdrm) -BuildRequires: libdrm-devel -BuildRequires: pkgconfig(libtbm) -%else BuildRequires: pkgconfig(libxml-2.0) -%endif BuildRequires: pkgconfig(libdri2) BuildRequires: pkgconfig(x11) BuildRequires: pkgconfig(xext) BuildRequires: pkgconfig(xv) BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dri2proto) BuildRequires: pkgconfig(xfixes) +BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(native-buffer) +BuildRequires: pkgconfig(libcrypto) %description GStreamer extra plugins (common) @@ -45,51 +38,31 @@ GStreamer extra plugins (common) %build -%if 0%{?tizen_profile_mobile} -cd mobile -%else -cd wearable -%endif - -export CFLAGS+=" -DGST_EXT_TIME_ANALYSIS -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " +export CFLAGS+=" -DCONTROL_PAGECACHE -DGST_EXT_TIME_ANALYSIS -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" " ./autogen.sh --disable-static -%if 0%{?tizen_profile_mobile} -%configure --disable-static -%else -%configure --disable-static \ - --disable-ext-evasimagesink\ - --disable-ext-evaspixmapsink\ - --disable-ext-xvimagesrc\ - --disable-ext-gstreamer-camera\ - --disable-ext-audiotp\ - --disable-ext-audioeq\ - --disable-ext-dashdemux\ - --disable-ext-pdpushsrc\ +%configure --disable-static \ + --enable-ext-hlsdemux2\ + --disable-ext-drmsrc\ +%if 0%{?tizen_build_binary_release_type_eng} + --enable-pcmdump %endif make %{?jobs:-j%jobs} %install rm -rf %{buildroot} - -%if 0%{?tizen_profile_mobile} -cd mobile -%else -cd wearable -%endif - mkdir -p %{buildroot}/usr/share/license cp COPYING %{buildroot}/usr/share/license/%{name} %make_install - +mkdir -p %{buildroot}/usr/etc/ +install -m 755 hlsdemux2/predefined_frame/* %{buildroot}/usr/etc/ %files -%if 0%{?tizen_profile_mobile} -%manifest mobile/gst-plugins-ext0.10.manifest -%else -%manifest wearable/gst-plugins-ext0.10.manifest -%endif -%defattr(-,root,root,-) +%manifest gst-plugins-ext0.10.manifest +%defattr(-,root,root,-) %{_libdir}/gstreamer-0.10/*.so -%{_datadir}/license/%{name} +/usr/share/license/%{name} +/usr/etc/blackframe_QVGA.264 +/usr/etc/sec_audio_fixed_qvga.264 +/usr/etc/sec_audio_fixed_qvga.jpg diff --git a/mobile/toggle/Makefile.am b/pdpushsrc/Makefile.am similarity index 100% rename from mobile/toggle/Makefile.am rename to pdpushsrc/Makefile.am diff --git a/wearable/pdpushsrc/src/Makefile.am b/pdpushsrc/src/Makefile.am similarity index 100% rename from wearable/pdpushsrc/src/Makefile.am rename to pdpushsrc/src/Makefile.am diff --git a/wearable/pdpushsrc/src/gstpdpushsrc.c b/pdpushsrc/src/gstpdpushsrc.c similarity index 98% rename from wearable/pdpushsrc/src/gstpdpushsrc.c rename to pdpushsrc/src/gstpdpushsrc.c index 210a1a7..f96344b 100755 --- a/wearable/pdpushsrc/src/gstpdpushsrc.c +++ b/pdpushsrc/src/gstpdpushsrc.c @@ -166,14 +166,14 @@ gst_pd_pushsrc_class_init (GstPDPushSrcClass * klass) "Location of the file to read", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); - + g_object_class_install_property (gobject_class, ARG_EOS, g_param_spec_boolean ("eos", "EOS recived on downloading pipeline", "download of clip is over", 0, G_PARAM_READWRITE)); - + gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_start); gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_stop); gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_pd_pushsrc_is_seekable); @@ -187,7 +187,7 @@ gst_pd_pushsrc_class_init (GstPDPushSrcClass * klass) } GST_LOG ("OUT"); - + } static void @@ -201,7 +201,7 @@ gst_pd_pushsrc_init (GstPDPushSrc * src, GstPDPushSrcClass * g_class) src->uri = NULL; src->is_regular = FALSE; src->is_eos = FALSE; - + gst_pad_set_checkgetrange_function (basesrc->srcpad, GST_DEBUG_FUNCPTR (gst_pd_pushsrc_checkgetrange)); GST_LOG ("OUT"); @@ -255,7 +255,7 @@ gst_pd_pushsrc_set_location (GstPDPushSrc * src, const gchar * location) } g_object_notify (G_OBJECT (src), "location"); gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri); - + GST_LOG ("OUT"); return TRUE; @@ -336,12 +336,12 @@ gst_pd_pushsrc_create_read (GstBaseSrc * basesrc, guint64 offset, guint length, return GST_FLOW_ERROR; src = GST_PD_PUSHSRC_CAST (basesrc); - - GST_LOG_OBJECT (src, "read position = %"G_GUINT64_FORMAT ", offset = %"G_GUINT64_FORMAT", length = %d", - src->read_position, offset, length); - + + GST_LOG_OBJECT (src, "read position = %"G_GUINT64_FORMAT ", offset = %"G_GUINT64_FORMAT", length = %d", + src->read_position, offset, length); + memset (&stat_results, 0, sizeof (stat_results)); - + if (fstat (src->fd, &stat_results) < 0) goto could_not_stat; @@ -366,7 +366,7 @@ gst_pd_pushsrc_create_read (GstBaseSrc * basesrc, guint64 offset, guint length, GST_DEBUG_OBJECT (src, "Going to wait for %ld msec", timeout.tv_usec); ret = select (src->fd + 1, &fds, NULL, NULL, &timeout); - if (-1 == ret) + if (-1 == ret) { GST_ERROR_OBJECT (src, "ERROR in select () : reason - %s...\n", strerror(errno)); return GST_FLOW_ERROR; @@ -378,7 +378,7 @@ gst_pd_pushsrc_create_read (GstBaseSrc * basesrc, guint64 offset, guint length, else { memset (&stat_results, 0, sizeof (stat_results)); - + if (fstat (src->fd, &stat_results) < 0) goto could_not_stat; @@ -405,7 +405,7 @@ gst_pd_pushsrc_create_read (GstBaseSrc * basesrc, guint64 offset, guint length, goto seek_failed; src->read_position = offset; } - + buf = gst_buffer_try_new_and_alloc (length); if (G_UNLIKELY (buf == NULL)) { GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length); @@ -562,7 +562,7 @@ gst_pd_pushsrc_get_size (GstBaseSrc * basesrc, guint64 * size) *size = G_MAXUINT64; GST_DEBUG ("size of the file = %"G_GUINT64_FORMAT, *size); - + GST_LOG ("OUT"); return TRUE; @@ -658,7 +658,7 @@ open_failed: } no_stat: { - GST_ERROR_OBJECT (src, "Could not get stat info..."); + GST_ERROR_OBJECT (src, "Could not get stat info..."); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("Could not get info on \"\"."), (NULL)); close (src->fd); @@ -674,7 +674,7 @@ was_directory: } was_socket: { - GST_ERROR_OBJECT (src, "Is a Socket"); + GST_ERROR_OBJECT (src, "Is a Socket"); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("File \"\" is a socket."), (NULL)); close (src->fd); @@ -772,7 +772,7 @@ gst_pd_pushsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) #ifdef G_OS_WIN32 /* Unfortunately, g_filename_from_uri() doesn't handle some UNC paths * correctly on windows, it leaves them with an extra backslash - * at the start if they're of the mozilla-style file://///host/path/file + * at the start if they're of the mozilla-style file://///host/path/file * form. Correct this. */ if (location[0] == '\\' && location[1] == '\\' && location[2] == '\\') diff --git a/wearable/pdpushsrc/src/gstpdpushsrc.h b/pdpushsrc/src/gstpdpushsrc.h similarity index 100% rename from wearable/pdpushsrc/src/gstpdpushsrc.h rename to pdpushsrc/src/gstpdpushsrc.h diff --git a/mobile/pdpushsrc/Makefile.am b/piffdemux/Makefile.am similarity index 100% rename from mobile/pdpushsrc/Makefile.am rename to piffdemux/Makefile.am diff --git a/piffdemux/src/Makefile.am b/piffdemux/src/Makefile.am new file mode 100755 index 0000000..a966f06 --- /dev/null +++ b/piffdemux/src/Makefile.am @@ -0,0 +1,47 @@ + +plugin_LTLIBRARIES = libgstpiff.la + +libgstpiffincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/ + +libgstpiff_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(DRM_CLIENT_CFLAGS) $(DRM_TRUSTED_CFLAGS) + +libgstpiff_la_LIBADD = \ + $(GST_PLUGINS_BASE_LIBS) \ + -lgstriff-@GST_MAJORMINOR@ \ + -lgstaudio-@GST_MAJORMINOR@ \ + -lgsttag-@GST_MAJORMINOR@ \ + -lgstpbutils-@GST_MAJORMINOR@ \ + $(GST_BASE_LIBS) $(GST_LIBS) $(ZLIB_LIBS) $(DRM_CLIENT_LIBS) $(DRM_TRUSTED_LIBS) + +libgstpiff_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} + +libgstpiff_la_SOURCES = piff-plugin.c \ + piffdemux.c \ + piffdemux_types.c \ + piffdemux_dump.c + +libgstpiff_la_LIBTOOLFLAGS = --tag=disable-static + +noinst_HEADERS = \ + piffatomparser.h \ + piffdemux_types.h \ + piffdemux_dump.h \ + piffdemux_fourcc.h \ + piffpalette.h \ + piffcommon.h + +#libgstpiffinclude_HEADERS = piffcommon.h + +Android.mk: Makefile.am $(BUILT_SOURCES) + androgenizer \ + -:PROJECT libgstpiff -:SHARED libgstpiff \ + -:TAGS eng debug \ + -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ + -:SOURCES $(libgstpiff_la_SOURCES) \ + -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(CPPFLAGS) $(libgstpiff_la_CFLAGS) \ + -:LDFLAGS $(libgstpiff_la_LDFLAGS) \ + $(libgstpiff_la_LIBADD) \ + -ldl \ + -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ + LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ + > $@ diff --git a/piffdemux/src/piff-plugin.c b/piffdemux/src/piff-plugin.c new file mode 100755 index 0000000..ee96f6e --- /dev/null +++ b/piffdemux/src/piff-plugin.c @@ -0,0 +1,23 @@ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +//#include "gst/gst-i18n-plugin.h" +#include "piffdemux.h" +#include + +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_element_register (plugin, "piffdemux", GST_RANK_PRIMARY, GST_TYPE_PIFFDEMUX)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "piffdemux", + "ISO base media file format support (PIFF)", + plugin_init, VERSION, "LGPL", "Samsung Electronics Co", "http://www.samsung.com"); diff --git a/piffdemux/src/piffatomparser.h b/piffdemux/src/piffatomparser.h new file mode 100755 index 0000000..f90d5db --- /dev/null +++ b/piffdemux/src/piffatomparser.h @@ -0,0 +1,139 @@ +/* GStreamer QuickTime atom parser + * Copyright (C) 2009 Tim-Philipp Müller + * Copyright (C) <2009> STEricsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef QT_ATOM_PARSER_H +#define QT_ATOM_PARSER_H + +#include + +/* our inlined version of GstByteReader */ + +static inline gboolean +piff_atom_parser_has_remaining (GstByteReader * parser, guint64 bytes_needed) +{ + return G_LIKELY (parser->size >= bytes_needed) && + G_LIKELY ((parser->size - bytes_needed) >= parser->byte); +} + +static inline gboolean +piff_atom_parser_has_chunks (GstByteReader * parser, guint32 n_chunks, + guint32 chunk_size) +{ + /* assumption: n_chunks and chunk_size are 32-bit, we cast to 64-bit here + * to avoid overflows, to handle e.g. (guint32)-1 * size correctly */ + return piff_atom_parser_has_remaining (parser, (guint64) n_chunks * chunk_size); +} + +static inline gboolean +piff_atom_parser_peek_sub (GstByteReader * parser, guint offset, guint size, + GstByteReader * sub) +{ + *sub = *parser; + + if (G_UNLIKELY (!gst_byte_reader_skip (sub, offset))) + return FALSE; + + return (gst_byte_reader_get_remaining (sub) >= size); +} + +static inline gboolean +piff_atom_parser_skipn_and_get_uint32 (GstByteReader * parser, + guint bytes_to_skip, guint32 * val) +{ + if (G_UNLIKELY (gst_byte_reader_get_remaining (parser) < (bytes_to_skip + 4))) + return FALSE; + + gst_byte_reader_skip_unchecked (parser, bytes_to_skip); + *val = gst_byte_reader_get_uint32_be_unchecked (parser); + return TRUE; +} + +/* off_size must be either 4 or 8 */ +static inline gboolean +piff_atom_parser_get_offset (GstByteReader * parser, guint off_size, + guint64 * val) +{ + if (G_UNLIKELY (gst_byte_reader_get_remaining (parser) < off_size)) + return FALSE; + + if (off_size == sizeof (guint64)) { + *val = gst_byte_reader_get_uint64_be_unchecked (parser); + } else { + *val = gst_byte_reader_get_uint32_be_unchecked (parser); + } + return TRUE; +} + +/* off_size must be either 4 or 8 */ +static inline guint64 +piff_atom_parser_get_offset_unchecked (GstByteReader * parser, guint off_size) +{ + if (off_size == sizeof (guint64)) { + return gst_byte_reader_get_uint64_be_unchecked (parser); + } else { + return gst_byte_reader_get_uint32_be_unchecked (parser); + } +} + +/* size must be from 1 to 4 */ +static inline guint32 +piff_atom_parser_get_uint_with_size_unchecked (GstByteReader * parser, + guint size) +{ + switch (size) { + case 1: + return gst_byte_reader_get_uint8_unchecked (parser); + case 2: + return gst_byte_reader_get_uint16_be_unchecked (parser); + case 3: + return gst_byte_reader_get_uint24_be_unchecked (parser); + case 4: + return gst_byte_reader_get_uint32_be_unchecked (parser); + default: + g_assert_not_reached (); + gst_byte_reader_skip_unchecked (parser, size); + break; + } + return 0; +} + +static inline gboolean +piff_atom_parser_get_fourcc (GstByteReader * parser, guint32 * fourcc) +{ + guint32 f_be; + + if (G_UNLIKELY (gst_byte_reader_get_remaining (parser) < 4)) + return FALSE; + + f_be = gst_byte_reader_get_uint32_be_unchecked (parser); + *fourcc = GUINT32_SWAP_LE_BE (f_be); + return TRUE; +} + +static inline guint32 +piff_atom_parser_get_fourcc_unchecked (GstByteReader * parser) +{ + guint32 fourcc; + + fourcc = gst_byte_reader_get_uint32_be_unchecked (parser); + return GUINT32_SWAP_LE_BE (fourcc); +} + +#endif /* QT_ATOM_PARSER_H */ diff --git a/piffdemux/src/piffcommon.h b/piffdemux/src/piffcommon.h new file mode 100755 index 0000000..e24a19c --- /dev/null +++ b/piffdemux/src/piffcommon.h @@ -0,0 +1,29 @@ + +#ifndef __GST_PIFFCOMMON_H__ +#define __GST_PIFFCOMMON_H__ + +G_BEGIN_DECLS + +typedef struct _piff_fragment_longtime_info_t +{ + guint64 ts; + guint64 duration; +}piff_fragment_longtime_info; + +typedef struct _piff_fragment_time_info_t +{ + guint32 ts; + guint32 duration; +}piff_fragment_time_info; + +typedef struct _live_param_t +{ + gboolean is_eos; /* is live session ended */ + guint count; /* fragment parameters count */ + gchar *media_type; + piff_fragment_time_info *info; + piff_fragment_longtime_info *long_info; +}piff_live_param_t; +G_END_DECLS + +#endif /* __GST_PIFFPALETTE_H__ */ diff --git a/piffdemux/src/piffdemux.c b/piffdemux/src/piffdemux.c new file mode 100755 index 0000000..e89b128 --- /dev/null +++ b/piffdemux/src/piffdemux.c @@ -0,0 +1,3261 @@ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "piffdemux.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIFF_DEFAULT_TRACKID -1 +#define PIFF_DEFAULT_FOURCC 0 +#define PIFF_DEFAULT_TIMESCALE 10000000 +#define PIFF_DEFAULT_DURATION -1 +#define PIFF_DEFAULT_START_TS 0 +#define PIFF_DEFAULT_START_TS 0 + +#define PIFF_DEFAULT_WIDTH 16 +#define PIFF_DEFAULT_HEIGHT 16 +#define PIFF_DEFAULT_BPS 16 + +#undef DEC_OUT_FRAME_DUMP + +#ifdef DEC_OUT_FRAME_DUMP +#include +FILE *piffdump = NULL; +#endif + +#define PIFFDEMUX_RB16(x) ((((const unsigned char*)(x))[0] << 8) | ((const unsigned char*)(x))[1]) +/* max. size considered 'sane' for non-mdat atoms */ +#define PIFFDEMUX_MAX_ATOM_SIZE (25*1024*1024) + +/* if the sample index is larger than this, something is likely wrong */ +#define PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE (50*1024*1024) + +GST_DEBUG_CATEGORY (piffdemux_debug); + +typedef struct _PiffDemuxSegment PiffDemuxSegment; +typedef struct _PiffDemuxSample PiffDemuxSample; +typedef struct _PiffDemuxSubSampleEncryption PiffDemuxSubSampleEncryption; +typedef struct _PiffDemuxSubSampleEntryInfo PiffDemuxSubSampleEntryInfo; + +enum +{ + PROR_PIFF_0, + PROP_PIFF_MEDIA_CAPS, + PROP_PIFF_MEDIA_TIMESCALE, + PROP_PIFF_MEDIA_DURATION, + PROP_PIFF_MEDIA_START_TIMESTAMP, + PROP_PIFF_IS_LIVE, + PROP_PIFF_LOOKAHEAD_COUNT, + PROP_PIFF_AVG_FRAME_DUR, +#ifdef DRM_ENABLE + PROP_PROTECTION_HEADER_BUFFER, +#endif +}; + +enum +{ + SIGNAL_LIVE_PARAM, + LAST_SIGNAL +}; + +static guint gst_piffdemux_signals[LAST_SIGNAL] = { 0 }; + +struct _PiffDemuxSubSampleEntryInfo +{ + guint16 LenofClearData; + guint32 LenofEncryptData; +}; + +struct _PiffDemuxSubSampleEncryption +{ + guint16 n_entries; + PiffDemuxSubSampleEntryInfo *sub_entry; +}; + +struct _PiffDemuxSample +{ + guint32 size; + gint32 pts_offset; /* Add this value to timestamp to get the pts */ + guint64 offset; + guint64 timestamp; /* DTS In mov time */ + guint32 duration; /* In mov time */ + gboolean keyframe; /* TRUE when this packet is a keyframe */ + guint8 *iv; /* initialization vector for decryption*/ + PiffDemuxSubSampleEncryption *sub_encry; +}; + +/* timestamp is the DTS */ +#define PIFFSAMPLE_DTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp,\ + GST_SECOND, (stream)->timescale) +/* timestamp + offset is the PTS */ +#define PIFFSAMPLE_PTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp + \ + (sample)->pts_offset, GST_SECOND, (stream)->timescale) +/* timestamp + duration - dts is the duration */ +#define PIFFSAMPLE_DUR_DTS(stream,sample,dts) (gst_util_uint64_scale ((sample)->timestamp + \ + (sample)->duration, GST_SECOND, (stream)->timescale) - (dts)); +/* timestamp + offset + duration - pts is the duration */ +#define PIFFSAMPLE_DUR_PTS(stream,sample,pts) (gst_util_uint64_scale ((sample)->timestamp + \ + (sample)->pts_offset + (sample)->duration, GST_SECOND, (stream)->timescale) - (pts)); + +#define PIFFSAMPLE_KEYFRAME(stream,sample) ((sample)->keyframe); + +typedef char uuid_t[16]; + +static const uuid_t tfxd_uuid = { 0x6d, 0x1d, 0x9b, 0x05, + 0x42, 0xd5, 0x44, 0xe6, + 0x80, 0xe2, 0x14, 0x1d, + 0xaf, 0xf7, 0x57, 0xb2 }; + +static const uuid_t tfrf_uuid = { 0xd4, 0x80, 0x7e, 0xf2, + 0xca, 0x39, 0x46, 0x95, + 0x8e, 0x54, 0x26, 0xcb, + 0x9e, 0x46, 0xa7, 0x9f }; + +static const uuid_t encrypt_uuid = { 0xa2, 0x39, 0x4f, 0x52, + 0x5a, 0x9b, 0x4f, 0x14, + 0xa2, 0x44, 0x6c, 0x42, + 0x7c, 0x64, 0x8d, 0xf4 }; + +#define SE_OVERRIDE_TE_FLAGS 0x000001 +#define SE_USE_SUBSAMPLE_ENCRYPTION 0x000002 + +typedef enum +{ + UUID_UNKNOWN = -1, + UUID_TFXD, + UUID_TFRF, + UUID_SAMPLE_ENCRYPT, +}uuid_type_t; + +struct _PiffDemuxSegment +{ + /* global time and duration, all gst time */ + guint64 time; + guint64 stop_time; + guint64 duration; + /* media time of trak, all gst time */ + guint64 media_start; + guint64 media_stop; + gdouble rate; +}; + + +struct _PiffDemuxStream +{ + /* stream type */ + guint32 subtype; + GstCaps *caps; + guint32 fourcc; + + /* duration/scale */ + guint64 duration; /* in timescale */ + guint32 timescale; + + /* our samples */ + guint32 n_samples; + PiffDemuxSample *samples; + guint32 min_duration; /* duration in timescale of first sample, used for figuring out + the framerate, in timescale units */ + + /* if we use chunks or samples */ + gboolean sampled; + guint padding; + + /* when a discontinuity is pending */ + gboolean discont; + + /* list of buffers to push first */ + GSList *buffers; + + /* buffer needs some custom processing, e.g. subtitles */ + gboolean need_process; + + /* current position */ + guint32 segment_index; + guint32 sample_index; + guint64 time_position; /* in gst time */ + + /* the Gst segment we are processing out, used for clipping */ + GstSegment segment; + + /* last GstFlowReturn */ + GstFlowReturn last_ret; + + + /* quicktime segments */ + guint32 n_segments; + PiffDemuxSegment *segments; + guint32 from_sample; + guint32 to_sample; + + gboolean sent_eos; + GstTagList *pending_tags; + gboolean send_global_tags; + + GstEvent *pending_event; + + gboolean sent_nsevent; + + guint64 start_ts; + + guint64 avg_dur; /* average frame duration */ +}; + + +enum PiffDemuxState +{ + PIFFDEMUX_STATE_INITIAL, /* Initial state (haven't got the header yet) */ + PIFFDEMUX_STATE_HEADER, /* Parsing the header */ + PIFFDEMUX_STATE_MOVIE, /* Parsing/Playing the media data */ + PIFFDEMUX_STATE_BUFFER_MDAT /* Buffering the mdat atom */ +}; + + +static GNode *piffdemux_tree_get_child_by_type (GNode * node, guint32 fourcc); +static GNode *piffdemux_tree_get_child_by_type_full (GNode * node, + guint32 fourcc, GstByteReader * parser); +static GNode *piffdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc); +static GNode *piffdemux_tree_get_sibling_by_type_full (GNode * node, + guint32 fourcc, GstByteReader * parser); + +static GstStaticPadTemplate gst_piffdemux_sink_template = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-piff") + ); + +static GstStaticPadTemplate gst_piffdemux_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS_ANY); + + +GST_BOILERPLATE (GstPiffDemux, gst_piffdemux, GstPiffDemux, GST_TYPE_ELEMENT); + +static void gst_piffdemux_dispose (GObject * object); + +static GstStateChangeReturn gst_piffdemux_change_state (GstElement * element, + GstStateChange transition); +static void +gst_piffdemux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void +gst_piffdemux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static GstFlowReturn gst_piffdemux_chain (GstPad * sinkpad, GstBuffer * inbuf); +static gboolean gst_piffdemux_handle_sink_event (GstPad * pad, GstEvent * event); +static gboolean piffdemux_parse_node (GstPiffDemux * piffdemux, GNode * node, const guint8 * buffer, guint length); +static gboolean piffdemux_parse_sample_encryption(GstPiffDemux * piffdemux, GstByteReader *sample_encrypt, PiffDemuxStream * stream); +static gboolean piffdemux_parse_mfhd (GstPiffDemux * piffdemux, GstByteReader * mfhd); +static gboolean gst_piffdemux_handle_src_event (GstPad * pad, GstEvent * event); +static const GstQueryType *gst_piffdemux_get_src_query_types (GstPad * pad); +static gboolean gst_piffdemux_handle_src_query (GstPad * pad, GstQuery * query); + +#ifdef DRM_ENABLE +static void piffdemux_get_playready_licence (GstPiffDemux *demux); +void test_drm_trusted_operation_cb(drm_trusted_user_operation_info_s *operation_info, void *output_data); +#endif + +static gboolean +ConvertH264_MetaDCI_to_3GPPDCI(unsigned char *dci_meta_buf, unsigned int dci_meta_size, unsigned char **dci_3gpp_buf, unsigned int *dci_3gpp_size); +void +__gst_piffdemux_marshal_BOOLEAN__OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data); + +static void +gst_piffdemux_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_piffdemux_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_piffdemux_src_template)); + gst_element_class_set_details_simple (element_class, "PIFF demuxer", + "Codec/Parser", + "Parser for PIFF file format", + "naveen ch "); + + GST_DEBUG_CATEGORY_INIT (piffdemux_debug, "piffdemux", 0, "piffdemux plugin"); +} + +static void +gst_piffdemux_class_init (GstPiffDemuxClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->dispose = gst_piffdemux_dispose; + gobject_class->set_property = gst_piffdemux_set_property; + gobject_class->get_property = gst_piffdemux_get_property; + + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_piffdemux_change_state); + + g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_CAPS, + g_param_spec_boxed ("caps", "Caps", + "The allowed caps for the src pad", GST_TYPE_CAPS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* timescale of media to be set by application */ + g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_TIMESCALE, + g_param_spec_uint64 ("timescale", "media timescale", + "media timescale in PIFF Manifest", 0, G_MAXUINT64, + PIFF_DEFAULT_TIMESCALE, + G_PARAM_READWRITE)); +#ifdef DRM_ENABLE + g_object_class_install_property (gobject_class, PROP_PROTECTION_HEADER_BUFFER, + gst_param_spec_mini_object ("protection-header", "protection header buffer", + "protection header used for playready", GST_TYPE_BUFFER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif + g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_DURATION, + g_param_spec_int64 ("duration", "Duration of media", + "Total duration of the content", -1, G_MAXINT64, + PIFF_DEFAULT_DURATION, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_PIFF_MEDIA_START_TIMESTAMP, + g_param_spec_uint64 ("start-ts", "expected start timestamp", + "expected start timestamp to avoid reset", 0, G_MAXUINT64, + PIFF_DEFAULT_START_TS, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_PIFF_IS_LIVE, + g_param_spec_boolean ("is-live", "Is presentation is Live or VOD", + "If Presentation is Live (true) else VOD (false)", + FALSE, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_PIFF_LOOKAHEAD_COUNT, + g_param_spec_uint ("lookahead-count", "Lookahead count value", + "Look ahead count used in case of Live presentation", 0, G_MAXUINT, + 0, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_PIFF_AVG_FRAME_DUR, + g_param_spec_uint64 ("frame-dur", "Average frame duration", + "Average frame duration", 0, G_MAXUINT64, + G_MAXUINT64, + G_PARAM_READABLE)); + + gst_piffdemux_signals[SIGNAL_LIVE_PARAM] = g_signal_new ("live-param", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstPiffDemuxClass, live_param), NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + +} + + +static void +gst_piffdemux_init (GstPiffDemux * piffdemux, GstPiffDemuxClass * klass) +{ + /* sink pad */ + piffdemux->sinkpad = gst_pad_new_from_static_template (&gst_piffdemux_sink_template, "sink"); + gst_pad_set_chain_function (piffdemux->sinkpad, gst_piffdemux_chain); + gst_pad_set_event_function (piffdemux->sinkpad, gst_piffdemux_handle_sink_event); + gst_element_add_pad (GST_ELEMENT_CAST (piffdemux), piffdemux->sinkpad); + + /* source pad */ + piffdemux->srcpad = gst_pad_new_from_static_template (&gst_piffdemux_src_template, "src"); + gst_pad_set_event_function (piffdemux->srcpad, gst_piffdemux_handle_src_event); + gst_pad_use_fixed_caps (piffdemux->srcpad); + gst_pad_set_query_type_function (piffdemux->srcpad, gst_piffdemux_get_src_query_types); + gst_pad_set_query_function (piffdemux->srcpad, gst_piffdemux_handle_src_query); + gst_element_add_pad (GST_ELEMENT_CAST (piffdemux), piffdemux->srcpad); + + piffdemux->stream = g_new0 (PiffDemuxStream, 1); + piffdemux->stream->fourcc = PIFF_DEFAULT_FOURCC; + piffdemux->stream->timescale = PIFF_DEFAULT_TIMESCALE; + piffdemux->stream->duration = PIFF_DEFAULT_DURATION; + piffdemux->stream->caps = NULL; + piffdemux->stream->discont = TRUE; + piffdemux->stream->need_process = FALSE; + piffdemux->stream->segment_index = -1; + piffdemux->stream->time_position = 0; + piffdemux->stream->sample_index = -1; + piffdemux->stream->last_ret = GST_FLOW_OK; + piffdemux->stream->sent_nsevent = FALSE; + piffdemux->stream->start_ts = PIFF_DEFAULT_START_TS; + piffdemux->stream->avg_dur = -1; + + piffdemux->state = PIFFDEMUX_STATE_INITIAL; + piffdemux->neededbytes = 16; + piffdemux->todrop = 0; + piffdemux->adapter = gst_adapter_new (); + piffdemux->offset = 0; + piffdemux->first_mdat = -1; + piffdemux->mdatoffset = GST_CLOCK_TIME_NONE; + piffdemux->mdatbuffer = NULL; + piffdemux->moof_rcvd = FALSE; + piffdemux->is_live = FALSE; + piffdemux->lookahead_cnt = 0; +#ifdef DRM_ENABLE + piffdemux->pr_handle = NULL; +#endif + piffdemux->decrypt_init = FALSE; + piffdemux->encrypt_content = FALSE; + +#ifdef DEC_OUT_FRAME_DUMP + piffdump = fopen ("/opt/media/piff_out_dump.dmp", "w+"); + if (piffdump == NULL) + { + g_print ("\nNot able to create frame dump file\n"); + } +#endif + + gst_segment_init (&piffdemux->segment, GST_FORMAT_TIME); +} + +static void +gst_piffdemux_dispose (GObject * object) +{ + GstPiffDemux *piffdemux = GST_PIFFDEMUX (object); + + if (piffdemux->adapter) { + g_object_unref (G_OBJECT (piffdemux->adapter)); + piffdemux->adapter = NULL; + } + +#ifdef DEC_OUT_FRAME_DUMP + { + fclose (piffdump); + piffdump = NULL; + } +#endif + G_OBJECT_CLASS (parent_class)->dispose (object); +} + + +static void +gst_piffdemux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstPiffDemux *piffdemux = GST_PIFFDEMUX (object); + + switch (prop_id) { + case PROP_PIFF_MEDIA_CAPS: { + if (piffdemux->stream->caps) + gst_caps_unref(piffdemux->stream->caps); + piffdemux->stream->caps = gst_caps_copy (gst_value_get_caps (value)); + gchar *caps_string = gst_caps_to_string(piffdemux->stream->caps); + GST_DEBUG_OBJECT (piffdemux, "stream caps = %s", caps_string); + g_free(caps_string); + caps_string = NULL; + if (!gst_pad_set_caps(piffdemux->srcpad, piffdemux->stream->caps)) { + GST_ERROR_OBJECT (piffdemux, "not able to set caps..."); + } + break; + } + case PROP_PIFF_MEDIA_TIMESCALE: + piffdemux->stream->timescale = g_value_get_uint64(value); + break; + case PROP_PIFF_MEDIA_DURATION: + piffdemux->stream->duration = g_value_get_int64(value); + break; + case PROP_PIFF_MEDIA_START_TIMESTAMP: + piffdemux->stream->start_ts = g_value_get_uint64(value); + GST_INFO_OBJECT (piffdemux, "start_ts = %"GST_TIME_FORMAT, GST_TIME_ARGS(piffdemux->stream->start_ts)); + break; + case PROP_PIFF_IS_LIVE: + piffdemux->is_live = g_value_get_boolean(value); + break; + case PROP_PIFF_LOOKAHEAD_COUNT: + piffdemux->lookahead_cnt = g_value_get_uint(value); + GST_DEBUG_OBJECT (piffdemux, "Look ahead count = %d", piffdemux->lookahead_cnt); + break; +#ifdef DRM_ENABLE + case PROP_PROTECTION_HEADER_BUFFER: + piffdemux->protection_header = gst_value_get_buffer(value); + piffdemux_get_playready_licence (piffdemux); + break; +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +gst_piffdemux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstPiffDemux *piffdemux = GST_PIFFDEMUX (object); + + switch (prop_id) { + case PROP_PIFF_MEDIA_CAPS: + gst_value_set_caps (value, piffdemux->stream->caps); + break; + case PROP_PIFF_MEDIA_TIMESCALE: + g_value_set_uint64 (value, piffdemux->stream->timescale); + break; + case PROP_PIFF_MEDIA_DURATION: + g_value_set_int64 (value, piffdemux->stream->duration); + break; + case PROP_PIFF_MEDIA_START_TIMESTAMP: + g_value_set_uint64 (value, piffdemux->stream->start_ts); + break; + case PROP_PIFF_IS_LIVE: + g_value_set_boolean(value, piffdemux->is_live); + break; + case PROP_PIFF_LOOKAHEAD_COUNT: + g_value_set_uint (value, piffdemux->lookahead_cnt); + break; + case PROP_PIFF_AVG_FRAME_DUR: + g_value_set_uint64 (value, piffdemux->stream->avg_dur); + break; +#ifdef DRM_ENABLE + case PROP_PROTECTION_HEADER_BUFFER: + gst_value_take_buffer (value, piffdemux->protection_header); + break; +#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +gst_piffdemux_post_no_playable_stream_error (GstPiffDemux * piffdemux) +{ + if (piffdemux->posted_redirect) { + GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX, + ("This file contains no playable streams."), + ("no known streams found, a redirect message has been posted")); + } else { + GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX, + ("This file contains no playable streams."), + ("no known streams found")); + } + +} + +static gboolean +gst_piffdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, + GstFormat dest_format, gint64 * dest_value) +{ + gboolean res = TRUE; + PiffDemuxStream *stream = gst_pad_get_element_private (pad); + GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad)); + + if (stream->subtype != FOURCC_vide) { + res = FALSE; + goto done; + } + + switch (src_format) { + case GST_FORMAT_TIME: + switch (dest_format) { + case GST_FORMAT_BYTES:{ + + break; + } + default: + res = FALSE; + break; + } + break; + case GST_FORMAT_BYTES: + switch (dest_format) { + case GST_FORMAT_TIME:{ + + break; + } + default: + res = FALSE; + break; + } + break; + default: + res = FALSE; + } + +done: + gst_object_unref (piffdemux); + + return res; +} + +static const GstQueryType * +gst_piffdemux_get_src_query_types (GstPad * pad) +{ + static const GstQueryType src_types[] = { + GST_QUERY_POSITION, + GST_QUERY_DURATION, + GST_QUERY_CONVERT, + GST_QUERY_FORMATS, + GST_QUERY_SEEKING, + 0 + }; + + return src_types; +} + +static gboolean +gst_piffdemux_get_duration (GstPiffDemux * piffdemux, gint64 * duration) +{ + gboolean res = TRUE; + + *duration = GST_CLOCK_TIME_NONE; + + if (piffdemux->stream->duration != 0) { + if (piffdemux->stream->duration != G_MAXINT64 && piffdemux->stream->timescale != 0) { + *duration = gst_util_uint64_scale (piffdemux->stream->duration, + GST_SECOND, piffdemux->stream->timescale); + } + } + return res; +} + +static gboolean +gst_piffdemux_handle_src_query (GstPad * pad, GstQuery * query) +{ + gboolean res = FALSE; + GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad)); + + GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_POSITION: + GST_ERROR ("Querying POSITION from piffdemux...."); + if (GST_CLOCK_TIME_IS_VALID (piffdemux->segment.last_stop)) { + gst_query_set_position (query, GST_FORMAT_TIME, + piffdemux->segment.last_stop); + res = TRUE; + } + break; + case GST_QUERY_DURATION:{ + GstFormat fmt; + GST_ERROR ("Querying DURATION from piffdemux...."); + + gst_query_parse_duration (query, &fmt, NULL); + if (fmt == GST_FORMAT_TIME) { + gint64 duration = -1; + + gst_piffdemux_get_duration (piffdemux, &duration); + if (duration > 0) { + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + res = TRUE; + } + } + break; + } + case GST_QUERY_CONVERT:{ + GstFormat src_fmt, dest_fmt; + gint64 src_value, dest_value = 0; + + gst_query_parse_convert (query, &src_fmt, &src_value, &dest_fmt, NULL); + + res = gst_piffdemux_src_convert (pad, + src_fmt, src_value, dest_fmt, &dest_value); + if (res) { + gst_query_set_convert (query, src_fmt, src_value, dest_fmt, dest_value); + res = TRUE; + } + break; + } + case GST_QUERY_FORMATS: + gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES); + res = TRUE; + break; + case GST_QUERY_SEEKING:{ + + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } + + gst_object_unref (piffdemux); + + return res; +} + + +static void +gst_piffdemux_push_tags (GstPiffDemux * piffdemux, PiffDemuxStream * stream) +{ + if (G_UNLIKELY (stream->pending_tags)) { + GST_DEBUG_OBJECT (piffdemux, "Sending tags %" GST_PTR_FORMAT, + stream->pending_tags); + gst_pad_push_event (piffdemux->srcpad, + gst_event_new_tag (stream->pending_tags)); + stream->pending_tags = NULL; + } + + if (G_UNLIKELY (stream->send_global_tags && piffdemux->tag_list)) { + GST_DEBUG_OBJECT (piffdemux, "Sending global tags %" GST_PTR_FORMAT, + piffdemux->tag_list); + gst_pad_push_event (piffdemux->srcpad, + gst_event_new_tag (gst_tag_list_copy (piffdemux->tag_list))); + stream->send_global_tags = FALSE; + } +} + + +static void +gst_piffdemux_push_event (GstPiffDemux * piffdemux, GstEvent * event) +{ + GstEventType etype = GST_EVENT_TYPE (event); + + GST_DEBUG_OBJECT (piffdemux, "pushing %s event on source pad", + GST_EVENT_TYPE_NAME (event)); + + if (piffdemux->stream->sent_eos) { + GST_INFO_OBJECT (piffdemux, "already sent eos"); + return; + } + + if (!gst_pad_push_event (piffdemux->srcpad, event)) { + GST_ERROR_OBJECT (piffdemux, "error in sending event to srcpad..."); + } + + if (etype == GST_EVENT_EOS) + piffdemux->stream->sent_eos = TRUE; +} + + +/* find the segment for @time_position for @stream + * + * Returns -1 if the segment cannot be found. + */ +static guint32 +gst_piffdemux_find_segment (GstPiffDemux * piffdemux, PiffDemuxStream * stream, + guint64 time_position) +{ + gint i; + guint32 seg_idx; + + GST_LOG_OBJECT (piffdemux, "finding segment for %" GST_TIME_FORMAT, + GST_TIME_ARGS (time_position)); + + /* find segment corresponding to time_position if we are looking + * for a segment. */ + seg_idx = -1; + for (i = 0; i < stream->n_segments; i++) { + PiffDemuxSegment *segment = &stream->segments[i]; + + GST_LOG_OBJECT (piffdemux, + "looking at segment %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, + GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->stop_time)); + + /* For the last segment we include stop_time in the last segment */ + if (i < stream->n_segments - 1) { + if (segment->time <= time_position && time_position < segment->stop_time) { + GST_LOG_OBJECT (piffdemux, "segment %d matches", i); + seg_idx = i; + break; + } + } else { + if (segment->time <= time_position && time_position <= segment->stop_time) { + GST_LOG_OBJECT (piffdemux, "segment %d matches", i); + seg_idx = i; + break; + } + } + } + return seg_idx; +} + + +static gboolean +gst_piffdemux_handle_src_event (GstPad * pad, GstEvent * event) +{ + gboolean res = TRUE; + GstPiffDemux *piffdemux = GST_PIFFDEMUX (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_QOS: + case GST_EVENT_NAVIGATION: + res = FALSE; + gst_event_unref (event); + break; + case GST_EVENT_SEEK: + default: + res = gst_pad_event_default (pad, event); + break; + } + + gst_object_unref (piffdemux); + + return res; +} + + +static void +gst_piffdemux_move_stream (GstPiffDemux * piffdemux, PiffDemuxStream * str, + guint32 index) +{ + /* no change needed */ + if (index == str->sample_index) + return; + + GST_DEBUG_OBJECT (piffdemux, "moving to sample %u of %u", index, + str->n_samples); + + /* position changed, we have a discont */ + str->sample_index = index; + /* Each time we move in the stream we store the position where we are + * starting from */ + str->from_sample = index; + str->discont = TRUE; +} + +// TODO: need to check more on this below function +/* stream/index return sample that is min/max w.r.t. byte position, + * time is min/max w.r.t. time of samples, + * the latter need not be time of the former sample */ +static void +gst_piffdemux_find_sample (GstPiffDemux * piffdemux, gint64 byte_pos, gboolean fw, + gboolean set, PiffDemuxStream ** _stream, gint * _index, gint64 * _time) +{ + gint i, index; + gint64 time, min_time; + PiffDemuxStream *stream; + PiffDemuxStream *str = piffdemux->stream; + gint inc; + gboolean set_sample; + + min_time = -1; + stream = NULL; + index = -1; + + set_sample = !set; + if (fw) { + i = 0; + inc = 1; + } else { + i = str->n_samples - 1; + inc = -1; + } + + for (; (i >= 0) && (i < str->n_samples); i += inc) { + if (str->samples[i].size && + ((fw && (str->samples[i].offset >= byte_pos)) || + (!fw && + (str->samples[i].offset + str->samples[i].size <= + byte_pos)))) { + /* move stream to first available sample */ + if (set) { + gst_piffdemux_move_stream (piffdemux, str, i); + set_sample = TRUE; + } + /* determine min/max time */ + time = str->samples[i].timestamp + str->samples[i].pts_offset; + time = gst_util_uint64_scale (time, GST_SECOND, str->timescale); + /*if (min_time == -1 || (!fw && time > min_time) || + (fw && time < min_time)) : Dead code*/ { + min_time = time; + } + index = i; + break; + } + } + /* no sample for this stream, mark eos */ + if (!set_sample) + gst_piffdemux_move_stream (piffdemux, str, str->n_samples); + + if (_time) + *_time = min_time; + if (_stream) + *_stream = str; + if (_index) + *_index = index; +} + + +static gboolean +gst_piffdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event) +{ + GstPiffDemux *demux = GST_PIFFDEMUX (GST_PAD_PARENT (sinkpad)); + gboolean res; + + GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_NEWSEGMENT: + { + GstFormat format; + gdouble rate, arate; + gint64 start, stop, time, offset = 0; + PiffDemuxStream *stream; + gint idx; + gboolean update; + GstSegment segment; + + /* some debug output */ + gst_segment_init (&segment, GST_FORMAT_UNDEFINED); + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, + &start, &stop, &time); + gst_segment_set_newsegment_full (&segment, update, rate, arate, format, + start, stop, time); + GST_ERROR_OBJECT (demux, + "received format %d newsegment %" GST_SEGMENT_FORMAT, format, + &segment); + + /* chain will send initial newsegment after pads have been added */ + if (demux->state != PIFFDEMUX_STATE_MOVIE ) { + GST_DEBUG_OBJECT (demux, "still starting, eating event"); + goto exit; + } + + /* we only expect a BYTE segment, e.g. following a seek */ + if (format == GST_FORMAT_BYTES) { + if (start > 0) { + gint64 requested_seek_time; + guint64 seek_offset; + + offset = start; + + GST_OBJECT_LOCK (demux); + requested_seek_time = demux->requested_seek_time; + seek_offset = demux->seek_offset; + demux->requested_seek_time = -1; + demux->seek_offset = -1; + GST_OBJECT_UNLOCK (demux); + + if (offset == seek_offset) { + start = requested_seek_time; + } else { + gst_piffdemux_find_sample (demux, start, TRUE, FALSE, NULL, NULL, + &start); + start = MAX (start, 0); + } + } + if (stop > 0) { + gst_piffdemux_find_sample (demux, stop, FALSE, FALSE, NULL, NULL, + &stop); + /* keyframe seeking should already arrange for start >= stop, + * but make sure in other rare cases */ + stop = MAX (stop, start); + } + } +#if 0 + else if (format == GST_FORMAT_TIME) { + // Supporting TIME_FORMAT for new_segment + //gst_piffdemux_push_event (demux,event); + PiffDemuxStream *stream = NULL; + int i = -1; + + demux->neededbytes = 16; + demux->state = PIFFDEMUX_STATE_INITIAL; + demux->offset = 0; + + /* Figure out which stream this is packet belongs to */ + for (i = 0; i < demux->n_streams; i++) { + stream = demux->streams[i]; + stream->last_ts = start; + stream->discont = TRUE; + stream->sample_index = stream->n_samples; + } + + /* accept upstream's notion of segment and distribute along */ + gst_segment_set_newsegment_full (&demux->segment, update, rate, arate, + GST_FORMAT_TIME, start, stop, start); + GST_ERROR_OBJECT (demux, "Pushing newseg update %d, rate %g, " + "applied rate %g, format %d, start %" GST_TIME_FORMAT ", " + "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME, + GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); + + gst_piffdemux_push_event (demux, + gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME, start, stop, start)); + + /* clear leftover in current segment, if any */ + gst_adapter_clear (demux->adapter); + + goto exit; + } +#endif + else { + GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring"); + goto exit; + } + + /* accept upstream's notion of segment and distribute along */ + gst_segment_set_newsegment_full (&demux->segment, update, rate, arate, + GST_FORMAT_TIME, start, stop, start); + GST_ERROR_OBJECT (demux, "Pushing newseg update %d, rate %g, " + "applied rate %g, format %d, start %" GST_TIME_FORMAT ", " + "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME, + GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); + + gst_piffdemux_push_event (demux, + gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME, + start, stop, start)); + + /* clear leftover in current segment, if any */ + gst_adapter_clear (demux->adapter); + /* set up streaming thread */ + gst_piffdemux_find_sample (demux, offset, TRUE, TRUE, &stream, &idx, NULL); + demux->offset = offset; + if (stream) { + demux->todrop = stream->samples[idx].offset - offset; + demux->neededbytes = demux->todrop + stream->samples[idx].size; + } else { + /* set up for EOS */ + demux->neededbytes = -1; + demux->todrop = 0; + } + exit: + gst_event_unref (event); + res = TRUE; + goto drop; + break; + } + case GST_EVENT_FLUSH_STOP: + { + /* clean up, force EOS if no more info follows */ + gst_adapter_clear (demux->adapter); + demux->offset = 0; + demux->neededbytes = -1; + /* reset flow return, e.g. following seek */ + demux->stream->last_ret = GST_FLOW_OK; + demux->stream->sent_eos = FALSE; + break; + } + case GST_EVENT_EOS: + break; + default: + break; + } + + res = gst_pad_event_default (demux->sinkpad, event); + +drop: + return res; +} + + +static void +gst_piffdemux_stream_free (GstPiffDemux * piffdemux, PiffDemuxStream * stream) +{ + int i = 0; + + g_return_if_fail (stream != NULL); + + while (stream->buffers) { + gst_buffer_unref (GST_BUFFER_CAST (stream->buffers->data)); + stream->buffers = g_slist_delete_link (stream->buffers, stream->buffers); + } + + for (i = 0; i < stream->n_samples; i++) { + if (stream->samples[i].iv) { + free (stream->samples[i].iv); + stream->samples[i].iv = NULL; + } + if (stream->samples[i].sub_encry) { + if (stream->samples[i].sub_encry->sub_entry) { + g_free (stream->samples[i].sub_encry->sub_entry); + stream->samples[i].sub_encry->sub_entry = NULL; + } + + free (stream->samples[i].sub_encry); + stream->samples[i].sub_encry = NULL; + } + } + + if (stream->samples) { + g_free (stream->samples); + stream->samples = NULL; + } + if (stream->caps) { + gst_caps_unref (stream->caps); + stream->caps = NULL; + } + if (stream->segments) { + g_free (stream->segments); + stream->segments = NULL; + } + if (stream->pending_tags) { + gst_tag_list_free (stream->pending_tags); + stream->pending_tags = NULL; + } + g_free (stream); +} + + +static GstStateChangeReturn +gst_piffdemux_change_state (GstElement * element, GstStateChange transition) +{ + GstPiffDemux *piffdemux = GST_PIFFDEMUX (element); + GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE; + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + break; + default: + break; + } + + result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY:{ + piffdemux->state = PIFFDEMUX_STATE_INITIAL; + piffdemux->neededbytes = 16; + piffdemux->todrop = 0; + piffdemux->posted_redirect = FALSE; + piffdemux->offset = 0; + piffdemux->first_mdat = -1; + piffdemux->mdatoffset = GST_CLOCK_TIME_NONE; + if (piffdemux->mdatbuffer) + gst_buffer_unref (piffdemux->mdatbuffer); + piffdemux->mdatbuffer = NULL; + if (piffdemux->tag_list) + gst_tag_list_free (piffdemux->tag_list); + piffdemux->tag_list = NULL; + gst_adapter_clear (piffdemux->adapter); + gst_piffdemux_stream_free (piffdemux, piffdemux->stream); + gst_segment_init (&piffdemux->segment, GST_FORMAT_TIME); + break; + } + default: + break; + } + + return result; +} + +static void +piffdemux_post_global_tags (GstPiffDemux * piffdemux) +{ + if (piffdemux->tag_list) { + /* all header tags ready and parsed, push them */ + GST_INFO_OBJECT (piffdemux, "posting global tags: %" GST_PTR_FORMAT, + piffdemux->tag_list); + /* post now, send event on pads later */ + gst_element_post_message (GST_ELEMENT (piffdemux), + gst_message_new_tag (GST_OBJECT (piffdemux), + gst_tag_list_copy (piffdemux->tag_list))); + } +} + + +/* caller verifies at least 8 bytes in buf */ +static void +extract_initial_length_and_fourcc (const guint8 * data, guint size, + guint64 * plength, guint32 * pfourcc) +{ + guint64 length; + guint32 fourcc; + + length = PIFF_UINT32 (data); + GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length); + fourcc = PIFF_FOURCC (data + 4); + GST_DEBUG ("atom type %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc)); + + if (length == 0) { + length = G_MAXUINT32; + } else if (length == 1 && size >= 16) { + /* this means we have an extended size, which is the 64 bit value of + * the next 8 bytes */ + length = PIFF_UINT64 (data + 8); + GST_DEBUG ("length 0x%08" G_GINT64_MODIFIER "x", length); + } + + if (plength) + *plength = length; + if (pfourcc) + *pfourcc = fourcc; +} + +static gboolean +piffdemux_update_sample_offset (GstPiffDemux * piffdemu, PiffDemuxStream * stream, gint64 uuid_offset) +{ + PiffDemuxSample *sample; + gint i; + + sample = stream->samples ; + for (i = 0; i < stream->n_samples; i++) + { + sample->offset = sample->offset + uuid_offset; + sample++; + } + return TRUE; +} + +static uuid_type_t +piffdemux_get_uuid_type(GstPiffDemux * piffdemux, GstByteReader *uuid_data, gint64 *uuid_offset) +{ + uuid_type_t uuid_type = UUID_UNKNOWN; + guint32 box_len = 0; + guint64 box_long_len = 0; + gchar uuid[16] = {0,}; + int i = 0; + + if (!gst_byte_reader_get_uint32_be (uuid_data, &box_len)) + goto invalid_uuid; + + /* Skipping fourcc */ + if (!gst_byte_reader_skip (uuid_data, 4)) + goto invalid_uuid; + + if (box_len == 1) + { + GST_WARNING ("TfxdBoxLongLength field is present..."); + if (!gst_byte_reader_get_uint64_be (uuid_data, &box_long_len)) + goto invalid_uuid; + GST_DEBUG ("tfxd long length = %llu", box_long_len); + + *uuid_offset = box_long_len; + } + else + { + GST_DEBUG ("Box Len = %d", box_len); + *uuid_offset = box_len; + } + + //g_print ("\n\n\n 0x"); + for (i = 0; i < sizeof (uuid); i++) + { + if (!gst_byte_reader_get_uint8 (uuid_data, &(uuid[i]))) + goto invalid_uuid; + //g_print ("%02x", uuid[i]); + } + //g_print ("\n\n\n"); + + if (!memcmp(uuid, tfxd_uuid, sizeof (uuid_t))) + { + GST_INFO ("Found TFXD box"); + return UUID_TFXD; + } + else if (!memcmp(uuid, tfrf_uuid, sizeof (uuid_t))) + { + GST_INFO ("Found TFRF box"); + return UUID_TFRF; + } + else if (!memcmp(uuid, encrypt_uuid, sizeof (uuid_t))) + { + GST_INFO ("Found sample encryption box"); + return UUID_SAMPLE_ENCRYPT; + } + else + { + GST_WARNING ("Not an valid UUID box.."); + goto invalid_uuid; + } + return uuid_type; + +invalid_uuid: + GST_ERROR ("Error in parsing UUID atom..."); + return UUID_UNKNOWN; +} + +static gboolean +piffdemux_parse_sample_encryption(GstPiffDemux * piffdemux, GstByteReader *sample_encrypt, PiffDemuxStream * stream) +{ + guint32 flags = 0; + guint32 sample_count = 0; + guint32 i = 0; + guint32 algo_id; + guint8 iv_size = 0; + + if (!gst_byte_reader_skip (sample_encrypt, 1) || + !gst_byte_reader_get_uint24_be (sample_encrypt, &flags)) + goto invalid_encryption; + + if (flags & SE_OVERRIDE_TE_FLAGS) { + /* get algorithm id */ + if (!gst_byte_reader_get_uint32_be (sample_encrypt, &algo_id)) + goto invalid_encryption; + + /* get IV size */ + if (!gst_byte_reader_get_uint8 (sample_encrypt, &iv_size)) + goto invalid_encryption; + + // TODO: need to add reading of KID + } else { + GST_INFO_OBJECT (piffdemux, "Override flags are not present... taking default IV_Size = 8"); + iv_size = 8; + } + + /* Get sample count*/ + if (!gst_byte_reader_get_uint32_be (sample_encrypt, &sample_count)) + goto invalid_encryption; + + GST_INFO_OBJECT (piffdemux, "Sample count = %d", sample_count); + + if (sample_count != stream->n_samples) { + GST_ERROR_OBJECT (piffdemux, "Not all samples has IV vectors... Don't know how to handle. sample_cnt = %d and stream->n_samples = %d", + sample_count, stream->n_samples); + goto invalid_encryption; + } + + for (i = 0; i < stream->n_samples; i++) { + guint8 iv_idx = iv_size; + + /* resetting entire IV array */ + stream->samples[i].iv = (guint8 *)malloc (iv_size); + if (NULL == stream->samples[i].iv) { + GST_ERROR ("Failed to allocate memory...\n"); + goto invalid_encryption; + } + + memset (stream->samples[i].iv, 0x00, iv_size); + + iv_idx = 0; + while (iv_idx < iv_size) { + /* get IV byte */ + if (!gst_byte_reader_get_uint8 (sample_encrypt, &(stream->samples[i].iv[iv_idx]))) + goto invalid_encryption; + + iv_idx++; + } + +#ifdef DEBUG_IV + { + guint8 tmp_idx = 0; + g_print ("sample[%d] : 0x ", i); + + while (tmp_idx < iv_size ) { + g_print ("%02x ", stream->samples[i].iv[tmp_idx]); + tmp_idx++; + } + g_print ("\n"); + } +#endif + + if (flags & SE_USE_SUBSAMPLE_ENCRYPTION) { + guint16 n_entries; + guint16 n_idx; + + /* NumberofEntries in SubSampleEncryption */ + if (!gst_byte_reader_get_uint16_be (sample_encrypt, &n_entries)) + goto invalid_encryption; + + stream->samples[i].sub_encry = (PiffDemuxSubSampleEncryption *)malloc (sizeof (PiffDemuxSubSampleEncryption)); + if (NULL == stream->samples[i].sub_encry) { + GST_ERROR ("Failed to allocate memory...\n"); + goto invalid_encryption; + } + + stream->samples[i].sub_encry->sub_entry = g_try_new0 (PiffDemuxSubSampleEntryInfo, n_entries); + if (NULL == stream->samples[i].sub_encry->sub_entry) { + GST_ERROR_OBJECT (piffdemux, "Failed to allocate memory..."); + goto invalid_encryption; + } + + stream->samples[i].sub_encry->n_entries = n_entries; + + GST_DEBUG_OBJECT (piffdemux,"No. of subsample entries = %d", stream->samples[i].sub_encry->n_entries); + + for (n_idx = 0; n_idx < n_entries; n_idx++) { + if (!gst_byte_reader_get_uint16_be (sample_encrypt, &(stream->samples[i].sub_encry->sub_entry[n_idx].LenofClearData))) + goto invalid_encryption; + + GST_DEBUG_OBJECT (piffdemux,"entry[%d] and lengthofClearData = %d", n_idx, stream->samples[i].sub_encry->sub_entry[n_idx].LenofClearData); + + if (!gst_byte_reader_get_uint32_be (sample_encrypt, &(stream->samples[i].sub_encry->sub_entry[n_idx].LenofEncryptData))) + goto invalid_encryption; + + GST_DEBUG_OBJECT (piffdemux,"entry[%d] and lengthofEncryptData = %d", n_idx, stream->samples[i].sub_encry->sub_entry[n_idx].LenofEncryptData); + } + } + } + + return TRUE; + +invalid_encryption: + { + GST_WARNING_OBJECT (piffdemux, "invalid sample encryption header"); + return FALSE; + } +} + + +static gboolean +piffdemux_parse_trun (GstPiffDemux * piffdemux, GstByteReader * trun, + PiffDemuxStream * stream, guint32 d_sample_duration, guint32 d_sample_size, + guint32 d_sample_flags, gint64 moof_offset, gint64 moof_length, + gint64 * base_offset, gint64 * running_offset) +{ + guint64 timestamp; + gint32 data_offset = 0; + guint32 flags = 0, first_flags = 0, samples_count = 0; + gint i; + guint8 *data; + guint entry_size, dur_offset, size_offset, flags_offset = 0, ct_offset = 0; + PiffDemuxSample *sample; + gboolean ismv = FALSE; + guint64 total_duration = 0; + + GST_LOG_OBJECT (piffdemux, "parsing trun stream ; " + "default dur %d, size %d, flags 0x%x, base offset %" G_GINT64_FORMAT, + d_sample_duration, d_sample_size, d_sample_flags, + *base_offset); + + //Resetting the samples + stream->n_samples = 0; + + if (!gst_byte_reader_skip (trun, 1) || + !gst_byte_reader_get_uint24_be (trun, &flags)) + goto fail; + + if (!gst_byte_reader_get_uint32_be (trun, &samples_count)) + goto fail; + + if (flags & TR_DATA_OFFSET) { + /* note this is really signed */ + if (!gst_byte_reader_get_int32_be (trun, &data_offset)) + goto fail; + GST_LOG_OBJECT (piffdemux, "trun data offset %d", data_offset); + /* default base offset = first byte of moof */ + if (*base_offset == -1) { + GST_LOG_OBJECT (piffdemux, "base_offset at moof and moof_offset = %"G_GINT64_FORMAT, moof_offset); + *base_offset = moof_offset; + } + *running_offset = *base_offset + data_offset; + } else { + /* if no offset at all, that would mean data starts at moof start, + * which is a bit wrong and is ismv crappy way, so compensate + * assuming data is in mdat following moof */ + if (*base_offset == -1) { + *base_offset = moof_offset + moof_length + 8; + GST_LOG_OBJECT (piffdemux, "base_offset assumed in mdat after moof"); + ismv = TRUE; + } + if (*running_offset == -1) + *running_offset = *base_offset; + } + + GST_LOG_OBJECT (piffdemux, "running offset now %" G_GINT64_FORMAT, + *running_offset); + GST_LOG_OBJECT (piffdemux, "trun offset %d, flags 0x%x, entries %d", + data_offset, flags, samples_count); + + if (flags & TR_FIRST_SAMPLE_FLAGS) { + if (G_UNLIKELY (flags & TR_SAMPLE_FLAGS)) { + GST_DEBUG_OBJECT (piffdemux, + "invalid flags; SAMPLE and FIRST_SAMPLE present, discarding latter"); + flags ^= TR_FIRST_SAMPLE_FLAGS; + } else { + if (!gst_byte_reader_get_uint32_be (trun, &first_flags)) + goto fail; + GST_LOG_OBJECT (piffdemux, "first flags: 0x%x", first_flags); + } + } + + /* FIXME ? spec says other bits should also be checked to determine + * entry size (and prefix size for that matter) */ + entry_size = 0; + dur_offset = size_offset = 0; + if (flags & TR_SAMPLE_DURATION) { + GST_LOG_OBJECT (piffdemux, "entry duration present"); + dur_offset = entry_size; + entry_size += 4; + } + if (flags & TR_SAMPLE_SIZE) { + GST_LOG_OBJECT (piffdemux, "entry size present"); + size_offset = entry_size; + entry_size += 4; + } + if (flags & TR_SAMPLE_FLAGS) { + GST_LOG_OBJECT (piffdemux, "entry flags present"); + flags_offset = entry_size; + entry_size += 4; + } + if (flags & TR_COMPOSITION_TIME_OFFSETS) { + GST_LOG_OBJECT (piffdemux, "entry ct offset present"); + ct_offset = entry_size; + entry_size += 4; + } + + if (!piff_atom_parser_has_chunks (trun, samples_count, entry_size)) + goto fail; + data = (guint8 *) gst_byte_reader_peek_data_unchecked (trun); + + if (stream->n_samples >= + PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE / sizeof (PiffDemuxSample)) + goto index_too_big; + + GST_DEBUG_OBJECT (piffdemux, "allocating n_samples %u * %u (%.2f MB)", + stream->n_samples, (guint) sizeof (PiffDemuxSample), + stream->n_samples * sizeof (PiffDemuxSample) / (1024.0 * 1024.0)); + + /* create a new array of samples if it's the first sample parsed */ + if (stream->n_samples == 0) + stream->samples = g_try_new0 (PiffDemuxSample, samples_count); + /* or try to reallocate it with space enough to insert the new samples */ + else + stream->samples = g_try_renew (PiffDemuxSample, stream->samples, + stream->n_samples + samples_count); + if (stream->samples == NULL) + goto out_of_memory; + + if (G_UNLIKELY (stream->n_samples == 0)) { + /* the timestamp of the first sample is also provided by the tfra entry + * but we shouldn't rely on it as it is at the end of files */ + timestamp = 0; + } else { + /* subsequent fragments extend stream */ + timestamp = + stream->samples[stream->n_samples - 1].timestamp + + stream->samples[stream->n_samples - 1].duration; + } + sample = stream->samples + stream->n_samples; + for (i = 0; i < samples_count; i++) { + guint32 dur, size, sflags, ct; + + /* first read sample data */ + if (flags & TR_SAMPLE_DURATION) { + dur = PIFF_UINT32 (data + dur_offset); + } else { + dur = d_sample_duration; + } + if (flags & TR_SAMPLE_SIZE) { + size = PIFF_UINT32 (data + size_offset); + } else { + size = d_sample_size; + } + + GST_DEBUG_OBJECT(piffdemux,"Size of sample %d is %d", i, size); + + if (flags & TR_FIRST_SAMPLE_FLAGS) { + if (i == 0) { + sflags = first_flags; + } else { + sflags = d_sample_flags; + } + } else if (flags & TR_SAMPLE_FLAGS) { + sflags = PIFF_UINT32 (data + flags_offset); + } else { + sflags = d_sample_flags; + } + if (flags & TR_COMPOSITION_TIME_OFFSETS) { + ct = PIFF_UINT32 (data + ct_offset); + } else { + ct = 0; + } + data += entry_size; + + /* fill the sample information */ + sample->offset = *running_offset; + sample->pts_offset = ct; + sample->size = size; + sample->timestamp = timestamp; + sample->duration = dur; + /* sample-is-difference-sample */ + /* ismv seems to use 0x40 for keyframe, 0xc0 for non-keyframe, + * now idea how it relates to bitfield other than massive LE/BE confusion */ + sample->keyframe = ismv ? ((sflags & 0xff) == 0x40) : !(sflags & 0x10000); + sample->iv = NULL; + sample->sub_encry = NULL; + + stream->samples[i] = *sample; + + *running_offset += size; + timestamp += dur; + sample++; + + /* calculate total duration of the present fragment */ + total_duration += gst_util_uint64_scale (dur, GST_SECOND, stream->timescale); + } + + stream->sample_index = 0; + + stream->n_samples += samples_count; + + /* calculate avg fps based on avg frame duration */ + stream->avg_dur = total_duration/samples_count; + g_print ("total dur = %"GST_TIME_FORMAT", avg_dur = %"GST_TIME_FORMAT"count = %d\n", + GST_TIME_ARGS(total_duration), GST_TIME_ARGS(stream->avg_dur), samples_count); + + return TRUE; + +fail: + { + GST_WARNING_OBJECT (piffdemux, "failed to parse trun"); + return FALSE; + } +out_of_memory: + { + GST_WARNING_OBJECT (piffdemux, "failed to allocate %d samples", + stream->n_samples); + return FALSE; + } +index_too_big: + { + GST_WARNING_OBJECT (piffdemux, "not allocating index of %d samples, would " + "be larger than %uMB (broken file?)", stream->n_samples, + PIFFDEMUX_MAX_SAMPLE_INDEX_SIZE >> 20); + return FALSE; + } +} + +static gboolean +piffdemux_parse_mfhd (GstPiffDemux * piffdemux, GstByteReader * mfhd) +{ + guint32 seq_num = 0; + + if (!gst_byte_reader_skip (mfhd, 4)) + goto invalid_mfhd; + + if (!gst_byte_reader_get_uint32_be (mfhd, &seq_num)) + goto invalid_mfhd; + + GST_DEBUG_OBJECT (piffdemux, "sequence number present in mfhd = %d", seq_num); + + return TRUE; + +invalid_mfhd: + { + GST_WARNING_OBJECT (piffdemux, "invalid movie fragment header"); + return FALSE; + } +} + + +static gboolean +piffdemux_parse_tfhd (GstPiffDemux * piffdemux, GstByteReader * tfhd, + guint32 * default_sample_duration, + guint32 * default_sample_size, guint32 * default_sample_flags, + gint64 * base_offset) +{ + guint32 flags = 0; + guint32 track_id = 0; + + if (!gst_byte_reader_skip (tfhd, 1) || + !gst_byte_reader_get_uint24_be (tfhd, &flags)) + goto invalid_track; + + if (!gst_byte_reader_get_uint32_be (tfhd, &track_id)) + goto invalid_track; + + GST_DEBUG_OBJECT (piffdemux, "trackID = %d", track_id); + + if (flags & TF_BASE_DATA_OFFSET) { + if (!gst_byte_reader_get_uint64_be (tfhd, (guint64 *) base_offset)) + goto invalid_track; + GST_DEBUG ("BaseData Offset = %"G_GUINT64_FORMAT, base_offset); + } + + /* FIXME: Handle TF_SAMPLE_DESCRIPTION_INDEX properly */ + if (flags & TF_SAMPLE_DESCRIPTION_INDEX) + if (!gst_byte_reader_skip (tfhd, 4)) + goto invalid_track; + + if (flags & TF_DEFAULT_SAMPLE_DURATION) + if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_duration)) + goto invalid_track; + + if (flags & TF_DEFAULT_SAMPLE_SIZE) + if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_size)) + goto invalid_track; + + if (flags & TF_DEFAULT_SAMPLE_FLAGS) + if (!gst_byte_reader_get_uint32_be (tfhd, default_sample_flags)) + goto invalid_track; + + return TRUE; + +invalid_track: + { + GST_WARNING_OBJECT (piffdemux, "invalid track fragment header"); + return FALSE; + } +} + +static gboolean +piffdemux_parse_tfxd (GstPiffDemux * piffdemux, PiffDemuxStream *stream,GstByteReader * tfxd) +{ + guint8 version = 0; + + // TODO: In my opinion, tfxd will be mainly useful when lookahead count = 0. In this case, based on this duration, next fragment timstamp can be calculted.. Need to test this using our server + + if (!gst_byte_reader_get_uint8 (tfxd, &version)) + goto invalid_tfxd; + + if (!gst_byte_reader_skip (tfxd, 3)) + goto invalid_tfxd; + + if (!piffdemux->lookahead_cnt) { + piffdemux->param = (piff_live_param_t *)malloc (sizeof (piff_live_param_t)); + if (NULL == piffdemux->param) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + return FALSE; + } + piffdemux->param->count = 1; + piffdemux->param->long_info = NULL; + piffdemux->param->info = NULL; + piffdemux->param->is_eos = FALSE; + + // TODO: presentation will be ended based on timeout in souphttpsrc in lookaheadcnt = 0 case + } + + if (version == 1) { + guint64 duration = 0; + guint64 timestamp = 0; + + GST_LOG_OBJECT (piffdemux, "Time and Duration are in 64-bit format..."); + if (!gst_byte_reader_get_uint64_be (tfxd, ×tamp)) + goto invalid_tfxd; + if (!gst_byte_reader_get_uint64_be (tfxd, &duration)) + goto invalid_tfxd; + + GST_DEBUG_OBJECT (piffdemux, "tfxd : absolute timestamp = %"G_GUINT64_FORMAT" and duration of fragment = %"G_GUINT64_FORMAT, + timestamp, duration); + + if (!piffdemux->lookahead_cnt) { + piffdemux->param->long_info = (piff_fragment_longtime_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_longtime_info)); + if (NULL == piffdemux->param->long_info) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + return FALSE; + } + + /* Calculate next fragment's timestamp using current fragment's timestamp + duration */ + piffdemux->param->long_info->duration = GST_CLOCK_TIME_NONE; + piffdemux->param->long_info->ts = timestamp +duration; + } + } else if (version == 0) { + guint32 duration = 0; + guint32 timestamp = 0; + GST_LOG_OBJECT (piffdemux, "Time and Duration are in 32-bit format..."); + + if (!gst_byte_reader_get_uint32_be (tfxd, ×tamp)) + goto invalid_tfxd; + + if (!gst_byte_reader_get_uint32_be (tfxd, &duration)) + goto invalid_tfxd; + + GST_DEBUG_OBJECT (piffdemux, "tfxd : absolute timestamp = %"G_GUINT32_FORMAT" and duration of fragment = %"G_GUINT32_FORMAT, + timestamp, duration); + + if (!piffdemux->lookahead_cnt) { + piffdemux->param->info = (piff_fragment_time_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_time_info)); + if (NULL == piffdemux->param->info) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + return FALSE; + } + /* Calculate next fragment's timestamp using current fragment's timestamp + duration */ + piffdemux->param->info->duration = GST_CLOCK_TIME_NONE; + piffdemux->param->info->ts = timestamp +duration; + } + } else { + GST_ERROR_OBJECT (piffdemux, "Invalid Version in tfxd..."); + return FALSE; + } + + if (!piffdemux->lookahead_cnt) { + GST_DEBUG_OBJECT (piffdemux, "Emitting live-param signal..."); + g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param); + } + + return TRUE; + +invalid_tfxd: + GST_ERROR ("Invalid TFXD atom..."); + return FALSE; +} + + +static gboolean +piffdemux_parse_tfrf (GstPiffDemux * piffdemux, PiffDemuxStream *stream,GstByteReader * tfrf) +{ + guint8 version = 0; + guint8 frag_cnt = 0; + guint8 i = 0; + + /* Getting version info */ + if (!gst_byte_reader_get_uint8 (tfrf, &version)) + goto invalid_tfrf; + + /* skipping reserved flags */ + if (!gst_byte_reader_skip (tfrf, 3)) + goto invalid_tfrf; + + if (!gst_byte_reader_get_uint8 (tfrf, &frag_cnt)) + goto invalid_tfrf; + + GST_INFO_OBJECT (piffdemux, "Subsequent fragments info count = %d", frag_cnt); + + piffdemux->param = (piff_live_param_t *)malloc(sizeof (piff_live_param_t)); + if (NULL == piffdemux->param) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + return FALSE; + } + + piffdemux->param->count = frag_cnt; + piffdemux->param->long_info = NULL; + piffdemux->param->info = NULL; + piffdemux->param->is_eos = FALSE; + + // TODO: Duration and timestamp values need to be posted to msl using g_signal_emit + + if (version == 1) { + guint64 duration = 0; + guint64 timestamp = 0; + GST_LOG_OBJECT (piffdemux, "Time and Duration are in 64-bit format..."); + + piffdemux->param->long_info = (piff_fragment_longtime_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_longtime_info)); + if (NULL == piffdemux->param->long_info) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + return FALSE; + } + + for (i = 0; i < frag_cnt; i++) { + if (!gst_byte_reader_get_uint64_be (tfrf, ×tamp)) + goto invalid_tfrf; + if (!gst_byte_reader_get_uint64_be (tfrf, &duration)) + goto invalid_tfrf; + GST_DEBUG_OBJECT (piffdemux, "tfrf long: absolute timestamp = %"G_GUINT64_FORMAT" and duration of fragment = %"G_GUINT64_FORMAT"\n", + timestamp, duration); + (piffdemux->param->long_info[i]).ts = timestamp; + (piffdemux->param->long_info[i]).duration = duration; + } + } else if (version == 0) { + guint32 duration = 0; + guint32 timestamp = 0; + GST_LOG_OBJECT (piffdemux, "Time and Duration are in 32-bit format..."); + + piffdemux->param->info = (piff_fragment_time_info *)malloc (piffdemux->param->count * sizeof (piff_fragment_time_info)); + if (NULL == piffdemux->param->info) { + GST_ERROR ("Memory not available...\n"); + return FALSE; + } + + for (i = 0; i < frag_cnt; i++) { + if (!gst_byte_reader_get_uint32_be (tfrf, ×tamp)) + goto invalid_tfrf; + if (!gst_byte_reader_get_uint32_be (tfrf, &duration)) + goto invalid_tfrf; + + GST_DEBUG_OBJECT (piffdemux, "tfrf int: absolute timestamp = %"G_GUINT32_FORMAT" and duration of fragment = %"G_GUINT32_FORMAT, + timestamp, duration); + (piffdemux->param->info[i]).ts = timestamp; + (piffdemux->param->info[i]).duration = duration; + } + } else { + GST_ERROR_OBJECT (piffdemux, "Invalid Version in tfrf..."); + return FALSE; + } + + g_print ("Signalling from TFRF box..\n"); + g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param); + + return TRUE; + +invalid_tfrf: + GST_ERROR_OBJECT (piffdemux, "Invalid TFRF atom..."); + return FALSE; +} + + +static gboolean +piffdemux_parse_moof (GstPiffDemux * piffdemux, const guint8 * buffer, guint length, + guint64 moof_offset, PiffDemuxStream * stream) +{ + GNode *moof_node, *mfhd_node, *traf_node, *tfhd_node, *trun_node, *uuid_node; + GstByteReader mfhd_data, trun_data, tfhd_data, uuid_data; + guint32 ds_size = 0, ds_duration = 0, ds_flags = 0; + gint64 base_offset, running_offset; + gint64 uuid_offset = 0; + gboolean found_tfxd = FALSE; + gboolean found_tfrf = FALSE; + + /* NOTE @stream ignored */ + + moof_node = g_node_new ((guint8 *) buffer); + piffdemux_parse_node (piffdemux, moof_node, buffer, length); + //piffdemux_node_dump (piffdemux, moof_node); + + /* unknown base_offset to start with */ + base_offset = running_offset = -1; + + mfhd_node = piffdemux_tree_get_child_by_type_full (moof_node, FOURCC_mfhd, &mfhd_data); + if (!mfhd_node) + goto missing_mfhd; + + if (!piffdemux_parse_mfhd (piffdemux, &mfhd_data)) + goto missing_mfhd; + + traf_node = piffdemux_tree_get_child_by_type (moof_node, FOURCC_traf); + while (traf_node) { + /* Fragment Header node */ + tfhd_node = + piffdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfhd, + &tfhd_data); + if (!tfhd_node) + goto missing_tfhd; + if (!piffdemux_parse_tfhd (piffdemux, &tfhd_data, &ds_duration, + &ds_size, &ds_flags, &base_offset)) + goto missing_tfhd; + + if (G_UNLIKELY (base_offset < -1)) + goto lost_offset; + + /* Track Run node */ + trun_node = + piffdemux_tree_get_child_by_type_full (traf_node, FOURCC_trun, + &trun_data); + while (trun_node) { + piffdemux_parse_trun (piffdemux, &trun_data, stream, + ds_duration, ds_size, ds_flags, moof_offset, length, &base_offset, + &running_offset); + /* iterate all siblings */ + trun_node = piffdemux_tree_get_sibling_by_type_full (trun_node, FOURCC_trun, + &trun_data); + } + + uuid_node = piffdemux_tree_get_child_by_type (traf_node, FOURCC_uuid); + while (uuid_node) { + uuid_type_t uuid_type; + guint8 *lbuffer = (guint8 *) uuid_node->data; + + gst_byte_reader_init (&uuid_data, lbuffer, PIFF_UINT32 (lbuffer)); + + uuid_type = piffdemux_get_uuid_type (piffdemux, &uuid_data, &uuid_offset); + + if ((UUID_TFXD == uuid_type) && piffdemux->is_live) { + // TODO: Dont know, why we should not consider tfxd offset...if we use tfxd offset also, not working.. PIFF doc does not say anything :( + found_tfxd = TRUE; + if (!piffdemux_parse_tfxd (piffdemux, stream, &uuid_data)) + goto fail; + } else if ((UUID_TFRF == uuid_type) && piffdemux->is_live && piffdemux->lookahead_cnt) { + found_tfrf = TRUE; + if (!piffdemux_parse_tfrf (piffdemux, stream, &uuid_data)) + goto fail; + piffdemux_update_sample_offset (piffdemux, stream, uuid_offset); + running_offset += uuid_offset; + } else if (UUID_SAMPLE_ENCRYPT == uuid_type) { + if (!piffdemux_parse_sample_encryption (piffdemux, &uuid_data, stream)) + goto fail; + } else { + GST_WARNING_OBJECT (piffdemux, "Ignoring Wrong UUID..."); + } + + /* iterate all siblings */ + uuid_node = piffdemux_tree_get_sibling_by_type (uuid_node, FOURCC_uuid); + } + + if (piffdemux->is_live) { + if (!found_tfxd) { + GST_ERROR_OBJECT (piffdemux, "TFXD box is not present for live stream"); + goto fail; + } + + if (!found_tfrf && piffdemux->lookahead_cnt) { + /* when lookahead count is non-zero in manifest & if tfrf box is not present., means EOS */ + GST_INFO_OBJECT (piffdemux, "Reached Endof Live presentation.."); + + piffdemux->param = (piff_live_param_t *)malloc (sizeof (piff_live_param_t)); + if (NULL == piffdemux->param) { + GST_ERROR_OBJECT (piffdemux, "Memory not available...\n"); + goto fail; + } + piffdemux->param->count = 0; + piffdemux->param->long_info = NULL; + piffdemux->param->info = NULL; + piffdemux->param->is_eos = TRUE; /* marking EOS */ + g_signal_emit (piffdemux, gst_piffdemux_signals[SIGNAL_LIVE_PARAM], 0, piffdemux->param); + } + } + + /* if no new base_offset provided for next traf, + * base is end of current traf */ + base_offset = running_offset; + running_offset = -1; + + /* iterate all siblings */ + traf_node = piffdemux_tree_get_sibling_by_type (traf_node, FOURCC_traf); + } + g_node_destroy (moof_node); + return TRUE; + +missing_mfhd: + { + GST_DEBUG_OBJECT (piffdemux, "missing mfhd box"); + goto fail; + } + +missing_tfhd: + { + GST_DEBUG_OBJECT (piffdemux, "missing tfhd box"); + goto fail; + } +lost_offset: + { + GST_DEBUG_OBJECT (piffdemux, "lost offset"); + goto fail; + } +fail: + { + g_node_destroy (moof_node); + + GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX, + ("This file is corrupt and cannot be played."), (NULL)); + + return FALSE; + } +} + + +/* activate the given segment number @seg_idx of @stream at time @offset. + * @offset is an absolute global position over all the segments. + * + * This will push out a NEWSEGMENT event with the right values and + * position the stream index to the first decodable sample before + * @offset. + */ +static gboolean +gst_piffdemux_activate_segment (GstPiffDemux * piffdemux, PiffDemuxStream * stream, + guint32 seg_idx, guint64 offset) +{ + GstEvent *event; + PiffDemuxSegment *segment; + guint64 seg_time; + guint64 start, stop, time; + gdouble rate; + + GST_LOG_OBJECT (piffdemux, "activate segment %d, offset %" G_GUINT64_FORMAT, + seg_idx, offset); + + /* update the current segment */ + stream->segment_index = seg_idx; + + /* get the segment */ + segment = &stream->segments[seg_idx]; + + if (G_UNLIKELY (offset < segment->time)) { + GST_WARNING_OBJECT (piffdemux, "offset < segment->time %" G_GUINT64_FORMAT, + segment->time); + return FALSE; + } + + /* segment lies beyond total indicated duration */ + if (G_UNLIKELY (piffdemux->segment.duration != -1 && + segment->time > piffdemux->segment.duration)) { + GST_WARNING_OBJECT (piffdemux, "file duration %" G_GINT64_FORMAT + " < segment->time %" G_GUINT64_FORMAT, piffdemux->segment.duration, + segment->time); + return FALSE; + } + + /* get time in this segment */ + seg_time = offset - segment->time; + + GST_LOG_OBJECT (piffdemux, "seg_time %" GST_TIME_FORMAT, + GST_TIME_ARGS (seg_time)); + + if (G_UNLIKELY (seg_time > segment->duration)) { + GST_LOG_OBJECT (piffdemux, "seg_time > segment->duration %" GST_TIME_FORMAT, + GST_TIME_ARGS (segment->duration)); + return FALSE; + } + + /* piffdemux->segment.stop is in outside-time-realm, whereas + * segment->media_stop is in track-time-realm. + * + * In order to compare the two, we need to bring segment.stop + * into the track-time-realm */ + + stop = piffdemux->segment.stop; + if (stop == -1) + stop = piffdemux->segment.duration; + if (stop == -1) + stop = segment->media_stop; + else + stop = + MIN (segment->media_stop, stop - segment->time + segment->media_start); + + if (piffdemux->segment.rate >= 0) { + start = MIN (segment->media_start + seg_time, stop); + time = offset; + } else { + if (segment->media_start >= piffdemux->segment.start) { + start = segment->media_start; + time = segment->time; + } else { + start = piffdemux->segment.start; + time = segment->time + (piffdemux->segment.start - segment->media_start); + } + + start = MAX (segment->media_start, piffdemux->segment.start); + stop = MIN (segment->media_start + seg_time, stop); + } + + GST_DEBUG_OBJECT (piffdemux, "newsegment %d from %" GST_TIME_FORMAT + " to %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT, seg_idx, + GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time)); + + /* combine global rate with that of the segment */ + rate = segment->rate * piffdemux->segment.rate; + + /* update the segment values used for clipping */ + gst_segment_init (&stream->segment, GST_FORMAT_TIME); + gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME, + start, stop, time); + + /* now prepare and send the segment */ + event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME, + start, stop, time); + gst_pad_push_event (piffdemux->srcpad, event); + /* assume we can send more data now */ + stream->last_ret = GST_FLOW_OK; + /* clear to send tags on this pad now */ + gst_piffdemux_push_tags (piffdemux, stream); + + return TRUE; +} + + +/* prepare to get the current sample of @stream, getting essential values. + * + * This function will also prepare and send the segment when needed. + * + * Return FALSE if the stream is EOS. + */ +static gboolean +gst_piffdemux_prepare_current_sample (GstPiffDemux * piffdemux, + PiffDemuxStream * stream, guint64 * offset, guint * size, guint64 * timestamp, + guint64 * duration, gboolean * keyframe) +{ + PiffDemuxSample *sample; + guint64 time_position; + guint32 seg_idx; + + g_return_val_if_fail (stream != NULL, FALSE); + + time_position = stream->time_position; + if (G_UNLIKELY (time_position == -1)) + goto eos; + + seg_idx = stream->segment_index; + if (G_UNLIKELY (seg_idx == -1)) { + /* find segment corresponding to time_position if we are looking + * for a segment. */ + seg_idx = gst_piffdemux_find_segment (piffdemux, stream, time_position); + + /* nothing found, we're really eos */ + if (seg_idx == -1) + goto eos; + } + + /* different segment, activate it, sample_index will be set. */ + if (G_UNLIKELY (stream->segment_index != seg_idx)) + gst_piffdemux_activate_segment (piffdemux, stream, seg_idx, time_position); + + GST_LOG_OBJECT (piffdemux, "segment active, index = %u of %u", + stream->sample_index, stream->n_samples); + + if (G_UNLIKELY (stream->sample_index >= stream->n_samples)) + goto eos; + + + /* now get the info for the sample we're at */ + sample = &stream->samples[stream->sample_index]; + + *timestamp = PIFFSAMPLE_PTS (stream, sample); + *offset = sample->offset; + *size = sample->size; + *duration = PIFFSAMPLE_DUR_PTS (stream, sample, *timestamp); + *keyframe = PIFFSAMPLE_KEYFRAME (stream, sample); + + return TRUE; + + /* special cases */ +eos: + { + stream->time_position = -1; + return FALSE; + } +} + +/* the input buffer metadata must be writable, + * but time/duration etc not yet set and need not be preserved */ +static GstBuffer * +gst_piffdemux_process_buffer (GstPiffDemux * piffdemux, PiffDemuxStream * stream, + GstBuffer * buf) +{ + guint8 *data; + guint size, nsize = 0; + gchar *str; + + data = GST_BUFFER_DATA (buf); + size = GST_BUFFER_SIZE (buf); + + if (G_UNLIKELY (stream->subtype != FOURCC_text)) { + return buf; + } + + if (G_LIKELY (size >= 2)) { + nsize = GST_READ_UINT16_BE (data); + nsize = MIN (nsize, size - 2); + } + + GST_LOG_OBJECT (piffdemux, "3GPP timed text subtitle: %d/%d", nsize, size); + + /* takes care of UTF-8 validation or UTF-16 recognition, + * no other encoding expected */ + str = gst_tag_freeform_string_to_utf8 ((gchar *) data + 2, nsize, NULL); + if (str) { + gst_buffer_unref (buf); + buf = gst_buffer_new (); + GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = (guint8 *) str; + GST_BUFFER_SIZE (buf) = strlen (str); + } else { + /* may be 0-size subtitle, which is also sent to keep pipeline going */ + GST_BUFFER_DATA (buf) = data + 2; + GST_BUFFER_SIZE (buf) = nsize; + } + + /* FIXME ? convert optional subsequent style info to markup */ + + return buf; +} + +/* Sets a buffer's attributes properly and pushes it downstream. + * Also checks for additional actions and custom processing that may + * need to be done first. + */ +static gboolean +gst_piffdemux_decorate_and_push_buffer (GstPiffDemux * piffdemux, + PiffDemuxStream * stream, GstBuffer * buf, + guint64 timestamp, guint64 duration, gboolean keyframe, guint64 position, + guint64 byte_position) +{ + GstFlowReturn ret = GST_FLOW_OK; + + if (!stream->caps) { + GST_WARNING_OBJECT (piffdemux, "caps are empty...creat any caps"); + stream->caps = gst_caps_new_any(); + if (!stream->caps) { + GST_ERROR_OBJECT (piffdemux, "failed to create caps..."); + ret = GST_FLOW_ERROR; + goto exit; + } + } + + /* position reporting */ + if (piffdemux->segment.rate >= 0) { + // TODO: Segment fault is coming here for Audio stream.. need to check + + gst_segment_set_last_stop (&piffdemux->segment, GST_FORMAT_TIME, position); + //gst_piffdemux_sync_streams (piffdemux); + } + + /* send out pending buffers */ + while (stream->buffers) { + GstBuffer *buffer = (GstBuffer *) stream->buffers->data; + + if (G_UNLIKELY (stream->discont)) { + GST_LOG_OBJECT (piffdemux, "marking discont buffer"); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT); + stream->discont = FALSE; + } + gst_buffer_set_caps (buffer, stream->caps); + + gst_pad_push (piffdemux->srcpad, buffer); + + stream->buffers = g_slist_delete_link (stream->buffers, stream->buffers); + } + + /* we're going to modify the metadata */ + buf = gst_buffer_make_metadata_writable (buf); + + /* for subtitle processing */ + if (G_UNLIKELY (stream->need_process)) + buf = gst_piffdemux_process_buffer (piffdemux, stream, buf); + + GST_BUFFER_TIMESTAMP (buf) = timestamp; + GST_BUFFER_DURATION (buf) = duration; + GST_BUFFER_OFFSET (buf) = -1; + GST_BUFFER_OFFSET_END (buf) = -1; + + if (G_UNLIKELY (stream->padding)) { + GST_BUFFER_DATA (buf) += stream->padding; + GST_BUFFER_SIZE (buf) -= stream->padding; + } + + if (G_UNLIKELY (buf == NULL)) + goto exit; + + if (G_UNLIKELY (stream->discont)) { + GST_LOG_OBJECT (piffdemux, "marking discont buffer"); + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); + stream->discont = FALSE; + } + + if (!keyframe) + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); + + //g_print ("\n\npad caps : %s\n\n", gst_caps_to_string (gst_pad_get_caps (stream->pad))); + + //gst_buffer_set_caps (buf, stream->caps); // commenting to avoid caps by setting properties + + // TODO: need to see how resolution switch will work + gst_buffer_set_caps (buf, stream->caps); + +#ifdef DRM_ENABLE + if (piffdemux->encrypt_content) { + drm_trusted_payload_info_s read_input_data = {0, }; + drm_trusted_read_decrypt_resp_data_s read_output_data = {0, }; + gint offset = 0; + PiffDemuxSample *sample = &stream->samples[stream->sample_index]; + + if (sample->sub_encry) { + offset = sample->sub_encry->sub_entry[0].LenofClearData; + } + + read_input_data.media_offset = 0; + read_input_data.payload_data = GST_BUFFER_DATA(buf) + offset; + read_input_data.payload_data_len = GST_BUFFER_SIZE(buf) - offset; + read_input_data.payload_iv_len = 8; + read_input_data.payload_iv = (unsigned char *) malloc (8); + read_input_data.payload_data_output = GST_BUFFER_DATA(buf) + offset; + if (NULL == read_input_data.payload_iv) { + GST_ERROR ("Failed to allocate memory..."); + ret = GST_FLOW_ERROR; + goto exit; + } + memcpy (read_input_data.payload_iv, sample->iv, 8); + + ret = drm_trusted_read_decrypt_session(piffdemux->pr_handle , &read_input_data, &read_output_data); + if (DRM_TRUSTED_RETURN_SUCCESS != ret) { + GST_ERROR_OBJECT (piffdemux, "failed to decrypt buffer..."); + free (read_input_data.payload_iv); + ret = GST_FLOW_ERROR; + goto exit; + } + + if (read_output_data.read_size != read_input_data.payload_data_len) { + g_print ("Decrypter did not consume data fully...\n\n\n"); + } + + free (read_input_data.payload_iv); + read_input_data.payload_iv = NULL; + + } +#endif + + GST_LOG_OBJECT (piffdemux, + "Pushing buffer of size = %d with time %" GST_TIME_FORMAT ", duration %" + GST_TIME_FORMAT, GST_BUFFER_SIZE(buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); + +#ifdef DEC_OUT_FRAME_DUMP + { + int written = 0; + written = fwrite (GST_BUFFER_DATA (buf), sizeof (unsigned char), GST_BUFFER_SIZE (buf), piffdump); + g_print ("PIFFDEMUX: written = %d\n", written); + fflush (piffdump); + } +#endif + + ret = gst_pad_push (piffdemux->srcpad, buf); + +exit: + return ret; +} + + +/* + * next_entry_size + * + * Returns the size of the first entry at the current offset. + * If -1, there are none (which means EOS or empty file). + */ +static guint64 +next_entry_size (GstPiffDemux * demux) +{ + PiffDemuxStream *stream = demux->stream; + PiffDemuxSample *sample; + + GST_LOG_OBJECT (demux, "Finding entry at offset %" G_GUINT64_FORMAT, + demux->offset); + + GST_DEBUG_OBJECT (demux, "demux->sample_index = %d", stream->sample_index); + + if (stream->sample_index == -1) + stream->sample_index = 0; + + if (stream->sample_index >= stream->n_samples) { + GST_LOG_OBJECT (demux, "stream %d samples exhausted n_samples = %d", + stream->sample_index, stream->n_samples); + return -1; + } + + sample = &stream->samples[stream->sample_index]; + + GST_LOG_OBJECT (demux, + "Checking Stream %d (sample_index:%d / offset:%" G_GUINT64_FORMAT + " / size:%" G_GUINT32_FORMAT ")", stream->sample_index, stream->sample_index, + sample->offset, sample->size); + + GST_LOG_OBJECT (demux, "stream : demux->offset :%"G_GUINT64_FORMAT, demux->offset); + + stream = demux->stream; + sample = &stream->samples[stream->sample_index]; + + if (sample->offset >= demux->offset) { + demux->todrop = sample->offset - demux->offset; + return sample->size + demux->todrop; + } + + GST_DEBUG_OBJECT (demux, + "There wasn't any entry at offset %" G_GUINT64_FORMAT, demux->offset); + return -1; +} + +static void +gst_piffdemux_post_progress (GstPiffDemux * demux, gint num, gint denom) +{ + gint perc = (gint) ((gdouble) num * 100.0 / (gdouble) denom); + + gst_element_post_message (GST_ELEMENT_CAST (demux), + gst_message_new_element (GST_OBJECT_CAST (demux), + gst_structure_new ("progress", "percent", G_TYPE_INT, perc, NULL))); +} + +static gboolean +piffdemux_seek_offset (GstPiffDemux * demux, guint64 offset) +{ + GstEvent *event; + gboolean res = 0; + + GST_DEBUG_OBJECT (demux, "Seeking to %" G_GUINT64_FORMAT, offset); + + event = + gst_event_new_seek (1.0, GST_FORMAT_BYTES, + GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset, + GST_SEEK_TYPE_NONE, -1); + + res = gst_pad_push_event (demux->sinkpad, event); + + return res; +} + +static GstFlowReturn +gst_piffdemux_chain (GstPad * sinkpad, GstBuffer * inbuf) +{ + GstPiffDemux *demux; + GstFlowReturn ret = GST_FLOW_OK; + demux = GST_PIFFDEMUX (gst_pad_get_parent (sinkpad)); +#ifdef DRM_ENABLE + if (demux->encrypt_content && !demux->decrypt_init) { + int ret = -1; + drm_trusted_permission_type_e perm_type = DRM_TRUSTED_PERMISSION_TYPE_PLAY; + drm_trusted_open_decrypt_info_s open_input_data = {0, }; + drm_trusted_open_decrypt_resp_data_s open_output_data = {0, }; + drm_trusted_set_consumption_state_info_s state_input_data = {0, }; + + open_input_data.file_type = DRM_TRUSTED_TYPE_PIFF; + open_input_data.permission = perm_type; + open_input_data.operation_callback.callback = test_drm_trusted_operation_cb; + open_input_data.lic_header.header = GST_BUFFER_DATA(demux->protection_header); + open_input_data.lic_header.header_len = GST_BUFFER_SIZE (demux->protection_header); + + /* Open Decrypt Session*/ + ret = drm_trusted_open_decrypt_session(&open_input_data, &open_output_data, &(demux->pr_handle)); + if (DRM_TRUSTED_RETURN_SUCCESS != ret) { + GST_ERROR_OBJECT (demux, "failed to open decrypt session"); + goto unknown_stream; + } + + /* Before Read, Appropriate state MUST be SET */ + state_input_data.state = DRM_CONSUMPTION_STARTED; + ret = drm_trusted_set_decrypt_state(demux->pr_handle, &state_input_data); + if (DRM_TRUSTED_RETURN_SUCCESS != ret) { + GST_ERROR_OBJECT (demux, "failed to set decrypt state..."); + goto unknown_stream; + } + + demux->decrypt_init = TRUE; + } +#endif + gst_adapter_push (demux->adapter, inbuf); + + /* we never really mean to buffer that much */ + if (demux->neededbytes == -1) + goto eos; + + GST_DEBUG_OBJECT (demux, "pushing in inbuf %p, neededbytes:%u, available:%u", + inbuf, demux->neededbytes, gst_adapter_available (demux->adapter)); + + while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) && + (ret == GST_FLOW_OK)) { + + GST_DEBUG_OBJECT (demux, + "state:%d , demux->neededbytes:%d, demux->offset:%" G_GUINT64_FORMAT, + demux->state, demux->neededbytes, demux->offset); + + switch (demux->state) { + case PIFFDEMUX_STATE_INITIAL:{ + const guint8 *data; + guint32 fourcc; + guint64 size; + + data = gst_adapter_peek (demux->adapter, demux->neededbytes); + + /* get fourcc/length, set neededbytes */ + extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes, + &size, &fourcc); + GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] " + "size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size); + if (size == 0) { + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, + ("This file is invalid and cannot be played."), + ("initial atom '%" GST_FOURCC_FORMAT "' has empty length", + GST_FOURCC_ARGS (fourcc))); + + ret = GST_FLOW_ERROR; + break; + } + + if (fourcc == FOURCC_mdat) { + if (demux->moof_rcvd) { + /* we have the headers, start playback */ + demux->state = PIFFDEMUX_STATE_MOVIE; + demux->neededbytes = next_entry_size (demux); + demux->mdatleft = size; + + /* Only post, event on pads is done after newsegment */ + piffdemux_post_global_tags (demux); + } else { + GST_ERROR_OBJECT (demux, "mdata received before moof.. not handled"); + goto unknown_stream; + } + } else if (G_UNLIKELY (size > PIFFDEMUX_MAX_ATOM_SIZE)) { + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, + ("This file is invalid and cannot be played."), + ("atom %" GST_FOURCC_FORMAT " has bogus size %" G_GUINT64_FORMAT, + GST_FOURCC_ARGS (fourcc), size)); + ret = GST_FLOW_ERROR; + break; + } else { + demux->neededbytes = size; + demux->state = PIFFDEMUX_STATE_HEADER; + } + break; + } + case PIFFDEMUX_STATE_HEADER:{ + const guint8 *data; + guint32 fourcc; + + GST_DEBUG_OBJECT (demux, "In header"); + + data = gst_adapter_peek (demux->adapter, demux->neededbytes); + + /* parse the header */ + extract_initial_length_and_fourcc (data, demux->neededbytes, NULL, + &fourcc); + if (fourcc == FOURCC_moof) { + GST_DEBUG_OBJECT (demux, "Parsing [moof]"); + if (!piffdemux_parse_moof (demux, data, demux->neededbytes, + demux->offset, demux->stream)) { + ret = GST_FLOW_ERROR; + goto done; + } + demux->moof_rcvd = TRUE; + } else { + GST_WARNING_OBJECT (demux, + "Unknown fourcc while parsing header : %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (fourcc)); + /* Let's jump that one and go back to initial state */ + } + + if (demux->mdatbuffer) { + /* the mdat was before the header */ + GST_DEBUG_OBJECT (demux, "We have mdatbuffer:%p", + demux->mdatbuffer); + gst_adapter_clear (demux->adapter); + demux->mdatbuffer = NULL; + demux->offset = demux->mdatoffset; + demux->neededbytes = next_entry_size (demux); + demux->state = PIFFDEMUX_STATE_MOVIE; + demux->mdatleft = gst_adapter_available (demux->adapter); + + /* Only post, event on pads is done after newsegment */ + piffdemux_post_global_tags (demux); + } else { + GST_DEBUG_OBJECT (demux, "Carrying on normally"); + gst_adapter_flush (demux->adapter, demux->neededbytes); + demux->offset += demux->neededbytes; + demux->neededbytes = 16; + demux->state = PIFFDEMUX_STATE_INITIAL; + } + + break; + } + case PIFFDEMUX_STATE_BUFFER_MDAT:{ + GstBuffer *buf; + + GST_DEBUG_OBJECT (demux, "Got our buffer at offset %" G_GUINT64_FORMAT, + demux->offset); + buf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes); + GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (PIFF_FOURCC (GST_BUFFER_DATA (buf) + 4))); + if (demux->mdatbuffer) + demux->mdatbuffer = gst_buffer_join (demux->mdatbuffer, buf); + else + demux->mdatbuffer = buf; + demux->offset += demux->neededbytes; + demux->neededbytes = 16; + demux->state = PIFFDEMUX_STATE_INITIAL; + gst_piffdemux_post_progress (demux, 1, 1); + + break; + } + case PIFFDEMUX_STATE_MOVIE:{ + GstBuffer *outbuf; + PiffDemuxStream *stream = demux->stream; + PiffDemuxSample *sample; + guint64 timestamp, duration, position; + gboolean keyframe; + + GST_DEBUG_OBJECT (demux, + "BEGIN // in MOVIE for offset %" G_GUINT64_FORMAT, demux->offset); + + if (demux->fragmented) { + GST_DEBUG_OBJECT (demux, "mdat remaining %" G_GUINT64_FORMAT, + demux->mdatleft); + if (G_LIKELY (demux->todrop < demux->mdatleft)) { + /* if needed data starts within this atom, + * then it should not exceed this atom */ + if (G_UNLIKELY (demux->neededbytes > demux->mdatleft)) { + + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, + ("This file is invalid and cannot be played."), + ("sample data crosses atom boundary")); + + ret = GST_FLOW_ERROR; + break; + } + demux->mdatleft -= demux->neededbytes; + } else { + GST_DEBUG_OBJECT (demux, "data atom emptied; resuming atom scan"); + /* so we are dropping more than left in this atom */ + demux->todrop -= demux->mdatleft; + demux->neededbytes -= demux->mdatleft; + demux->mdatleft = 0; + /* need to resume atom parsing so we do not miss any other pieces */ + demux->state = PIFFDEMUX_STATE_INITIAL; + demux->neededbytes = 16; + break; + } + } + + if (demux->todrop) { + GST_LOG_OBJECT (demux, "Dropping %d bytes", demux->todrop); + gst_adapter_flush (demux->adapter, demux->todrop); + demux->neededbytes -= demux->todrop; + demux->offset += demux->todrop; + } + + if ( !stream->sent_nsevent) { + //TODO: better to parse sink event function and send that new_segment +#if 1 + demux->pending_newsegment = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + demux->stream->start_ts, -1, demux->stream->start_ts); +#else + demux->pending_newsegment = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, + 0, gst_util_uint64_scale (stream->duration, GST_SECOND, stream->timescale), 0); +#endif + + GST_INFO_OBJECT (demux, "New segment event : start = %"GST_TIME_FORMAT", stop = %" GST_TIME_FORMAT, + GST_TIME_ARGS (demux->stream->start_ts), GST_TIME_ARGS(gst_util_uint64_scale (stream->duration, GST_SECOND, stream->timescale))); + + if (!gst_pad_push_event (demux->srcpad, demux->pending_newsegment)) { + GST_ERROR_OBJECT (demux, "failding to send new segment..."); + goto newsegment_error; + } + stream->sent_nsevent = TRUE; + } + + /* Put data in a buffer, set timestamps, caps, ... */ + outbuf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes); + + GST_DEBUG_OBJECT (demux, "Taken %d size buffer from adapter...", outbuf ? GST_BUFFER_SIZE (outbuf) : 0); + + GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (stream->fourcc)); + + g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); + + sample = &stream->samples[stream->sample_index]; + + GST_DEBUG_OBJECT (demux, "start_ts = %"GST_TIME_FORMAT" ts : %"GST_TIME_FORMAT" ts = %llu, pts_offset = %u, scale = %d\n", + GST_TIME_ARGS(stream->start_ts),GST_TIME_ARGS(sample->timestamp), sample->timestamp, + sample->pts_offset,stream->timescale); + + position = PIFFSAMPLE_DTS (stream, sample); + timestamp = PIFFSAMPLE_PTS (stream, sample) + stream->start_ts; // Adding to avoid resetting of timestamp + duration = PIFFSAMPLE_DUR_DTS (stream, sample, position); + keyframe = PIFFSAMPLE_KEYFRAME (stream, sample); + + ret = gst_piffdemux_decorate_and_push_buffer (demux, stream, outbuf, + timestamp, duration, keyframe, position, demux->offset); + + stream->sample_index++; + + /* update current offset and figure out size of next buffer */ + GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u", + demux->offset, demux->neededbytes); + demux->offset += demux->neededbytes; + GST_LOG_OBJECT (demux, "offset is now %" G_GUINT64_FORMAT, + demux->offset); + + if ((demux->neededbytes = next_entry_size (demux)) == -1) { + GST_DEBUG_OBJECT (demux, "finished parsing mdat, need to search next moof atom"); + demux->neededbytes = 16; + demux->state = PIFFDEMUX_STATE_INITIAL; + GST_DEBUG ("\n\n Storing %s last_ts %"GST_TIME_FORMAT"\n\n", stream->subtype == FOURCC_vide ? "video" : "audio", GST_TIME_ARGS(timestamp)); + stream->start_ts = timestamp + duration; + //goto eos; + } + break; + } + default: + goto invalid_state; + } + } + + /* when buffering movie data, at least show user something is happening */ + if (ret == GST_FLOW_OK && demux->state == PIFFDEMUX_STATE_BUFFER_MDAT && + gst_adapter_available (demux->adapter) <= demux->neededbytes) { + gst_piffdemux_post_progress (demux, gst_adapter_available (demux->adapter), + demux->neededbytes); + } +done: + gst_object_unref (demux); + + return ret; + + /* ERRORS */ +unknown_stream: + { + GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), ("unknown stream found")); + ret = GST_FLOW_ERROR; + goto done; + } +eos: + { + GST_DEBUG_OBJECT (demux, "no next entry, EOS"); + ret = GST_FLOW_UNEXPECTED; + goto done; + } +invalid_state: + { + GST_ELEMENT_ERROR (demux, STREAM, FAILED, + (NULL), ("piffdemuxer invalid state %d", demux->state)); + ret = GST_FLOW_ERROR; + goto done; + } +newsegment_error: + { + GST_ELEMENT_ERROR (demux, STREAM, FAILED, + (NULL), ("could not send newsegment event")); + ret = GST_FLOW_ERROR; + goto done; + } +} + +static gboolean +piffdemux_parse_container (GstPiffDemux * piffdemux, GNode * node, const guint8 * buf, + const guint8 * end) +{ + while (G_UNLIKELY (buf < end)) { + GNode *child; + guint32 len; + + if (G_UNLIKELY (buf + 4 > end)) { + GST_LOG_OBJECT (piffdemux, "buffer overrun"); + break; + } + len = PIFF_UINT32 (buf); + if (G_UNLIKELY (len == 0)) { + GST_LOG_OBJECT (piffdemux, "empty container"); + break; + } + if (G_UNLIKELY (len < 8)) { + GST_WARNING_OBJECT (piffdemux, "length too short (%d < 8)", len); + break; + } + if (G_UNLIKELY (len > (end - buf))) { + GST_WARNING_OBJECT (piffdemux, "length too long (%d > %d)", len, + (gint) (end - buf)); + break; + } + + child = g_node_new ((guint8 *) buf); + g_node_append (node, child); + GST_LOG_OBJECT (piffdemux, "adding new node of len %d", len); + piffdemux_parse_node (piffdemux, child, buf, len); + + buf += len; + } + return TRUE; +} + + +static gboolean +piffdemux_parse_node (GstPiffDemux * piffdemux, GNode * node, const guint8 * buffer, + guint length) +{ + guint32 fourcc = 0; + guint32 node_length = 0; + const PiffNodeType *type; + const guint8 *end; + + GST_LOG_OBJECT (piffdemux, "piffdemux_parse buffer %p length %u", buffer, length); + + if (G_UNLIKELY (length < 8)) + goto not_enough_data; + + node_length = PIFF_UINT32 (buffer); + fourcc = PIFF_FOURCC (buffer + 4); + + /* ignore empty nodes */ + if (G_UNLIKELY (fourcc == 0 || node_length == 8)) + return TRUE; + + type = piffdemux_type_get (fourcc); + + end = buffer + length; + + GST_LOG_OBJECT (piffdemux, + "parsing '%" GST_FOURCC_FORMAT "', length=%u, name '%s'", + GST_FOURCC_ARGS (fourcc), node_length, type->name); + + if (node_length > length) + goto broken_atom_size; + + if (type->flags & PIFF_FLAG_CONTAINER) { + piffdemux_parse_container (piffdemux, node, buffer + 8, end); + } + GST_LOG_OBJECT (piffdemux, "parsed '%" GST_FOURCC_FORMAT "'", + GST_FOURCC_ARGS (fourcc)); + return TRUE; + +/* ERRORS */ +not_enough_data: + { + + GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX, + ("This file is corrupt and cannot be played."), + ("Not enough data for an atom header, got only %u bytes", length)); + + return FALSE; + } +broken_atom_size: + { + GST_ELEMENT_ERROR (piffdemux, STREAM, DEMUX, + ("This file is corrupt and cannot be played."), + ("Atom '%" GST_FOURCC_FORMAT "' has size of %u bytes, but we have only " + "%u bytes available.", GST_FOURCC_ARGS (fourcc), node_length, + length)); + + return FALSE; + } +} + + +static GNode * +piffdemux_tree_get_child_by_type (GNode * node, guint32 fourcc) +{ + GNode *child; + guint8 *buffer; + guint32 child_fourcc; + + for (child = g_node_first_child (node); child; + child = g_node_next_sibling (child)) { + buffer = (guint8 *) child->data; + + child_fourcc = PIFF_FOURCC (buffer + 4); + + if (G_UNLIKELY (child_fourcc == fourcc)) { + return child; + } + } + return NULL; +} + +static GNode * +piffdemux_tree_get_child_by_type_full (GNode * node, guint32 fourcc, + GstByteReader * parser) +{ + GNode *child; + guint8 *buffer; + guint32 child_fourcc, child_len; + + for (child = g_node_first_child (node); child; + child = g_node_next_sibling (child)) { + buffer = (guint8 *) child->data; + + child_len = PIFF_UINT32 (buffer); + child_fourcc = PIFF_FOURCC (buffer + 4); + + if (G_UNLIKELY (child_fourcc == fourcc)) { + if (G_UNLIKELY (child_len < (4 + 4))) + return NULL; + /* FIXME: must verify if atom length < parent atom length */ + gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4)); + return child; + } + } + return NULL; +} + +static GNode * +piffdemux_tree_get_sibling_by_type_full (GNode * node, guint32 fourcc, + GstByteReader * parser) +{ + GNode *child; + guint8 *buffer; + guint32 child_fourcc, child_len; + + for (child = g_node_next_sibling (node); child; + child = g_node_next_sibling (child)) { + buffer = (guint8 *) child->data; + + child_fourcc = PIFF_FOURCC (buffer + 4); + + if (child_fourcc == fourcc) { + if (parser) { + child_len = PIFF_UINT32 (buffer); + if (G_UNLIKELY (child_len < (4 + 4))) + return NULL; + /* FIXME: must verify if atom length < parent atom length */ + gst_byte_reader_init (parser, buffer + (4 + 4), child_len - (4 + 4)); + } + return child; + } + } + return NULL; +} + +static GNode * +piffdemux_tree_get_sibling_by_type (GNode * node, guint32 fourcc) +{ + return piffdemux_tree_get_sibling_by_type_full (node, fourcc, NULL); +} + +#define _codec(name) \ + do { \ + if (codec_name) { \ + *codec_name = g_strdup (name); \ + } \ + } while (0) + +void +gst_piffdemux_set_video_params (GstPiffDemux * piffdemux, guint fourcc, + guint width, guint height, + guint fps_n, guint fps_d, unsigned char *codec_data, unsigned int codec_data_len) +{ + GstCaps *caps = NULL; + GstBuffer *dci = NULL; + + if (codec_data && codec_data_len) { + dci = gst_buffer_new_and_alloc (codec_data_len); + if (!dci) { + GST_ERROR_OBJECT (piffdemux, "failed to create codec data buffer..."); + } else { + memcpy (GST_BUFFER_DATA(dci), codec_data, codec_data_len); + } + } + + switch (fourcc) { + + case GST_MAKE_FOURCC ('a', 'v', 'c', '1'): + caps = gst_caps_new_simple ("video/x-h264", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "stream-format", G_TYPE_STRING, "avc", + "alignment", G_TYPE_STRING, "au", + "codec_data", GST_TYPE_BUFFER, dci, + NULL); + break; + + case FOURCC_ovc1: + caps = gst_caps_new_simple ("video/x-wmv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "wmvversion", G_TYPE_INT, 3, + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'), + "codec_data", GST_TYPE_BUFFER, dci, + NULL); + break; + + default: { + char *s; + s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (fourcc)); + caps = gst_caps_new_simple (s, + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + "framerate", GST_TYPE_FRACTION, fps_n, fps_d, + "codec_data", GST_TYPE_BUFFER, dci, + NULL); + break; + } + } + + piffdemux->stream->caps = caps; + gchar *caps_string = gst_caps_to_string(caps); + GST_INFO_OBJECT (piffdemux, "prepared video caps : %s", caps_string); + g_free(caps_string); + caps_string = NULL; +} + +void +gst_piffdemux_set_audio_params (GstPiffDemux * piffdemux, guint fourcc, + guint sampling_rate, guint bps, guint channels, unsigned char *codec_data, unsigned int codec_data_len) +{ + GstCaps *caps = NULL; + GstBuffer *dci = NULL; + + if (codec_data && codec_data_len) { + dci = gst_buffer_new_and_alloc (codec_data_len); + if (!dci) { + GST_ERROR_OBJECT (piffdemux, "failed to create codec data buffer..."); + } else { + memcpy (GST_BUFFER_DATA(dci), codec_data, codec_data_len); + } + } + + switch (fourcc) { + + case GST_MAKE_FOURCC ('m', 'p', '4', 'a'): + caps = gst_caps_new_simple ("audio/mpeg", + "mpegversion", G_TYPE_INT, 4, + "framed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, "raw", + "rate", G_TYPE_INT, (int) sampling_rate, + "channels", G_TYPE_INT, channels, + NULL); + break; + + case FOURCC_owma: + caps = gst_caps_new_simple ("audio/x-wma", + "rate", G_TYPE_INT, (int) sampling_rate, + "channels", G_TYPE_INT, channels, + NULL); + break; + + default: { + char *s; + s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (fourcc)); + caps = gst_caps_new_simple (s, + "rate", G_TYPE_INT, (int) sampling_rate, + "channels", G_TYPE_INT, channels, + NULL); + break; + } + } + + piffdemux->stream->caps = caps; + char *tmp_caps_name = gst_caps_to_string(caps); + GST_INFO_OBJECT (piffdemux, "prepared audio caps : %s", tmp_caps_name); + g_free(tmp_caps_name); + +} + +#define g_marshal_value_peek_object(v) g_value_get_object (v) + +void +__gst_piffdemux_marshal_BOOLEAN__OBJECT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT) (gpointer data1, + gpointer arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__OBJECT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__OBJECT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_object (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +#define PIFFDEMUX_SPSPPS_LENGTH_SIZE 2 + +static gboolean +ConvertH264_MetaDCI_to_3GPPDCI(unsigned char *dci_meta_buf, unsigned int dci_meta_size, unsigned char **dci_3gpp_buf, unsigned int *dci_3gpp_size) +{ + unsigned short unit_size = 0; + unsigned int total_size = 0; + unsigned char unit_nb = 0; + unsigned char sps_done = 0; + const unsigned char *extradata = NULL; + unsigned int h264_nal_length_size = 0; + unsigned char *out = NULL; + //g_print ("\n\nConvertH264_MetaDCI_to_3GPPDCI Entering.............\n"); + + /* nothing to filter */ + if ((dci_meta_buf == NULL) || (dci_meta_size < 6)) + { + GST_ERROR ("Insufficient codec data...\n"); + return FALSE; + } + + /* Removing unnecessary info in meta data */ + extradata = (unsigned char *)dci_meta_buf + 4; + + /* retrieve Length of Length*/ + h264_nal_length_size = (*extradata++ & 0x03) + 1; + + GST_LOG ("Length Of Length is %d\n", h264_nal_length_size); + if (h264_nal_length_size == 3) + { + GST_ERROR ("LengthOfLength is WRONG...\n"); + return FALSE; + } + + /* retrieve sps and pps unit(s) */ + unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ + GST_LOG ("No. of SPS units = %u\n", unit_nb); + + if (!unit_nb) + { + GST_ERROR ("SPS is not present....\n"); + return FALSE; + } + + while (unit_nb--) + { + /* get SPS/PPS data Length*/ + unit_size = PIFFDEMUX_RB16(extradata); + + GST_LOG ("SPS size = %d", unit_size); + + /* Extra 4 bytes for adding size of the packet */ + total_size += unit_size + h264_nal_length_size; + + /* Check if SPS/PPS Data Length crossed buffer Length */ + if ((extradata + 2 + unit_size) > (dci_meta_buf + dci_meta_size)) + { + GST_ERROR ("SPS Length is wrong in DCI...\n"); + if (out) + { + free (out); + } + return FALSE; + } + out = realloc(out, total_size); + if (!out) + { + GST_ERROR ("realloc FAILED...\n"); + return FALSE; + } + /* Copy length of SPS header */ + // tmp = (unsigned int *)(out + total_size - unit_size - h264_nal_length_size); + // *tmp = unit_size; + (out + total_size - unit_size - h264_nal_length_size)[0] = 0; + (out + total_size - unit_size - h264_nal_length_size)[1] = 0; + (out + total_size - unit_size - h264_nal_length_size)[2] = 0; + (out + total_size - unit_size - h264_nal_length_size)[3] = (unsigned char)unit_size; + + // memcpy(out + total_size - unit_size - h264_nal_length_size, &unit_size, h264_nal_length_size); + //g_print ("out[0] = %02x, out[1] = %02x, out[2] = %02x = out[3] = %02x\n", + //out[total_size - unit_size - h264_nal_length_size], out[total_size - unit_size - h264_nal_length_size+1], + //out[total_size - unit_size - h264_nal_length_size + 2], out[total_size - unit_size - h264_nal_length_size + 3]); + + /* Copy SPS/PPS Length and data */ + memcpy(out + total_size - unit_size, extradata + PIFFDEMUX_SPSPPS_LENGTH_SIZE, unit_size); + + extradata += (PIFFDEMUX_SPSPPS_LENGTH_SIZE + unit_size); + + if (!unit_nb && !sps_done++) + { + /* Completed reading SPS data, now read PPS data */ + unit_nb = *extradata++; /* number of pps unit(s) */ + GST_DEBUG ("No. of PPS units = %d\n", unit_nb); + } + } + + *dci_3gpp_buf = malloc (total_size); + if (NULL == *dci_3gpp_buf) + { + GST_ERROR ("Memory Allocation FAILED...\n"); + free (out); + return FALSE; + } + + memcpy(*dci_3gpp_buf, out, total_size); + *dci_3gpp_size = total_size; + + GST_DEBUG ("SPS_PPS size = %d\n", total_size); + + free(out); + + return TRUE; + } + +#ifdef DRM_ENABLE +static void +piffdemux_get_playready_licence (GstPiffDemux *demux) +{ + int ret = -1; + drm_trusted_piff_get_license_info_s license_info; + drm_trusted_request_type_e request_type = DRM_TRUSTED_REQ_TYPE_PIFF_GET_LICENSE; + + memset(&license_info, 0x00, sizeof(drm_trusted_piff_get_license_info_s)); + + license_info.lic_header.header = (unsigned char*) GST_BUFFER_DATA (demux->protection_header); + license_info.lic_header.header_len = GST_BUFFER_SIZE (demux->protection_header); + + ret = drm_trusted_handle_request(request_type, (void *) &license_info, NULL); + if (DRM_TRUSTED_RETURN_SUCCESS != ret) { + GST_ERROR_OBJECT (demux,"failed to get license..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to get license"), (NULL)); + return; + } + + GST_INFO_OBJECT (demux, "Got license....\n"); + + demux->encrypt_content = TRUE; + + return; +} + +void +test_drm_trusted_operation_cb(drm_trusted_user_operation_info_s *operation_info, void *output_data) +{ + g_print ("Callback Hit:test_drm_trusted_operation_cb\n"); + g_print ("operation_status=%d\n",operation_info->operation_status); + g_print ("operation_type=%d\n",operation_info->operation_type); +} +#endif + diff --git a/piffdemux/src/piffdemux.h b/piffdemux/src/piffdemux.h new file mode 100755 index 0000000..2147ea6 --- /dev/null +++ b/piffdemux/src/piffdemux.h @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_PIFFDEMUX_H__ +#define __GST_PIFFDEMUX_H__ + +#include +#include +#include "piffcommon.h" + +#ifdef DRM_ENABLE +#include +#include +#include +#include +#endif + +G_BEGIN_DECLS + +GST_DEBUG_CATEGORY_EXTERN (piffdemux_debug); +#define GST_CAT_DEFAULT piffdemux_debug + +#define GST_TYPE_PIFFDEMUX \ + (gst_piffdemux_get_type()) +#define GST_PIFFDEMUX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PIFFDEMUX,GstPiffDemux)) +#define GST_PIFFDEMUX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PIFFDEMUX,GstPiffDemuxClass)) +#define GST_IS_PIFFDEMUX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PIFFDEMUX)) +#define GST_IS_PIFFDEMUX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PIFFDEMUX)) + +#define GST_PIFFDEMUX_CAST(obj) ((GstPiffDemux *)(obj)) + +/* piffdemux produces these for atoms it cannot parse */ +#define GST_PIFF_DEMUX_PRIVATE_TAG "private-piff-tag" +#define GST_PIFF_DEMUX_CLASSIFICATION_TAG "classification" + +#define GST_PIFFDEMUX_MAX_STREAMS 8 + +typedef struct _GstPiffDemux GstPiffDemux; +typedef struct _GstPiffDemuxClass GstPiffDemuxClass; +typedef struct _PiffDemuxStream PiffDemuxStream; + +struct _GstPiffDemux { + GstElement element; + + /* pads */ + GstPad *sinkpad; + GstPad *srcpad; + + PiffDemuxStream *stream; + + guint32 timescale; + gint64 duration; + + gboolean fragmented; + guint64 moof_offset; + gint state; + gboolean posted_redirect; + + /* push based variables */ + guint neededbytes; + guint todrop; + GstAdapter *adapter; + GstBuffer *mdatbuffer; + guint64 mdatleft; + + /* offset of the media data (i.e.: Size of header) */ + guint64 offset; + /* offset of the mdat atom */ + guint64 mdatoffset; + guint64 first_mdat; + + GstTagList *tag_list; + + /* configured playback region */ + GstSegment segment; + gboolean segment_running; + GstEvent *pending_newsegment; + + /* gst index support */ + GstIndex *element_index; + gint index_id; + + gint64 requested_seek_time; + guint64 seek_offset; + gboolean moof_rcvd; + + /* live specific params */ + piff_live_param_t *param; + guint lookahead_cnt; + gboolean is_live; + + gboolean encrypt_content; + gboolean decrypt_init; +#ifdef DRM_ENABLE + DRM_DECRYPT_HANDLE pr_handle; +#endif + GstBuffer *protection_header; +}; + +struct _GstPiffDemuxClass { + GstElementClass parent_class; + void (*live_param) (GstPiffDemux *piff, const piff_live_param_t *param); +}; + +GType gst_piffdemux_get_type (void); + +/* prepares video caps based on input params */ +void gst_piffdemux_set_video_params (GstPiffDemux * piffdemux, guint fourcc, guint width, guint height, + guint fps_n, guint fps_d, unsigned char *codec_data, unsigned int codec_data_len); +/* prepares audio caps based on input params */ +void gst_piffdemux_set_audio_params (GstPiffDemux * piffdemux, guint fourcc, guint sampling_rate, guint bps, + guint channels, unsigned char *codec_data, unsigned int codec_data_len); +G_END_DECLS + +#endif /* __GST_PIFFDEMUX_H__ */ + diff --git a/piffdemux/src/piffdemux_dump.c b/piffdemux/src/piffdemux_dump.c new file mode 100755 index 0000000..b2d55f7 --- /dev/null +++ b/piffdemux/src/piffdemux_dump.c @@ -0,0 +1,325 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) 2009 Tim-Philipp Müller + * Copyright (C) <2009> STEricsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "piffdemux_types.h" +#include "piffdemux_dump.h" + +#include "piffatomparser.h" + +#include + +#define GET_UINT8(data) gst_byte_reader_get_uint8_unchecked(data) +#define GET_UINT16(data) gst_byte_reader_get_uint16_be_unchecked(data) +#define GET_UINT32(data) gst_byte_reader_get_uint32_be_unchecked(data) +#define GET_UINT64(data) gst_byte_reader_get_uint64_be_unchecked(data) +#define GET_FP32(data) (gst_byte_reader_get_uint32_be_unchecked(data)/65536.0) +#define GET_FP16(data) (gst_byte_reader_get_uint16_be_unchecked(data)/256.0) +#define GET_FOURCC(data) piff_atom_parser_get_fourcc_unchecked(data) + +gboolean +piffdemux_dump_vmhd (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + if (!piff_atom_parser_has_remaining (data, 4 + 4)) + return FALSE; + + GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); + GST_LOG ("%*s mode/color: %08x", depth, "", GET_UINT32 (data)); + return TRUE; +} + + +gboolean +piffdemux_dump_mfro (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + if (!piff_atom_parser_has_remaining (data, 4)) + return FALSE; + + GST_LOG ("%*s size: %d", depth, "", GET_UINT32 (data)); + return TRUE; +} + +gboolean +piffdemux_dump_tfra (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + guint64 time = 0, moof_offset = 0; + guint32 len = 0, num_entries = 0, ver_flags = 0, track_id = 0, i; + guint value_size, traf_size, trun_size, sample_size; + + if (!gst_byte_reader_get_uint32_be (data, &ver_flags)) + return FALSE; + + GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); + + if (!gst_byte_reader_get_uint32_be (data, &track_id) || + gst_byte_reader_get_uint32_be (data, &len) || + gst_byte_reader_get_uint32_be (data, &num_entries)) + return FALSE; + + GST_LOG ("%*s track ID: %u", depth, "", track_id); + GST_LOG ("%*s length: 0x%x", depth, "", len); + GST_LOG ("%*s n entries: %u", depth, "", num_entries); + + value_size = ((ver_flags >> 24) == 1) ? sizeof (guint64) : sizeof (guint32); + sample_size = (len & 3) + 1; + trun_size = ((len & 12) >> 2) + 1; + traf_size = ((len & 48) >> 4) + 1; + + if (!piff_atom_parser_has_chunks (data, num_entries, + value_size + value_size + traf_size + trun_size + sample_size)) + return FALSE; + + for (i = 0; i < num_entries; i++) { + piff_atom_parser_get_offset (data, value_size, &time); + piff_atom_parser_get_offset (data, value_size, &moof_offset); + GST_LOG ("%*s time: %" G_GUINT64_FORMAT, depth, "", time); + GST_LOG ("%*s moof_offset: %" G_GUINT64_FORMAT, + depth, "", moof_offset); + GST_LOG ("%*s traf_number: %u", depth, "", + piff_atom_parser_get_uint_with_size_unchecked (data, traf_size)); + GST_LOG ("%*s trun_number: %u", depth, "", + piff_atom_parser_get_uint_with_size_unchecked (data, trun_size)); + GST_LOG ("%*s sample_number: %u", depth, "", + piff_atom_parser_get_uint_with_size_unchecked (data, sample_size)); + } + + return TRUE; +} + +gboolean +piffdemux_dump_tfhd (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + guint32 flags = 0, n = 0, track_id = 0; + guint64 base_data_offset = 0; + + if (!gst_byte_reader_skip (data, 1) || + !gst_byte_reader_get_uint24_be (data, &flags)) + return FALSE; + GST_LOG ("%*s flags: %08x", depth, "", flags); + + if (!gst_byte_reader_get_uint32_be (data, &track_id)) + return FALSE; + GST_LOG ("%*s track_id: %u", depth, "", track_id); + + if (flags & TF_BASE_DATA_OFFSET) { + if (!gst_byte_reader_get_uint64_be (data, &base_data_offset)) + return FALSE; + GST_LOG ("%*s base-data-offset: %" G_GUINT64_FORMAT, + depth, "", base_data_offset); + } + + if (flags & TF_SAMPLE_DESCRIPTION_INDEX) { + if (!gst_byte_reader_get_uint32_be (data, &n)) + return FALSE; + GST_LOG ("%*s sample-description-index: %u", depth, "", n); + } + + if (flags & TF_DEFAULT_SAMPLE_DURATION) { + if (!gst_byte_reader_get_uint32_be (data, &n)) + return FALSE; + GST_LOG ("%*s default-sample-duration: %u", depth, "", n); + } + + if (flags & TF_DEFAULT_SAMPLE_SIZE) { + if (!gst_byte_reader_get_uint32_be (data, &n)) + return FALSE; + GST_LOG ("%*s default-sample-size: %u", depth, "", n); + } + + if (flags & TF_DEFAULT_SAMPLE_FLAGS) { + if (!gst_byte_reader_get_uint32_be (data, &n)) + return FALSE; + GST_LOG ("%*s default-sample-flags: %u", depth, "", n); + } + + GST_LOG ("%*s duration-is-empty: %s", depth, "", + flags & TF_DURATION_IS_EMPTY ? "yes" : "no"); + + return TRUE; +} + +gboolean +piffdemux_dump_trun (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + guint32 flags = 0, samples_count = 0, data_offset = 0, first_sample_flags = 0; + guint32 sample_duration = 0, sample_size = 0, sample_flags = + 0, composition_time_offsets = 0; + int i = 0; + + if (!gst_byte_reader_skip (data, 1) || + !gst_byte_reader_get_uint24_be (data, &flags)) + return FALSE; + + GST_LOG ("%*s flags: %08x", depth, "", flags); + + if (!gst_byte_reader_get_uint32_be (data, &samples_count)) + return FALSE; + GST_LOG ("%*s samples_count: %u", depth, "", samples_count); + + if (flags & TR_DATA_OFFSET) { + if (!gst_byte_reader_get_uint32_be (data, &data_offset)) + return FALSE; + GST_LOG ("%*s data-offset: %u", depth, "", data_offset); + } + + if (flags & TR_FIRST_SAMPLE_FLAGS) { + if (!gst_byte_reader_get_uint32_be (data, &first_sample_flags)) + return FALSE; + GST_LOG ("%*s first-sample-flags: %u", depth, "", first_sample_flags); + } + + for (i = 0; i < samples_count; i++) { + if (flags & TR_SAMPLE_DURATION) { + if (!gst_byte_reader_get_uint32_be (data, &sample_duration)) + return FALSE; + GST_LOG ("%*s sample-duration: %u", depth, "", sample_duration); + } + + if (flags & TR_SAMPLE_SIZE) { + if (!gst_byte_reader_get_uint32_be (data, &sample_size)) + return FALSE; + GST_LOG ("%*s sample-size: %u", depth, "", sample_size); + } + + if (flags & TR_SAMPLE_FLAGS) { + if (!gst_byte_reader_get_uint32_be (data, &sample_flags)) + return FALSE; + GST_LOG ("%*s sample-flags: %u", depth, "", sample_flags); + } + + if (flags & TR_COMPOSITION_TIME_OFFSETS) { + if (!gst_byte_reader_get_uint32_be (data, &composition_time_offsets)) + return FALSE; + GST_LOG ("%*s composition_time_offsets: %u", depth, "", + composition_time_offsets); + } + } + + return TRUE; +} + +gboolean +piffdemux_dump_trex (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + if (!piff_atom_parser_has_remaining (data, 4 + 4 + 4 + 4 + 4 + 4)) + return FALSE; + + GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); + GST_LOG ("%*s track ID: %08x", depth, "", GET_UINT32 (data)); + GST_LOG ("%*s default sample desc. index: %08x", depth, "", + GET_UINT32 (data)); + GST_LOG ("%*s default sample duration: %08x", depth, "", + GET_UINT32 (data)); + GST_LOG ("%*s default sample size: %08x", depth, "", + GET_UINT32 (data)); + GST_LOG ("%*s default sample flags: %08x", depth, "", + GET_UINT32 (data)); + + return TRUE; +} + + +gboolean +piffdemux_dump_sdtp (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + guint32 version; + guint8 val; + guint i = 1; + + version = GET_UINT32 (data); + GST_LOG ("%*s version/flags: %08x", depth, "", version); + + /* the sample_count is specified in the stsz or stz2 box. + * the information for a sample is stored in a single byte, + * so we read until there are no remaining bytes */ + while (piff_atom_parser_has_remaining (data, 1)) { + val = GET_UINT8 (data); + GST_LOG ("%*s sample number: %d", depth, "", i); + GST_LOG ("%*s sample_depends_on: %d", depth, "", + ((guint16) (val)) & 0x3); + GST_LOG ("%*s sample_is_depended_on: %d", depth, "", + ((guint16) (val >> 2)) & 0x3); + GST_LOG ("%*s sample_has_redundancy: %d", depth, "", + ((guint16) (val >> 4)) & 0x3); + ++i; + } + return TRUE; +} + +gboolean +piffdemux_dump_unknown (GstPiffDemux * piffdemux, GstByteReader * data, int depth) +{ + int len; + + len = gst_byte_reader_get_remaining (data); + GST_LOG ("%*s length: %d", depth, "", len); + + GST_MEMDUMP_OBJECT (piffdemux, "unknown atom data", + gst_byte_reader_peek_data_unchecked (data), len); + return TRUE; +} + +static gboolean +piffdemux_node_dump_foreach (GNode * node, gpointer piffdemux) +{ + GstByteReader parser; + guint8 *buffer = (guint8 *) node->data; /* FIXME: move to byte reader */ + guint32 node_length; + guint32 fourcc; + const PiffNodeType *type; + int depth; + + node_length = GST_READ_UINT32_BE (buffer); + fourcc = GST_READ_UINT32_LE (buffer + 4); + + g_warn_if_fail (node_length >= 8); + + gst_byte_reader_init (&parser, buffer + 8, node_length - 8); + + type = piffdemux_type_get (fourcc); + + depth = (g_node_depth (node) - 1) * 2; + GST_LOG ("%*s'%" GST_FOURCC_FORMAT "', [%d], %s", + depth, "", GST_FOURCC_ARGS (fourcc), node_length, type->name); + + if (type->dump) { + gboolean ret; + + ret = type->dump (GST_PIFFDEMUX_CAST (piffdemux), &parser, depth); + + if (!ret) { + GST_WARNING ("%*s not enough data parsing atom %" GST_FOURCC_FORMAT, + depth, "", GST_FOURCC_ARGS (fourcc)); + } + } + + return FALSE; +} + +gboolean +piffdemux_node_dump (GstPiffDemux * piffdemux, GNode * node) +{ + if (__gst_debug_min < GST_LEVEL_LOG) + return TRUE; + + g_node_traverse (node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, + piffdemux_node_dump_foreach, piffdemux); + return TRUE; +} diff --git a/piffdemux/src/piffdemux_dump.h b/piffdemux/src/piffdemux_dump.h new file mode 100755 index 0000000..5f34b50 --- /dev/null +++ b/piffdemux/src/piffdemux_dump.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2009> STEricsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_PIFFDEMUX_DUMP_H__ +#define __GST_PIFFDEMUX_DUMP_H__ + +#include +#include + +G_BEGIN_DECLS + +gboolean piffdemux_dump_vmhd (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_mfro (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_tfra (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_tfhd (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_trun (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_trex (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_sdtp (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); +gboolean piffdemux_dump_unknown (GstPiffDemux * piffdemux, GstByteReader * data, + int depth); + +gboolean piffdemux_node_dump (GstPiffDemux * piffdemux, GNode * node); + +G_END_DECLS +#endif /* __GST_PIFFDEMUX_DUMP_H__ */ diff --git a/piffdemux/src/piffdemux_fourcc.h b/piffdemux/src/piffdemux_fourcc.h new file mode 100755 index 0000000..7ce7a7a --- /dev/null +++ b/piffdemux/src/piffdemux_fourcc.h @@ -0,0 +1,86 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_QTDEMUX_FOURCC_H__ +#define __GST_QTDEMUX_FOURCC_H__ + +#include + +G_BEGIN_DECLS + + +#define FOURCC_vide GST_MAKE_FOURCC('v','i','d','e') +#define FOURCC_soun GST_MAKE_FOURCC('s','o','u','n') +#define FOURCC_subp GST_MAKE_FOURCC('s','u','b','p') +#define FOURCC_hint GST_MAKE_FOURCC('h','i','n','t') +#define FOURCC_mp4a GST_MAKE_FOURCC('m','p','4','a') +#define FOURCC_mp4v GST_MAKE_FOURCC('m','p','4','v') +#define FOURCC_MP4V GST_MAKE_FOURCC('M','P','4','V') +#define FOURCC_fmp4 GST_MAKE_FOURCC('f','m','p','4') +#define FOURCC_FMP4 GST_MAKE_FOURCC('F','M','P','4') + +#define FOURCC_meta GST_MAKE_FOURCC('m','e','t','a') + +#define FOURCC_____ GST_MAKE_FOURCC('-','-','-','-') + +#define FOURCC_free GST_MAKE_FOURCC('f','r','e','e') + +#define FOURCC_drms GST_MAKE_FOURCC('d','r','m','s') +#define FOURCC_drmi GST_MAKE_FOURCC('d','r','m','i') +#define FOURCC_avc1 GST_MAKE_FOURCC('a','v','c','1') +#define FOURCC_avcC GST_MAKE_FOURCC('a','v','c','C') + +#define FOURCC_ulaw GST_MAKE_FOURCC('u','l','a','w') +#define FOURCC_alaw GST_MAKE_FOURCC('a','l','a','w') + +#define FOURCC_raw_ GST_MAKE_FOURCC('r','a','w',' ') + +#define FOURCC_alac GST_MAKE_FOURCC('a','l','a','c') +#define FOURCC_samr GST_MAKE_FOURCC('s','a','m','r') +#define FOURCC_sawb GST_MAKE_FOURCC('s','a','w','b') +#define FOURCC_mdat GST_MAKE_FOURCC('m','d','a','t') +#define FOURCC_in24 GST_MAKE_FOURCC('i','n','2','4') + +#define FOURCC_text GST_MAKE_FOURCC('t','e','x','t') +#define FOURCC_tx3g GST_MAKE_FOURCC('t','x','3','g') +#define FOURCC_mp4s GST_MAKE_FOURCC('m','p','4','s') +#define FOURCC_uuid GST_MAKE_FOURCC('u','u','i','d') + +/* Fragmented MP4 */ + +#define FOURCC_mfhd GST_MAKE_FOURCC('m','f','h','d') +#define FOURCC_mfra GST_MAKE_FOURCC('m','f','r','a') +#define FOURCC_mfro GST_MAKE_FOURCC('m','f','r','o') +#define FOURCC_moof GST_MAKE_FOURCC('m','o','o','f') +#define FOURCC_mvex GST_MAKE_FOURCC('m','v','e','x') +#define FOURCC_sdtp GST_MAKE_FOURCC('s','d','t','p') +#define FOURCC_tfhd GST_MAKE_FOURCC('t','f','h','d') +#define FOURCC_tfxd GST_MAKE_FOURCC('t','f','x','d') +#define FOURCC_tfra GST_MAKE_FOURCC('t','f','r','a') +#define FOURCC_traf GST_MAKE_FOURCC('t','r','a','f') +#define FOURCC_trex GST_MAKE_FOURCC('t','r','e','x') +#define FOURCC_trun GST_MAKE_FOURCC('t','r','u','n') +#define FOURCC_ovc1 GST_MAKE_FOURCC('o','v','c','1') +#define FOURCC_owma GST_MAKE_FOURCC('o','w','m','a') +#define FOURCC_uuid GST_MAKE_FOURCC('u','u','i','d') +#define FOURCC_tfrf GST_MAKE_FOURCC('t','f','r','f') + +G_END_DECLS + +#endif /* __GST_QTDEMUX_FOURCC_H__ */ diff --git a/piffdemux/src/piffdemux_types.c b/piffdemux/src/piffdemux_types.c new file mode 100755 index 0000000..2fa8ea8 --- /dev/null +++ b/piffdemux/src/piffdemux_types.c @@ -0,0 +1,76 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "piffdemux_types.h" +#include "piffdemux_dump.h" +#include "piffdemux_fourcc.h" + +static const PiffNodeType piff_node_types[] = { + {FOURCC_vide, "video media", 0}, + {FOURCC_hint, "hint", 0,}, + {FOURCC_mp4a, "mp4a", 0,}, + {FOURCC_mp4v, "mp4v", 0,}, + {FOURCC_alac, "alac", 0,}, + {FOURCC_meta, "meta", 0, piffdemux_dump_unknown}, + {FOURCC_____, "----", PIFF_FLAG_CONTAINER,}, + {FOURCC_free, "free", 0,}, + {FOURCC_mfra, "movie fragment random access", + PIFF_FLAG_CONTAINER,}, + {FOURCC_tfra, "track fragment random access", 0, + piffdemux_dump_tfra}, + {FOURCC_mfro, "movie fragment random access offset", 0, + piffdemux_dump_mfro}, + {FOURCC_moof, "movie fragment", PIFF_FLAG_CONTAINER,}, + {FOURCC_mfhd, "movie fragment header", 0,}, + {FOURCC_traf, "track fragment", PIFF_FLAG_CONTAINER,}, + {FOURCC_tfhd, "track fragment header", 0, + piffdemux_dump_tfhd}, + {FOURCC_sdtp, "independent and disposable samples", 0, + piffdemux_dump_sdtp}, + {FOURCC_trun, "track fragment run", 0, piffdemux_dump_trun}, + {FOURCC_mdat, "moovie data", 0, piffdemux_dump_unknown}, + {FOURCC_trex, "moovie data", 0, piffdemux_dump_trex}, + {FOURCC_mvex, "mvex", PIFF_FLAG_CONTAINER,}, + {FOURCC_ovc1, "ovc1", 0}, + {FOURCC_owma, "owma", 0}, + {FOURCC_tfxd, "tfxd", 0}, + {FOURCC_tfrf, "tfrf", 0}, + {FOURCC_uuid, "uuid", 0}, + + {0, "unknown", 0,}, +}; + +static const int n_piff_node_types = + sizeof (piff_node_types) / sizeof (piff_node_types[0]); + +const PiffNodeType * +piffdemux_type_get (guint32 fourcc) +{ + int i; + + for (i = 0; i < n_piff_node_types; i++) { + if (G_UNLIKELY (piff_node_types[i].fourcc == fourcc)) + return piff_node_types + i; + } + + GST_WARNING ("unknown QuickTime node type %" GST_FOURCC_FORMAT, + GST_FOURCC_ARGS (fourcc)); + + return piff_node_types + n_piff_node_types - 1; +} diff --git a/piffdemux/src/piffdemux_types.h b/piffdemux/src/piffdemux_types.h new file mode 100755 index 0000000..2c94887 --- /dev/null +++ b/piffdemux/src/piffdemux_types.h @@ -0,0 +1,67 @@ + +#ifndef __GST_PIFFDEMUX_TYPES_H__ +#define __GST_PIFFDEMUX_TYPES_H__ + +#include +#include + +#include "piffdemux.h" + +G_BEGIN_DECLS + +typedef gboolean (*PiffDumpFunc) (GstPiffDemux * piffdemux, GstByteReader * data, int depth); + +typedef struct _PiffNodeType PiffNodeType; + +#define PIFF_UINT32(a) (GST_READ_UINT32_BE(a)) +#define PIFF_UINT24(a) (GST_READ_UINT32_BE(a) >> 8) +#define PIFF_UINT16(a) (GST_READ_UINT16_BE(a)) +#define PIFF_UINT8(a) (GST_READ_UINT8(a)) +#define PIFF_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0) +#define PIFF_SFP32(a) (((gint)(GST_READ_UINT32_BE(a)))/65536.0) +#define PIFF_FP16(a) ((GST_READ_UINT16_BE(a))/256.0) +#define PIFF_FOURCC(a) (GST_READ_UINT32_LE(a)) +#define PIFF_UINT64(a) ((((guint64)PIFF_UINT32(a))<<32)|PIFF_UINT32(((guint8 *)a)+4)) + +typedef enum { + PIFF_FLAG_NONE = (0), + PIFF_FLAG_CONTAINER = (1 << 0) +} PiffFlags; + +struct _PiffNodeType { + guint32 fourcc; + const gchar *name; + PiffFlags flags; + PiffDumpFunc dump; +}; + +enum TfFlags +{ + TF_BASE_DATA_OFFSET = 0x000001, /* base-data-offset-present */ + TF_SAMPLE_DESCRIPTION_INDEX = 0x000002, /* sample-description-index-present */ + TF_DEFAULT_SAMPLE_DURATION = 0x000008, /* default-sample-duration-present */ + TF_DEFAULT_SAMPLE_SIZE = 0x000010, /* default-sample-size-present */ + TF_DEFAULT_SAMPLE_FLAGS = 0x000020, /* default-sample-flags-present */ + TF_DURATION_IS_EMPTY = 0x100000 /* duration-is-empty */ +}; + +enum TrFlags +{ + TR_DATA_OFFSET = 0x000001, /* data-offset-present */ + TR_FIRST_SAMPLE_FLAGS = 0x000004, /* first-sample-flags-present */ + TR_SAMPLE_DURATION = 0x000100, /* sample-duration-present */ + TR_SAMPLE_SIZE = 0x000200, /* sample-size-present */ + TR_SAMPLE_FLAGS = 0x000400, /* sample-flags-present */ + TR_COMPOSITION_TIME_OFFSETS = 0x000800 /* sample-composition-time-offsets-presents */ +}; + +enum SEFlags +{ + SE_OVERRIDE_TE_FLAGS = 0x000001, /* override existing track encryption parameters */ + SE_USE_SUBSAMPLE_ENCRYPTION = 0x000002, /* Use SubSample Encryption */ +}; +const PiffNodeType *piffdemux_type_get (guint32 fourcc); + +G_END_DECLS + +#endif /* __GST_PIFFDEMUX_TYPES_H__ */ diff --git a/piffdemux/src/piffpalette.h b/piffdemux/src/piffpalette.h new file mode 100755 index 0000000..d3b4552 --- /dev/null +++ b/piffdemux/src/piffpalette.h @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_PIFFPALLETE_H__ +#define __GST_PIFFPALLETE_H__ + +#include + +G_BEGIN_DECLS + +static const guint32 ff_piff_default_palette_2[2] = { + 0xffffff, 0x000000 +}; + +static const guint32 ff_piff_default_palette_4[4] = { + 0x93655e, 0xffffff, 0xdfd0ab, 0x000000 +}; + +static const guint32 ff_piff_default_palette_16[16] = { + 0xfffbff, 0xefd9bb, 0xe8c9b1, 0x93655e, + 0xfcdee8, 0x9d8891, 0xffffff, 0xffffff, + 0xffffff, 0x474837, 0x7a5e55, 0xdfd0ab, + 0xfffbf9, 0xe8cac5, 0x8a7c77, 0x000000 +}; +static const guint32 ff_piff_default_palette_256[256] = { + 0xFFFFFF, 0xFFFFCC, 0xFFFF99, 0xFFFF66, 0xFFFF33, 0xFFFF00, + 0xFFCCFF, 0xFFCCCC, 0xFFCC99, 0xFFCC66, 0xFFCC33, 0xFFCC00, + 0xFF99FF, 0xFF99CC, 0xFF9999, 0xFF9966, 0xFF9933, 0xFF9900, + 0xFF66FF, 0xFF66CC, 0xFF6699, 0xFF6666, 0xFF6633, 0xFF6600, + 0xFF33FF, 0xFF33CC, 0xFF3399, 0xFF3366, 0xFF3333, 0xFF3300, + 0xFF00FF, 0xFF00CC, 0xFF0099, 0xFF0066, 0xFF0033, 0xFF0000, + 0xCCFFFF, 0xCCFFCC, 0xCCFF99, 0xCCFF66, 0xCCFF33, 0xCCFF00, + 0xCCCCFF, 0xCCCCCC, 0xCCCC99, 0xCCCC66, 0xCCCC33, 0xCCCC00, + 0xCC99FF, 0xCC99CC, 0xCC9999, 0xCC9966, 0xCC9933, 0xCC9900, + 0xCC66FF, 0xCC66CC, 0xCC6699, 0xCC6666, 0xCC6633, 0xCC6600, + 0xCC33FF, 0xCC33CC, 0xCC3399, 0xCC3366, 0xCC3333, 0xCC3300, + 0xCC00FF, 0xCC00CC, 0xCC0099, 0xCC0066, 0xCC0033, 0xCC0000, + 0x99FFFF, 0x99FFCC, 0x99FF99, 0x99FF66, 0x99FF33, 0x99FF00, + 0x99CCFF, 0x99CCCC, 0x99CC99, 0x99CC66, 0x99CC33, 0x99CC00, + 0x9999FF, 0x9999CC, 0x999999, 0x999966, 0x999933, 0x999900, + 0x9966FF, 0x9966CC, 0x996699, 0x996666, 0x996633, 0x996600, + 0x9933FF, 0x9933CC, 0x993399, 0x993366, 0x993333, 0x993300, + 0x9900FF, 0x9900CC, 0x990099, 0x990066, 0x990033, 0x990000, + 0x66FFFF, 0x66FFCC, 0x66FF99, 0x66FF66, 0x66FF33, 0x66FF00, + 0x66CCFF, 0x66CCCC, 0x66CC99, 0x66CC66, 0x66CC33, 0x66CC00, + 0x6699FF, 0x6699CC, 0x669999, 0x669966, 0x669933, 0x669900, + 0x6666FF, 0x6666CC, 0x666699, 0x666666, 0x666633, 0x666600, + 0x6633FF, 0x6633CC, 0x663399, 0x663366, 0x663333, 0x663300, + 0x6600FF, 0x6600CC, 0x660099, 0x660066, 0x660033, 0x660000, + 0x33FFFF, 0x33FFCC, 0x33FF99, 0x33FF66, 0x33FF33, 0x33FF00, + 0x33CCFF, 0x33CCCC, 0x33CC99, 0x33CC66, 0x33CC33, 0x33CC00, + 0x3399FF, 0x3399CC, 0x339999, 0x339966, 0x339933, 0x339900, + 0x3366FF, 0x3366CC, 0x336699, 0x336666, 0x336633, 0x336600, + 0x3333FF, 0x3333CC, 0x333399, 0x333366, 0x333333, 0x333300, + 0x3300FF, 0x3300CC, 0x330099, 0x330066, 0x330033, 0x330000, + 0x00FFFF, 0x00FFCC, 0x00FF99, 0x00FF66, 0x00FF33, 0x00FF00, + 0x00CCFF, 0x00CCCC, 0x00CC99, 0x00CC66, 0x00CC33, 0x00CC00, + 0x0099FF, 0x0099CC, 0x009999, 0x009966, 0x009933, 0x009900, + 0x0066FF, 0x0066CC, 0x006699, 0x006666, 0x006633, 0x006600, + 0x0033FF, 0x0033CC, 0x003399, 0x003366, 0x003333, 0x003300, + 0x0000FF, 0x0000CC, 0x000099, 0x000066, 0x000033, 0xEE0000, + 0xDD0000, 0xBB0000, 0xAA0000, 0x880000, 0x770000, 0x550000, + 0x440000, 0x220000, 0x110000, 0x00EE00, 0x00DD00, 0x00BB00, + 0x00AA00, 0x008800, 0x007700, 0x005500, 0x004400, 0x002200, + 0x001100, 0x0000EE, 0x0000DD, 0x0000BB, 0x0000AA, 0x000088, + 0x000077, 0x000055, 0x000044, 0x000022, 0x000011, 0xEEEEEE, + 0xDDDDDD, 0xBBBBBB, 0xAAAAAA, 0x888888, 0x777777, 0x555555, + 0x444444, 0x222222, 0x111111, 0x000000 +}; + +static const guint32 ff_piff_grayscale_palette_16[16] = { + 0xffffff, 0xeeeeee, 0xdddddd, 0xcccccc, + 0xbbbbbb, 0xaaaaaa, 0x999999, 0x888888, + 0x777777, 0x666666, 0x555555, 0x444444, + 0x333333, 0x222222, 0x111111, 0x000000 +}; + +static const guint32 ff_piff_grayscale_palette_256[256] = { + 0xffffff, 0xfefefe, 0xfdfdfd, 0xfcfcfc, 0xfbfbfb, 0xfafafa, 0xf9f9f9, + 0xf8f8f8, 0xf7f7f7, 0xf6f6f6, 0xf5f5f5, 0xf4f4f4, 0xf3f3f3, 0xf2f2f2, + 0xf1f1f1, 0xf0f0f0, 0xefefef, 0xeeeeee, 0xededed, 0xececec, 0xebebeb, + 0xeaeaea, 0xe9e9e9, 0xe8e8e8, 0xe7e7e7, 0xe6e6e6, 0xe5e5e5, 0xe4e4e4, + 0xe3e3e3, 0xe2e2e2, 0xe1e1e1, 0xe0e0e0, 0xdfdfdf, 0xdedede, 0xdddddd, + 0xdcdcdc, 0xdbdbdb, 0xdadada, 0xd9d9d9, 0xd8d8d8, 0xd7d7d7, 0xd6d6d6, + 0xd5d5d5, 0xd4d4d4, 0xd3d3d3, 0xd2d2d2, 0xd1d1d1, 0xd0d0d0, 0xcfcfcf, + 0xcecece, 0xcdcdcd, 0xcccccc, 0xcbcbcb, 0xcacaca, 0xc9c9c9, 0xc8c8c8, + 0xc7c7c7, 0xc6c6c6, 0xc5c5c5, 0xc4c4c4, 0xc3c3c3, 0xc2c2c2, 0xc1c1c1, + 0xc0c0c0, 0xbfbfbf, 0xbebebe, 0xbdbdbd, 0xbcbcbc, 0xbbbbbb, 0xbababa, + 0xb9b9b9, 0xb8b8b8, 0xb7b7b7, 0xb6b6b6, 0xb5b5b5, 0xb4b4b4, 0xb3b3b3, + 0xb2b2b2, 0xb1b1b1, 0xb0b0b0, 0xafafaf, 0xaeaeae, 0xadadad, 0xacacac, + 0xababab, 0xaaaaaa, 0xa9a9a9, 0xa8a8a8, 0xa7a7a7, 0xa6a6a6, 0xa5a5a5, + 0xa4a4a4, 0xa3a3a3, 0xa2a2a2, 0xa1a1a1, 0xa0a0a0, 0x9f9f9f, 0x9e9e9e, + 0x9d9d9d, 0x9c9c9c, 0x9b9b9b, 0x9a9a9a, 0x999999, 0x989898, 0x979797, + 0x969696, 0x959595, 0x949494, 0x939393, 0x929292, 0x919191, 0x909090, + 0x8f8f8f, 0x8e8e8e, 0x8d8d8d, 0x8c8c8c, 0x8b8b8b, 0x8a8a8a, 0x898989, + 0x888888, 0x878787, 0x868686, 0x858585, 0x848484, 0x838383, 0x828282, + 0x818181, 0x808080, 0x7f7f7f, 0x7e7e7e, 0x7d7d7d, 0x7c7c7c, 0x7b7b7b, + 0x7a7a7a, 0x797979, 0x787878, 0x777777, 0x767676, 0x757575, 0x747474, + 0x737373, 0x727272, 0x717171, 0x707070, 0x6f6f6f, 0x6e6e6e, 0x6d6d6d, + 0x6c6c6c, 0x6b6b6b, 0x6a6a6a, 0x696969, 0x686868, 0x676767, 0x666666, + 0x656565, 0x646464, 0x636363, 0x626262, 0x616161, 0x606060, 0x5f5f5f, + 0x5e5e5e, 0x5d5d5d, 0x5c5c5c, 0x5b5b5b, 0x5a5a5a, 0x595959, 0x585858, + 0x575757, 0x565656, 0x555555, 0x545454, 0x535353, 0x525252, 0x515151, + 0x505050, 0x4f4f4f, 0x4e4e4e, 0x4d4d4d, 0x4c4c4c, 0x4b4b4b, 0x4a4a4a, + 0x494949, 0x484848, 0x474747, 0x464646, 0x454545, 0x444444, 0x434343, + 0x424242, 0x414141, 0x404040, 0x3f3f3f, 0x3e3e3e, 0x3d3d3d, 0x3c3c3c, + 0x3b3b3b, 0x3a3a3a, 0x393939, 0x383838, 0x373737, 0x363636, 0x353535, + 0x343434, 0x333333, 0x323232, 0x313131, 0x303030, 0x2f2f2f, 0x2e2e2e, + 0x2d2d2d, 0x2c2c2c, 0x2b2b2b, 0x2a2a2a, 0x292929, 0x282828, 0x272727, + 0x262626, 0x252525, 0x242424, 0x232323, 0x222222, 0x212121, 0x202020, + 0x1f1f1f, 0x1e1e1e, 0x1d1d1d, 0x1c1c1c, 0x1b1b1b, 0x1a1a1a, 0x191919, + 0x181818, 0x171717, 0x161616, 0x151515, 0x141414, 0x131313, 0x121212, + 0x111111, 0x101010, 0x0f0f0f, 0x0e0e0e, 0x0d0d0d, 0x0c0c0c, 0x0b0b0b, + 0x0a0a0a, 0x090909, 0x080808, 0x070707, 0x060606, 0x050505, 0x040404, + 0x030303, 0x020202, 0x010101, 0x000000 +}; + +G_END_DECLS + +#endif /* __GST_PIFFPALETTE_H__ */ diff --git a/mobile/evasimagesink/Makefile.am b/ssdemux/Makefile.am old mode 100644 new mode 100755 similarity index 100% rename from mobile/evasimagesink/Makefile.am rename to ssdemux/Makefile.am diff --git a/mobile/pdpushsrc/src/Makefile.am b/ssdemux/src/Makefile.am similarity index 68% rename from mobile/pdpushsrc/src/Makefile.am rename to ssdemux/src/Makefile.am index 090c2d1..5647e01 100755 --- a/mobile/pdpushsrc/src/Makefile.am +++ b/ssdemux/src/Makefile.am @@ -3,7 +3,7 @@ ############################################################################## # change libgstplugin.la to something more suitable, e.g. libmysomething.la # ############################################################################## -plugin_LTLIBRARIES = libgstpdpushsrc.la +plugin_LTLIBRARIES = libgstssdemux.la ############################################################################## # for the next set of variables, rename the prefix if you renamed the .la, # @@ -14,13 +14,13 @@ plugin_LTLIBRARIES = libgstpdpushsrc.la ############################################################################## # sources used to compile this plug-in -libgstpdpushsrc_la_SOURCES = gstpdpushsrc.c +libgstssdemux_la_SOURCES = gstssdemux.c ssmanifestparse.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed -libgstpdpushsrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) -libgstpdpushsrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) -libgstpdpushsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstssdemux_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(SOUP_CFLAGS) $(XML2_CFLAGS) $(GST_APP_CFLAGS) -I$(srcdir)/../../piffdemux/src +libgstssdemux_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(SOUP_LIBS) $(XML2_LIBS) $(GST_APP_LIBS) -lgstapp-0.10 +libgstssdemux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) # headers we need but don't want installed -noinst_HEADERS = gstpdpushsrc.h +noinst_HEADERS = gstssdemux.h ssmanifestparse.h diff --git a/ssdemux/src/gstssdemux.c b/ssdemux/src/gstssdemux.c new file mode 100755 index 0000000..ca7c503 --- /dev/null +++ b/ssdemux/src/gstssdemux.c @@ -0,0 +1,1551 @@ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include +//#include +#include "gstssdemux.h" + +enum +{ + PROP_0, + PROP_COOKIES, + PROP_ALLOW_AUDIO_ONLY, + PROP_CACHE_TIME, + PROP_LOW_PERCENTAGE, + PROP_HIGH_PERCENTAGE, + PROP_BITRATE_SWITCH_TOLERANCE, + PROP_LAST +}; + +static GstStaticPadTemplate ssdemux_videosrc_template = +GST_STATIC_PAD_TEMPLATE ("video", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate ssdemux_audiosrc_template = +GST_STATIC_PAD_TEMPLATE ("audio", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate ssdemux_subsrc_template = +GST_STATIC_PAD_TEMPLATE ("subtitle", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); + +static GstStaticPadTemplate ssdemux_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("application/x-ss")); // Need to decide source mimetype + +GST_DEBUG_CATEGORY_STATIC (gst_ss_demux_debug); +#define GST_CAT_DEFAULT gst_ss_demux_debug + +#undef SIMULATE_AUDIO_ONLY /* enable to simulate audio only case forcibly */ + +static void +_do_init (GType type) +{ + GST_DEBUG_CATEGORY_INIT (gst_ss_demux_debug, "ssdemux", 0, "ssdemux element"); +} + +GST_BOILERPLATE_FULL (GstSSDemux, gst_ss_demux, GstElement, + GST_TYPE_ELEMENT, _do_init); + +#define DEFAULT_CACHE_TIME 6*GST_SECOND +#define DEFAULT_BITRATE_SWITCH_TOLERANCE 0.4 +#define DEFAULT_LOW_PERCENTAGE 1 +#define DEFAULT_HIGH_PERCENTAGE 99 + +struct _GstSSDemuxStream +{ + /* Streaming task */ + void *parent; + GstPad *pad; + gchar *name; + SS_STREAM_TYPE type; + GstTask *stream_task; + GStaticRecMutex stream_lock; + GstElement *pipe; + GstElement *urisrc; + GstElement *parser; + GstElement *sink; + GstBus *bus; + GMutex *lock; + GCond *cond; + GMutex *queue_lock; + GCond *queue_full; + GCond *queue_empty; + guint frag_cnt; + GQueue *queue; + gchar *uri; + guint64 start_ts; + gboolean sent_ns; + GstCaps *caps; + guint64 switch_ts; + guint64 avg_dur; + gboolean is_buffering; + gint64 percent; + gboolean rcvd_percent; + guint64 push_block_time; + gint64 cached_duration; + + /* for fragment download rate calculation */ + guint64 download_start_ts; + guint64 download_stop_ts; + guint64 download_size; + +}; + +static void gst_ss_demux_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_ss_demux_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static gboolean gst_ss_demux_sink_event (GstPad * pad, GstEvent * event); +static GstStateChangeReturn gst_ss_demux_change_state (GstElement * element, GstStateChange transition); +static void gst_ss_demux_dispose (GObject * obj); +static GstFlowReturn gst_ss_demux_chain (GstPad * pad, GstBuffer * buf); +static void gst_ss_demux_stream_loop (GstSSDemux * demux); +static gboolean gst_ss_demux_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data); +static void gst_ss_demux_stream_init (GstSSDemux *demux, GstSSDemuxStream *stream, SS_STREAM_TYPE stream_type); +static void gst_ss_demux_stream_free (GstSSDemux * demux, GstSSDemuxStream * stream); +static void gst_ssm_demux_on_new_buffer (GstElement * appsink, void* data); +static gboolean gst_ss_demux_download_fragment (GstSSDemux *demux, GstSSDemuxStream *stream, const gchar * uri, guint64 start_ts); +static gboolean gst_ss_demux_create_download_pipe (GstSSDemux * demux, GstSSDemuxStream *stream, const gchar * uri, guint64 start_ts); +static void gst_ss_demux_stop (GstSSDemux * demux, GstSSDemuxStream *stream); +static gboolean gst_ss_demux_create_dummy_pipe (GstSSDemux * demux, GstSSDemuxStream *stream); +static gboolean gst_ss_demux_create_dummy_sender(GstSSDemux *demux, GstSSDemuxStream *stream); +static void gst_ss_demux_push_loop (GstSSDemuxStream *stream); +static void gst_ss_demux_update_buffering (GstSSDemuxStream *stream, guint64 percent); + +static void +gst_ss_demux_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&ssdemux_videosrc_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&ssdemux_audiosrc_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&ssdemux_subsrc_template)); + gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&ssdemux_sink_template)); + + gst_element_class_set_details_simple (element_class, + "SS Demuxer", + "Demuxer/URIList", + "Smooth Streaming demuxer", + "Naveen Cherukuri"); +} + +static void +gst_ss_demux_class_init (GstSSDemuxClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_ss_demux_set_property; + gobject_class->get_property = gst_ss_demux_get_property; + gobject_class->dispose = gst_ss_demux_dispose; + + /* to share cookies with other sessions */ + g_object_class_install_property (gobject_class, PROP_COOKIES, + g_param_spec_boxed ("cookies", "Cookies", "HTTP request cookies", + G_TYPE_STRV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* will be considered only in LIVE case */ + g_object_class_install_property (gobject_class, PROP_ALLOW_AUDIO_ONLY, + g_param_spec_boolean ("allow-audio-only", "Allow audio only when downloadrate is less in live case", + "Allow audio only stream download in live case when download rate is less", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CACHE_TIME, + g_param_spec_uint64 ("max-cache-time", "caching time", + "amount of data that can be cached in seconds", 0, G_MAXUINT64, + DEFAULT_CACHE_TIME, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_LOW_PERCENTAGE, + g_param_spec_int ("low-percent", "Low Percent", + "Low threshold to start buffering", + 1, 100, DEFAULT_LOW_PERCENTAGE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_HIGH_PERCENTAGE, + g_param_spec_int ("high-percent", "High percent", + "High threshold to complete buffering", + 2, 100, DEFAULT_HIGH_PERCENTAGE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_BITRATE_SWITCH_TOLERANCE, + g_param_spec_float ("bitrate-switch-tolerance", + "Bitrate switch tolerance", + "Tolerance with respect of the fragment duration to switch to " + "a different bitrate if the client is too slow/fast.", + 0, 1, DEFAULT_BITRATE_SWITCH_TOLERANCE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_ss_demux_change_state); +} + +static void +gst_ss_demux_init (GstSSDemux * demux, GstSSDemuxClass * klass) +{ + /* sink pad */ + demux->sinkpad = gst_pad_new_from_static_template (&ssdemux_sink_template, "sink"); + gst_pad_set_chain_function (demux->sinkpad, + GST_DEBUG_FUNCPTR (gst_ss_demux_chain)); + gst_pad_set_event_function (demux->sinkpad, + GST_DEBUG_FUNCPTR (gst_ss_demux_sink_event)); + gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); + + demux->max_cache_time = DEFAULT_CACHE_TIME; + demux->cookies = NULL; + demux->ss_mode = SS_MODE_NO_SWITCH; + demux->switch_eos = FALSE; + demux->allow_audio_only = FALSE; + demux->percent = 100; + demux->low_percent = DEFAULT_LOW_PERCENTAGE; + demux->high_percent = DEFAULT_HIGH_PERCENTAGE; + demux->eos = FALSE; +} + +static void +gst_ss_demux_dispose (GObject * obj) +{ + GstSSDemux *demux = GST_SS_DEMUX (obj); + int n =0; + + for (n = 0; n < SS_STREAM_NUM; n++) { + if (demux->streams[n]) { + gst_pad_stop_task ((demux->streams[n])->pad); + g_print ("\n\n\nstopped the TASK\n\n\n"); + gst_ss_demux_stream_free (demux, demux->streams[n]); + demux->streams[n] = NULL; + } + } + + if (demux->parser) { + gst_ssm_parse_free (demux->parser); + demux->parser = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (obj); +} + +static void +gst_ss_demux_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstSSDemux *demux = GST_SS_DEMUX (object); + + switch (prop_id) { + case PROP_COOKIES: + g_strfreev (demux->cookies); + demux->cookies = g_strdupv (g_value_get_boxed (value)); + break; + case PROP_ALLOW_AUDIO_ONLY: + demux->allow_audio_only = g_value_get_boolean (value); + break; + case PROP_CACHE_TIME: + demux->max_cache_time = g_value_get_uint64 (value); + break; + case PROP_LOW_PERCENTAGE: + demux->low_percent = g_value_get_int (value); + break; + case PROP_HIGH_PERCENTAGE: + demux->high_percent = g_value_get_int (value); + break; + case PROP_BITRATE_SWITCH_TOLERANCE: + demux->bitrate_switch_tol = g_value_get_float (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_ss_demux_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstSSDemux *demux = GST_SS_DEMUX (object); + + switch (prop_id) { + case PROP_COOKIES: + g_value_set_boxed (value, g_strdupv (demux->cookies)); + break; + case PROP_ALLOW_AUDIO_ONLY: + g_value_set_boolean (value, demux->allow_audio_only); + break; + case PROP_CACHE_TIME: + g_value_set_uint64 (value, demux->max_cache_time); + break; + case PROP_LOW_PERCENTAGE: + g_value_set_int (value, demux->low_percent); + break; + case PROP_HIGH_PERCENTAGE: + g_value_set_int (value, demux->high_percent); + break; + case PROP_BITRATE_SWITCH_TOLERANCE: + g_value_set_float (value, demux->bitrate_switch_tol); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gst_ss_demux_sink_event (GstPad * pad, GstEvent * event) +{ + GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); + GstQuery *query = NULL; + gboolean ret; + gchar *uri; + + switch (event->type) { + case GST_EVENT_EOS: { + int i = 0; + if (demux->manifest == NULL) { + GST_ERROR_OBJECT (demux, "Received EOS without a manifest."); + goto error; + } + + GST_DEBUG_OBJECT (demux, "Got EOS on the sink pad: mainifest file fetched"); + + query = gst_query_new_uri (); + ret = gst_pad_peer_query (demux->sinkpad, query); + if (ret) { + gst_query_parse_uri (query, &uri); + demux->parser = gst_ssm_parse_new (uri); + g_free (uri); + } else { + GST_ERROR_OBJECT (demux, "failed to query URI from upstream"); + goto error; + } + gst_query_unref (query); + query = NULL; + + GST_LOG_OBJECT (demux, "data = %p & size = %d", GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest)); + if (!gst_ssm_parse_manifest (demux->parser, (char *)GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest))) { + /* In most cases, this will happen if we set a wrong url in the + * source element and we have received the 404 HTML response instead of + * the playlist */ + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), (NULL)); + goto error; + } + + { + unsigned char *protection_data = NULL; + unsigned int protection_len = 0; + + /* get protection-header from manifest parser */ + ret = gst_ssm_parse_get_protection_header (demux->parser, &protection_data, &protection_len); + if (!ret) { + GST_ERROR_OBJECT (demux, "failed to get protection header..."); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("fragment allocation failed..."), (NULL)); + goto error; + } + + if (protection_data && protection_len) { + g_print ("Got the protection header...\n"); + demux->protection_header = gst_buffer_new (); + GST_BUFFER_DATA (demux->protection_header) = GST_BUFFER_MALLOCDATA (demux->protection_header) = protection_data; + GST_BUFFER_SIZE (demux->protection_header) = protection_len; + } + } + + for( i = 0; i < SS_STREAM_NUM; i++) { + if (gst_ssm_parse_check_stream (demux->parser, i)) { + GstSSDemuxStream *stream = g_new0 (GstSSDemuxStream, 1); + + // Add pad emission of the stream + gst_ss_demux_stream_init (demux, stream, i); + + if (!gst_pad_is_linked (stream->pad)) { + GST_WARNING_OBJECT (demux, "%s - stream pad is not linked...clean up", ssm_parse_get_stream_name(i)); + gst_ss_demux_stream_free (demux, stream); + continue; + } + + /* create stream task */ + g_static_rec_mutex_init (&stream->stream_lock); + stream->stream_task = gst_task_create ((GstTaskFunction) gst_ss_demux_stream_loop, demux); + if (NULL == stream->stream_task) { + GST_ERROR_OBJECT (demux, "failed to create stream task..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to create stream task"), (NULL)); + goto error; + } + gst_task_set_lock (stream->stream_task, &stream->stream_lock); + + /* create stream push loop */ + if (!gst_pad_start_task (stream->pad, (GstTaskFunction) gst_ss_demux_push_loop, stream)) { + GST_ERROR_OBJECT (demux, "failed to create push loop..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to create push loop"), (NULL)); + goto error; + } + + demux->streams[i] = stream; + g_print ("Starting stream - %d task loop...\n", i); + gst_task_start (stream->stream_task); + } + } + + gst_event_unref (event); + gst_object_unref (demux); + return TRUE; + } + case GST_EVENT_NEWSEGMENT: + /* Swallow newsegments, we'll push our own */ + gst_event_unref (event); + gst_object_unref (demux); + return TRUE; + default: + break; + } + + return gst_pad_event_default (pad, event); + +error: + // TODO: add closing + + //gst_ss_demux_stop (demux); + gst_event_unref (event); + gst_object_unref (demux); + + if (query) + gst_query_unref (query); + + g_print ("Returning from sink event...\n"); + return FALSE; + +} + +static gboolean +gst_ss_demux_handle_src_query (GstPad * pad, GstQuery * query) +{ + gboolean res = FALSE; + GstSSDemux *ssdemux = GST_SS_DEMUX (gst_pad_get_parent (pad)); + + GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query)); + + // TODO: need to add other query types as well + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_DURATION:{ + GstFormat fmt; + + gst_query_parse_duration (query, &fmt, NULL); + if (fmt == GST_FORMAT_TIME) { + gint64 duration = -1; + + duration = gst_util_uint64_scale (GST_SSM_PARSE_GET_DURATION(ssdemux->parser), GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(ssdemux->parser)); + if (duration > 0) { + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + res = TRUE; + } + } + break; + } + default: + res = gst_pad_query_default (pad, query); + break; + } + + gst_object_unref (ssdemux); + + return res; +} + + +static gboolean +gst_ss_demux_handle_src_event (GstPad * pad, GstEvent * event) +{ + GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); + + switch (event->type) { + case GST_EVENT_SEEK: + { + gdouble rate; + GstFormat format; + GstSeekFlags flags; + GstSeekType start_type, stop_type; + gint64 start, stop; + gint i = 0; + GstSSDemuxStream *stream = NULL; + + GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK"); + + // TODO: should be able to seek in DVR window + if (GST_SSM_PARSE_IS_LIVE_PRESENTATION (demux->parser)) { + GST_WARNING_OBJECT (demux, "Received seek event for live stream"); + return FALSE; + } + + gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, + &stop_type, &stop); + + if (format != GST_FORMAT_TIME) { + GST_WARNING_OBJECT (demux, "Only time format is supported in seek"); + return FALSE; + } + + GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT + " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start), + GST_TIME_ARGS (stop)); + + + for( i = 0; i < SS_STREAM_NUM; i++) { + if (stream = demux->streams[i]) { + g_cond_signal (stream->cond); + gst_task_stop (stream->stream_task); + } + } + + if (flags & GST_SEEK_FLAG_FLUSH) { + GST_INFO_OBJECT (demux, "sending flush start"); + + for( i = 0; i < SS_STREAM_NUM; i++) { + if (stream = demux->streams[i]) { + gst_pad_push_event (stream->pad, gst_event_new_flush_start ()); + } + } + } + + gst_ssm_parse_seek_manifest (demux->parser, start); + + if (flags & GST_SEEK_FLAG_FLUSH) { + GST_INFO_OBJECT (demux, "sending flush stop"); + for( i = 0; i < SS_STREAM_NUM; i++) { + if (stream = demux->streams[i]) { + gst_pad_push_event (stream->pad, gst_event_new_flush_stop ()); + GST_LOG_OBJECT (stream->pad, "Starting pad TASK again...\n"); + stream->sent_ns = FALSE; + stream->frag_cnt = 0; /*resetting to start buffering on SEEK */ + gst_task_start (stream->stream_task); + } + } + } + + return TRUE; + } + default: + break; + } + + return gst_pad_event_default (pad, event); +} + +static GstStateChangeReturn +gst_ss_demux_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + break; + default: + break; + } + return ret; +} + + +static GstFlowReturn +gst_ss_demux_chain (GstPad * pad, GstBuffer * buf) +{ + GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); + + if (demux->manifest == NULL) + demux->manifest = buf; + else + demux->manifest = gst_buffer_join (demux->manifest, buf); + gst_object_unref (demux); + + return GST_FLOW_OK; +} + + +static gboolean +gst_ss_demux_get_next_fragment (GstSSDemux * demux, SS_STREAM_TYPE stream_type) +{ + GstSSDemuxStream *stream = demux->streams[stream_type]; + gchar *next_fragment_uri = NULL; + guint64 start_ts = 0; + + if (!gst_ssm_parse_get_next_fragment_url (demux->parser, stream_type, &next_fragment_uri, &start_ts )) { + GST_INFO_OBJECT (demux, "This Manifest does not contain more fragments"); + goto end_of_list; + } + + GST_ERROR_OBJECT (demux, "Fetching next fragment %s", next_fragment_uri); + + stream->uri = g_strdup(next_fragment_uri); + stream->start_ts = start_ts; + + if (!gst_ss_demux_download_fragment (demux, stream, next_fragment_uri, start_ts)) { + GST_ERROR_OBJECT (demux, "failed to download fragment..."); + goto error; + } + + return TRUE; + +error: + { + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("failed to download fragment"), (NULL)); + gst_ss_demux_stop (demux, stream); + return FALSE; + } +end_of_list: + { + GST_INFO_OBJECT (demux, "Reached end of playlist, sending EOS"); + demux->eos = TRUE; + gst_ss_demux_stop (demux, stream); + return TRUE; + } +} + +static void +gst_ss_demux_push_loop (GstSSDemuxStream *stream) +{ + GstBuffer *outbuf = NULL; + GstSSDemux *demux = stream->parent; + GstFlowReturn fret = GST_FLOW_OK; + + // TODO: need to take care of EOS handling.... + + g_mutex_lock (stream->queue_lock); + + if (g_queue_is_empty (stream->queue)) { + GST_DEBUG_OBJECT (stream->pad,"queue is empty wait till, some buffers are available..."); + if (demux->eos) { + GST_INFO_OBJECT (stream->pad, "stream EOS, pause the task"); + gst_pad_push_event (stream->pad, gst_event_new_eos ()); + gst_pad_pause_task (stream->pad); + g_print ("Paused the task"); + return; + } + g_cond_wait (stream->queue_empty, stream->queue_lock); + } + + outbuf = g_queue_pop_head (stream->queue); + + if (GST_BUFFER_DURATION_IS_VALID (outbuf)) { + stream->cached_duration -= GST_BUFFER_DURATION(outbuf); + } else { + g_print ("\nDuration field is not valid.. check this issue !!!!!!!!\n"); + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid duration of a frame"), (NULL)); + g_mutex_unlock (stream->queue_lock); + return; + } + + g_cond_signal (stream->queue_full); + //g_print ("[%s] Signalled full condition...\n", ssm_parse_get_stream_name(stream->type)); + g_mutex_unlock (stream->queue_lock); + + if (!stream->sent_ns) { + guint64 duration = GST_CLOCK_TIME_NONE; + guint64 start = GST_CLOCK_TIME_NONE; + GstEvent *event = NULL; + + duration = gst_util_uint64_scale (GST_SSM_PARSE_GET_DURATION(demux->parser), GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(demux->parser)); + + start = gst_util_uint64_scale (GST_SSM_PARSE_NS_START(demux->parser), GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(demux->parser)); + + event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, start, duration, start); + + GST_DEBUG_OBJECT(demux," new_segment start = %"GST_TIME_FORMAT, GST_TIME_ARGS(start)); + + if (!gst_pad_push_event (stream->pad, event)) { + GST_ERROR_OBJECT (demux, "failed to push newsegment event"); + return; // No need to close task for this, because sometimes pad can unlined + } + stream->sent_ns = TRUE; + } + + if (stream->type == SS_STREAM_VIDEO && demux->ss_mode == SS_MODE_AONLY) { + GST_BUFFER_TIMESTAMP (outbuf) = stream->switch_ts; + GST_BUFFER_DURATION (outbuf) = ((float)1/25) * GST_SECOND; + stream->switch_ts = GST_BUFFER_TIMESTAMP (outbuf) + GST_BUFFER_DURATION (outbuf); + g_print ("Dummy buffers ts : %"GST_TIME_FORMAT" and dur : %"GST_TIME_FORMAT"\n", + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_ARGS(GST_BUFFER_DURATION (outbuf))); + gchar *caps_string = gst_caps_to_string(GST_BUFFER_CAPS(outbuf)); + g_print ("caps : %s\n", caps_string); + g_free(caps_string); + caps_string = NULL; + } + + /* push data to downstream*/ + fret = gst_pad_push (stream->pad, outbuf); + if (fret != GST_FLOW_OK) { + GST_ERROR_OBJECT (demux, "failed to push data, reason : %s", gst_flow_get_name (fret)); + goto error; + } + + //g_print ("[%s] pushed buffer\n", ssm_parse_get_stream_name(stream->type)); +error: + // TODO: need to close task & post error to bus + return; +} + +static void +gst_ss_demux_stream_loop (GstSSDemux * demux) +{ + GThread *self = NULL; + int stream_type = 0; + GstSSDemuxStream *stream = NULL; + + self = g_thread_self (); + + for (stream_type = 0; stream_type < SS_STREAM_NUM; stream_type++) { + if (demux->streams[stream_type] && demux->streams[stream_type]->stream_task->abidata.ABI.thread == self) { + stream = demux->streams[stream_type]; + break; + } + } + + if (stream) { + /* download next fragment of stream_type */ + if (!gst_ss_demux_get_next_fragment (demux, stream_type)) { + GST_ERROR_OBJECT (demux, "failed to get next fragment..."); + goto error; + } + } + + return; + +error: + { + gst_task_pause (stream->stream_task); + GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, + ("could not download fragments"), (NULL)); + gst_ss_demux_stop (demux, stream); + return; + } +} + +static gboolean +gst_ss_demux_download_fragment (GstSSDemux *demux, GstSSDemuxStream *stream, const gchar * uri, guint64 start_ts) +{ + GstStateChangeReturn ret; + GTimeVal time = {0, }; + + g_print ("Going to download fragment : %s\n", uri); + if (!gst_ss_demux_create_download_pipe (demux, stream, uri, start_ts)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + return FALSE; + } + + /* download rate calculation : note down start time*/ + g_get_current_time (&time); + stream->download_start_ts = (time.tv_sec * 1000000)+ time.tv_usec; + + ret = gst_element_set_state (stream->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (demux, "set_state failed..."); + return FALSE; + } + + if (stream->pipe && demux->ss_mode == SS_MODE_AONLY && + stream->type == SS_STREAM_VIDEO) { + + GST_DEBUG_OBJECT (demux, "Waiting to fetch the URI"); + g_mutex_lock (stream->lock); + g_cond_wait (stream->cond, stream->lock); + GST_INFO_OBJECT (stream->pad, "Recived signal to shutdown..."); + g_mutex_unlock (stream->lock); + + /* put live pipeline to PAUSED state to unlink urisrc & piffdemux */ + gst_element_set_state (stream->pipe, GST_STATE_NULL); + gst_element_get_state (stream->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + + stream->pipe = NULL; + + stream->switch_ts = stream->start_ts; + + /* create dummy frame sender */ + if (!gst_ss_demux_create_dummy_sender (demux, stream)) { + GST_ERROR_OBJECT (demux, "failed to create dummy sender pipeline..."); + GST_ELEMENT_ERROR (demux, RESOURCE, FAILED, ("Unable to create dummy pipe."), (NULL)); + return FALSE; + } + } + + /* wait until: + * - the download succeed (EOS) + * - the download failed (Error message on the fetcher bus) + * - the download was canceled + */ + GST_DEBUG_OBJECT (demux, "Waiting to fetch the URI"); + g_mutex_lock (stream->lock); + g_cond_wait (stream->cond, stream->lock); + GST_INFO_OBJECT (stream->pad, "Recived signal to shutdown..."); + g_mutex_unlock (stream->lock); + + gst_element_set_state (stream->pipe, GST_STATE_NULL); + gst_element_get_state (stream->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + stream->pipe = NULL; + + return TRUE; +} + +static gboolean +gst_ss_demux_create_dummy_sender(GstSSDemux *demux, GstSSDemuxStream *stream) +{ + GstStateChangeReturn ret; + + if (!gst_ss_demux_create_dummy_pipe (demux, stream)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + return FALSE; + } + + ret = gst_element_set_state (stream->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (demux, "set_state failed..."); + return FALSE; + } + +#if 0 + GST_DEBUG_OBJECT (demux, "Waiting to download next video URI"); + g_mutex_lock (stream->lock); + g_cond_wait (stream->cond, stream->lock); + if (stream->pipe) { + gst_element_set_state (stream->pipe, GST_STATE_NULL); + gst_element_get_state (stream->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + stream->pipe = NULL; + } + g_mutex_unlock (stream->lock); +#endif + + return TRUE; +} + +static void +gst_ss_demux_append_live_params(GstElement *piffparser, piff_live_param_t *param, gpointer data) +{ + GstSSDemuxStream *stream = (GstSSDemuxStream *)data; + GstSSDemux *demux = stream->parent; + int i =0; + guint64 timestamp = 0; + guint64 duration = 0; + + GST_LOG_OBJECT (demux, "received signal structs count = %d\n", param->count); + + for (i = 0 ; i< param->count; i++) { + if (param->long_info) { + piff_fragment_longtime_info *info = &(param->long_info[i]); + timestamp = info->ts; + duration = info->duration; + } else if (param->info) { + piff_fragment_time_info *info = &(param->info[i]); + timestamp = info->ts; + duration = info->duration; + } + + GST_LOG_OBJECT (demux, "Received ts = %llu and dur = %llu\n", timestamp, duration); + + if (!gst_ssm_parse_append_next_fragment (demux->parser, stream->type, timestamp, duration)) { + GST_ERROR_OBJECT (demux, "failed to append new fragment"); + GST_ELEMENT_ERROR (demux, RESOURCE, NO_SPACE_LEFT, ("fragment allocation failed..."), (NULL)); + return; + } + } + + if (param->long_info) { + free (param->long_info); + param->long_info = NULL; + } + + if (param->info) { + free (param->info); + param->info = NULL; + } + + free (param); + + if ((stream->type == SS_STREAM_VIDEO) && (demux->ss_mode == SS_MODE_AONLY)) { + g_print ("\n\n\t\tSignalling download pipe shutdonw....\n\n"); + + g_object_get (stream->parser, "frame-dur", &stream->avg_dur, NULL); + g_print ("frame duration = %"GST_TIME_FORMAT"\n\n\n", GST_TIME_ARGS(stream->avg_dur)); + g_cond_signal (stream->cond); + } + +} + +static gboolean +gst_ss_demux_create_download_pipe (GstSSDemux * demux, GstSSDemuxStream *stream, const gchar * uri, guint64 start_ts) +{ + gchar *name = NULL; + gchar *caps_string = NULL; + + if (!gst_uri_is_valid (uri)) + return FALSE; + + name = g_strdup_printf("%s-%s", stream->name, "downloader"); + + stream->pipe = gst_pipeline_new (name); + if (!stream->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + g_free(name); + name = NULL; + return FALSE; + } + + name = g_strdup_printf("%s-%s", stream->name, "httpsrc"); + GST_DEBUG ("Creating source element for the URI:%s", uri); + stream->urisrc = gst_element_make_from_uri (GST_URI_SRC, uri, name); + if (!stream->urisrc) { + GST_ERROR_OBJECT (demux, "failed to create urisrc"); + g_free(name); + return FALSE; + } + + if (GST_SSM_PARSE_IS_LIVE_PRESENTATION(demux->parser)) + g_object_set (G_OBJECT (stream->urisrc), "is-live", TRUE, NULL); + else + g_object_set (G_OBJECT (stream->urisrc), "is-live", FALSE, NULL); + + name = g_strdup_printf("%s-%s", stream->name, "parser"); + stream->parser = gst_element_factory_make ("piffdemux", name); + if (!stream->parser) { + GST_ERROR_OBJECT (demux, "failed to create piffdemux element"); + g_free(name); + name = NULL; + return FALSE; + } + + if (stream->caps) + gst_caps_unref (stream->caps); + + stream->caps = ssm_parse_get_stream_caps (demux->parser, stream->type); + caps_string = gst_caps_to_string(stream->caps); + GST_INFO_OBJECT (stream->pad, "prepare caps = %s", caps_string); + g_free(caps_string); + caps_string = NULL; + + g_object_set (G_OBJECT (stream->parser), "caps", stream->caps, NULL); + g_object_set (G_OBJECT (stream->parser), "start-ts", start_ts, NULL); + g_object_set (G_OBJECT (stream->parser), "duration", GST_SSM_PARSE_GET_DURATION(demux->parser), NULL); + g_object_set (G_OBJECT (stream->parser), "is-live", GST_SSM_PARSE_IS_LIVE_PRESENTATION(demux->parser), NULL); + g_object_set (G_OBJECT (stream->parser), "lookahead-count", GST_SSM_PARSE_LOOKAHEAD_COUNT(demux->parser), NULL); + if (demux->protection_header) + g_object_set (G_OBJECT (stream->parser), "protection-header", demux->protection_header, NULL); + g_signal_connect (stream->parser, "live-param", G_CALLBACK (gst_ss_demux_append_live_params), stream); + + name = g_strdup_printf("%s-%s", stream->name, "sink"); + stream->sink = gst_element_factory_make ("appsink", name); + if (!stream->sink) { + GST_ERROR_OBJECT (demux, "failed to create appsink element"); + g_free(name); + name = NULL; + return FALSE; + } + g_object_set (G_OBJECT (stream->sink), "emit-signals", TRUE, "sync", FALSE, NULL); + g_signal_connect (stream->sink, "new-buffer", G_CALLBACK (gst_ssm_demux_on_new_buffer), stream); + + gst_bin_add_many (GST_BIN (stream->pipe), stream->urisrc, stream->parser, stream->sink, NULL); + if (!gst_element_link_many (stream->urisrc, stream->parser, stream->sink, NULL)) { + GST_ERROR ("failed to link elements..."); + return FALSE; + } + + stream->bus = gst_pipeline_get_bus (GST_PIPELINE (stream->pipe)); + gst_bus_add_watch (stream->bus, (GstBusFunc)gst_ss_demux_download_bus_cb, stream); + gst_object_unref (stream->bus); + + g_free(name); + name = NULL; + + return TRUE; +} + +#if 0 +static gboolean +gst_ss_demux_create_dummy_pipe (GstSSDemux * demux, GstSSDemuxStream *stream) +{ + gchar *name = NULL; + GstCaps *caps = NULL; + GstElement *capsfilter = NULL; + GstElement *enc = NULL; + guint64 avg_dur = -1; + guint frame_rate = 0; + + name = g_strdup_printf("%s-%s", stream->name, "dummy"); + + stream->pipe = gst_pipeline_new (name); + if (!stream->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + return FALSE; + } + g_free(name); + + /* create dummy sender source */ + name = g_strdup_printf("%s-%s", stream->name, "dummysrc"); + stream->urisrc = gst_element_factory_make ("imagereader", name); + if (!stream->urisrc) { + GST_ERROR_OBJECT (demux,"failed to create filesrc element"); + return FALSE; + } + g_free(name); + g_object_set (G_OBJECT (stream->urisrc), "location", "/opt/home/root/aonly_VGA_1frame_I420.yuv", NULL); + g_object_set (G_OBJECT (stream->urisrc), "framerate", 25, NULL); + g_object_set (G_OBJECT (stream->urisrc), "num-buffers", 60, NULL); + + /* caps filter */ + capsfilter = gst_element_factory_make ("capsfilter", NULL); + if (!capsfilter) { + GST_ERROR_OBJECT (demux, "failed to create capsfilter element"); + return FALSE; + } + caps = gst_caps_new_simple ("video/x-raw-yuv", + "width", G_TYPE_INT, 640, + "height", G_TYPE_INT, 480, + "framerate",GST_TYPE_FRACTION, 25,1, + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'), + NULL); + g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL); + + /* create h264parse element */ + enc = gst_element_factory_make ("savsenc_h264", "H264 encoder"); + if (!enc) { + GST_ERROR_OBJECT (demux, "failed to create h264 parse element"); + return FALSE; + } + name = g_strdup_printf("%s-%s", stream->name, "sink"); + stream->sink = gst_element_factory_make ("appsink", name); + if (!stream->sink) { + GST_ERROR_OBJECT (demux, "failed to create appsink element"); + return FALSE; + } + g_free(name); + g_object_set (G_OBJECT (stream->sink), "emit-signals", TRUE, "sync", FALSE, NULL); + g_signal_connect (stream->sink, "new-buffer", G_CALLBACK (gst_ssm_demux_on_new_buffer), stream); + + /* add to pipeline & link all elements */ + gst_bin_add_many (GST_BIN (stream->pipe), stream->urisrc, capsfilter, enc, stream->sink, NULL); + + if (!gst_element_link_many (stream->urisrc, capsfilter, enc, stream->sink, NULL)) { + GST_ERROR_OBJECT (demux,"failed to link dummy pipe elements..."); + return FALSE; + } + + stream->bus = gst_pipeline_get_bus (GST_PIPELINE (stream->pipe)); + gst_bus_add_watch (stream->bus, (GstBusFunc)gst_ss_demux_download_bus_cb, stream); + gst_object_unref (stream->bus); + + return TRUE; +} +#else +static gboolean +gst_ss_demux_create_dummy_pipe (GstSSDemux * demux, GstSSDemuxStream *stream) +{ + gchar *name = NULL; + GstBus *bus = NULL; + GstCaps *caps = NULL; + + name = g_strdup_printf("%s-%s", stream->name, "dummy"); + + stream->pipe = gst_pipeline_new (name); + if (!stream->pipe) { + GST_ERROR_OBJECT (demux, "failed to create pipeline"); + return FALSE; + } + g_free(name); + + /* create dummy sender source */ + name = g_strdup_printf("%s-%s", stream->name, "dummysrc"); + stream->urisrc = gst_element_factory_make ("filesrc", name); + if (!stream->urisrc) { + GST_ERROR_OBJECT (demux,"failed to create filesrc element"); + return FALSE; + } + g_free(name); + g_object_set (G_OBJECT (stream->urisrc), "location", "/opt/home/root/sound_2sec.264", NULL); + + /* create appsink element */ + name = g_strdup_printf("%s-%s", stream->name, "parser"); + stream->parser= gst_element_factory_make ("legacyh264parse", name); + if (!stream->parser) { + GST_ERROR_OBJECT (demux, "failed to create h264 parse element"); + return FALSE; + } + g_object_set (G_OBJECT (stream->parser), "output-format", 1, NULL); + + /* create appsink element */ + name = g_strdup_printf("%s-%s", stream->name, "sink"); + stream->sink = gst_element_factory_make ("appsink", name); + if (!stream->sink) { + GST_ERROR_OBJECT (demux, "failed to create appsink element"); + return FALSE; + } + g_object_set (G_OBJECT (stream->sink), "emit-signals", TRUE, "sync", FALSE, NULL); + + caps = gst_caps_new_simple ("video/x-h264", + "width", G_TYPE_INT, 640, + "height", G_TYPE_INT, 480, + "stream-format", G_TYPE_STRING, "byte-stream", + NULL); + g_object_set (G_OBJECT (stream->sink), "caps", caps, NULL); + + g_signal_connect (stream->sink, "new-buffer", G_CALLBACK (gst_ssm_demux_on_new_buffer), stream); + g_free(name); + + /* add to pipeline & link all elements */ + gst_bin_add_many (GST_BIN (stream->pipe), stream->urisrc, stream->parser, stream->sink, NULL); + if (!gst_element_link_many (stream->urisrc, stream->parser, stream->sink, NULL)) { + GST_ERROR_OBJECT (demux,"failed to link elements..."); + return FALSE; + } + + bus = gst_pipeline_get_bus (GST_PIPELINE (stream->pipe)); + gst_bus_add_watch (bus, (GstBusFunc)gst_ss_demux_download_bus_cb, stream); + gst_object_unref (bus); + + return TRUE; +} + + +#endif +static gboolean +gst_ss_demux_download_bus_cb(GstBus *bus, GstMessage *msg, gpointer data) +{ + GstSSDemuxStream *stream = (GstSSDemuxStream *)data; + GstSSDemux *demux = stream->parent; + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + GTimeVal time = {0, }; + gint idx = 0; + guint64 total_push_time = 0; + guint64 download_rate = 0; + + GST_INFO_OBJECT (stream->pad, "received EOS on download pipe.."); + // increase the fragment count on EOS + stream->frag_cnt++; + + /* download rate calculation : note down start time*/ + g_get_current_time (&time); + stream->download_stop_ts = (time.tv_sec * 1000000)+ time.tv_usec; + + download_rate = ((stream->download_size * 8 * 1000000) / (stream->download_stop_ts - stream->download_start_ts - stream->push_block_time)); + g_print("*********** '%s' download rate = %"G_GUINT64_FORMAT" bpssss **************\n", stream->name, download_rate); + stream->download_size = 0; + stream->download_stop_ts = stream->download_start_ts = 0; + stream->push_block_time = 0; + + if ((stream->type == SS_STREAM_VIDEO) && (demux->ss_mode != SS_MODE_AONLY)) { + if (!stream->is_buffering) { + /* for switching, we are considering video download rate only */ + demux->ss_mode = gst_ssm_parse_switch_qualitylevel (demux->parser, download_rate); + } + } else if (stream->type == SS_STREAM_AUDIO && (demux->ss_mode == SS_MODE_AONLY)) { + /* when video is not present using audio download rate to calculate switching */ + demux->ss_mode = gst_ssm_parse_switch_qualitylevel (demux->parser, download_rate); + if (demux->ss_mode != SS_MODE_AONLY) { + g_print ("\n\nMoving to AV mode by audio considering audio download rate\n\n\n\n"); + } + } + + g_cond_signal (stream->cond); + +#ifdef SIMULATE_AUDIO_ONLY + /* when fragment count is multiple of 4, switch to audio only case */ + if ((stream->frag_cnt % 4 == 0) && (stream->type == SS_STREAM_VIDEO) && + GST_SSM_PARSE_IS_LIVE_PRESENTATION(demux->parser)) { + g_print ("\n\t ######## Forcibly switching to audio only for testing ##########\n"); + demux->ss_mode = SS_MODE_AONLY; + } + #endif + GST_DEBUG_OBJECT (stream->pad, "Signalling eos condition..."); + + GST_DEBUG_OBJECT (demux, "number of fragments downloaded = %d", stream->frag_cnt); + break; + } + case GST_MESSAGE_ERROR: { + GError *error = NULL; + gchar* debug = NULL; + + g_print ("Error from %s\n", gst_element_get_name (GST_MESSAGE_SRC(msg))); + + gst_message_parse_error( msg, &error, &debug); + if (error) + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: error= %s\n", error->message); + + GST_ERROR_OBJECT (demux, "GST_MESSAGE_ERROR: debug = %s\n", debug); + + /* handling error, when client requests url, which is yet to be prepared by server */ + if (GST_IS_URI_HANDLER(GST_MESSAGE_SRC(msg))) { + GstStateChangeReturn ret; + + /* wait for 1sec & request the url again */ + // TODO: need to make wait time as generic or Adding loop count to request again & again + if (error) + GST_INFO_OBJECT (demux, "ERROR : code = %d, msg = %s, NEED to request again", error->code, error->message); + + usleep (1000000); // 1 sec + + /* put the current pipeline to NULL state */ + gst_element_set_state (stream->pipe, GST_STATE_NULL); + gst_element_get_state (stream->pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + stream->pipe = stream->urisrc = stream->parser = stream->sink = NULL; + + g_print ("Going to download fragment AGAIN : %s\n", stream->uri); + if (!gst_ss_demux_create_download_pipe (demux, stream, stream->uri, stream->start_ts)) { + GST_ERROR_OBJECT (demux, "failed to create download pipeline"); + if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + g_free(debug); + debug = NULL; + + return FALSE; + } + } + + ret = gst_element_set_state (stream->pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + return FALSE; + } + } + + } else { + if (error) + g_print ("GST_MESSAGE_ERROR: error= %s\n", error->message); + + g_print ("GST_MESSAGE_ERROR: debug = %s\n", debug); + if (!gst_element_post_message (GST_ELEMENT(demux), msg)) { + GST_ERROR_OBJECT (demux, "failed to post error"); + gst_ss_demux_stop (demux, stream); + g_free(debug); + debug = NULL; + g_error_free(error); + return FALSE; + } + gst_ss_demux_stop (demux, stream); + } + + g_free( debug); + debug = NULL; + g_error_free( error); + break; + } + case GST_MESSAGE_BUFFERING: { + int n =0; + int total_cache_perc = 0; + int active_stream_cnt = 0; + GstSSDemuxStream *cur_stream = NULL; + int avg_percent = 0; + + /* update buffer percent */ + gst_message_parse_buffering (msg, &stream->rcvd_percent); + gchar *name = gst_element_get_name (GST_MESSAGE_SRC (msg)); + GST_LOG_OBJECT (stream->pad, "Internal bus : Buffering from %s = %d\n", name, stream->rcvd_percent); + g_free(name); + name = NULL; + // TODO: need to check for better logic + for (n = 0; n < SS_STREAM_NUM; n++) { + cur_stream = demux->streams[n]; + if (cur_stream) { + active_stream_cnt++; + total_cache_perc += cur_stream->rcvd_percent; + } + } + + avg_percent = total_cache_perc / active_stream_cnt; + + GST_LOG_OBJECT (demux, "avg buffering completed = %d", avg_percent); + + if (avg_percent > 100) + avg_percent = 100; + + // TODO: need to add mutex for protecting percent + if (avg_percent != demux->percent) { + demux->percent = avg_percent; + GST_LOG_OBJECT (demux, "#########Posting %d buffering msg to main bus ###########", demux->percent); + + gst_element_post_message (GST_ELEMENT (demux), gst_message_new_buffering (GST_OBJECT (demux), avg_percent)); + } + } + break; + case GST_MESSAGE_WARNING: { + char* debug = NULL; + GError* error = NULL; + gst_message_parse_warning(msg, &error, &debug); + GST_WARNING_OBJECT(demux, "warning : %s\n", error->message); + GST_WARNING_OBJECT(demux, "debug : %s\n", debug); + g_error_free( error ); + g_free( debug); + break; + } + default : { + GST_LOG_OBJECT(demux, "unhandled message : %s\n", gst_message_type_get_name (GST_MESSAGE_TYPE (msg))); + break; + } + } + + return TRUE; +} + +static void +gst_ss_demux_update_buffering (GstSSDemuxStream *stream, guint64 percent) +{ + gboolean do_post = FALSE; + GstSSDemux *demux = stream->parent; + + if (stream->is_buffering) { + do_post = TRUE; + if (percent >= demux->high_percent) + stream->is_buffering = FALSE; + } else { + if (percent < demux->low_percent) { + stream->is_buffering = TRUE; + do_post = TRUE; + } + } + + if (do_post) { + GstMessage *message; + GstBufferingMode mode; + gint64 buffering_left = -1; + + percent = percent * 100 / demux->high_percent; + + if (percent > 100) + percent = 100; + + if (percent != stream->percent) { + stream->percent = percent; + + GST_DEBUG_OBJECT (stream->pad, "buffering %d percent", (gint) percent); + g_print ("'%s' buffering %d percent done\n", stream->name, (gint) percent); + + /* posting buffering to internal bus, which will take average & post to main bus */ + message = gst_message_new_buffering (GST_OBJECT_CAST (stream->sink), (gint) percent); + gst_element_post_message (GST_ELEMENT_CAST (stream->sink), message); + } + } + +} + +static void +gst_ssm_demux_on_new_buffer (GstElement * appsink, void* data) +{ + GstSSDemuxStream *stream = (GstSSDemuxStream *)data; + GstSSDemux *demux = stream->parent; + GstBuffer *inbuf = NULL; + GstFlowReturn fret = GST_FLOW_OK; + GstBuffer *headbuf = NULL; + gint64 diff = 0; + gint64 percent = 0; + GTimeVal start = {0, }; + GTimeVal stop = {0, }; + guint64 push_start_time = 0; + guint64 push_end_time =0; + + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_WARNING_OBJECT (demux, "Input buffer not available.,..\n"); + return; + } + + g_mutex_lock (stream->queue_lock); + + stream->download_size += GST_BUFFER_SIZE(inbuf); + + /* download rate calculation : note push_start_ts */ + g_get_current_time (&start); + push_start_time = (start.tv_sec * 1000000)+ start.tv_usec; + + GST_LOG_OBJECT (stream->pad, "Inbuf : size = %d, ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_BUFFER_SIZE(inbuf), GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(inbuf)), GST_TIME_ARGS(GST_BUFFER_DURATION(inbuf))); + + g_queue_push_tail (stream->queue, inbuf); + + if (GST_BUFFER_DURATION_IS_VALID (inbuf)) { + stream->cached_duration += GST_BUFFER_DURATION(inbuf); + } else { + g_print ("\nDuration field is not valid.. check this issue !!!!!!!!\n"); + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid duration of a frame"), (NULL)); + g_mutex_unlock (stream->queue_lock); + return; + } + + if (stream->cached_duration >= 0) { + percent = (stream->cached_duration * 100) / demux->max_cache_time; + //g_print ("[%s] percent done = %d[%"G_GINT64_FORMAT"]\n", ssm_parse_get_stream_name(stream->type), percent, percent); + + // TODO: need to decide, whther to call before wait or after ?? + gst_ss_demux_update_buffering (stream, percent); + + if (percent > 100) { + /* update buffering & wait if space is not available */ + GST_DEBUG_OBJECT (stream->pad, "Reached more than 100 percent, queue full & wait till free"); + g_cond_wait(stream->queue_full, stream->queue_lock); + GST_DEBUG_OBJECT (stream->pad,"Received signal to add more data..."); + } + } else { + g_print ("cached duration can not be negative\n\n\n"); + GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid cached duration"), (NULL)); + g_mutex_unlock (stream->queue_lock); + return; + } + + /* download rate calculation : note push_stop_ts */ + g_get_current_time (&stop); + push_end_time = (stop.tv_sec * 1000000)+ stop.tv_usec; + + stream->push_block_time += push_end_time - push_start_time; + + g_cond_signal (stream->queue_empty); + + g_mutex_unlock (stream->queue_lock); + return; +} + +static void +gst_ss_demux_stop (GstSSDemux * demux, GstSSDemuxStream *stream) +{ + if (GST_TASK_STATE (stream->stream_task) != GST_TASK_STOPPED) + gst_task_stop (stream->stream_task); +} + +static void +gst_ss_demux_stream_init (GstSSDemux *demux, GstSSDemuxStream *stream, SS_STREAM_TYPE stream_type) +{ + stream->cond = g_cond_new (); + stream->lock = g_mutex_new (); + stream->queue = g_queue_new (); + stream->queue_full = g_cond_new (); + stream->queue_empty = g_cond_new (); + stream->queue_lock = g_mutex_new (); + stream->parent = demux; + stream->pipe = NULL; + stream->urisrc = NULL; + stream->parser = NULL; + stream->sink = NULL; + stream->frag_cnt = 0; + stream->type = stream_type ; + stream->uri = NULL; + stream->start_ts = -1; + stream->sent_ns = FALSE; + stream->switch_ts = GST_CLOCK_TIME_NONE; + stream->avg_dur = GST_CLOCK_TIME_NONE; + stream->percent = 100; + stream->rcvd_percent = 0; + stream->push_block_time = 0; + stream->cached_duration = 0; + stream->download_start_ts = 0; + stream->download_stop_ts = 0; + stream->download_size = 0; + + if (stream->type == SS_STREAM_VIDEO) { + stream->pad = gst_pad_new_from_static_template (&ssdemux_videosrc_template, "video"); + stream->name = g_strdup("video"); + } else if (stream->type == SS_STREAM_AUDIO) { + stream->pad = gst_pad_new_from_static_template (&ssdemux_audiosrc_template, "audio"); + stream->name = g_strdup("audio"); + } else if (stream->type == SS_STREAM_TEXT) { + stream->pad = gst_pad_new_from_static_template (&ssdemux_subsrc_template, "subtitle"); + stream->name = g_strdup("text"); + } + + GST_PAD_ELEMENT_PRIVATE (stream->pad) = stream; + + gst_pad_use_fixed_caps (stream->pad); + gst_pad_set_event_function (stream->pad, gst_ss_demux_handle_src_event); + gst_pad_set_query_function (stream->pad, gst_ss_demux_handle_src_query); + + stream->caps = ssm_parse_get_stream_caps (demux->parser, stream->type); + gchar *caps_name = gst_caps_to_string(stream->caps); + g_print ("prepare video caps = %s", caps_name); + g_free(caps_name); + + GST_DEBUG_OBJECT (demux, "setting caps %" GST_PTR_FORMAT, stream->caps); + gst_pad_set_caps (stream->pad, stream->caps); + + GST_DEBUG_OBJECT (demux, "adding pad %s %p to demux %p", GST_OBJECT_NAME (stream->pad), stream->pad, demux); + gst_pad_set_active (stream->pad, TRUE); + gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->pad); +} + +static void +gst_ss_demux_stream_free (GstSSDemux * demux, GstSSDemuxStream * stream) +{ + if (stream->queue) { + while (!g_queue_is_empty(stream->queue)) { + gst_buffer_unref (g_queue_pop_head (stream->queue)); + } + g_queue_free (stream->queue); + stream->queue = NULL; + } + + if (stream->pad) { + gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad); + stream->pad = NULL; + } + if (stream->cond) { + g_cond_free (stream->cond); + stream->cond = NULL; + } + if (stream->lock) { + g_mutex_free (stream->lock); + stream->lock = NULL; + } + if (stream->queue_lock) { + g_mutex_free (stream->queue_lock); + stream->queue_lock = NULL; + } + if (stream->queue_full) { + g_cond_free (stream->queue_full); + stream->queue_full = NULL; + } + if (stream->queue_empty) { + g_cond_free (stream->queue_empty); + stream->queue_empty= NULL; + } + g_free (stream); +} +static gboolean +ssdemux_init (GstPlugin * plugin) +{ + if (!gst_element_register (plugin, "ssdemux", GST_RANK_PRIMARY, + GST_TYPE_SS_DEMUX) || FALSE) + return FALSE; + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "ssdemux", + "Smooth streaming demux plugin", + ssdemux_init, VERSION, "LGPL", PACKAGE_NAME, "http://www.samsung.com/") + diff --git a/ssdemux/src/gstssdemux.h b/ssdemux/src/gstssdemux.h new file mode 100755 index 0000000..b230b96 --- /dev/null +++ b/ssdemux/src/gstssdemux.h @@ -0,0 +1,69 @@ + +#ifndef __GST_SS_DEMUX_H__ +#define __GST_SS_DEMUX_H__ + +#include +#include +#include +#include +#include "ssmanifestparse.h" +#include "piffcommon.h" + +G_BEGIN_DECLS +#define GST_TYPE_SS_DEMUX \ + (gst_ss_demux_get_type()) +#define GST_SS_DEMUX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_SS_DEMUX, GstSSDemux)) +#define GST_SS_DEMUX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SS_DEMUX,GstSSDemuxClass)) +#define GST_IS_SS_DEMUX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SS_DEMUX)) +#define GST_IS_SS_DEMUX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SS_DEMUX)) + +typedef struct _GstSSDemux GstSSDemux; +typedef struct _GstSSDemuxClass GstSSDemuxClass; +typedef struct _GstSSDemuxStream GstSSDemuxStream; + + +/** + * GstSSDemux: + * + * Opaque #GstSSDemux data structure. + */ +struct _GstSSDemux +{ + GstElement parent; + + GstPad *sinkpad; + + /* Properties */ + gchar **cookies; /* HTTP request cookies. */ + gboolean allow_audio_only; /*In LIVE case, allow audio only download when downloadrate is less */ + guint64 max_cache_time; + gfloat bitrate_switch_tol; /* tolerance with respect to the fragment duration to switch the bitarate*/ + GstBuffer *manifest; + GstSSMParse *parser; /* manifest parser */ + gint percent; + gint low_percent; + gint high_percent; + gboolean eos; + GstSSDemuxStream *streams[SS_STREAM_NUM]; + SS_BW_MODE ss_mode; + gboolean switch_eos; + GstBuffer *protection_header; +}; + +struct _GstSSDemuxClass +{ + GstElementClass parent_class; +}; + +GType gst_ss_demux_get_type (void); + +G_END_DECLS +#endif /* __GST_SS_DEMUX_H__ */ + + + + diff --git a/ssdemux/src/ssmanifestparse.c b/ssdemux/src/ssmanifestparse.c new file mode 100755 index 0000000..5b1c6b2 --- /dev/null +++ b/ssdemux/src/ssmanifestparse.c @@ -0,0 +1,1668 @@ +#include "ssmanifestparse.h" + +static gboolean ssm_parse_root_node (GstSSMParse *parser, xmlNodePtr root_node); +GstCaps * ssm_prepare_video_caps (GstSSMParse *parser, GstSSMStreamNode *stream); +GstCaps * ssm_prepare_audio_caps (GstSSMParse *parser, GstSSMStreamNode *stream); +GstCaps *ssm_prepare_text_caps (GstSSMParse *parser, GstSSMStreamNode *stream); +static gboolean convert_NALUnitDCI_to_PacktizedDCI (unsigned char *nalu_dci, unsigned char **packetized_dci, unsigned int *packetized_dci_len); + +#define MANIFEST_LOCK(parser) g_mutex_lock(parser->lock) +#define MANIFEST_UNLOCK(parser) g_mutex_unlock(parser->lock) +#define START_TS_MAX(a,b) ((a)>(b) ? (a) : (b)) + +const gchar * +ssm_parse_get_stream_name(SS_STREAM_TYPE type) +{ + if (type == SS_STREAM_VIDEO) return "video"; \ + else if (type == SS_STREAM_AUDIO) return "audio"; \ + else if (type == SS_STREAM_TEXT) return "text"; \ + else return "unknown"; +} + + +static gboolean +int_from_string (gchar * ptr, gchar ** endptr, gint * val, gint base) +{ + gchar *end; + g_return_val_if_fail (ptr != NULL, FALSE); + g_return_val_if_fail (val != NULL, FALSE); + + errno = 0; + *val = strtol (ptr, &end, base); + if ((errno == ERANGE && (*val == LONG_MAX || *val == LONG_MIN)) || (errno != 0 && *val == 0)) { + g_print ("Error in strtol : %s\n", strerror(errno)); + return FALSE; + } + + if (endptr) + *endptr = end; + + return end != ptr; +} + +static gboolean +ssm_parse_get_xml_prop_boolean (GstSSMParse *parser, xmlNode * node, + const gchar * property) +{ + xmlChar *prop_string; + gboolean prop_bool = FALSE; + + prop_string = xmlGetProp (node, (const xmlChar *) property); + if (prop_string) { + if ((xmlStrcmp (prop_string, (xmlChar *) "false") == 0) || + (xmlStrcmp (prop_string, (xmlChar *) "FALSE") == 0)) { + GST_LOG (" - %s: false", property); + } else if ((xmlStrcmp (prop_string, (xmlChar *) "true") == 0) || + (xmlStrcmp (prop_string, (xmlChar *) "TRUE") == 0)) { + GST_LOG(" - %s: true", property); + prop_bool = TRUE; + } else { + GST_WARNING("failed to parse boolean property %s from xml string %s", property, prop_string); + } + xmlFree (prop_string); + } + + return prop_bool; +} + +static guint +ssm_parse_get_xml_prop_uint (GstSSMParse *parser, + xmlNode * node, const gchar * property, guint default_val) +{ + xmlChar *prop_string; + guint prop_uint = default_val; + + prop_string = xmlGetProp (node, (const xmlChar *) property); + if (prop_string) { + if (sscanf ((gchar *) prop_string, "%u", &prop_uint)) { + GST_LOG (" - %s: %u", property, prop_uint); + } else { + GST_WARNING("failed to parse unsigned integer property %s from xml string %s", + property, prop_string); + } + xmlFree (prop_string); + } + + return prop_uint; +} + +static guint64 +ssm_parse_get_xml_prop_uint64 (GstSSMParse *parser, + xmlNode * node, const gchar * property, guint64 default_val) +{ + xmlChar *prop_string; + guint64 prop_uint64 = default_val; + + prop_string = xmlGetProp (node, (const xmlChar *) property); + if (prop_string) { + if (sscanf ((gchar *) prop_string, "%llu", &prop_uint64)) { + GST_LOG (" - %s: %s[%"G_GUINT64_FORMAT"]", property, prop_string, prop_uint64); + } else { + GST_WARNING("failed to parse unsigned integer property %s from xml string %s", + property, prop_string); + } + xmlFree (prop_string); + } + + return prop_uint64; +} + +static gint +ssm_parser_sort_qualitylevels_by_bitrate (gconstpointer a, gconstpointer b) +{ + return ((GstSSMQualityNode *) (a))->bitrate - ((GstSSMQualityNode *) (b))->bitrate; //sorting in ascending order + //return ((GstSSMQualityNode *) (b))->bitrate - ((GstSSMQualityNode *) (a))->bitrate; // sorting in descending order +} + + +static void +gst_ssm_parse_free_quality_node (GstSSMQualityNode *qualitynode) +{ + if (qualitynode) { + g_free (qualitynode->codec_data); + g_free (qualitynode->fourcc); + g_slice_free (GstSSMQualityNode, qualitynode); + } +} + +static void +gst_ssm_parse_free_fragment_node (GstSSMFragmentNode*fragnode) +{ + if (fragnode) { + g_slice_free (GstSSMFragmentNode, fragnode); + } +} + + +static void +gst_ssm_parse_free_stream_node (GstSSMStreamNode *streamnode) +{ + if (streamnode) { + if (streamnode->quality_lists) { + streamnode->quality_lists = g_list_first (streamnode->quality_lists); + g_list_foreach (streamnode->quality_lists, (GFunc) gst_ssm_parse_free_quality_node, NULL); + g_list_free (streamnode->quality_lists); + streamnode->quality_lists = NULL; + } + if (streamnode->fragment_lists) { + streamnode->fragment_lists = g_list_first (streamnode->fragment_lists); + g_list_foreach (streamnode->fragment_lists, (GFunc) gst_ssm_parse_free_fragment_node, NULL); + g_list_free (streamnode->fragment_lists); + streamnode->fragment_lists = NULL; + } + if (streamnode->StreamType) { + g_free(streamnode->StreamType); + streamnode->StreamType = NULL; + } + if (streamnode->StreamUrl) { + g_free(streamnode->StreamUrl); + streamnode->StreamUrl = NULL; + } + if (streamnode->StreamSubType) { + g_free(streamnode->StreamSubType); + streamnode->StreamSubType = NULL; + } + if (streamnode->StreamName) { + g_free(streamnode->StreamName); + streamnode->StreamName = NULL; + } + if (streamnode->frag_cond) { + g_cond_free (streamnode->frag_cond); + streamnode->frag_cond = NULL; + } + if (streamnode->frag_lock) { + g_mutex_free (streamnode->frag_lock); + streamnode->frag_lock = NULL; + } + g_slice_free (GstSSMStreamNode, streamnode); + } +} + +GstSSMParse * +gst_ssm_parse_new (const gchar * uri) +{ + GstSSMParse *parser; + gchar *tmp = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + parser = g_new0 (GstSSMParse, 1); + + parser->uri = g_strdup (uri); + parser->lock = g_mutex_new(); + tmp = strrchr(uri, '/'); + tmp = tmp+1; + parser->presentation_uri = (gchar *) malloc (tmp - uri + 1); + if (NULL == parser->presentation_uri) { + GST_ERROR ("Failed to allocate memory..\n"); + return NULL; + } + + strncpy (parser->presentation_uri, uri, tmp - uri); + parser->presentation_uri[tmp-uri] = '\0'; + parser->ns_start = GST_CLOCK_TIME_NONE; + GST_INFO ("Presentation URI : %s", parser->presentation_uri); + return parser; +} + +void +gst_ssm_parse_free (GstSSMParse *parser) +{ + int i =0; + + g_return_if_fail (parser != NULL); + + g_mutex_free(parser->lock); + + // TODO: cleanup memory allocated..... + if (parser->RootNode) { + for (i = 0; i < SS_STREAM_NUM; i++) { + if (parser->RootNode->streams[i]) { + g_list_foreach (parser->RootNode->streams[i], (GFunc) gst_ssm_parse_free_stream_node, NULL); + parser->RootNode->streams[i] = NULL; + } + } + if (parser->RootNode->ProtectNode) { + g_slice_free (GstSSMProtectionNode, parser->RootNode->ProtectNode); + parser->RootNode->ProtectNode = NULL; + } + g_slice_free (GstSSMRootNode, parser->RootNode); + parser->RootNode = NULL; + } + + g_free (parser); +} + + +static gboolean +gst_ssm_parse_confirm_audiotag(gchar ** fourcc, gint audio_tag) +{ + switch(audio_tag){ + case 255: + *fourcc = (gchar *)strdup("AACL"); + break; + case 353: + *fourcc = (gchar *)strdup("WMAP"); + break; + default: + return FALSE; + } + return TRUE; +} + +static gboolean +ssm_parse_quality_node (GstSSMParse *parser, GstSSMStreamNode *stream, xmlNodePtr quality_node) +{ + GstSSMQualityNode *quality_level = NULL; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (quality_node != NULL, FALSE); + g_return_val_if_fail (stream != NULL, FALSE); + + quality_level = g_slice_new0 (GstSSMQualityNode); + if (quality_level == NULL) { + GST_ERROR ("Allocation of quality_level node failed!"); + return FALSE; + } + + quality_level->codec_data = NULL; + quality_level->fourcc = NULL; + + quality_level->index = ssm_parse_get_xml_prop_uint (parser, quality_node, "Index", -1); + GST_DEBUG("Quality Index = %d", quality_level->index); + if (SS_STREAM_VIDEO == stream->type && (quality_level->index == -1)) { + GST_ERROR ("Index attribute is not present for VIDEO stream..."); + return FALSE; + } + + /* MANDATORY : parsing Bitrate attribute */ + quality_level->bitrate = ssm_parse_get_xml_prop_uint (parser, quality_node, "Bitrate", -1); + GST_DEBUG("Bitrate = %d", quality_level->bitrate); + if (quality_level->bitrate == -1) { + GST_ERROR ("bitrate attribute is not present..."); + return FALSE; + } + + /* MANDATORY for video: parsing MaxWidth attribute */ + quality_level->max_width = ssm_parse_get_xml_prop_uint (parser, quality_node, "MaxWidth", -1); + GST_DEBUG("MaxWidth = %d", quality_level->max_width); + if (SS_STREAM_VIDEO == stream->type && (quality_level->max_width == -1)) { + GST_ERROR ("max_width attribute is not present in VIDEO..."); + return FALSE; + } + + /* MANDATORY for video: parsing MaxHeight attribute */ + quality_level->max_height = ssm_parse_get_xml_prop_uint (parser, quality_node, "MaxHeight", -1); + GST_DEBUG("MaxWidth = %d", quality_level->max_height); + if (SS_STREAM_VIDEO == stream->type && (quality_level->max_height == -1)) { + GST_ERROR ("max_height attribute is not present in VIDEO..."); + return FALSE; + } + + /* MANDATORY for audio: parsing SamplingRate attribute */ + quality_level->samplingrate = ssm_parse_get_xml_prop_uint (parser, quality_node, "SamplingRate", -1); + GST_DEBUG("SamplingRate = %d", quality_level->samplingrate); + if (SS_STREAM_AUDIO == stream->type && (quality_level->samplingrate == -1)) { + GST_ERROR ("SamplingRate attribute is not present for AUDIO..."); + return FALSE; + } + + /* MANDATORY for audio: parsing Channels attribute */ + quality_level->channels = ssm_parse_get_xml_prop_uint (parser, quality_node, "Channels", -1); + GST_DEBUG("SamplingRate = %d", quality_level->channels); + if (SS_STREAM_AUDIO == stream->type && (quality_level->channels == -1)) { + GST_ERROR ("Channels attribute is not present for AUDIO..."); + return FALSE; + } + + /* MANDATORY for audio: parsing BitsPerSample attribute */ + quality_level->bps = ssm_parse_get_xml_prop_uint (parser, quality_node, "BitsPerSample", -1); + GST_DEBUG("BitsPerSample = %d", quality_level->bps); + if (SS_STREAM_AUDIO == stream->type && (quality_level->bps == -1)) { + GST_ERROR ("BitsPerSample attribute is not present for AUDIO..."); + return FALSE; + } + + /* MANDATORY for audio: parsing PacketSize attribute */ + quality_level->packet_size = ssm_parse_get_xml_prop_uint (parser, quality_node, "PacketSize", -1); + GST_DEBUG("PacketSize = %d", quality_level->packet_size); + if (SS_STREAM_AUDIO == stream->type && (quality_level->packet_size == -1)) { + GST_ERROR ("PacketSize attribute is not present for AUDIO..."); + return FALSE; + } + + + /* MANDATORY for audio: parsing AudioTag attribute */ + quality_level->audio_tag = ssm_parse_get_xml_prop_uint (parser, quality_node, "AudioTag", -1); + GST_DEBUG("AudioTag = %d", quality_level->audio_tag); + if (SS_STREAM_AUDIO == stream->type && (quality_level->audio_tag == -1)) { + GST_ERROR ("AudioTag attribute is not present for AUDIO..."); + return FALSE; + } + + /* MANDATORY for audio & video: parsing FourCC attribute */ + quality_level->fourcc = (gchar *)xmlGetProp(quality_node, (const xmlChar *) "FourCC"); + if(!quality_level->fourcc && SS_STREAM_AUDIO == stream->type){ + if(!gst_ssm_parse_confirm_audiotag(&quality_level->fourcc, quality_level->audio_tag)){ + GST_ERROR ("failed to set fourcc from audio tag %d",quality_level->audio_tag); + return FALSE; + } + } + + if (!quality_level->fourcc && ((SS_STREAM_AUDIO == stream->type) || (SS_STREAM_VIDEO == stream->type))) { + GST_ERROR ("failed to parse fourcc from quality node"); + return FALSE; + } + + if (quality_level->fourcc && !((!strncmp ((char *)quality_level->fourcc, "AACL", 4)) || !strncmp ((char *)quality_level->fourcc, "WMAP", 4) || + (!strncmp ((char *)quality_level->fourcc, "H264", 4)) || !strncmp ((char *)quality_level->fourcc, "WVC1", 4) || + (!strncmp ((char *)quality_level->fourcc, "TTML", 4)))) { + GST_INFO ("Not a proper Fourcc Code...If possible take from SubType\n\n\n"); + free (quality_level->fourcc); + + GST_DEBUG ("Subtype = %s\n\n",stream->StreamSubType); + quality_level->fourcc = g_strdup (stream->StreamSubType); + if (!((!strncmp ((char *)quality_level->fourcc, "AACL", 4)) || !strncmp ((char *)quality_level->fourcc, "WMAP", 4) || + (!strncmp ((char *)quality_level->fourcc, "H264", 4)) || !strncmp ((char *)quality_level->fourcc, "WVC1", 4))) { + GST_ERROR ("Subtype also does not contain valid fourcc code...ERROR\n"); + return FALSE; + } + } + + GST_DEBUG("FourCC = %s", quality_level->fourcc); + + // TODO: need to check whether it is required for all video & audio + + /* MANDATORY for audio & video: parsing CodecPrivateData attribute */ + quality_level->codec_data = (gchar *)xmlGetProp(quality_node, (const xmlChar *) "CodecPrivateData"); + if (!quality_level->codec_data && ((SS_STREAM_AUDIO == stream->type) || (SS_STREAM_VIDEO == stream->type))) { + GST_ERROR ("failed to get codec data from quality node"); + return FALSE; + } + + /* Optional for VIDEO H264: parsing NALUnitLengthField attribute */ + quality_level->NALULengthofLength = ssm_parse_get_xml_prop_uint (parser, quality_node, "NALUnitLengthField", 4); + GST_DEBUG("NALUnitLengthField = %d", quality_level->NALULengthofLength); + + stream->quality_lists = g_list_append (stream->quality_lists, quality_level); + + GST_LOG ("Appened quality level to stream..."); + + return TRUE; + +} + +static gboolean +ssm_parse_fragment_node (GstSSMParse *parser, GstSSMStreamNode *stream, xmlNodePtr fragment_node) +{ + GstSSMFragmentNode *fragment = NULL; + gboolean found_time = FALSE; + gboolean found_duration = FALSE; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (fragment_node != NULL, FALSE); + g_return_val_if_fail (stream != NULL, FALSE); + + fragment = g_slice_new0 (GstSSMFragmentNode); + if (fragment == NULL) { + GST_ERROR ("Allocation of fragment failed!"); + return FALSE; + } + + /*parsing fragmentnumber attribute */ + fragment->num = ssm_parse_get_xml_prop_uint (parser, fragment_node, "n", -1); + GST_DEBUG ("fragment number = %d", fragment->num); + + /*parsing duration attribute */ + fragment->dur = ssm_parse_get_xml_prop_uint64 (parser, fragment_node, "d", -1); + if (fragment->dur == -1 && !fragment_node->next) { + GST_ERROR ("Fragment Duration for last fragment is mandatory"); + return FALSE; + } else if (fragment->dur != -1) { + GST_DEBUG ("Fragment duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (fragment->dur)); + found_duration = TRUE; + } + + /*parsing time attribute */ + fragment->time = ssm_parse_get_xml_prop_uint64 (parser, fragment_node, "t", -1); + if (fragment->time != -1) { + GST_DEBUG ("Fragment time = %"GST_TIME_FORMAT, GST_TIME_ARGS(fragment->time)); + found_time = TRUE; + } + + if (!found_time && !found_duration) { + GST_ERROR ("Both time & duration attributes are NOT present.. ERROR"); + return FALSE; + } else if (!found_time && found_duration) { + GList *prev_fragment_list = NULL; + GstSSMFragmentNode *prev_fragment = NULL; + + GST_DEBUG ("Only Duration attribute is present..."); + if (stream->fragment_lists) { + prev_fragment_list = g_list_last(stream->fragment_lists); + if (NULL == prev_fragment_list) { + GST_ERROR ("Error last fragment lists are not present..\n"); + return FALSE; + } + prev_fragment = (GstSSMFragmentNode *)prev_fragment_list->data; + fragment->time = prev_fragment->time + prev_fragment->dur; + GST_DEBUG ("Fragment time = %llu", fragment->time); + } else { + GST_INFO ("Frament list is empty, assuming it as first fragment..."); + fragment->time = 0; + } + } else if (found_time && !found_duration) { + xmlNodePtr next_fragment_node = NULL; + guint64 next_ts = 0; + + GST_DEBUG ("Only time attribute is present..."); + + next_fragment_node = fragment_node->next; + if (next_fragment_node) { + next_ts = ssm_parse_get_xml_prop_uint64 (parser, fragment_node, "t", -1); + if (next_ts == -1) { + GST_ERROR ("Next fragment time not present to calculate duration of present fragment..."); + return FALSE; + } else { + fragment->dur = next_ts - fragment->time; + GST_DEBUG ("Current fragment duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(fragment->dur)); + } + } else { + GST_ERROR ("Next fragment not present to calculate duration of present fragment..."); + return FALSE; + } + } + +#if 1 + /*error check for timestamps as specified in spec */ + { + xmlNodePtr next_fragment_node = NULL; + unsigned long long next_ts = 0; + + next_fragment_node = fragment_node->next; + if (next_fragment_node) { + next_ts = ssm_parse_get_xml_prop_uint64 (parser, fragment_node, "t", -1); + if (next_ts != -1) { + GST_DEBUG ("Next Fragment time = %llu and Current fragment time = %llu\n", next_ts, fragment->time); + + if ( next_ts < fragment->time) { + GST_ERROR ("Error in timestamp sequence..."); + return FALSE; + } + } + } + } +#endif + + stream->stream_duration += fragment->dur; + + stream->fragment_lists = g_list_append (stream->fragment_lists, fragment); + GST_DEBUG ("Added fragment node to list..."); + // TODO: Need to invetigate on TrackFragmentIndex Attribute + + return TRUE; +} + +static gboolean +ssm_parse_stream_index_node (GstSSMParse *parser, xmlNodePtr stream_node) +{ + GstSSMStreamNode *stream = NULL; + xmlNodePtr stream_children = NULL; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (stream_node != NULL, FALSE); + + stream = g_slice_new0 (GstSSMStreamNode); + if (stream == NULL) { + GST_WARNING ("Allocation of stream node failed!"); + return FALSE; + } + + stream->frag_lock = g_mutex_new (); + stream->frag_cond = g_cond_new (); + + /* Type, Chunks, QualityLevels are MUST attributes */ + stream->StreamType = (gchar *)xmlGetProp(stream_node, (const xmlChar *) "Type"); + if (NULL == stream->StreamType) { + GST_ERROR ("Type attribute is not present"); + return FALSE; + } + GST_DEBUG ("Type = %s", stream->StreamType); + + if (!strncmp ((char *)stream->StreamType, "video", 5)) + stream->type = SS_STREAM_VIDEO; + else if (!strncmp ((char *)stream->StreamType, "audio", 5)) + stream->type = SS_STREAM_AUDIO; + else if (!strncmp ((char *)stream->StreamType, "text", 4)) + stream->type = SS_STREAM_TEXT; + else { + GST_ERROR ("UnKnown Stream type..."); + return FALSE; + } + + /* Optional SubType Attribute */ + stream->StreamSubType = (gchar *)xmlGetProp(stream_node, (const xmlChar *) "Subtype"); + if (stream->StreamSubType) + GST_DEBUG ("StreamSubType = %s", stream->StreamSubType); + + stream->StreamTimeScale = ssm_parse_get_xml_prop_uint64 (parser, stream_node, "TimeScale", parser->RootNode->TimeScale); + GST_LOG("StreamTimeScale = %"G_GUINT64_FORMAT, stream->StreamTimeScale); + + /* Optional StreamName Attribute */ + stream->StreamName = (gchar *)xmlGetProp(stream_node, (const xmlChar *) "Name"); + if (stream->StreamName) + GST_DEBUG ("StreamName = %s", stream->StreamName); + + // TODO: need to understand more on this chunks whether mandatory or not in LIVE case + stream->nChunks = ssm_parse_get_xml_prop_uint (parser, stream_node, "Chunks", 0); + if (!stream->nChunks && !parser->RootNode->PresentationIsLive) { + GST_ERROR ("nChunks is zero in VOD case...ERROR"); + return FALSE; + } + GST_DEBUG("nChunks = %d", stream->nChunks); + + stream->nQualityLevels = ssm_parse_get_xml_prop_uint (parser, stream_node, "QualityLevels", 0); + GST_DEBUG("nQualityLevels = %d", stream->nQualityLevels); + + stream->StreamUrl = (gchar *)xmlGetProp(stream_node, (const xmlChar *) "Url"); + if (NULL == stream->StreamUrl) { + GST_ERROR ("Url Pattern attribute is not present"); + return FALSE; + } + GST_DEBUG ("Url = %s", stream->StreamUrl); + + if (stream->type == SS_STREAM_VIDEO) { + /* Video stream specific attributes */ + stream->MaxWidth = ssm_parse_get_xml_prop_uint (parser, stream_node, "MaxWidth", 0); + GST_DEBUG("MaxWidth = %d", stream->MaxWidth); + + stream->MaxHeight = ssm_parse_get_xml_prop_uint (parser, stream_node, "MaxHeight", 0); + GST_DEBUG("MaxHeight = %d", stream->MaxHeight); + + stream->DisplayWidth = ssm_parse_get_xml_prop_uint (parser, stream_node, "DisplayWidth", 0); + GST_DEBUG("DisplayWidth = %d", stream->DisplayWidth); + + stream->DisplayHeight = ssm_parse_get_xml_prop_uint (parser, stream_node, "DisplayHeight", 0); + GST_DEBUG("DisplayHeight = %d", stream->DisplayHeight); + } + + /* get the children nodes */ + stream_children = stream_node->xmlChildrenNode; + if (NULL == stream_children) { + GST_ERROR ("No Children for StreamIndex Node...\n"); + return FALSE; + } + + /* Parse StreamIndex Children Nodes i.e. QualityLevel */ + while (stream_children) { + if ( xmlIsBlankNode (stream_children)) {/* skip blank nodes */ + stream_children = stream_children->next; + continue; + } + if (!xmlStrcmp(stream_children->name, (const xmlChar *) "QualityLevel")) { + if (!ssm_parse_quality_node (parser, stream, stream_children)) { + GST_ERROR ("failed to parse quality node"); + return FALSE; + } + } else if (!xmlStrcmp(stream_children->name, (const xmlChar *) "c")) { + if (!ssm_parse_fragment_node (parser, stream, stream_children)) { + GST_ERROR ("failed to parse fragment node"); + return FALSE; + } + } else { + GST_WARNING (" ==== >>>>>> Unknow ChildrenNode in StreamNode : %s", stream_children->name); + } + stream_children = stream_children->next; + } + + /* sort the quality lists */ + if (stream->quality_lists && (g_list_length(stream->quality_lists) > 1)) { + stream->quality_lists = g_list_sort (stream->quality_lists, (GCompareFunc) ssm_parser_sort_qualitylevels_by_bitrate); + } + + parser->RootNode->streams[stream->type] = g_list_append (parser->RootNode->streams[stream->type], stream); + + return TRUE; + +} + + +static gboolean +ssm_parse_protection_node (GstSSMParse *parser, xmlNodePtr protection_node) +{ + xmlChar *xml_string = NULL; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (protection_node != NULL, FALSE); + + parser->RootNode->ProtectNode = g_slice_new0 (GstSSMFragmentNode); + if (NULL == parser->RootNode->ProtectNode) { + GST_ERROR ("Failed to allocate memory...\n"); + return FALSE; + } + + parser->RootNode->ProtectNode->SystemID = NULL; + parser->RootNode->ProtectNode->Content = NULL; + parser->RootNode->ProtectNode->ContentSize = 0; + + if (!xmlStrcmp(protection_node->name, (const xmlChar *) "ProtectionHeader")) { + parser->RootNode->ProtectNode->SystemID = (unsigned char *) xmlGetProp(protection_node, (const xmlChar *) "SystemID"); + if (NULL == parser->RootNode->ProtectNode->SystemID) { + GST_ERROR ("System ID is not present... need to decide ERROR or NOT... returning ERROR now\n"); + return FALSE; + } + + GST_DEBUG ("system ID = %s\n", parser->RootNode->ProtectNode->SystemID); + + if (!strncasecmp ((char *)parser->RootNode->ProtectNode->SystemID, + "9A04F079-9840-4286-AB92-E65BE0885F95", + 36)) { + g_print ("======== >>>>>>>. Content is encrypted using PLAYREADY\n"); + } else { + GST_ERROR ("\n\n ******** UN-supported encrypted content... *********\n\n"); + return FALSE; + } + + xml_string = xmlNodeGetContent(protection_node); + if (NULL == xml_string) { + GST_ERROR ("Content is not present... need to decide ERROR or NOT\n"); + return FALSE; + } else { + gsize content_size = 0; + + g_print ("Content = %s\n", xml_string); + + parser->RootNode->ProtectNode->Content = g_base64_decode ((gchar*)xml_string, &content_size); + if (NULL == parser->RootNode->ProtectNode->Content) { + GST_ERROR ("Failed to do base64 decoding...\n"); + free (xml_string); + xml_string = NULL; + return FALSE; + } + + parser->RootNode->ProtectNode->ContentSize = content_size; + free (xml_string); + xml_string = NULL; + + GST_DEBUG ("ProtectionNode content = %s and size = %d\n", parser->RootNode->ProtectNode->Content, content_size); + } + } else { + GST_ERROR ("ProtectionHeader is NOT PRESENT in Protection node...ERROR\n"); + return FALSE; + } + + GST_LOG ("successfully parsed protectionheader node..."); + return TRUE; +} + +static gboolean +ssm_parse_root_node (GstSSMParse *parser, xmlNodePtr root_node) +{ + int i = 0; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (root_node != NULL, FALSE); + + parser->RootNode = g_slice_new0 (GstSSMRootNode); + if (parser->RootNode == NULL) { + GST_WARNING ("Allocation of root node failed!"); + return FALSE; + } + + for (i = 0; i < SS_STREAM_NUM; i++) { + parser->RootNode->streams[i] = NULL; + } + + parser->RootNode->ProtectNode = NULL; + + /* MANDATORY : parsing MajorVersion attribute */ + parser->RootNode->MajorVersion = ssm_parse_get_xml_prop_uint (parser, root_node, "MajorVersion", -1); + if (parser->RootNode->MajorVersion != 2) { + GST_ERROR("Majorversion should be 2"); + return FALSE; + } + GST_LOG("SmoothStreamingMedia :: Majorversion = %d", parser->RootNode->MajorVersion); + + /* MANDATORY : parsing MinorVersion attribute */ + parser->RootNode->MinorVersion = ssm_parse_get_xml_prop_uint (parser, root_node, "MinorVersion", 0); + GST_LOG("SmoothStreamingMedia :: MinorVersion = %d", parser->RootNode->MinorVersion); + + parser->RootNode->TimeScale = ssm_parse_get_xml_prop_uint64 (parser, root_node, "TimeScale", 10000000); + GST_LOG("SmoothStreamingMedia :: TimeScale = %"G_GUINT64_FORMAT, parser->RootNode->TimeScale); + + parser->RootNode->Duration = ssm_parse_get_xml_prop_uint64 (parser, root_node, "Duration", -1); + GST_LOG("SmoothStreamingMedia :: Duration = %"G_GUINT64_FORMAT, parser->RootNode->Duration); + + parser->RootNode->PresentationIsLive = ssm_parse_get_xml_prop_boolean (parser, root_node, "IsLive"); + GST_LOG("SmoothStreamingMedia :: IsLive = %d", parser->RootNode->PresentationIsLive); + + /* valid for live presentation only*/ + if (parser->RootNode->PresentationIsLive) { + + parser->RootNode->LookAheadCount = ssm_parse_get_xml_prop_uint (parser, root_node, "LookaheadCount", -1); + GST_LOG("SmoothStreamingMedia :: LookaheadCount = %d", parser->RootNode->LookAheadCount); + + if (parser->RootNode->LookAheadCount == -1) { + GST_INFO ("fallback case of lookaheadcount..."); + parser->RootNode->LookAheadCount = ssm_parse_get_xml_prop_uint (parser, root_node, "LookAheadFragmentCount", -1); + GST_LOG("SmoothStreamingMedia :: LookAheadFragmentCount = %d", parser->RootNode->LookAheadCount); + } + + parser->RootNode->DVRWindowLength = ssm_parse_get_xml_prop_uint64 (parser, root_node, "DVRWindowLength", 0); + GST_LOG("SmoothStreamingMedia :: DVRWindowLength = %"G_GUINT64_FORMAT, parser->RootNode->DVRWindowLength); + if (parser->RootNode->DVRWindowLength == 0) + GST_INFO ("DVR Window Length is zero...means INFINITE"); + } + + return TRUE; +} + + +gboolean +gst_ssm_parse_manifest (GstSSMParse *parser, char *data, unsigned int size) +{ + xmlNodePtr root = NULL; + xmlNodePtr curnode = NULL; + xmlDocPtr doc; + int i; + + g_return_val_if_fail (parser != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size != 0, FALSE); + + /* parse manifest xml file */ + doc = xmlReadMemory ((gchar *) data, size, NULL, NULL, 0); + if (doc == NULL ) { + GST_ERROR("failed to parse manifest file..."); + goto error; + } + + /* Get the root element */ + root = xmlDocGetRootElement(doc); + if (root == NULL) { + GST_ERROR("no ROOT node in manifest file..."); + goto error; + } + + if (!xmlStrcmp(root->name, (const xmlChar *) "SmoothStreamingMedia")) { + /* parsing of ROOT Node SmoothStreamingMedia attributes */ + if (!ssm_parse_root_node (parser, root)) { + GST_ERROR("failed to parse root node..."); + goto error; + } + GST_DEBUG ("Parsing ROOT element is successful"); + } else { + GST_ERROR ("SmoothStreamingMedia ROOT element is not present..."); + goto error; + } + + /* moving to children nodes */ + curnode = root->xmlChildrenNode; + + while (curnode) { + if (xmlIsBlankNode (curnode)) {/* skip blank node */ + curnode = curnode->next; + continue; + } + + if (!xmlStrcmp(curnode->name, (const xmlChar *)"StreamIndex")) { + /* Parsing Stream Node */ + if (!ssm_parse_stream_index_node (parser, curnode)) { + GST_ERROR ("failed to parse stream index node..."); + return FALSE; + } + } else if (!xmlStrcmp(curnode->name, (const xmlChar *) "Protection")) { + xmlNodePtr protect_node; + + /* get the children */ + protect_node = curnode->xmlChildrenNode; + if (NULL == protect_node) { + GST_ERROR ("No Children for Protection Node...\n"); + return FALSE; + } else { + if (!ssm_parse_protection_node (parser, protect_node)) { + GST_ERROR ("failed to parse protectionheader node"); + return FALSE; + } + } + } + curnode = curnode->next; + } + + /* Move to last fragment when presentation is LIVE */ + if (parser->RootNode->PresentationIsLive) { + for (i = 0; i < SS_STREAM_NUM; i++) { + if (parser->RootNode->streams[i]) { + GST_INFO ("Live presentation, so moved to last node..."); + ((GstSSMStreamNode *)(parser->RootNode->streams[i]->data))->fragment_lists = + g_list_last (((GstSSMStreamNode *)(parser->RootNode->streams[i]->data))->fragment_lists); + } + } + } + + parser->ns_start = 0; + + /* get new segment start */ + for (i = 0; i < SS_STREAM_NUM; i++) { + GstSSMStreamNode *stream = NULL; + GList *frag_list = NULL; + guint64 start_ts = GST_CLOCK_TIME_NONE; + + if (parser->RootNode->streams[i]) { + /* Move to last fragment when presentation is LIVE */ + if (parser->RootNode->PresentationIsLive) { + GST_INFO ("Live presentation, so moved to last node..."); + ((GstSSMStreamNode *)(parser->RootNode->streams[i]->data))->fragment_lists = + g_list_last (((GstSSMStreamNode *)(parser->RootNode->streams[i]->data))->fragment_lists); + } + + stream = (parser->RootNode->streams[i])->data; + frag_list = stream->fragment_lists; + start_ts = ((GstSSMFragmentNode *)frag_list->data)->time; + + GST_LOG ("ns_start = %"G_GUINT64_FORMAT" and start_ts[%s] = %"G_GUINT64_FORMAT, + parser->ns_start, ssm_parse_get_stream_name(i), start_ts); + + /* take MAX of stream's start as new_segment start */ + parser->ns_start = START_TS_MAX (parser->ns_start, start_ts); + } + } + + GST_INFO ("ns_start = %"G_GUINT64_FORMAT, parser->ns_start); + + if (doc) { + xmlFreeDoc(doc); + doc = NULL; + } + + GST_DEBUG ("successfully parsed manifest"); + + return TRUE; + +error: + if (doc) { + xmlFreeDoc(doc); + doc = NULL; + } + + return FALSE; +} + +/* Only supporting url in 'QualityLevels({bitrate})/Fragments(xxxxxx={start time})' + * FIXME : Add support for any */ +gboolean +gst_ssm_parse_get_next_fragment_url (GstSSMParse *parser, SS_STREAM_TYPE stream_type, gchar **uri, guint64 *start_ts) +{ + GstSSMStreamNode *stream = NULL; + GList *frag_list = NULL; + GPtrArray *strs; + guint64 time = 0; + gchar **splitter1 = NULL; + gchar **splitter2 = NULL; + gchar **splitter3 = NULL; + + MANIFEST_LOCK(parser); + stream = (parser->RootNode->streams[stream_type])->data; //get current video stream + g_mutex_lock (stream->frag_lock); + + if (stream->fraglist_eos) { + if (parser->RootNode->PresentationIsLive) { + /* Live Presentation need to wait for next uri */ + g_print ("waiting for next URI in LIVE presentation...\n"); + g_cond_wait (stream->frag_cond, stream->frag_lock); + g_print ("Received signal after appending new URI...move to next now\n"); + ((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists = + g_list_next (((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists); + } else { + /* VOD presentation reached EOS */ + GST_INFO("Fragment list is empty in VOD case..."); + g_mutex_unlock (stream->frag_lock); + MANIFEST_UNLOCK(parser); + return FALSE; + } + } + + stream = (parser->RootNode->streams[stream_type])->data; //get current video stream + + frag_list = stream->fragment_lists; + + strs = g_ptr_array_new (); + + /* adding presentation uri */ + g_ptr_array_add (strs, g_strdup(parser->presentation_uri)); + + splitter1 = g_strsplit (stream->StreamUrl, "{", 3); + + /* add stream url till first '{' */ + g_ptr_array_add (strs, g_strdup(splitter1[0])); + + /* adding bitrate param */ + g_ptr_array_add (strs, g_strdup_printf ("%d", ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate)); + + /* tokenize based on '}' */ + splitter2 = g_strsplit (splitter1[1], "}", 2); + + g_ptr_array_add (strs, g_strdup(splitter2[1])); + + time = ((GstSSMFragmentNode *)frag_list->data)->time; + + /* adding fragment time */ + g_ptr_array_add (strs, g_strdup_printf ("%llu", time)); + + *start_ts = gst_util_uint64_scale (time, GST_SECOND, parser->RootNode->TimeScale); + + /* tokenize based on '}' */ + splitter3 = g_strsplit (splitter1[2], "}", 2); + + g_ptr_array_add (strs, g_strdup(splitter3[1])); + + /* add a terminating NULL */ + g_ptr_array_add (strs, NULL); + + if (frag_list = g_list_next (((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists)) { + ((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists = frag_list; + } else { + GST_INFO ("Reached end of fragment list...\n"); + ((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fraglist_eos = TRUE; + } + + *uri = g_strjoinv (NULL, (gchar **) strs->pdata); + g_strfreev ((gchar **) g_ptr_array_free (strs, FALSE)); + + g_mutex_unlock (stream->frag_lock); + + MANIFEST_UNLOCK(parser); + + return TRUE; +} + +GstCaps * +ssm_parse_get_stream_caps (GstSSMParse *parser, SS_STREAM_TYPE stream_type) +{ + GstSSMStreamNode *stream = NULL; + MANIFEST_LOCK(parser); + + stream = parser->RootNode->streams[stream_type]->data; + GstCaps *caps = NULL; + if (stream_type == SS_STREAM_VIDEO) { + caps = ssm_prepare_video_caps (parser, stream); + } else if (stream_type == SS_STREAM_AUDIO) { + caps = ssm_prepare_audio_caps (parser, stream); + } else if (stream_type == SS_STREAM_TEXT) { + caps = ssm_prepare_text_caps (parser, stream); + } + MANIFEST_UNLOCK(parser); + return caps; +} + +GstCaps * +ssm_prepare_video_caps (GstSSMParse *parser, GstSSMStreamNode *stream) +{ + GstSSMQualityNode *cur_quality_node = (GstSSMQualityNode *)(stream->quality_lists->data); + GstBuffer *codec_data = NULL; + GstCaps *caps = NULL; + + codec_data = gst_buffer_new (); + if (!codec_data) { + GST_ERROR ("failed to allocate buffer"); + return NULL; + } + + if (!strncmp ((char *)cur_quality_node->fourcc, "H264", 4)) { + /* converting NALU codec data to 3GPP codec data format */ + if (!convert_NALUnitDCI_to_PacktizedDCI (cur_quality_node->codec_data, &(GST_BUFFER_DATA(codec_data)), &GST_BUFFER_SIZE(codec_data))) { + GST_ERROR ("Error in converting NALUDCI to Packetized DCI...\n"); + return NULL; + } + GST_BUFFER_MALLOCDATA(codec_data) = GST_BUFFER_DATA(codec_data); + } else if (!strncmp ((char *)cur_quality_node->fourcc, "WVC1", 4)) { + unsigned char *codec_data = cur_quality_node->codec_data; + unsigned int DCI_len = strlen ((char *)cur_quality_node->codec_data); + gchar tmp[3] = {0, }; + gint val = 0; + gint codec_data_len = 0; + gint idx = 0; + + codec_data_len = (DCI_len >>1); + + codec_data = gst_buffer_new_and_alloc (codec_data_len); + if (!codec_data) { + GST_ERROR ("Failed to allocate memory..\n"); + return FALSE; + } + + /* copy codec data */ + while (DCI_len) { + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)codec_data, 2); + tmp[2] = '\0'; + if (!int_from_string ((char*)tmp, NULL, &val, 16)) { + GST_ERROR ("Failed to int from string..."); + return NULL; + } + (GST_BUFFER_DATA(codec_data))[idx] = val; + codec_data += 2; + DCI_len = DCI_len - 2; + idx++; + } + } + + if (!strncmp ((char *)cur_quality_node->fourcc, "H264", 4)) { + /* prepare H264 caps */ + caps = gst_caps_new_simple ("video/x-h264", + "width", G_TYPE_INT, cur_quality_node->max_width, + "height", G_TYPE_INT, cur_quality_node->max_height, + "framerate", GST_TYPE_FRACTION, 30, 1, + "stream-format", G_TYPE_STRING, "avc", + "alignment", G_TYPE_STRING, "au", + "codec_data", GST_TYPE_BUFFER, codec_data, + NULL); + } else if (!strncmp ((char *)cur_quality_node->fourcc, "WVC1", 4)) { + /* prepare VC1 caps */ + caps = gst_caps_new_simple ("video/x-wmv", + "width", G_TYPE_INT, cur_quality_node->max_width, + "height", G_TYPE_INT, cur_quality_node->max_height, + "framerate", GST_TYPE_FRACTION, 30, 1, + "wmvversion", G_TYPE_INT, 3, + "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'), + "codec_data", GST_TYPE_BUFFER, codec_data, + NULL); + } else { + char *s; + /* prepare gst generic caps caps */ + GST_ERROR ("Wrong VIDEO fourcc..."); + s = g_strdup_printf ("video/x-gst-fourcc-%s", "unknown"); + caps = gst_caps_new_simple (s, + "width", G_TYPE_INT, cur_quality_node->max_width, + "height", G_TYPE_INT, cur_quality_node->max_height, + "framerate", GST_TYPE_FRACTION, 30, 1, + "codec_data", GST_TYPE_BUFFER, codec_data, + NULL); + } + + gchar *caps_name = gst_caps_to_string(caps); + GST_INFO ( "prepared video caps : %s\n", caps_name); + g_free(caps_name); + + return caps; +} + +GstCaps * +ssm_prepare_audio_caps (GstSSMParse *parser, GstSSMStreamNode *stream) +{ + GstSSMQualityNode *cur_quality_node = (GstSSMQualityNode *)(stream->quality_lists->data); + GstBuffer *codec_data = NULL; + GstCaps *caps = NULL; + + if (cur_quality_node->codec_data && + ((!strncmp ((char *)cur_quality_node->fourcc, "AACL", 4)) || !strncmp ((char *)cur_quality_node->fourcc, "WMAP", 4))) { + guint DCI_len = strlen ((char *)cur_quality_node->codec_data); + gchar *dci = cur_quality_node->codec_data; + gchar tmp[3] = {0, }; + gint val = 0; + gint codec_data_len = (DCI_len >>1); + gint idx = 0; + + codec_data = gst_buffer_new_and_alloc (codec_data_len); + if (NULL == codec_data) { + GST_ERROR ("Failed to allocate memory..\n"); + return NULL; + } + + /* copy codec data */ + while (DCI_len) { + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)dci, 2); + tmp[2] = '\0'; + if (!int_from_string ((char*)tmp, NULL, &val , 16)) { + GST_ERROR ("Failed to int from string..."); + return NULL; + } + (GST_BUFFER_DATA(codec_data))[idx] = val; + dci += 2; + DCI_len = DCI_len - 2; + //g_print ("val = 0x%02x, codec_data_length = %d, idx = %d\n", val, DCI_len, idx); + idx++; + } + } else { + GST_ERROR ("\n\n\nUnsupported Audio Codec Fourcc...\n\n\n"); + return NULL; + } + + if (!strncmp ((char *)cur_quality_node->fourcc, "AACL", 4)) { + caps = gst_caps_new_simple ("audio/mpeg", + "mpegversion", G_TYPE_INT, 4, + "framed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, "raw", + "rate", G_TYPE_INT, (int) cur_quality_node->samplingrate, + "channels", G_TYPE_INT, cur_quality_node->channels, + "codec_data", GST_TYPE_BUFFER, codec_data, + NULL); + } else if (!strncmp ((char *)cur_quality_node->fourcc, "WMAP", 4)) { + caps = gst_caps_new_simple ("audio/x-wma", + "rate", G_TYPE_INT, (int) cur_quality_node->samplingrate, + "channels", G_TYPE_INT, cur_quality_node->channels, + NULL); + } else { + char *s; + + GST_ERROR ("Wrong Audio fourcc..."); + s = g_strdup_printf ("audio/x-gst-fourcc-%s", "unknown"); + caps = gst_caps_new_simple (s, + "rate", G_TYPE_INT, (int) cur_quality_node->samplingrate, + "channels", G_TYPE_INT, cur_quality_node->channels, + NULL); + } + gchar *caps_name = gst_caps_to_string(caps); + GST_INFO ( "prepared video caps : %s\n", caps_name); + g_free(caps_name); + + return caps; +} + +GstCaps * +ssm_prepare_text_caps (GstSSMParse *parser, GstSSMStreamNode *stream) +{ + // TODO: Yet to add support for text caps + return NULL; +} + +SS_BW_MODE +gst_ssm_parse_switch_qualitylevel (GstSSMParse *parser, guint drate) +{ + GstSSMStreamNode *stream = parser->RootNode->streams[SS_STREAM_VIDEO]->data; + guint bitrate = ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate; + SS_BW_MODE ret = SS_MODE_NO_SWITCH; + + /* check for upward transition */ + while (drate > (bitrate + BITRATE_SWITCH_UPPER_THRESHOLD * bitrate)) { + if (g_list_next (stream->quality_lists)) { + stream->quality_lists = g_list_next (stream->quality_lists); + g_print ("Move to next quality level : drate = %d and bitrate = %d\n", drate, ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate); + ret = SS_MODE_AV; + bitrate = ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate; + } else { + g_print ("Already at MAX Bitrate possible...\n"); + ret = SS_MODE_NO_SWITCH; + break; + } + } + + /* check for downward transition */ + while (drate < (bitrate + BITRATE_SWITCH_LOWER_THRESHOLD * bitrate)) { + if (g_list_previous (stream->quality_lists)) { + stream->quality_lists = g_list_previous (stream->quality_lists); + g_print ("Move to previous quality level : drate = %d and bitrate = %d\n", drate, ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate); + bitrate = ((GstSSMQualityNode *)stream->quality_lists->data)->bitrate; + } else { + g_print ("Reached MIN video bitrate possible...\n"); + if (GST_SSM_PARSE_IS_LIVE_PRESENTATION(parser)) { + g_print ("Going to audio-only because of LIVE...\n"); + ret = SS_MODE_AONLY; + } else { + ret = SS_MODE_AV; + } + break; + } + } + + return ret; +} + +gboolean +gst_ssm_parse_append_next_fragment (GstSSMParse *parser, SS_STREAM_TYPE stream_type, guint64 timestamp, guint64 duration) +{ + GstSSMStreamNode *stream = NULL; + GstSSMFragmentNode *new_fragment = NULL; + GstSSMFragmentNode *last_fragment = NULL; + GList *last_node = NULL; + + g_return_val_if_fail (parser != NULL, FALSE); + + /*get current stream based on stream_type */ + stream = (parser->RootNode->streams[stream_type])->data; + + g_return_val_if_fail (stream->fragment_lists, FALSE); + + g_mutex_lock (stream->frag_lock); + + last_node = g_list_last(stream->fragment_lists); + + last_fragment = (GstSSMFragmentNode *)(last_node->data); + + if (last_fragment->time < timestamp) { + + GST_LOG ("+++++ last_fragment time = %llu and current recd = %llu +++++\n", last_fragment->time, timestamp); + + /* allocate new fragment node */ + new_fragment = g_slice_new0 (GstSSMFragmentNode); + if (new_fragment == NULL) { + GST_ERROR ("Allocation of fragment failed!"); + return FALSE; + } + + if (duration == GST_CLOCK_TIME_NONE) { + /* useful when lookahead count is zero */ + // TODO: need to check how to handle, when there is discontinuity + duration = timestamp - last_fragment->time; + } + + // TODO: need to handle when either time or duration present OR if both are non proper values + new_fragment->dur = duration; + new_fragment->time = timestamp; + new_fragment->num = 0; + + /* add the new fragment duration to total stream duration */ + stream->stream_duration += duration; + + /* append new fragment list to stream fragment list */ + ((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists = + g_list_append (((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists, new_fragment); + + GST_DEBUG ("+++++ Appened new '%s' URL and signaling the condition and duration = %llu ++++++\n", + ssm_parse_get_stream_name(stream_type), stream->stream_duration); + + if (stream->fraglist_eos) { + GST_INFO ("Need to move the list now to next.. as we received new one\n"); + ((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists = + g_list_next (((GstSSMStreamNode *)(parser->RootNode->streams[stream_type]->data))->fragment_lists); + stream->fraglist_eos = FALSE; + } + /* signal fragment wait */ + g_cond_signal (stream->frag_cond); + + } else { + g_print ("--------- Received '%s' fragment is less than Last fragment in the list -----------\n", ssm_parse_get_stream_name(stream_type)); + } + + g_mutex_unlock (stream->frag_lock); + + return TRUE; +} + +gboolean +gst_ssm_parse_seek_manifest (GstSSMParse *parser, guint64 seek_time) +{ + gint i = 0; + GstSSMStreamNode *stream = NULL; + guint64 stream_time = -1; + guint64 start_ts = -1; + + parser->ns_start = 0; + + for (i = 0; i < SS_STREAM_NUM; i++) { + if (parser->RootNode->streams[i]) { + stream = parser->RootNode->streams[i]->data; // get current stream + stream_time = ((GstSSMFragmentNode *)stream->fragment_lists->data)->time; + stream_time = gst_util_uint64_scale (stream_time, GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(parser)); + + if (seek_time > stream_time) { + /* forward seek */ + while (seek_time > stream_time) { + stream->fragment_lists = g_list_next (stream->fragment_lists); + if(stream->fragment_lists && stream->fragment_lists->data) { + stream_time = gst_util_uint64_scale (((GstSSMFragmentNode *)stream->fragment_lists->data)->time, GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(parser)); + GST_LOG ("seek time = %"GST_TIME_FORMAT", cur_time = %"GST_TIME_FORMAT, + GST_TIME_ARGS(seek_time), GST_TIME_ARGS(stream_time)); + } + } + + /* moving to fragment before our seeked time */ + stream->fragment_lists = g_list_previous (stream->fragment_lists); + if(stream->fragment_lists && stream->fragment_lists->data) + start_ts = ((GstSSMFragmentNode *)stream->fragment_lists->data)->time; + } else if (seek_time < stream_time) { + /* backward seek */ + while (seek_time < stream_time) { + stream->fragment_lists = g_list_previous (stream->fragment_lists); + if(stream->fragment_lists && stream->fragment_lists->data) { + stream_time = gst_util_uint64_scale (((GstSSMFragmentNode *)stream->fragment_lists->data)->time, GST_SECOND, + GST_SSM_PARSE_GET_TIMESCALE(parser)); + GST_LOG ("seek time = %"GST_TIME_FORMAT", cur_time = %"GST_TIME_FORMAT, + GST_TIME_ARGS(seek_time), GST_TIME_ARGS(stream_time)); + start_ts = ((GstSSMFragmentNode *)stream->fragment_lists->data)->time; + } + } + } else { + /* rare case */ + start_ts = ((GstSSMFragmentNode *)stream->fragment_lists->data)->time; + } + + if (stream->type == SS_STREAM_VIDEO) { + /* move to least possible bitrate variant*/ + stream->quality_lists = g_list_first (stream->quality_lists); + } + + GST_INFO ("SEEK : ns_start = %"G_GUINT64_FORMAT" and start_ts[%s] = %"G_GUINT64_FORMAT, + parser->ns_start, ssm_parse_get_stream_name(i), start_ts); + + /* take max of stream's start as new_segment start */ + parser->ns_start = START_TS_MAX (parser->ns_start, start_ts); + } + } + + GST_INFO ("ns_start = %"G_GUINT64_FORMAT, parser->ns_start); + + return TRUE; +} + +gboolean +gst_ssm_parse_get_protection_header (GstSSMParse *parser, unsigned char **protection_header, unsigned int *protection_header_len) +{ + if (!parser->RootNode->ProtectNode) { + *protection_header = NULL; + *protection_header_len = 0; + return TRUE; + } + + if (parser->RootNode->ProtectNode->ContentSize && parser->RootNode->ProtectNode->Content) { + *protection_header = g_malloc0 (parser->RootNode->ProtectNode->ContentSize); + if (*protection_header == NULL) { + GST_ERROR ("failed to allocate memory..."); + return FALSE; + } + + memcpy (*protection_header, parser->RootNode->ProtectNode->Content, parser->RootNode->ProtectNode->ContentSize); + *protection_header_len = parser->RootNode->ProtectNode->ContentSize; + } + + return TRUE; +} + +static gboolean +convert_NALUnitDCI_to_PacktizedDCI (unsigned char *nalu_dci, unsigned char **packetized_dci, unsigned int *packetized_dci_len) +{ +#ifndef CHECK_NALU_OUT + gboolean bret = TRUE; + unsigned char *pps_start = NULL; + unsigned char *pps_end = NULL; + unsigned int sps_len = 0; + unsigned int pps_len = 0; + unsigned char *sps_data = NULL; + unsigned char *pps_data = NULL; + unsigned char *tmp_sps_ptr = NULL; + unsigned char *tmp_pps_ptr = NULL; + unsigned char tmp[3] = {0, }; + int val; + unsigned int idx = 0; + + // TODO: need to generalize this logic for finding multiple SPS and PPS sets and finding SPS/PPS by ANDing 0x1F + + pps_start = strstr ((char*)nalu_dci, "0000000168"); + pps_end = nalu_dci + strlen ((char *)nalu_dci); + GST_DEBUG ("nalu_dci length= %d\n", strlen ((char *)nalu_dci)); + + sps_len = pps_start - nalu_dci; + + GST_DEBUG ("sps length = %d\n", sps_len); + + sps_data = (unsigned char*) malloc (sps_len + 1); + if (NULL == sps_data) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + /* Copy SPS data */ + strncpy ((char*)sps_data, (char *)nalu_dci, sps_len); + sps_data[sps_len] = '\0'; + + tmp_sps_ptr = sps_data; + + GST_DEBUG ("SPS data = %s\n", sps_data); + + pps_len = pps_end - pps_start; + GST_DEBUG ("pps length = %d\n", pps_len); + + pps_data = (unsigned char*)malloc (pps_len + 1); + if (NULL == pps_data) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + /* Copy PPS data */ + strncpy ((char*)pps_data, (char*)pps_start, pps_len); + pps_data[pps_len] = '\0'; + tmp_pps_ptr = pps_data; + + GST_DEBUG ("PPS data = %s\n", pps_data); + + /* 6 bytes of metadata */ + *packetized_dci_len = 8; + + *packetized_dci = (unsigned char*) malloc (*packetized_dci_len); + if (NULL == *packetized_dci) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + /* configurationVersion */ + (*packetized_dci)[0] = 0x01; + + /* AVCProfileIndication */ + memset (tmp, 0x00, 3); + + strncpy ((char*)tmp, (char*)sps_data+10, 2); + tmp[2] = '\0'; + + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + + (*packetized_dci)[1] = val; + + /* profile_compatibility*/ + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)sps_data+12, 2); + tmp[2] = '\0'; + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + (*packetized_dci)[2] = val; + + /* AVCLevelIndication */ + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)sps_data+14, 2); + tmp[2] = '\0'; + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + + (*packetized_dci)[3] = val; + + /* Reserver (6) + LengthSizeMinusOne (2) */ + (*packetized_dci)[4] = 0xff; // hardcoding lengthoflength = 4 for present + + /* Reserver (3) + numOfSequenceParameterSets (5) */ + (*packetized_dci)[5] = 0xe1; // hardcoding numOfSequenceParameterSets = 1 for present + + /* avoiding NALU start code 0x00 00 00 01 */ + sps_len = sps_len -8; + sps_data = sps_data + 8; + + (*packetized_dci)[6] = (sps_len >>1) >> 16; + (*packetized_dci)[7] = (sps_len >>1); + + *packetized_dci_len += (sps_len/2); + + *packetized_dci = (unsigned char*) realloc (*packetized_dci, *packetized_dci_len); + if (NULL == *packetized_dci) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + idx = 8; + + /* convert SPS data and store*/ + while (sps_len) + { + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)sps_data, 2); + tmp[2] = '\0'; + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + (*packetized_dci)[idx] = val; + sps_data += 2; + sps_len = sps_len - 2; + //g_print ("val = 0x%02x, sps_len = %d, idx = %d\n", val, sps_len, idx); + idx++; + } + + /* avoiding NALU start code 0x00 00 00 01 */ + pps_len = pps_len -8; + pps_data = pps_data + 8; + + /* no.of PPS sets (1 byte) + Lengthof PPS (2 bytes) + PPS length */ + *packetized_dci_len = *packetized_dci_len + 1 + 2 + (pps_len/2) ; + *packetized_dci = (unsigned char*)realloc (*packetized_dci, *packetized_dci_len); + if (NULL == *packetized_dci) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + (*packetized_dci)[idx++] = 0x01; // Harding no.of PPS sets + (*packetized_dci)[idx++] = (pps_len>>1) >> 16; + (*packetized_dci)[idx++] = (pps_len >>1); + + /* convert PPS data and store */ + while (pps_len) + { + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)pps_data, 2); + tmp[2] = '\0'; + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + + (*packetized_dci)[idx] = val; + pps_data += 2; + pps_len = pps_len - 2; + //g_print ("val = 0x%02x, pps_len = %d, idx = %d\n", val, pps_len, idx); + idx++; + } + idx = 0; + +#if 0 + g_print ("\n\n"); + + g_print ("Complete VIDEO packetized_dci: 0x"); + while (idx < *packetized_dci_len) + { + g_print ("%02x", (*packetized_dci)[idx]); + idx++; + } + + g_print ("\n\n"); +#endif + +exit: + if (tmp_sps_ptr) + { + free (tmp_sps_ptr); + tmp_sps_ptr = NULL; + } + if (tmp_pps_ptr) + { + free (tmp_pps_ptr); + tmp_pps_ptr = NULL; + } + if ((FALSE == bret) && *packetized_dci) + { + free (*packetized_dci); + *packetized_dci = NULL; + } + + return bret; + +#else + /* code for sending NALU DCI as it is */ + guint nalu_dci_len = strlen ((char *)nalu_dci); + unsigned char *nalu = nalu_dci; + guint idx = 0; + unsigned char tmp[3] = {0, }; + gboolean bret = TRUE; + int val = 0; + + *packetized_dci_len = (nalu_dci_len/2); + + *packetized_dci = (unsigned char*) malloc (*packetized_dci_len); + if (NULL == *packetized_dci) + { + GST_ERROR ("Failed to allocate memory..\n"); + bret = FALSE; + goto exit; + } + + /* copy entire DCI*/ + while (nalu_dci_len) + { + memset (tmp, 0x00, 3); + strncpy ((char*)tmp, (char*)nalu, 2); + tmp[2] = '\0'; + bret = int_from_string ((char*)tmp, NULL, &val , 16); + if (FALSE == bret) + { + GST_ERROR ("Failed to int from string..."); + goto exit; + } + (*packetized_dci)[idx] = val; + nalu += 2; + nalu_dci_len = nalu_dci_len - 2; + //g_print ("val = 0x%02x, dci_len = %d, idx = %d\n", val, nalu_dci_len, idx); + idx++; + } + + idx = 0; + + g_print ("\n\n NEW DCI : 0x "); + + while (idx < *packetized_dci_len) + { + g_print ("%02x", (*packetized_dci)[idx] ); + idx++; + } + + g_print ("\n\n\n"); + +exit: + + if ((FALSE == bret) && *packetized_dci) + { + free (*packetized_dci); + *packetized_dci = NULL; + } + + return bret; +#endif +} + + + + diff --git a/ssdemux/src/ssmanifestparse.h b/ssdemux/src/ssmanifestparse.h new file mode 100755 index 0000000..16c900c --- /dev/null +++ b/ssdemux/src/ssmanifestparse.h @@ -0,0 +1,129 @@ + + +#ifndef __SS_MANIFEST_PARSE_H__ +#define __SS_MANIFEST_PARSE_H__ + +#include +#include +#include + +G_BEGIN_DECLS +typedef struct _GstSSMParse GstSSMParse; + +#define GST_SSMPARESE(m) ((GstSSMParse*)m) +#define XML_MAKE_FOURCC(a,b,c,d) ((guint32)((a)|(b)<<8|(c)<<16|(d)<<24)) +#define BITRATE_SWITCH_UPPER_THRESHOLD 0.4 +#define BITRATE_SWITCH_LOWER_THRESHOLD 0.1 + + +typedef enum +{ + SS_STREAM_UNKNOWN = -1, + SS_STREAM_VIDEO = 0, + SS_STREAM_AUDIO, + SS_STREAM_TEXT, + SS_STREAM_NUM, +}SS_STREAM_TYPE; + +typedef enum +{ + SS_MODE_NO_SWITCH, /* no switch is need */ + SS_MODE_AONLY, /* switch to audio only */ + SS_MODE_AV, +}SS_BW_MODE; + +typedef struct +{ + guint64 StreamTimeScale; + guint64 stream_duration; + SS_STREAM_TYPE type; + guint nChunks; + guint nQualityLevels; + guint MaxWidth; + guint MaxHeight; + guint DisplayWidth; + guint DisplayHeight; + GList *quality_lists; + GList *fragment_lists; + gchar *StreamType; + gchar *StreamUrl; + gchar *StreamSubType; + gchar *StreamName; + gboolean fraglist_eos; + GMutex *frag_lock; + GCond *frag_cond; +}GstSSMStreamNode; + +typedef struct +{ + guint index; + guint bitrate; + guint max_width; + guint max_height; + guint samplingrate; + guint channels; + guint bps; /* bits per sample */ + guint packet_size; + guint audio_tag; + guint NALULengthofLength; + gchar *fourcc; + gchar *codec_data; +}GstSSMQualityNode; + +typedef struct +{ + guint num; + guint64 dur; + guint64 time; + guint media_type; +}GstSSMFragmentNode; + +typedef struct +{ + gchar *SystemID; + gchar *Content; + guint ContentSize; +}GstSSMProtectionNode; + +typedef struct +{ + guint MajorVersion; + guint MinorVersion; + guint64 TimeScale; + guint64 Duration; + guint LookAheadCount; + guint64 DVRWindowLength; + gboolean PresentationIsLive; + GList *streams[SS_STREAM_NUM]; + GstSSMProtectionNode *ProtectNode; +}GstSSMRootNode; + +struct _GstSSMParse +{ + gchar *uri; /* manifest URI */ + gchar *presentation_uri; + GstSSMRootNode *RootNode; + GMutex *lock; + guint64 ns_start; +}; + +#define gst_ssm_parse_check_stream(parser, stream_type) (parser->RootNode->streams[stream_type]) +#define GST_SSM_PARSE_GET_DURATION(parser) (parser->RootNode->Duration) +#define GST_SSM_PARSE_GET_TIMESCALE(parser) (parser->RootNode->TimeScale) +#define GST_SSM_PARSE_IS_LIVE_PRESENTATION(parser) (parser->RootNode->PresentationIsLive) +#define GST_SSM_PARSE_LOOKAHEAD_COUNT(parser) (parser->RootNode->LookAheadCount) +#define GST_SSM_PARSE_NS_START(parser) (parser->ns_start) + +const gchar *ssm_parse_get_stream_name(SS_STREAM_TYPE type); +GstSSMParse *gst_ssm_parse_new (const gchar * uri); +void gst_ssm_parse_free (GstSSMParse *parser); +gboolean gst_ssm_parse_manifest (GstSSMParse *parser, char *data, unsigned int size); +gboolean gst_ssm_parse_get_next_fragment_url (GstSSMParse *parser, SS_STREAM_TYPE stream_type, gchar **uri, guint64 *start_ts); +gboolean gst_ssm_parse_append_next_fragment (GstSSMParse *parser, SS_STREAM_TYPE stream_type, guint64 timestamp, guint64 duration); +GstCaps *ssm_parse_get_stream_caps (GstSSMParse *parser, SS_STREAM_TYPE stream_type); +SS_BW_MODE gst_ssm_parse_switch_qualitylevel (GstSSMParse *parser, guint drate); +gboolean gst_ssm_parse_seek_manifest (GstSSMParse *parser, guint64 seek_time); +gboolean gst_ssm_parse_get_protection_header (GstSSMParse *parser, unsigned char **protection_header, unsigned int *protection_header_len); +G_END_DECLS +#endif /* __SS_MANIFEST_PARSE_H__ */ + diff --git a/mobile/encodebin/Makefile.am b/submux/Makefile.am old mode 100644 new mode 100755 similarity index 100% rename from mobile/encodebin/Makefile.am rename to submux/Makefile.am diff --git a/mobile/toggle/src/Makefile.am b/submux/src/Makefile.am similarity index 68% rename from mobile/toggle/src/Makefile.am rename to submux/src/Makefile.am index 4d761d7..695e81c 100755 --- a/mobile/toggle/src/Makefile.am +++ b/submux/src/Makefile.am @@ -1,30 +1,27 @@ -# plugindir is set in configure - -############################################################################## -# change libgstplugin.la to something more suitable, e.g. libmysomething.la # -############################################################################## -plugin_LTLIBRARIES = libgsttoggle.la - -############################################################################## -# for the next set of variables, rename the prefix if you renamed the .la, # -# e.g. libgstplugin_la_SOURCES => libmysomething_la_SOURCES # -# libgstplugin_la_CFLAGS => libmysomething_la_CFLAGS # -# libgstplugin_la_LIBADD => libmysomething_la_LIBADD # -# libgstplugin_la_LDFLAGS => libmysomething_la_LDFLAGS # -############################################################################## - -# sources used to compile this plug-in -libgsttoggle_la_SOURCES = gsttoggle.c - - - -# flags used to compile this plugin -# add other _CFLAGS and _LIBS as needed -libgsttoggle_la_CFLAGS = $(GST_CFLAGS) -libgsttoggle_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) -#libgsttoggle_la_LIBADD = $(GST_BASE_LIBS) -libgsttoggle_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -# headers we need but don't want installed -noinst_HEADERS = gsttoggle.h - +# plugindir is set in configure + +############################################################################## +# change libgstplugin.la to something more suitable, e.g. libmysomething.la # +############################################################################## +plugin_LTLIBRARIES = libgstsubmux.la + +############################################################################## +# for the next set of variables, rename the prefix if you renamed the .la, # +# e.g. libgstplugin_la_SOURCES => libmysomething_la_SOURCES # +# libgstplugin_la_CFLAGS => libmysomething_la_CFLAGS # +# libgstplugin_la_LIBADD => libmysomething_la_LIBADD # +# libgstplugin_la_LDFLAGS => libmysomething_la_LDFLAGS # +############################################################################## + +# sources used to compile this plug-in +libgstsubmux_la_SOURCES = gstsubmux.c + +# flags used to compile this plugin +# add other _CFLAGS and _LIBS as needed +libgstsubmux_la_CFLAGS = $(GST_CFLAGS) $(DRM_CLIENT_CFLAGS) $(DRM_TRUSTED_CFLAGS) $(MMTA_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +libgstsubmux_la_LIBADD = $(GST_LIBS) $(DRM_CLIENT_LIBS)$(DRM_TRUSTED_LIBS) $(GST_BASE_LIBS) $(MMTA_LIBS)$(GST_APP_LIBS) -lgstapp-0.10 $(CRYPTO_LIBS) +libgstsubmux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +# headers we need but don't want installed +noinst_HEADERS = gstsubmux.h + diff --git a/submux/src/gstsubmux.c b/submux/src/gstsubmux.c new file mode 100755 index 0000000..1db46c5 --- /dev/null +++ b/submux/src/gstsubmux.c @@ -0,0 +1,2458 @@ +/* + * SLP2.0 + * Copyright (c) 2011 Samsung Electronics, Inc. + * All rights reserved. + * + * This software is a confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung Electronics. + */ + +/* + * @file gstsubmux.c + * @author Deepak Singh (deep.singh@samsung.com) + * @version 1.0 + * @brief This source code implements the gstreamer plugin for subtitle muxing requirement in media player. + * + */ + +/*! Revision History: + *! --------------------------------------------------------------------------- + *! DATE | AUTHOR | COMMENTS + *! --------------------------------------------------------------------------- + *! 1-4-2014 deep.singh@samsung.com created. + */ + +#include "config.h" +#include "gstsubmux.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static const GstElementDetails gst_submux_plugin_details = GST_ELEMENT_DETAILS( + "submux", + "Codec/Parser/Subtitle", + "muxing of different subtitle stream", + "Samsung Electronics " +); +static GstStaticPadTemplate gst_submux_sink_template = GST_STATIC_PAD_TEMPLATE( + "sink%d", + GST_PAD_SINK, + GST_PAD_REQUEST, + GST_STATIC_CAPS("video/x-dvd-subpicture; text/plain; application/x-subtitle; " + "text/x-pango-markup;" + "application/x-usf; subpicture/x-pgs; subtitle/x-kate; application/x-subtitle; " + "application/x-subtitle-sami; application/x-subtitle-tmplayer; " + "application/x-subtitle-mpl2; application/x-subtitle-dks; " + "application/x-subtitle-qttext") +); +static GstStaticPadTemplate gst_submux_src_template = GST_STATIC_PAD_TEMPLATE( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("text/plain; text/x-pango-markup") +); +enum +{ + PROP_0, + PROP_ENCODING, + PROP_VIDEOFPS, + PROP_EXTSUB_CURRENT_LANGUAGE, + PROP_IS_INTERNAL, + PROP_LANG_LIST + +}; + +GST_DEBUG_CATEGORY_STATIC (gst_submux_debug); +#define GST_CAT_DEFAULT gst_submux_debug +#define _do_init(bla) \ + GST_DEBUG_CATEGORY_INIT (gst_submux_debug, "submux", 0, "submux"); +//////////////////////////////////////////////////////// +// Gstreamer Base Prototype // +//////////////////////////////////////////////////////// + +GST_BOILERPLATE_FULL(Gstsubmux, gst_submux, GstElement, GST_TYPE_ELEMENT, _do_init); + +#define GST_SUBMUX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_SUBMUX, GstsubmuxPrivate)) +#define MAX_LANGUAGE 10 +static gint gst_submux_buffer_list_sorting (gconstpointer a, gconstpointer b); +static gboolean gst_submux_create_pipelines(Gstsubmux *self,GstPad * pad); +static GstPad* gst_submux_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * req_name); +static void gst_submux_release_pad (GstElement * element, GstPad * pad); +static gchar* gst_submux_extract_data (Gstsubmux *submux); +static gboolean gst_create_own_language_list (Gstsubmux *submux) ; +static GstSubMuxFormat gst_submux_data_format_autodetect (gchar * match_str); +static gpointer gst_submux_data_format_autodetect_regex_once (GstSubMuxRegex regtype); +static gboolean gst_submux_format_autodetect (Gstsubmux * self); +static void gst_submux_base_init(gpointer klass); +static void gst_submux_class_init(GstsubmuxClass *klass); +static GstStateChangeReturn gst_submux_change_state (GstElement * element, GstStateChange transition); +static void gst_submux_init(Gstsubmux *submux, GstsubmuxClass *klass); +static gboolean gst_submux_setcaps(GstPad *pad, GstCaps *caps); +static GstFlowReturn gst_submux_chain (GstPad *pad, GstBuffer *buffer); +static void gst_submux_dispose(GObject *object); +static void gst_submux_loop (Gstsubmux * submux); +static gboolean gst_submux_stream_init(GstSubmuxStream * stream); +static void gst_submux_stream_deinit(GstSubmuxStream * stream,Gstsubmux * submux); +static void gst_submux_on_new_buffer (GstElement *appsink, void *data); +static gboolean gst_submux_handle_src_event (GstPad * pad, GstEvent * event); + +static gboolean gst_submux_handle_sink_event (GstPad * pad, GstEvent * event); +//////////////////////////////////////////////////////// +// Plugin Utility Prototype // +//////////////////////////////////////////////////////// +static void gst_submux_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_submux_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static gboolean gst_submux_deinit_private_values(Gstsubmux *submux); +static gchar *convert_to_utf8 (const gchar * str, gsize len, const gchar * encoding, + gsize * consumed, GError ** err, Gstsubmux * self); +#define DEFAULT_ENCODING NULL +#define DEFAULT_CURRENT_LANGUAGE NULL + +//////////////////////////////////////////////////////// +// Gstreamer Base Functions // +//////////////////////////////////////////////////////// + +/* +** +** Description : base init +** Params : (1) instance of gclass +** return : none +** Comments : The following code registers templates for src and sink pad. +** +*/ +static void +gst_submux_base_init(gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&gst_submux_sink_template)); + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&gst_submux_src_template)); + gst_element_class_set_details(element_class, &gst_submux_plugin_details); +} + +/* +** +** Description : Initilizes the Gstsubmux's class +** Params : @ klass instance of submux plugin's class +** return : None +** Comments : Declaring properties and over-writing function pointers +** +*/ +static void +gst_submux_class_init(GstsubmuxClass *klass) +{ + GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass); + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + g_type_class_add_private (klass, sizeof (GstsubmuxPrivate)); + gobject_class->set_property = gst_submux_set_property; + gobject_class->get_property = gst_submux_get_property; + g_object_class_install_property (gobject_class, PROP_ENCODING, + g_param_spec_string ("subtitle-encoding", "subtitle charset encoding", + "Encoding to assume if input subtitles are not in UTF-8 or any other " + "Unicode encoding. If not set, the GST_SUBTITLE_ENCODING environment " + "variable will be checked for an encoding to use. If that is not set " + "either, ISO-8859-15 will be assumed.", DEFAULT_ENCODING, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_VIDEOFPS, + gst_param_spec_fraction ("video-fps", "Video framerate", + "Framerate of the video stream. This is needed by some subtitle " + "formats to synchronize subtitles and video properly. If not set " + "and the subtitle format requires it subtitles may be out of sync.", + 0, 1, G_MAXINT, 1, 24000, 1001, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_EXTSUB_CURRENT_LANGUAGE, + g_param_spec_string ("current-language", "Current language", + "Current language of the subtitle in external subtitle case.", + DEFAULT_CURRENT_LANGUAGE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_IS_INTERNAL, + g_param_spec_boolean ("is-internal", "is internal", + "TRUE for internal subtitle case", + FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_LANG_LIST, + g_param_spec_pointer ("lang-list", "language list", "List of languages selected/not selected", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + parent_class = g_type_class_peek_parent (klass); + gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR(gst_submux_request_new_pad); + gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_submux_dispose); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_submux_change_state); + gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_submux_release_pad); +} + +/* +** +** Description : Initilizes the submux element +** Params : (1)instance of submux (2) instance of submux class +** return : None +** Comments : instantiate pads and add them to element, set pad calback functions +** +*/ +static void +gst_submux_init(Gstsubmux *submux, GstsubmuxClass *klass) +{ + GST_DEBUG_OBJECT (submux, "Entering in init"); + submux->priv = GST_SUBMUX_GET_PRIVATE(submux); + submux->srcpad = gst_pad_new_from_static_template(&gst_submux_src_template, "src"); + gst_pad_set_event_function (submux->srcpad, + GST_DEBUG_FUNCPTR (gst_submux_handle_src_event)); + submux->priv->first_buffer = FALSE; + gst_segment_init (&submux->segment, GST_FORMAT_TIME); + submux->flushing = FALSE; + submux->msl_streams = NULL; + submux->stop_loop = FALSE; + submux->need_segment = TRUE; + submux->pipeline_made = FALSE; + submux->external_sinkpad = FALSE; + submux->detected_encoding = NULL; + submux->encoding = NULL; + submux->seek_came = FALSE; + submux->sinkpads_count = 0; + submux->langlist_msg_posted = FALSE; + submux->cur_buf_array = NULL; + GST_DEBUG_OBJECT (submux, "Making flushing FALSE"); + submux->priv->is_internal = FALSE; + submux->external_filepath = NULL; + gst_element_add_pad (GST_ELEMENT (submux), submux->srcpad); + GST_DEBUG_OBJECT (submux, "Exiting in init"); +} + +/* +** +** Description : for setting the property of submux +** return : None +** Comments : To set the various properties of submux +** +*/ +static void +gst_submux_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + Gstsubmux *submux = GST_SUBMUX (object); + guint length = 0; + gint i = 0; + GstLangStruct *cur_language=NULL; + GstSubmuxStream *cur_stream = NULL; + GST_OBJECT_LOCK (submux); + length = g_list_length(submux->priv->lang_list); + switch (prop_id) { + case PROP_ENCODING: + g_free (submux->encoding); + submux->encoding = g_value_dup_string (value); + GST_DEBUG_OBJECT (submux, "subtitle encoding set to %s", + GST_STR_NULL (submux->encoding)); + for(i = 0;i < length;i++) { + cur_stream = g_list_nth_data(submux->streams,i); + GST_DEBUG_OBJECT (submux, "setting the subtitle-encoding to %s", submux->encoding); + g_object_set (G_OBJECT (cur_stream->pipe_struc.parser), "subtitle-encoding", submux->encoding, NULL); + } + break; + case PROP_VIDEOFPS: + { + submux->fps_n = gst_value_get_fraction_numerator (value); + submux->fps_d = gst_value_get_fraction_denominator (value); + GST_DEBUG_OBJECT (submux, "video framerate set to %d/%d", submux->fps_n, submux->fps_d); + break; + } + case PROP_EXTSUB_CURRENT_LANGUAGE: { + for (i = 0; i < length; i++) { + cur_stream = g_list_nth_data(submux->streams, i); + cur_language = g_list_nth_data(submux->priv->lang_list, i); + GST_DEBUG_OBJECT (submux, "value of current-language key is %s", cur_language->language_key); + g_object_set (G_OBJECT (cur_stream->pipe_struc.parser), "current-language", + cur_language->language_key, NULL); + } + gchar *dup = g_value_dup_string (value); + GST_DEBUG_OBJECT (submux, "Setting property to %s", dup); + g_free(dup); + } + break; + case PROP_IS_INTERNAL: { + submux->priv->is_internal = g_value_get_boolean (value); + GST_DEBUG_OBJECT (submux, "Setting the is_internal prop to %d", submux->priv->is_internal); + break; + } + case PROP_LANG_LIST: { + submux->priv->lang_list = (GList*) g_value_get_pointer (value); + GST_DEBUG_OBJECT (submux, "updating the languages list and length is %d", g_list_length (submux->priv->lang_list)); + submux->msl_streams = g_list_copy (submux->priv->lang_list); + + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + GST_OBJECT_UNLOCK (submux); +} + +/* +** +** Description : for getting the property of submux +** return : None +** Comments : To get the various properties of submux in case called by MSL +** +*/ +static void +gst_submux_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + Gstsubmux *submux = GST_SUBMUX (object); + + GST_OBJECT_LOCK (submux); + switch (prop_id) { + case PROP_ENCODING: + g_value_set_string (value, submux->encoding); + break; + case PROP_VIDEOFPS: + gst_value_set_fraction (value, submux->fps_n, submux->fps_d); + break; + case PROP_EXTSUB_CURRENT_LANGUAGE: + GST_DEBUG_OBJECT (submux, "Getting the current language"); + break; + case PROP_IS_INTERNAL: { + g_value_set_boolean(value,submux->priv->is_internal); + break; + } + case PROP_LANG_LIST: { + g_value_set_pointer(value,(gpointer)(submux->priv->lang_list)); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + GST_OBJECT_UNLOCK (submux); +} + +static void +gst_submux_dispose (GObject *object) +{ + Gstsubmux *submux = GST_SUBMUX(object); + int i = 0; + gchar *pad_name = gst_pad_get_name (submux->srcpad); + if (submux && GST_PAD_TASK(submux->srcpad)) { + GST_INFO_OBJECT (submux, "Stopping pad task : %s", pad_name); + GST_DEBUG_OBJECT (submux, "Stopping pad task : on src pad %p", submux->srcpad); + gst_pad_stop_task (submux->srcpad); + GST_INFO_OBJECT (submux, "stopped pad task : %s", pad_name); + } + g_free(pad_name); + if (submux->srcpad) { + gst_element_remove_pad (GST_ELEMENT_CAST (submux), submux->srcpad); + submux->srcpad = NULL; + } + if (submux->priv->is_internal) { + for (i = 0; i < (submux->sinkpads_count); i++){ + gst_submux_stream_deinit (g_list_nth_data (submux->streams, i), submux); + } + } else { + for (i = 0; i < g_list_length (submux->priv->lang_list); i++) { + gst_submux_stream_deinit (g_list_nth_data (submux->streams, i), submux); + } + } + gst_submux_deinit_private_values (submux); + + GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); + GST_DEBUG_OBJECT (submux, "Returning from finalize"); +} + +static void +gst_submux_stop (Gstsubmux* submux) +{ + GstSubmuxStream *new_stream = NULL; + guint i = 0; + submux->stop_loop = TRUE; + GST_INFO_OBJECT (submux, "stopping the loop"); + if (submux->priv->is_internal) { + for (i = 0; i < (submux->sinkpads_count); i++) { + new_stream = g_list_nth_data (submux->streams, i); + if (new_stream) { + g_mutex_lock (new_stream->queue_lock); + g_cond_signal (new_stream->queue_empty); + g_mutex_unlock (new_stream->queue_lock); + } + } + } else { + for (i = 0; i < g_list_length (submux->priv->lang_list); i++) { + new_stream = g_list_nth_data (submux->streams, i); + if (new_stream) { + g_mutex_lock (new_stream->queue_lock); + g_cond_signal (new_stream->queue_empty); + g_mutex_unlock (new_stream->queue_lock); + } + } + } +} + +static GstStateChangeReturn +gst_submux_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + Gstsubmux *submux = GST_SUBMUX (element); + gboolean bret = FALSE; + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + GST_INFO_OBJECT (submux,"PAUSED->PLAYING"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT (submux,"PAUSED->READY"); + gst_submux_stop (submux); + break; + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_INFO_OBJECT (submux,"PLAYING->PAUSED"); + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_INFO_OBJECT (submux,"PAUSED->READY"); + if(submux->msl_streams) { + g_list_free(submux->msl_streams); + submux->msl_streams = NULL; + } + if (submux->priv->lang_list && !submux->priv->is_internal) { + g_list_free (submux->priv->lang_list); + submux->priv->lang_list = NULL; + } + if (submux->external_filepath) { + g_free (submux->external_filepath); + submux->external_filepath = NULL; + } + GST_WARNING_OBJECT(submux,"stopping has been called ...Moved after change_state"); + break; + case GST_STATE_CHANGE_READY_TO_NULL: + GST_INFO_OBJECT (submux,"READY->NULL"); + break; + default: + break; + } + return ret; +} + +/* +** +** Description : Setting the caps on sink pad based on upstream element's src pad +** Params : (1) GstPad to set the capabilities of +** (2) caps to be set +** return : TRUE on success +** Comments : this function handles the link with other elements +** +*/ +static gboolean +gst_submux_setcaps (GstPad *pad, GstCaps *caps) +{ + return TRUE; +} + +/*extracting data for file format detection*/ +static gchar* gst_submux_extract_data (Gstsubmux *submux){ + gchar * file_path_type = NULL; + gchar * file_path = NULL; + gchar * temp_path = NULL; + gchar *line = NULL; + gboolean is_converted = FALSE; + gchar *converted = NULL; + FILE * fp = NULL; + guint charCount = 0; + GError *err = NULL; + gsize * consumed = NULL; + + GstQuery *cquery; + GstStructure *structure; + const GValue *value; + GstPad *sinkpad = (GstPad *)g_list_nth_data (submux->sinkpad, 0); + structure = gst_structure_new ("FileSrcURI", + "file-uri", G_TYPE_STRING, NULL, NULL); + + cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure); + + if (!gst_pad_peer_query (sinkpad, cquery)) + { + GST_ERROR_OBJECT (submux, "Failed to query SMI file path"); + gst_query_unref (cquery); + return NULL; + } + structure = gst_query_get_structure (cquery); + value = gst_structure_get_value (structure, "file-uri"); + file_path = g_strdup (g_value_get_string (value)); + + if (file_path == NULL){ + GST_ERROR_OBJECT (submux, "Could not parse the SMI file path"); + gst_query_unref (cquery); + return NULL; + } + + gst_query_unref (cquery); + temp_path = file_path; + GST_INFO_OBJECT (submux, "File path comes as %s", file_path); + + file_path_type = g_strndup ((gchar *) file_path, 4); + GST_INFO_OBJECT (submux, "Received file path by query = %s, %s", file_path, file_path_type); + if (!g_strcmp0(file_path_type, "file")){ + file_path += 7; + GST_INFO_OBJECT (submux, "File path comes as %s", file_path); + + fp = fopen (file_path, "r"); + if (!fp){ + GST_ERROR_OBJECT (submux, "Failed to open file"); + g_free(file_path_type); + g_free(temp_path); + return NULL; + } + } else { + GST_ERROR_OBJECT (submux, "File is not local"); + g_free(file_path_type); + g_free(temp_path); + return NULL; + } + line = (gchar*)g_malloc (2049); + charCount = fread (line, sizeof(char), 2048, fp); + line[charCount] = '\0'; + if (submux->encoding && strcmp (submux->encoding, "UTF-8")) + converted = convert_to_utf8 (line, charCount, submux->encoding, consumed, &err, submux); + + if (converted) + { + GST_INFO("returned from conversion and length of converted string is[%d]", strlen(converted)); + is_converted = TRUE; + } + if (!charCount) { + GST_WARNING_OBJECT (submux, "fread returned zero bytes"); + fclose (fp); + g_free(file_path_type); + g_free(temp_path); + if(is_converted) { + g_free(converted); + } + g_free(line); + return NULL; + } + g_free(file_path_type); + g_free(temp_path); + fclose (fp); + if(is_converted) { + return converted; + } + return line; +} + +static gpointer +gst_submux_data_format_autodetect_regex_once (GstSubMuxRegex regtype) +{ + gpointer result = NULL; + GError *gerr = NULL; + switch (regtype) { + case GST_SUB_PARSE_REGEX_MDVDSUB: + result = + (gpointer) g_regex_new ("^\\{[0-9]+\\}\\{[0-9]+\\}", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &gerr); + if (result == NULL) { + g_warning ("Compilation of mdvd regex failed: %s", gerr->message); + g_error_free (gerr); + } + break; + case GST_SUB_PARSE_REGEX_SUBRIP: + result = (gpointer) g_regex_new ("^ {0,3}[ 0-9]{1,4}\\s*(\x0d)?\x0a" + " ?[0-9]{1,2}: ?[0-9]{1,2}: ?[0-9]{1,2}[,.] {0,2}[0-9]{1,3}" + " +--> +[0-9]{1,2}: ?[0-9]{1,2}: ?[0-9]{1,2}[,.] {0,2}[0-9]{1,2}", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &gerr); + if (result == NULL) { + g_warning ("Compilation of subrip regex failed: %s", gerr->message); + g_error_free (gerr); + } + break; + case GST_SUB_PARSE_REGEX_DKS: + result = (gpointer) g_regex_new ("^\\[[0-9]+:[0-9]+:[0-9]+\\].*", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, &gerr); + if (result == NULL) { + g_warning ("Compilation of dks regex failed: %s", gerr->message); + g_error_free (gerr); + } + break; + default: + GST_WARNING ("Trying to allocate regex of unknown type %u", regtype); + } + return result; +} + +static GstSubMuxFormat +gst_submux_data_format_autodetect (gchar * match_str) +{ + guint n1, n2, n3; + + static GOnce mdvd_rx_once = G_ONCE_INIT; + static GOnce subrip_rx_once = G_ONCE_INIT; + static GOnce dks_rx_once = G_ONCE_INIT; + + GRegex *mdvd_grx; + GRegex *subrip_grx; + GRegex *dks_grx; + + g_once (&mdvd_rx_once, + (GThreadFunc) gst_submux_data_format_autodetect_regex_once, + (gpointer) GST_SUB_PARSE_REGEX_MDVDSUB); + g_once (&subrip_rx_once, + (GThreadFunc) gst_submux_data_format_autodetect_regex_once, + (gpointer) GST_SUB_PARSE_REGEX_SUBRIP); + g_once (&dks_rx_once, + (GThreadFunc) gst_submux_data_format_autodetect_regex_once, + (gpointer) GST_SUB_PARSE_REGEX_DKS); + + mdvd_grx = (GRegex *) mdvd_rx_once.retval; + subrip_grx = (GRegex *) subrip_rx_once.retval; + dks_grx = (GRegex *) dks_rx_once.retval; + + if (g_regex_match (mdvd_grx, match_str, 0, NULL) == TRUE) { + GST_LOG ("MicroDVD (frame based) format detected"); + return GST_SUB_PARSE_FORMAT_MDVDSUB; + } + if (g_regex_match (subrip_grx, match_str, 0, NULL) == TRUE) { + GST_LOG ("SubRip (time based) format detected"); + return GST_SUB_PARSE_FORMAT_SUBRIP; + } + if (g_regex_match (dks_grx, match_str, 0, NULL) == TRUE) { + GST_LOG ("DKS (time based) format detected"); + return GST_SUB_PARSE_FORMAT_DKS; + } + + if (!strncmp (match_str, "FORMAT=TIME", 11)) { + GST_LOG ("MPSub (time based) format detected"); + return GST_SUB_PARSE_FORMAT_MPSUB; + } + if (strstr (match_str, "") != NULL || + strstr (match_str, "") != NULL) { + GST_LOG ("SAMI (time based) format detected"); + return GST_SUB_PARSE_FORMAT_SAMI; + } + /* we're boldly assuming the first subtitle appears within the first hour */ + if (sscanf (match_str, "0:%02u:%02u:", &n1, &n2) == 2 || + sscanf (match_str, "0:%02u:%02u=", &n1, &n2) == 2 || + sscanf (match_str, "00:%02u:%02u:", &n1, &n2) == 2 || + sscanf (match_str, "00:%02u:%02u=", &n1, &n2) == 2 || + sscanf (match_str, "00:%02u:%02u,%u=", &n1, &n2, &n3) == 3) { + GST_LOG ("TMPlayer (time based) format detected"); + return GST_SUB_PARSE_FORMAT_TMPLAYER; + } + if (sscanf (match_str, "[%u][%u]", &n1, &n2) == 2) { + GST_LOG ("MPL2 (time based) format detected"); + return GST_SUB_PARSE_FORMAT_MPL2; + } + if (strstr (match_str, "[INFORMATION]") != NULL) { + GST_LOG ("SubViewer (time based) format detected"); + return GST_SUB_PARSE_FORMAT_SUBVIEWER; + } + if (strstr (match_str, "{QTtext}") != NULL) { + GST_LOG ("QTtext (time based) format detected"); + return GST_SUB_PARSE_FORMAT_QTTEXT; + } + + GST_WARNING ("no subtitle format detected"); + return GST_SUB_PARSE_FORMAT_UNKNOWN; +} + +/*checking the type of subtitle*/ +static gboolean +gst_submux_format_autodetect (Gstsubmux *self) +{ + gchar *data; + GstSubMuxFormat format; + gchar * line = NULL; + if (self->priv->is_internal) { + GST_DEBUG_OBJECT (self, "File is of internal type"); + return TRUE; + } + line = gst_submux_extract_data (self); + if (!line) + return FALSE; + if (strlen (line) < 30) { + GST_WARNING_OBJECT (self, "File too small to be a subtitles file"); + g_free(line); + return FALSE; + } + + data = g_strndup (line, 35); + format = gst_submux_data_format_autodetect (data); + g_free (data); + + self->priv->parser_type = format; + g_free(line); + + return TRUE; +} + +/*to validate the number of languages in case of sami files*/ +static gboolean +gst_calculate_number_languages(Gstsubmux *self) { + gchar* text=NULL; + gchar *start = NULL; + gchar *end = NULL; + gint count = 0; + gchar* found = NULL; + gchar * name_temp = NULL; + int i = 0, j = 0; + + GST_DEBUG_OBJECT (self, "Entering in language number"); + + if ((self->priv->parser_type != GST_SUB_PARSE_FORMAT_SAMI) || self->priv->is_internal) + return TRUE; + + text = gst_submux_extract_data (self); + start = g_strstr_len (text, strlen (text), "!--"); + if (!start) { + GST_ERROR_OBJECT (self, "Could not found the language start code in smi file"); + return gst_create_own_language_list(self); + } + end = g_strstr_len (start, strlen (start), "-->"); + if (!end){ + GST_ERROR_OBJECT (self, "Could not found the language end code in smi file"); + goto error; + } + + found = start + 1; + + while (TRUE) { + found = (gchar*)strcasestr (found, "lang"); + if (!found) + break; + found++; + count++; + } + + if (!count) + { + return gst_create_own_language_list(self); + } + + for (i = 0; i < count; i++) { + gchar *attr_name = NULL, *attr_value = NULL; + GstLangStruct *new = NULL; + + start = (gchar*)strcasestr (start, "lang:"); + attr_value = (gchar*)malloc (3); + if (!attr_value) { + GST_ERROR_OBJECT (self, "memory could not be allocated through malloc call"); + goto error; + } + start = start + 5; + strncpy (attr_value, start, 2); + attr_value[2] = '\0'; + GST_DEBUG_OBJECT (self, "Language value comes as %s", attr_value); + name_temp = start; + while (TRUE) { + if (*name_temp == '{') { + int character_count = 0; + while (TRUE) { + name_temp--; + + if (*name_temp == '.') { + attr_name = (gchar*) malloc (character_count + 1); + break; + } else if (*name_temp != ' ') + character_count++; + } + break; + } + name_temp--; + } + if (!attr_name) { + GST_ERROR_OBJECT (self, "Could not find the languages field in the file"); + free(attr_value); + goto error; + } + name_temp++; + for (j = 0; *(name_temp + j) != ' '; j++) { + attr_name[j] = *(name_temp + j); + } + attr_name[j] = '\0'; + new = g_new0 (GstLangStruct, 1); + new->language_code = (gchar*) malloc (strlen (attr_value) + 1); + if (new->language_code && attr_value) + strcpy (new->language_code, attr_value); + new->language_key = (gchar*) malloc (strlen (attr_name) + 1); + if (new->language_key && attr_name) + strcpy (new->language_key, attr_name); + free (attr_name); + free (attr_value); + self->priv->lang_list = g_list_append (self->priv->lang_list, new); + } + g_free(text); + return TRUE; +error: + g_free(text); + return FALSE; +} + +/*to initialize stream*/ +static gboolean gst_submux_stream_init(GstSubmuxStream * stream) +{ + stream->duration = 0; + stream->need_segment = TRUE; + stream->flushing = FALSE; + stream->eos_sent = FALSE; + stream->eos_came = FALSE; + stream->discont_came = FALSE; + stream->eos_ts = -1; + stream->last_ts = -1; + stream->queue = g_queue_new (); + stream->queue_empty = g_cond_new (); + stream->queue_lock = g_mutex_new (); + stream->flush_done = FALSE; + return TRUE; +} + +/*to create pipelines according to internal and external subtitle*/ +gboolean gst_submux_create_pipelines(Gstsubmux *self, GstPad * pad) +{ + int i = 0; + GstStateChangeReturn ret; + GstSubmuxStream *new_stream; + guint length = 0; + + if (!self->priv->is_internal) { + GstLangStruct *cur_language=NULL; + + GST_DEBUG_OBJECT (self, "creating the pipeline for external pipeline"); + if (self->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) { + if (!self->priv->lang_list) { + GST_ERROR_OBJECT(self, "failed to get the lang list"); + return FALSE; + } + length = g_list_length (self->priv->lang_list); + } else { + length = 1; + } + + GST_DEBUG_OBJECT (self, "number of tentative languages present are %d", length); + + for (i = 0; i < length; i++) { + new_stream = g_new0 (GstSubmuxStream, 1); + if (!gst_submux_stream_init(new_stream)) { + GST_ERROR_OBJECT (self, "stream init is failed"); + return FALSE; + } + GST_DEBUG_OBJECT (self, "stream init has been done for stream[%d]", i); + + new_stream->pipe_struc.pipe = gst_pipeline_new ("subtitle-pipeline"); + if (!new_stream->pipe_struc.pipe) { + GST_ERROR_OBJECT (self, "failed to create pipeline"); + return FALSE; + } + GST_DEBUG_OBJECT (self, "creating appsrc"); + + /* creating source element */ + new_stream->pipe_struc.appsrc = gst_element_factory_make ("appsrc", "pipe_appsrc"); + if (!new_stream->pipe_struc.appsrc) { + GST_ERROR_OBJECT (self, "failed to create appsrc"); + return FALSE; + } + + g_object_set (G_OBJECT (new_stream->pipe_struc.appsrc), "block", 1, NULL); + g_object_set (G_OBJECT (new_stream->pipe_struc.appsrc), "max-bytes", (guint64)1, NULL); + /* create sink element */ + new_stream->pipe_struc.appsink = gst_element_factory_make ("appsink", "pipe_appsink"); + if (!new_stream->pipe_struc.appsink) { + GST_ERROR_OBJECT (self, "failed to create appsink"); + return FALSE; + } + g_object_set (G_OBJECT (new_stream->pipe_struc.appsink), "sync", FALSE, "emit-signals", TRUE, NULL); + g_object_set(G_OBJECT (new_stream->pipe_struc.appsrc),"emit-signals", TRUE, NULL); + + + /* create parsing element */ + new_stream->pipe_struc.parser = gst_element_factory_make("subparse","pipe_parser"); + if (!new_stream->pipe_struc.parser) { + GST_ERROR_OBJECT (self, "failed to create parser"); + return FALSE; + } + if (self->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) { + cur_language = g_list_nth_data(self->priv->lang_list, i); + g_object_set (G_OBJECT (new_stream->pipe_struc.parser), "current-language", + cur_language->language_key, NULL); + } + GST_DEBUG_OBJECT (self, "value of subtitle-encoding is %s", self->encoding); + g_object_set (G_OBJECT (new_stream->pipe_struc.parser), "subtitle-encoding", self->encoding, NULL); + g_object_set (G_OBJECT (new_stream->pipe_struc.appsrc), "stream-type",0,"format",GST_FORMAT_TIME, NULL); + gst_bin_add_many (GST_BIN ( new_stream->pipe_struc.pipe), new_stream->pipe_struc.appsink, new_stream->pipe_struc.appsrc,new_stream->pipe_struc.parser, NULL); + if (!gst_element_link_many (new_stream->pipe_struc.appsrc, new_stream->pipe_struc.parser,new_stream->pipe_struc.appsink, NULL)) { + GST_ERROR_OBJECT (self, "failed to link elements"); + return FALSE; + } + + GST_DEBUG_OBJECT (self, "reached here and linking successful"); + + ret = gst_element_set_state (new_stream->pipe_struc.pipe, GST_STATE_PLAYING); + if (ret == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT (self, "set_state failed..."); + return FALSE; + } + GST_DEBUG_OBJECT (self, "state has been changed succesfully"); + self->streams = g_list_append(self->streams, new_stream); + self->priv->stream_count++; + g_signal_connect (new_stream->pipe_struc.appsink, "new-buffer", G_CALLBACK (gst_submux_on_new_buffer), g_list_nth_data(self->streams,i) ); + } + } else { + length = self->sinkpads_count; + for (i = 0; i < length; i++) { + new_stream = g_new0 (GstSubmuxStream, 1); + if (!gst_submux_stream_init (new_stream)) { + GST_ERROR_OBJECT (self, "stream init is failed"); + return FALSE; + } + + self->streams=g_list_append(self->streams,new_stream); + self->priv->stream_count++; + } + self->pipeline_made = TRUE; + } + + self->cur_buf_array = g_malloc0 (self->priv->stream_count * (sizeof (GstBuffer *))); + if (!self->cur_buf_array) { + GST_ERROR_OBJECT (self, "failed to allocate memory.."); + return FALSE; + } + return TRUE; +} + +/* call back on recieving the new buffer in appsink pad */ +static void +gst_submux_on_new_buffer (GstElement *appsink, void *data) +{ + GstSubmuxStream *stream = (GstSubmuxStream *)data; + GstBuffer *inbuf = NULL; + + if (!stream) { + GST_WARNING("Stream not available..."); + return; + } + g_mutex_lock (stream->queue_lock); + inbuf = gst_app_sink_pull_buffer ((GstAppSink *)appsink); + if (!inbuf) { + GST_WARNING_OBJECT (stream, "Input buffer not available..."); + g_mutex_unlock (stream->queue_lock); + return; + } + if(stream->eos_ts == -1) { + if (!strcmp ((const char*)GST_BUFFER_DATA (inbuf), "eos") && GST_BUFFER_FLAG_IS_SET(inbuf,GST_BUFFER_FLAG_GAP)){ + stream->eos_ts = stream->last_ts; + if (stream->eos_ts <= stream->seek_ts) { + g_queue_push_tail (stream->queue, inbuf); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + GST_INFO_OBJECT (stream, "signaling queue empty signal as we are seeking beyond last subtitle"); + return; + } + gst_buffer_unref(inbuf); + } else { + stream->last_ts = GST_BUFFER_DURATION(inbuf) + GST_BUFFER_TIMESTAMP(inbuf); + } + } else if (stream->eos_ts <= stream->seek_ts) { + gst_buffer_unref(inbuf); + GstBuffer *buf = gst_buffer_new_and_alloc (3 + 1); + GST_DEBUG_OBJECT(stream, "sending EOS buffer to chain\n"); + GST_DEBUG_OBJECT (stream, "EOS. Pushing remaining text (if any)"); + GST_BUFFER_DATA (buf)[0] = 'e'; + GST_BUFFER_DATA (buf)[1] = 'o'; + GST_BUFFER_DATA (buf)[2] = 's'; + GST_BUFFER_DATA (buf)[3] = '\0'; + /* play it safe */ + GST_BUFFER_SIZE (buf) = 3; + GST_BUFFER_FLAG_SET(buf,GST_BUFFER_FLAG_GAP); + g_queue_push_tail (stream->queue, buf); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + GST_INFO_OBJECT (stream,"signaling queue empty signal as we are seeking beyond last subtitle"); + return; + } + if (!stream->discont_came) { + stream->discont_came = GST_BUFFER_IS_DISCONT (inbuf); + if (stream->discont_came) { + GST_DEBUG_OBJECT (stream, "first buffer with discont on new_buffer for stream with ts = %" + GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(inbuf)), + GST_TIME_ARGS(GST_BUFFER_DURATION(inbuf))); + } + } + + if (!stream->discont_came) { + GST_DEBUG_OBJECT (stream, "rejecting the buffer in appsink on new_buffer for stream with ts = %" + GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(inbuf)), + GST_TIME_ARGS(GST_BUFFER_DURATION(inbuf))); + gst_buffer_unref(inbuf); + g_mutex_unlock (stream->queue_lock); + return; + } + g_queue_push_tail (stream->queue, inbuf); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + GST_DEBUG_OBJECT (stream, "signaling queue empty signal"); + return; +} + +gchar * +convert_to_utf8 (const gchar * str, gsize len, const gchar * encoding, + gsize * consumed, GError ** err, Gstsubmux * self) +{ + gchar *ret = NULL; + + /* The char cast is necessary in glib < 2.24 */ + ret = + g_convert_with_fallback (str, len, "UTF-8", encoding, (char *) "*", + consumed, NULL, err); + + if (ret == NULL) + { + GST_DEBUG_OBJECT (self, "g_convert_with_fallback returns NULL"); + return ret; + } + + /* + 3 to skip UTF-8 BOM if it was added */ + len = strlen (ret); + if (len >= 3 && (guint8) ret[0] == 0xEF && (guint8) ret[1] == 0xBB + && (guint8) ret[2] == 0xBF) + g_memmove (ret, ret + 3, len + 1 - 3); + + return ret; +} + +static gchar * +detect_encoding (const gchar * str, gsize len) +{ + if (len >= 3 && (guint8) str[0] == 0xEF && (guint8) str[1] == 0xBB + && (guint8) str[2] == 0xBF) + return g_strdup ("UTF-8"); + + if (len >= 2 && (guint8) str[0] == 0xFE && (guint8) str[1] == 0xFF) + return g_strdup ("UTF-16BE"); + + if (len >= 2 && (guint8) str[0] == 0xFF && (guint8) str[1] == 0xFE) + return g_strdup ("UTF-16LE"); + + if (len >= 4 && (guint8) str[0] == 0x00 && (guint8) str[1] == 0x00 + && (guint8) str[2] == 0xFE && (guint8) str[3] == 0xFF) + return g_strdup ("UTF-32BE"); + + if (len >= 4 && (guint8) str[0] == 0xFF && (guint8) str[1] == 0xFE + && (guint8) str[2] == 0x00 && (guint8) str[3] == 0x00) + return g_strdup ("UTF-32LE"); + + return NULL; +} + +/* If language list is not present in smi file, check the body and create our own list */ +static gboolean +gst_create_own_language_list (Gstsubmux *self) +{ + gchar * file_path_type = NULL; + gchar * temp_path = NULL; + gchar * file_path = NULL; + gsize * consumed = NULL; + guint keyCount = 0; + GError *err = NULL; + GstPad *sinkpad = (GstPad *) g_list_nth_data(self->sinkpad, 0); + GstQuery *cquery; + GstStructure *structure; + const GValue *value; + gchar* langkey[MAX_LANG]; + gint langKey_length[MAX_LANG]; + FILE *fp=NULL; + gint i=0; + structure = gst_structure_new ("FileSrcURI", "file-uri", G_TYPE_STRING, NULL, NULL); + + cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure); + + if (!gst_pad_peer_query (sinkpad, cquery)) { + GST_ERROR_OBJECT (self, "Failed to query SMI file path"); + gst_query_unref (cquery); + return FALSE; + } + structure = gst_query_get_structure (cquery); + value = gst_structure_get_value (structure, "file-uri"); + file_path = g_strdup (g_value_get_string (value)); + + if (file_path == NULL){ + GST_ERROR_OBJECT (self, "Could not parse the SMI file path"); + gst_query_unref (cquery); + return FALSE; + } + gst_query_unref (cquery); + temp_path = file_path; + GST_INFO_OBJECT (self, "File path comes as %s", file_path); + + file_path_type = g_strndup ((gchar *) file_path, 4); + GST_INFO_OBJECT (self, "Received file path by query = %s, %s", file_path, file_path_type); + if (!g_strcmp0(file_path_type, "file")){ + file_path += 7; + GST_INFO_OBJECT (self, "File path comes as %s", file_path); + + fp = fopen (file_path, "r"); + if (!fp){ + GST_ERROR_OBJECT (self, "Failed to open file"); + g_free(temp_path); + g_free(file_path_type); + return FALSE; + } + } + for( i=0;idetected_encoding,self->encoding); + if (self->detected_encoding && strcmp (self->detected_encoding, "UTF-8") && conversion){ + result = convert_to_utf8 (line, charCount, self->detected_encoding, consumed, &err, self); + GST_DEBUG_OBJECT (self, " Converted convert_to_utf8 result %d ",result); + } + if (result == NULL) { + result = line; + conversion = FALSE; + } + con_temp = result; + temp = con_temp; + + while (con_temp){ + gchar* tempKey = NULL; + guint i = 0; + + con_temp = strcasestr(con_temp,"class="); + if(con_temp) + delimiter = strcasestr(con_temp, ">"); + GST_DEBUG_OBJECT (self, " Delimiter ...Entering if %s",con_temp); + if (con_temp && (delimiter!=NULL)){ + gchar* tempChar = con_temp + 6; + GST_DEBUG_OBJECT (self, "Has class= reading string %s",tempChar); + GST_DEBUG_OBJECT (self, "Has class= "); + while (*tempChar != '>'){ + keyLength++; + tempChar++; + GST_DEBUG_OBJECT (self, " keyLength %d tempChar %c",keyLength,*tempChar); + } + GST_DEBUG_OBJECT (self, " keyLength %d",keyLength); + tempChar -= keyLength; + tempKey = (gchar*) g_malloc (keyLength + 1); + if(!tempKey){ + GST_DEBUG_OBJECT (self, "Error 1"); + goto error; + } + gchar* temp1 =tempKey; + GST_DEBUG_OBJECT (self, "tempChar %s keyLength %d",tempChar,keyLength); + while (*tempChar != '>'){ + *tempKey = *tempChar; + tempKey++; + tempChar++; + } + tempKey =temp1; + tempKey[keyLength]='\0'; + GST_DEBUG_OBJECT (self, "tempKey %s keyLength %d keyCount %d",tempKey,keyLength,keyCount); + int k =0; + for (k = 0; k < keyCount; k++){ + if(langkey[k]){ + if (!strcasecmp (tempKey,langkey[k])) + { + GST_DEBUG_OBJECT (self, "Has the key already so breaking..Entry %d tempKey %s langkey[i] %s ",k,tempKey,langkey[k]); + lang_found = TRUE; + break; + } + } + } + if(lang_found == FALSE){ + langkey[keyCount] = (gchar*) g_malloc (keyLength); + if(! langkey[keyCount]) + goto error; + strcpy(langkey[keyCount],tempKey); + langKey_length[keyCount]=keyLength; + keyCount++; + } + lang_found =FALSE; + keyLength =0; + if(tempKey){ + g_free(tempKey); + tempKey=NULL; + } + } else { + keyLength =0; + lang_found =FALSE; + break; + } + con_temp+=6; + GST_DEBUG_OBJECT (self, " ..increment con_temp %s",con_temp); + } + } + GST_DEBUG_OBJECT (self, " At end keyCount no of langs is %d ",keyCount); + for(i=0;ilanguage_code = (gchar*)malloc (3); + if(!(new->language_code)){ + GST_DEBUG_OBJECT (self, " .Error 2"); + goto error; + } + gchar *attr_val=new->language_code ; + strcpy (attr_val, "un"); + attr_val[2]='\0'; + + new->language_key = (gchar*) malloc (langKey_length[i] + 1); + if(!(new->language_key)){ + GST_DEBUG_OBJECT (self, " ..Error 3"); + goto error; + } + strcpy (new->language_key, langkey[i]); + self->priv->lang_list = g_list_append (self->priv->lang_list, new); + GST_DEBUG_OBJECT (self, " new...Successfull"); + g_free(langkey[i]); + } + } + if (fp) { + g_free(temp_path); + g_free(file_path_type); + fclose(fp); + } + return TRUE; +error: + GST_DEBUG_OBJECT (self, " In Error"); + if (fp) { + g_free(temp_path); + g_free(file_path_type); + fclose(fp); + } + return FALSE; +} + +gboolean +validate_langlist_body(GList * lang_list, Gstsubmux * self){ + gchar * file_path_type = NULL; + gchar * file_path = NULL; + gchar line[1025]; + FILE * fp = NULL; + guint i = 0, found_count = 0,k = 0; + const guint list_len = g_list_length(lang_list); + gboolean counter[MAX_LANGUAGE]; + GstPad *sinkpad = NULL; + struct LangStruct + { + gchar *language_code; + gchar *language_key; + } * lang; + sinkpad = (GstPad *) g_list_nth_data(self->sinkpad, 0); + GstQuery *cquery; + GstStructure *structure; + const GValue *value; + structure = gst_structure_new ("FileSrcURI", "file-uri", G_TYPE_STRING, NULL, NULL); + + cquery = gst_query_new_application (GST_QUERY_CUSTOM, structure); + + if (!gst_pad_peer_query (sinkpad, cquery)) { + GST_ERROR_OBJECT (self, "Failed to query SMI file path"); + gst_query_unref (cquery); + return FALSE; + } + structure = gst_query_get_structure (cquery); + value = gst_structure_get_value (structure, "file-uri"); + file_path = g_strdup (g_value_get_string (value)); + + if (file_path == NULL){ + GST_ERROR_OBJECT (self, "Could not parse the SMI file path"); + gst_query_unref (cquery); + return FALSE; + } + + if (self->external_filepath == NULL) { + self->external_filepath = file_path; + } + else { + if (!g_strcmp0 (file_path, self->external_filepath)) { + GST_INFO_OBJECT (self, "Same external file URI, no need to parse again"); + gst_query_unref (cquery); + g_free(file_path); + return TRUE; + } + else { + g_free (self->external_filepath); + self->external_filepath = NULL; + self->external_filepath = file_path; + } + } + + gst_query_unref (cquery); + GST_INFO_OBJECT (self, "File path comes as %s", file_path); + + file_path_type = g_strndup ((gchar *) file_path, 4); + GST_INFO_OBJECT (self, "Received file path by query = %s, %s", file_path, file_path_type); + if (!g_strcmp0(file_path_type, "file")){ + file_path += 7; + GST_INFO_OBJECT (self, "File path comes as %s", file_path); + + fp = fopen (file_path, "r"); + if (!fp){ + GST_ERROR_OBJECT (self, "Failed to open file"); + g_free(file_path_type); + return FALSE; + } + + for (i = 0; i < list_len; i++){ + counter[i] = FALSE; + } + + while (!feof (fp) && found_count < list_len){ + GError *err = NULL; + gsize * consumed = NULL; + gint gap = 0; + guint charCount = 0; + gchar* result = NULL; + gchar* temp = NULL; + gchar* temp_lang = NULL; + gchar* con_temp_end = NULL; + gchar* con_temp_start = NULL; + gchar* new_key = NULL; + gint new_key_length = 0; + gboolean new_key_found = FALSE; + gchar * temp1 = NULL; + gchar *con_temp_lang = NULL; + gchar *con_temp = NULL; + gboolean conversion = TRUE; + charCount = fread (line, sizeof(char), 1024, fp); + line[charCount] = '\0'; + if (!charCount) { + GST_WARNING_OBJECT (self, "fread returned zero bytes"); + continue; + } + + GST_DEBUG_OBJECT (self, "value of detected encoding is %s and self encoding is %s", + self->detected_encoding,self->encoding); + if (self->detected_encoding && strcmp (self->detected_encoding, "UTF-8") && conversion){ + result = convert_to_utf8 (line, charCount, self->detected_encoding, consumed, &err, self); + } + if (result == NULL) { + result = line; + conversion = FALSE; + } + con_temp = g_utf8_strdown (result, strlen (result)); + temp = con_temp; + while (con_temp) { + con_temp = g_strstr_len(con_temp, strlen (con_temp), "class="); + if (con_temp) { + temp1 = g_strstr_len(con_temp+1, strlen (con_temp), "class="); + } + if (temp1 && con_temp){ + gap = strlen (con_temp) - strlen (temp1); + } else if (con_temp) { + gap = strlen (con_temp); + } else { + continue; + } + if (con_temp){ + for (i = 0; i < list_len; i++){ + if (counter[i] == TRUE) { + con_temp = con_temp + 1; + continue; + } + lang = (struct LangStruct *) g_list_nth_data (lang_list, i); + if (lang) { + temp_lang = (gchar*)g_malloc (strlen (lang->language_key) + 1); + strcpy (temp_lang, lang->language_key); + con_temp_lang = g_utf8_strdown (temp_lang, strlen (temp_lang)); + if (g_strstr_len (con_temp, gap, con_temp_lang)) { + found_count++; + counter[i] = TRUE; + GST_INFO_OBJECT (self, "Valid Language in list : [%s]", lang->language_key); + con_temp = con_temp + 1; + } +/* Fix Me: Cases where there is no body for a specific language + * inside a single language .smi file */ +#if 0 + else { + con_temp_start = con_temp; + con_temp_end = con_temp; + while(con_temp_end) { + if(*con_temp_end == '=') { + con_temp_start = con_temp_end+1; + con_temp_end++; + }else if(*con_temp_end == '>') { + con_temp_end = con_temp_end; + new_key_found = TRUE; + break; + }else { + con_temp_end++; + new_key_found = FALSE; + } + } + if(new_key_found) { + new_key_length = strlen(con_temp_start)-strlen(con_temp_end); + new_key = g_malloc(new_key_length +1); + for(k=0;klanguage_key); + g_free(new_key); + found_count++; + counter[i] = TRUE; + con_temp = con_temp + 1; + } + } +#endif + g_free (temp_lang); + g_free (con_temp_lang); + } + } + } + } + if (conversion) + g_free (result); + if (temp) + g_free (temp); + } + + if (found_count < list_len) { + for (i = 0; i < list_len; i++) { + if (counter[i] == FALSE) + lang_list = g_list_delete_link (lang_list, g_list_nth (lang_list, i)); + } + } + } else { + GST_ERROR_OBJECT (self, "File is not a local file"); + g_free(file_path_type); + return FALSE; + } + fclose (fp); + g_free(file_path_type); + return TRUE; +} + +/* +** +** Description : Chain function used to push the subtitle buffer to internal pipelines of submux element +** Params : (1) sink pad on which buffer is arriving (2) the buffer itself +** return : GST_FLOW_OK on successfully pushing subtitle buffer to next element +** +*/ +static GstFlowReturn +gst_submux_chain(GstPad *pad, GstBuffer *buffer) +{ + guint length = 0; + guint i=0; + GstPad *checkpad = NULL; + Gstsubmux *submux = GST_SUBMUX(GST_PAD_PARENT(pad)); + gboolean ret = FALSE; + GstFlowReturn fret = GST_FLOW_ERROR; + GstSubmuxStream *stream = NULL; + GstMessage *m = NULL; + + if (GST_BUFFER_IS_DISCONT (buffer)) + GST_DEBUG_OBJECT(submux, "Discont buffer came in chain function"); + GST_DEBUG_OBJECT (submux, "^^^^^entering in chain^^^^^^"); + if (!submux->priv->is_internal) { + if (!submux->priv->first_buffer) { + submux->detected_encoding = detect_encoding ((gchar*)GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); + } + if (!submux->langlist_msg_posted && submux->priv->lang_list) { + if (!validate_langlist_body (submux->priv->lang_list, submux)){ + GST_WARNING_OBJECT(submux, "Error occured while validating language list. Posting without validation"); + } + if (submux->priv->lang_list) { + GList* temp_list_to_post = NULL; + temp_list_to_post = g_list_copy (submux->priv->lang_list); + m = gst_message_new_element (GST_OBJECT_CAST (submux), gst_structure_new("Ext_Sub_Language_List", + "lang_list", G_TYPE_POINTER, temp_list_to_post, NULL)); + + gst_element_post_message (GST_ELEMENT_CAST (submux), m); + submux->langlist_msg_posted = TRUE; + } + GST_DEBUG_OBJECT (submux, "LANGLIST POSTED"); + } + if (submux->need_segment) { + ret = gst_pad_push_event (submux->srcpad, gst_event_new_new_segment (FALSE, submux->segment.rate, + submux->segment.format, submux->segment.start, submux->segment.stop, + submux->segment.time)); + GST_DEBUG_OBJECT (submux, "pushing newsegment event with %" GST_SEGMENT_FORMAT, &submux->segment); + if (!ret) { + GST_ERROR_OBJECT (submux, "Sending newsegment to next element is failed"); + return GST_FLOW_ERROR; + } + GST_DEBUG_OBJECT (submux, "Starting the loop again"); + if (!gst_pad_start_task (submux->srcpad, (GstTaskFunction) gst_submux_loop, submux)) { + GST_ERROR_OBJECT (submux, "failed to start srcpad task..."); + GST_ELEMENT_ERROR (submux, RESOURCE, FAILED, ("failed to create push loop"), (NULL)); + return GST_FLOW_ERROR; + } + submux->need_segment = FALSE; + } + GST_DEBUG_OBJECT (submux, "before pushing buffer to each apprsrc"); + if (!submux->priv->lang_list && submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) { + GST_ERROR_OBJECT (submux, "lang list is not there"); + return GST_FLOW_ERROR; + } + if (submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) + length = g_list_length (submux->priv->lang_list); + else + length = 1; + + for (i = 0; i < length; i++) { + stream = g_list_nth_data(submux->streams, i); + if ((submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) && !submux->priv->first_buffer){ + GstLangStruct *lang = g_list_nth_data(submux->priv->lang_list, i); + if(submux->msl_streams){ + GstLangStruct *lang1 = g_list_nth_data(submux->msl_streams, i); + lang->active = lang1->active; + } else { + if (i == 0) + lang->active = TRUE; + else + lang->active = FALSE; + } + } + GST_DEBUG_OBJECT (submux, "making stream need segment false"); + stream->need_segment = FALSE; + } + + for (i = 0; i < length; i++) { + stream = g_list_nth_data(submux->streams, i); + if (!stream){ + GST_ERROR_OBJECT (submux, "stream not found"); + return GST_FLOW_ERROR; + } + + if (!stream->pipe_struc.appsrc) { + GST_ERROR_OBJECT (submux, "appsrc not found"); + return GST_FLOW_ERROR; + } + if (i < (length - 1)) + gst_buffer_ref (buffer); + + fret = gst_app_src_push_buffer ((GstAppSrc*)stream->pipe_struc.appsrc, buffer); + + if (fret != GST_FLOW_OK) { + GST_ERROR_OBJECT (submux, "push buffer failed with fret is %d", fret); + return fret; + } + GST_DEBUG_OBJECT (submux, "pad_push successfull to appsrc %p buffer", buffer); + } + } else { + length = submux->sinkpads_count; + checkpad = (GstPad *) g_list_nth_data (submux->sinkpad, 0); + if (checkpad == pad) { + if (submux->need_segment) { + ret = gst_pad_push_event (submux->srcpad, gst_event_new_new_segment (FALSE, submux->segment.rate, + submux->segment.format, submux->segment.start, submux->segment.stop, + submux->segment.time)); + GST_DEBUG_OBJECT (submux, "pushing newsegment event with %" GST_SEGMENT_FORMAT, &submux->segment); + if (!ret) { + GST_ERROR_OBJECT (submux, "Sending newsegment to next element is failed"); + return GST_FLOW_ERROR; + } + GST_DEBUG_OBJECT (submux, "Starting the loop again"); + if (!gst_pad_start_task (submux->srcpad, (GstTaskFunction) gst_submux_loop, submux)) { + GST_ERROR_OBJECT (submux, "failed to start srcpad task..."); + GST_ELEMENT_ERROR (submux, RESOURCE, FAILED, ("failed to create push loop"), (NULL)); + return GST_FLOW_ERROR; + } + submux->need_segment = FALSE; + } + } + for (i = 0; i < length; i++) { + checkpad = (GstPad *) g_list_nth_data(submux->sinkpad, i); + if (checkpad == pad) { + stream = g_list_nth_data (submux->streams, i); + if (!stream) { + GST_ERROR_OBJECT (submux, "Stream not available..."); + return GST_FLOW_ERROR; + } + if (stream->flushing){ + GST_DEBUG_OBJECT (submux, "flushing going on in appsink"); + return GST_FLOW_OK ; + } + + g_mutex_lock (stream->queue_lock); + g_queue_push_tail (stream->queue, buffer); + g_cond_signal (stream->queue_empty); + g_mutex_unlock (stream->queue_lock); + fret = GST_FLOW_OK; + GST_DEBUG_OBJECT (submux, "push buffer success to appsrc with fret is %d for stream[%d]", fret, i); + break; + } + } + } + + if (!submux->priv->first_buffer) { + GST_DEBUG_OBJECT (submux, "got the first buffer"); + submux->priv->first_buffer = TRUE; + if (submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) { + + } + } + GST_DEBUG_OBJECT (submux, "^^^^^exiting in chain^^^^^^"); + return fret; +} + +/* stream_denit */ +static void +gst_submux_stream_deinit (GstSubmuxStream *stream,Gstsubmux *submux) +{ + GstBuffer *buf = NULL; + + if (stream) { + if (stream->queue) { + while (!g_queue_is_empty (stream->queue)) { + buf = g_queue_pop_head (stream->queue); + gst_buffer_unref (buf); + buf = NULL; + } + g_queue_free (stream->queue); + stream->queue = NULL; + } + + if (stream->pipe_struc.pipe) { + gst_element_set_state (stream->pipe_struc.pipe, GST_STATE_NULL); + gst_element_get_state (stream->pipe_struc.pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_object_unref(GST_OBJECT(stream->pipe_struc.appsrc)); + gst_object_unref(GST_OBJECT(stream->pipe_struc.appsink)); + gst_object_unref (stream->pipe_struc.pipe); + } + + if (stream->queue_lock) { + g_cond_broadcast(stream->queue_empty); + g_mutex_free (stream->queue_lock); + stream->queue_lock = NULL; + } + + if (stream->queue_empty) { + g_cond_free (stream->queue_empty); + stream->queue_empty= NULL; + } + + g_free (stream); + GST_DEBUG_OBJECT (submux, "stream deinit completed"); + } +} + +/* releasing the requested pad */ +static void +gst_submux_release_pad (GstElement * element, GstPad * pad) +{ + Gstsubmux *submux = GST_SUBMUX_CAST (element); + GstPad *check_pad; + int i=0; + guint length; + GST_INFO_OBJECT(element,"entering in the release pad"); + length = g_list_length(submux->sinkpad); + GST_DEBUG_OBJECT (element, "Releasing %s:%s", GST_DEBUG_PAD_NAME (pad)); + + for (i=1;i<=length;i++) { + check_pad = (struct GstPad *) g_list_nth_data(submux->sinkpad,i); + if (check_pad == pad) { + /* this is it, remove */ + submux->sinkpad = g_list_remove_link (submux->sinkpad, pad); + gst_element_remove_pad (element, pad); + break; + } + } +} + +/* request new pad */ +static GstPad * +gst_submux_request_new_pad (GstElement * element, + GstPadTemplate * templ, const gchar * req_name) +{ + GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + Gstsubmux *submux = GST_SUBMUX_CAST (element); + GstPad *newpad = NULL; + gchar *name = NULL; + + if (templ->direction != GST_PAD_SINK) { + GST_ERROR_OBJECT (submux, "templ direction is not sinkpad, returning from here"); + goto wrong_direction; + } + + if (templ == gst_element_class_get_pad_template (klass, "sink%d")) { + name = g_strdup_printf ("sink%d", submux->sinkpads_count++); + } + + GST_DEBUG_OBJECT (submux, "Requested pad: %s", name); + newpad = (GstPad*)g_new0 (GstPad*, 1); + /* create pad and add to collections */ + newpad = gst_pad_new_from_template (templ, name); + g_free (name); + if(!submux->priv->is_internal) { + submux->external_sinkpad = TRUE; + } + submux->sinkpad = g_list_append (submux->sinkpad, newpad); + /* set up pad */ + + /* set up pad functions */ + gst_pad_set_setcaps_function (newpad, GST_DEBUG_FUNCPTR (gst_submux_setcaps)); + gst_pad_set_event_function (newpad, GST_DEBUG_FUNCPTR (gst_submux_handle_sink_event)); + gst_pad_set_chain_function(newpad, GST_DEBUG_FUNCPTR (gst_submux_chain)); + gst_pad_set_active (newpad, TRUE); + gst_element_add_pad (element, newpad); + + return newpad; + +/* ERRORS */ +wrong_direction: + GST_WARNING_OBJECT (submux, "Request pad that is not a SINK pad."); + return NULL; +} + +static gboolean +gst_submux_handle_src_event (GstPad * pad, GstEvent * event) +{ + Gstsubmux *submux = GST_SUBMUX(GST_PAD_PARENT(pad)); + gboolean ret = FALSE; + guint length = 0; + gint i = 0; + gboolean update; + GstSubmuxStream *cur_stream = NULL; + + GST_DEBUG_OBJECT (submux, "Handling %s event", GST_EVENT_TYPE_NAME (event)); + length = g_list_length(submux->streams); + + switch (GST_EVENT_TYPE (event)) { + /* this event indicates speed change or seek */ + case GST_EVENT_SEEK: { + GstFormat format; + GstSeekType start_type, stop_type; + gint64 start, stop; + gdouble rate; + GstPad *sinkpad = (GstPad *) g_list_nth_data (submux->sinkpad, 0); + gst_event_parse_seek (event, &rate, &format, &submux->segment_flags, + &start_type, &start, &stop_type, &stop); + gst_segment_set_seek (&submux->segment, rate, format, submux->segment_flags, + start_type, start, stop_type, stop, &update); + if (submux->priv->is_internal || submux->priv->parser_type != GST_SUB_PARSE_FORMAT_SAMI) { + length = g_list_length (submux->sinkpad); + } else { + length = g_list_length(submux->streams); + } + if (!submux->priv->is_internal) { + ret = gst_pad_push_event (sinkpad, gst_event_new_seek (rate, GST_FORMAT_BYTES, submux->segment_flags, + GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, 0)); + gst_event_unref (event); + } else { + GST_DEBUG_OBJECT (submux, "handling seek in case of internal"); + ret = gst_pad_event_default (pad, event); + } + + if (!ret) { + GST_ERROR_OBJECT (submux, "sending seek event to sink pad failed"); + break; + } + GST_DEBUG_OBJECT (submux, "sending seek event to sink pad passed"); + + break; + } + + default: { + ret = gst_pad_event_default (pad, event); + break; + } + } + + return ret; +} + +static gboolean +gst_submux_handle_sink_event (GstPad * pad, GstEvent * event) +{ + Gstsubmux *submux = GST_SUBMUX (GST_PAD_PARENT (pad)); + gboolean ret = FALSE; + guint length = 0; + GstBuffer *buf = NULL; + GstPad *checkpad = NULL; + gint i = 0; + GstSubmuxStream *cur_stream = NULL; + + GST_DEBUG_OBJECT (submux, "Handling %s event", GST_EVENT_TYPE_NAME (event)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_EOS:{ + length = g_list_length (submux->sinkpad); + GST_OBJECT_LOCK (submux); + for (i = 0; i < length; i++) { + GST_DEBUG_OBJECT(submux, "inside the handling of EOS event"); + cur_stream = g_list_nth_data(submux->streams,i); + if (!cur_stream->eos_sent) { + GstBuffer *buf = gst_buffer_new_and_alloc (3 + 1); + GST_DEBUG_OBJECT(submux, "sending EOS buffer to chain\n"); + GST_DEBUG_OBJECT (submux, "EOS. Pushing remaining text (if any)"); + GST_BUFFER_DATA (buf)[0] = 'e'; + GST_BUFFER_DATA (buf)[1] = 'o'; + GST_BUFFER_DATA (buf)[2] = 's'; + GST_BUFFER_DATA (buf)[3] = '\0'; + /* play it safe */ + GST_BUFFER_SIZE (buf) = 3; + GST_BUFFER_FLAG_SET(buf,GST_BUFFER_FLAG_GAP); + gst_submux_chain (g_list_nth_data(submux->sinkpad,i), buf);// + cur_stream->eos_sent = TRUE; + } + } + GST_OBJECT_UNLOCK (submux); + gst_event_unref(event); + ret = TRUE; + break; + } + case GST_EVENT_NEWSEGMENT: { + GstFormat format; + gdouble rate,arate; + gint64 start, stop, time; + gboolean update; + GST_OBJECT_LOCK (submux); + if (!submux->pipeline_made) { + if (!gst_submux_format_autodetect (submux)) { + GST_ERROR_OBJECT (submux, "auto detect function failed"); + return FALSE; + } + if (!gst_calculate_number_languages(submux)) { + GST_ERROR_OBJECT (submux, "failed to calculate number of languages"); + return FALSE; + } + if (!gst_submux_create_pipelines (submux, pad)) { + GST_ERROR_OBJECT (submux, "failed to create pipelines"); + return FALSE; + } + } + + if (!submux->priv->is_internal) { + gst_event_unref(event); + length = g_list_length(submux->streams); + for (i = 0; i < length; i++) { + GST_DEBUG_OBJECT (submux, "inside the handling of new_segment event"); + cur_stream = g_list_nth_data(submux->streams,i); + GST_DEBUG_OBJECT (submux, "pushing newsegment event with %" GST_SEGMENT_FORMAT, &submux->segment); + if (!cur_stream->pipe_struc.pipe) { + GST_ERROR_OBJECT (submux, "pipeline is null"); + return FALSE; + } + cur_stream = g_list_nth_data(submux->streams,i); + cur_stream->seek_ts = submux->segment.start; + ret = gst_element_send_event (cur_stream->pipe_struc.pipe, gst_event_new_new_segment (FALSE, + submux->segment.rate, submux->segment.format, + submux->segment.start, submux->segment.stop, submux->segment.time)); + if (!ret){ + GST_ERROR_OBJECT(submux, "sending newsegment event to stream[%d] failed", i); + break; + } + } + submux->need_segment = TRUE; + } else { + length = g_list_length (submux->sinkpad); + if (length == g_list_length (submux->streams) && submux->need_segment) { + for (i = 0; i < length; i++) { + GST_DEBUG_OBJECT (submux, "inside the handling of new_segment event"); + cur_stream = g_list_nth_data(submux->streams, i); + if (cur_stream->need_segment) { + gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, &start, &stop, &time); + gst_segment_set_newsegment_full (&submux->segment, update, rate, arate, format, start, stop, time); + GST_DEBUG_OBJECT (submux, "pushing newsegment event with %" GST_SEGMENT_FORMAT, &submux->segment); + ret = TRUE; + cur_stream->need_segment = FALSE; + } + } + submux->need_segment = TRUE; + gst_event_unref(event); + } + } + GST_OBJECT_UNLOCK (submux); + break; + } + case GST_EVENT_FLUSH_START: { + length = g_list_length(submux->streams); + if (!submux->priv->is_internal) { + gst_event_unref(event); + ret = gst_pad_event_default (pad, gst_event_new_flush_start ()); + for (i = 0;i < length;i++) { + cur_stream = g_list_nth_data(submux->streams,i); + cur_stream->flushing = TRUE; + cur_stream->discont_came = FALSE; + GST_DEBUG_OBJECT (submux, "making discont false"); + GST_DEBUG_OBJECT (submux, "making flushing TRUE"); + cur_stream->eos_came = FALSE; + cur_stream->eos_sent = FALSE; + GST_DEBUG_OBJECT (submux, "making eos_came and eos_sent FALSE"); + } + for (i = 0; i < length; i++) { + cur_stream = g_list_nth_data(submux->streams,i); + ret= gst_element_send_event(cur_stream->pipe_struc.appsrc,gst_event_new_flush_start ()); + ret= gst_element_send_event(cur_stream->pipe_struc.appsrc,gst_event_new_flush_stop ()); + ret = gst_element_send_event(cur_stream->pipe_struc.appsrc,gst_event_new_eos ()); + GST_INFO_OBJECT(cur_stream,"flush stop and start and eos is done with ret %d",ret); + submux->flushing =TRUE; + g_mutex_lock (cur_stream->queue_lock); + g_cond_signal (cur_stream->queue_empty); + g_mutex_unlock(cur_stream->queue_lock); + cur_stream->flush_done = TRUE; + GST_DEBUG_OBJECT (cur_stream, "signaling queue empty signal from flush start"); + ret = TRUE; + GST_DEBUG_OBJECT (submux, "sending flush start event to stream[%d] success", i); + } + + if (!ret){ + GST_ERROR_OBJECT (submux, "sending flush start event to srcpad pad failed"); + break; + } + + if (submux && GST_PAD_TASK(submux->srcpad)) { + GST_INFO_OBJECT (submux, "trying acquire srcpad lock"); + GST_PAD_STREAM_LOCK (submux->srcpad); + GST_INFO_OBJECT (submux, "acquired stream lock"); + GST_PAD_STREAM_UNLOCK (submux->srcpad); + } + /*changes for new design*/ + for (i = 0;i < length;i++) { + cur_stream = g_list_nth_data(submux->streams,i); + gst_submux_stream_deinit(cur_stream,submux); + } + g_list_free(submux->streams); + submux->streams = NULL; + gst_submux_deinit_private_values (submux); + + submux->stop_loop = FALSE; + submux->need_segment = TRUE; + submux->langlist_msg_posted = FALSE; + GST_DEBUG_OBJECT (submux, "flush start successfully send to next element"); + } else { + GST_DEBUG_OBJECT(submux, "flusht start in case of internal subtitle"); + gst_event_unref (event); + submux->flushing = TRUE; + checkpad = (GstPad *) g_list_nth_data (submux->sinkpad, length - 1); + if (checkpad == pad) { + ret = gst_pad_event_default (pad, gst_event_new_flush_start ()); + for (i = 0; i < length; i++) { + cur_stream = g_list_nth_data(submux->streams, i); + cur_stream->flushing = TRUE; + GST_DEBUG_OBJECT (submux, "in case of internal making discont unchanged"); + GST_DEBUG_OBJECT (submux, "making flushing TRUE"); + } + for (i = 0; i < length; i++) { + cur_stream = g_list_nth_data(submux->streams, i); + submux->flushing = TRUE; + g_mutex_lock (cur_stream->queue_lock); + while (!g_queue_is_empty (cur_stream->queue)) { + buf = g_queue_pop_head (cur_stream->queue); + gst_buffer_unref (buf); + } + GST_DEBUG_OBJECT (submux, "cleared stream cur_stream->queue"); + g_queue_clear (cur_stream->queue); + g_cond_signal (cur_stream->queue_empty); + g_mutex_unlock(cur_stream->queue_lock); + GST_DEBUG_OBJECT (cur_stream, "signaling queue empty signal from flush start"); + cur_stream->eos_came = FALSE; + cur_stream->eos_sent = FALSE; + GST_DEBUG_OBJECT (submux, "making eos_came and eos_sent FALSE"); + ret = TRUE; + GST_DEBUG_OBJECT (submux, "sending flush start event to stream[%d] success", i); + } + if (!ret){ + GST_ERROR_OBJECT (submux, "sending flush start event to srcpad pad failed"); + break; + } + + if (submux && GST_PAD_TASK (submux->srcpad)) { + GST_INFO_OBJECT (submux, "trying acquire srcpad lock"); + GST_PAD_STREAM_LOCK (submux->srcpad); + GST_INFO_OBJECT (submux, "acquired srcpad lock"); + GST_PAD_STREAM_UNLOCK (submux->srcpad); + } + GST_DEBUG_OBJECT(submux, "flush start successfully send to next element"); + } + } + break; + } + case GST_EVENT_FLUSH_STOP: { + gst_event_unref(event); + if (!submux->priv->is_internal) { + guint idx = 0; + submux->flushing = FALSE; + ret = gst_pad_event_default (pad, gst_event_new_flush_stop ()); + if (!ret){ + GST_ERROR_OBJECT (submux, "sending flush-stop event to srcpad pad failed"); + break; + } + for (idx = 0; idx < submux->priv->stream_count; idx++) { + submux->cur_buf_array[idx] = NULL; + } + GST_DEBUG_OBJECT (submux, "flush stop successfully send to next element"); + } else { + length = g_list_length(submux->streams); + GST_DEBUG_OBJECT (submux, "flusht stop in case of internal subtitle"); + checkpad = (GstPad *) g_list_nth_data (submux->sinkpad, length - 1); + if (checkpad == pad) { + for (i = 0; i < length; i++) { + cur_stream = g_list_nth_data(submux->streams, i); + cur_stream->need_segment = TRUE; + submux->cur_buf_array[i] = NULL; + submux->need_segment = TRUE; + GST_DEBUG_OBJECT (submux, "making need_segment true"); + submux->flushing = FALSE; + cur_stream->flushing = FALSE; + GST_DEBUG_OBJECT (submux, "making flushing FALSE"); + ret = TRUE; + GST_DEBUG_OBJECT (submux, "sending %s event to stream[%d] success", GST_EVENT_TYPE_NAME (event), i); + } + ret = gst_pad_event_default (pad, gst_event_new_flush_stop ()); + if (!ret){ + GST_ERROR_OBJECT (submux, "sending flush-stop event to srcpad pad failed"); + break; + } + GST_DEBUG_OBJECT (submux, "flush stop successfully send to next element"); + } + } + break; + } + default:{ + if (!submux->priv->is_internal) { + ret = gst_pad_event_default (pad, event); + } else { + checkpad = (GstPad *) g_list_nth_data (submux->sinkpad, length - 1); + if (checkpad == pad) { + ret = gst_pad_event_default (pad, event); + } else { + ret = TRUE; + } + } + if (!ret){ + GST_ERROR_OBJECT (submux, "sending %s event to srcpad pad failed", GST_EVENT_TYPE_NAME (event)); + break; + } + break; + } + } + return ret; +} + +static gint gst_submux_buffer_list_sorting (gconstpointer a, gconstpointer b) +{ + GstBuffer *buf_a = (GstBuffer *) a; + GstBuffer *buf_b = (GstBuffer *) b; + if (GST_BUFFER_TIMESTAMP(buf_a)>GST_BUFFER_TIMESTAMP(buf_b)) + return -1; + else if(GST_BUFFER_TIMESTAMP(buf_a)= ref_stop)) + return FALSE; + + /* if a stop position is given and is before the segment start, + * we're outside of the segment. Special case is were start + * and stop are equal to the segment start. In that case we + * are inside the segment. */ + if (G_UNLIKELY (stop != -1 && (stop < ref_start || (start != stop && stop == ref_start)))) + return FALSE; + + return TRUE; +} + +/* This function do the actual muxing of buffer on the basis of timestamps */ +static GList* +gst_submux_muxing (Gstsubmux *submux) +{ + GstClockTime min_timestamp = 0; + int min_stream = 0; + int overlap = 0; + GstClockTime next_min_time = 0; + int idx = 0; + GList *push_list = NULL; + + /* Finding least timestamp of all streams and their stream ID */ + for (idx = 0; idx < submux->priv->stream_count; idx++) { + if(submux->cur_buf_array[idx] && !min_timestamp) { + min_timestamp = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]); + min_stream = idx; + } + if(submux->cur_buf_array[idx] && (GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]) < min_timestamp)) { + min_timestamp = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]); + min_stream = idx; + } + } + + GST_DEBUG_OBJECT (submux, "Identified least timestamp: %"GST_TIME_FORMAT" for stream: %d", + GST_TIME_ARGS(min_timestamp), min_stream); + + /* Finding overlap buffers and next least timestamp */ + for (idx = 0; idx < submux->priv->stream_count; idx++) { + if(submux->cur_buf_array[idx] && (idx != min_stream) && (!next_min_time)) { + next_min_time = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]); + } + if(submux->cur_buf_array[idx] && (idx != min_stream)) { + if(gst_submux_is_muxing_needed (submux->cur_buf_array[min_stream], submux->cur_buf_array[idx])) { + overlap = overlap | (1<cur_buf_array[idx]) < next_min_time) + next_min_time = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]); + } + } + } + + GST_DEBUG_OBJECT (submux, "Identified overlap: %d next least timestamp: %"GST_TIME_FORMAT" ", overlap, GST_TIME_ARGS(next_min_time)); + + /* If no overlap send buffer as it is */ + if(!overlap) { + GST_DEBUG_OBJECT (submux, "pushing string: %s....", (gchar*)GST_BUFFER_DATA(submux->cur_buf_array[min_stream])); + push_list = g_list_append(push_list, submux->cur_buf_array[min_stream]); + GST_DEBUG_OBJECT (submux, "No overlap found pushing buffer of ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream])), GST_TIME_ARGS(GST_BUFFER_DURATION(submux->cur_buf_array[min_stream]))); + submux->cur_buf_array[min_stream] = NULL; + } else { + GstBuffer *push_buf = NULL; + GstClockTime stop_time = 0; + int stop_idx = 0; + GstBuffer *overlap_buf = NULL; + guint overlap_buf_length = 0; + GString *overlap_text = NULL; + gchar *text = NULL; + + if(next_min_time > GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream])) { + GST_DEBUG_OBJECT (submux, "Before duration change ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream])), GST_TIME_ARGS(GST_BUFFER_DURATION(submux->cur_buf_array[min_stream]))); + push_buf = gst_buffer_copy (submux->cur_buf_array[min_stream]); + push_buf->duration = next_min_time - GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream]); + GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream]) = next_min_time; + GST_BUFFER_DURATION(submux->cur_buf_array[min_stream]) -= push_buf->duration; + GST_DEBUG_OBJECT (submux, "After duration change ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(submux->cur_buf_array[min_stream])), GST_TIME_ARGS(GST_BUFFER_DURATION(submux->cur_buf_array[min_stream]))); + + min_timestamp = next_min_time; + GST_INFO_OBJECT (submux, "pushing string: %s...", (gchar*)GST_BUFFER_DATA(push_buf)); + push_list = g_list_append(push_list, push_buf); + GST_DEBUG_OBJECT (submux, "Overlap found pushing initial partial buffer of ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(push_buf)), GST_TIME_ARGS(GST_BUFFER_DURATION(push_buf))); + } + + for (idx = 0; idx < submux->priv->stream_count; idx++) { + if(submux->cur_buf_array[idx] && !stop_time) { + stop_time = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]) + GST_BUFFER_DURATION(submux->cur_buf_array[idx]); + stop_idx = idx; + } + if(submux->cur_buf_array[idx] && + ((GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx])+ GST_BUFFER_DURATION(submux->cur_buf_array[idx])) < stop_time)) { + stop_time = GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx]) + GST_BUFFER_DURATION(submux->cur_buf_array[idx]); + stop_idx = idx; + } + } + GST_DEBUG_OBJECT (submux, "Identified least stop timestamp: %"GST_TIME_FORMAT" for stream: %d", + GST_TIME_ARGS(stop_time), stop_idx); + + overlap_text = g_string_new (""); + overlap = overlap | (1<priv->stream_count; idx++) { + int finder = 1<cur_buf_array[idx])); + g_string_append (overlap_text, (gchar*)GST_BUFFER_DATA (submux->cur_buf_array[idx])); + GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx])+= (stop_time - min_timestamp); + GST_BUFFER_DURATION(submux->cur_buf_array[idx])-= (stop_time - min_timestamp); + if(overlap > (1<<(idx+1))) g_string_append_c (overlap_text, '\n'); + } + } + text = g_string_free (overlap_text, FALSE); + overlap_buf_length = strlen(text); + overlap_buf = gst_buffer_new_and_alloc (overlap_buf_length + 1); + memcpy (GST_BUFFER_DATA (overlap_buf), text, overlap_buf_length + 1); + overlap_buf->timestamp = min_timestamp; + overlap_buf->duration = stop_time - min_timestamp; + g_free (text); + text = NULL; + submux->cur_buf_array[stop_idx] = NULL; + GST_DEBUG_OBJECT (submux, "pushing string: %s....", (gchar*)GST_BUFFER_DATA(overlap_buf)); + push_list = g_list_append(push_list, overlap_buf); + GST_DEBUG_OBJECT (submux, "Overlap found pushing merged buffer of ts = %"GST_TIME_FORMAT", dur = %"GST_TIME_FORMAT, + GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(overlap_buf)), GST_TIME_ARGS(GST_BUFFER_DURATION(overlap_buf))); + GST_DEBUG_OBJECT (submux, "request for new buffer for stream %d", stop_idx); + for (idx = 0; idx < submux->priv->stream_count; idx++) { + if(submux->cur_buf_array[idx] && + ((GST_BUFFER_TIMESTAMP(submux->cur_buf_array[idx])+ GST_BUFFER_DURATION(submux->cur_buf_array[idx])) <= stop_time)) { + submux->cur_buf_array[idx] = NULL; + GST_DEBUG_OBJECT (submux, "request for new buffer for stream %d", idx); + } + } + } + return push_list; +} + +static void gst_submux_loop (Gstsubmux *submux) +{ + guint length = 0; + GstBuffer *src_buffer = NULL; + GstBuffer *temp_buffer = NULL; + GstBuffer *check_buffer = NULL; + GstSubmuxStream *cur_stream = NULL; + GstSubmuxStream *check_stream = NULL; + gboolean match = FALSE; + GstFlowReturn fret = GST_FLOW_OK; + GstClockTime cur_duration = 0 ; + GstClockTime cur_ts = 0; + gboolean eos = TRUE; + guint i= 0,k = 0; + GList *push_list = NULL; + GstBuffer *push_buf = NULL; + + if (!submux->priv->first_buffer) { + GST_INFO_OBJECT (submux, "exiting from lopp"); + return; + } + + if (submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI) { + length = g_list_length (submux->priv->lang_list); + } else { + length = submux->sinkpads_count; + } + + gboolean made = FALSE; + // length = 2; + + for (i = 0; i < length; i++) { + +re_pop: + cur_stream = g_list_nth_data (submux->streams, i); + GST_DEBUG_OBJECT (submux, "Before lock acquired in loop stream[%d]", i); + g_mutex_lock (cur_stream->queue_lock); + GST_DEBUG_OBJECT (submux, "Lock acquired in loop stream[%d]", i); + + if (g_queue_is_empty (cur_stream->queue) && !submux->flushing) { + GST_DEBUG_OBJECT (submux, "Queue is empty, waiting for the condition signal stream[%d]", i); + g_cond_wait (cur_stream->queue_empty, cur_stream->queue_lock); + } + GST_DEBUG_OBJECT (submux, "Got the queue condition signal stream[%d]", i); + + if (submux->flushing || submux->stop_loop) { + GST_DEBUG_OBJECT (submux, "Flushing going on in loop"); + GST_DEBUG_OBJECT (submux, "Got the condition signal"); + g_mutex_unlock (cur_stream->queue_lock); + goto error; + } + + check_buffer = g_queue_peek_head (cur_stream->queue); + if (!strcmp ((const char*)GST_BUFFER_DATA (check_buffer), "eos")){ + cur_stream->eos_came = TRUE; + GST_DEBUG_OBJECT (submux, "Eos recieved for stream"); + } + for (k = 0; k < length; k++) { + check_stream = g_list_nth_data(submux->streams, k); + if (!check_stream->eos_came) { + eos = FALSE; + break; + } else { + eos = TRUE; + } + } + if (eos) { + GST_DEBUG_OBJECT (submux, "Sending EOS to submux srcpad"); + gst_pad_push_event(submux->srcpad, gst_event_new_eos ()); + g_mutex_unlock (cur_stream->queue_lock); + goto eos_sent; + } + + if (!cur_stream->eos_came && (submux->priv->parser_type == GST_SUB_PARSE_FORMAT_SAMI || + submux->priv->is_internal)) { + GstLangStruct *lang = NULL; + if (submux->priv->lang_list) { + if (submux->cur_buf_array[i] == NULL) { + check_buffer = g_queue_pop_head (cur_stream->queue); + lang = g_list_nth_data(submux->priv->lang_list, i); + if (!lang->active) { + if(check_buffer) { + gst_buffer_unref(check_buffer); + check_buffer = NULL; + GST_DEBUG_OBJECT (submux, "unreffing the non-active stream[%d] buffer", i); + } + submux->cur_buf_array[i] = NULL; + g_mutex_unlock (cur_stream->queue_lock); + GST_DEBUG_OBJECT(submux,"rejecting not selected language"); + continue; + } else { + if (!check_buffer) { + GST_WARNING_OBJECT (submux, "checkbuffer null.. repop"); + g_mutex_unlock (cur_stream->queue_lock); + goto re_pop; + } + if (!GST_BUFFER_DURATION(check_buffer)) { + GST_WARNING_OBJECT (submux, "duration of buffer is zero..re-pop"); + gst_buffer_unref (check_buffer); + g_mutex_unlock (cur_stream->queue_lock); + goto re_pop; + } + submux->cur_buf_array[i] = check_buffer; + GST_DEBUG_OBJECT (submux, "consuming active stream [%d] buffer : ts = %"GST_TIME_FORMAT"and dur = %"GST_TIME_FORMAT, + i, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (check_buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION (check_buffer))); + } + } + } else { + g_mutex_unlock (cur_stream->queue_lock); + GST_DEBUG_OBJECT(submux,"Coming to Else case lang submux->priv->lang_list %x ",submux->priv->lang_list); + continue; + } + } else if (!cur_stream->eos_came) { + /* External subtitle format other than smi */ + if (submux->sinkpad) { + if (submux->cur_buf_array[i] == NULL) { + check_buffer = g_queue_pop_head (cur_stream->queue); + if (!check_buffer) { + GST_WARNING_OBJECT (submux, "checkbuffer null.. repop"); + g_mutex_unlock (cur_stream->queue_lock); + goto re_pop; + } + if (!GST_BUFFER_DURATION (check_buffer)) { + GST_WARNING_OBJECT (submux, "duration of buffer is zero..re-pop"); + gst_buffer_unref (check_buffer); + g_mutex_unlock (cur_stream->queue_lock); + goto re_pop; + } + submux->cur_buf_array[i] = check_buffer; + GST_DEBUG_OBJECT (submux, "consuming active stream [%d] buffer : ts = %"GST_TIME_FORMAT"and dur = %"GST_TIME_FORMAT, + i, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP (check_buffer)), GST_TIME_ARGS(GST_BUFFER_DURATION (check_buffer))); + } + } else { + g_mutex_unlock (cur_stream->queue_lock); + GST_DEBUG_OBJECT(submux,"Coming to Else case submux->sinkpad %x ",submux->sinkpad); + continue; + } + } else { + GST_DEBUG_OBJECT (submux, "already received EOS on this stream[%d] and cur_buf_array[idx] = NULL", i); + submux->cur_buf_array[i] = NULL; + } + + g_mutex_unlock (cur_stream->queue_lock); + GST_DEBUG_OBJECT (submux, "After unlocking in loop and signal queue full"); + } + + push_list = gst_submux_muxing (submux); + if (push_list) { + guint idx = 0; + GST_LOG_OBJECT (submux, "length of push list = %d", g_list_length (push_list)); + + for (idx = 0; idx < g_list_length (push_list); idx++) { + push_buf = g_list_nth_data (push_list, idx); + + if (push_buf) { + GST_DEBUG_OBJECT (submux, "pushing buffer : ts = %"GST_TIME_FORMAT", " + "dur = %"GST_TIME_FORMAT" and data %s ...", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (push_buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (push_buf)), (gchar*)GST_BUFFER_DATA (push_buf)); + + fret = gst_pad_push (submux->srcpad, push_buf); + if (fret != GST_FLOW_OK) { + GST_ERROR_OBJECT (submux, "failed to push buffer. reason : %s", gst_flow_get_name (fret)); + /* clean any left buffers in push_list */ + idx++; + for (; idx < g_list_length (push_list); idx++) { + push_buf = g_list_nth_data (push_list, idx); + gst_buffer_unref (push_buf); + } + g_list_free (push_list); + goto error; + } + } + } + + g_list_free (push_list); + } + + GST_DEBUG_OBJECT (submux, "Exiting from lopp in last"); + + return; + +eos_sent: +error: + GST_WARNING_OBJECT (submux->srcpad, "Pausing the push task..."); + if (fret < GST_FLOW_UNEXPECTED) { + GST_ERROR_OBJECT (submux, "Crtical error in push loop...."); + GST_ELEMENT_ERROR (submux, CORE, PAD, ("failed to push. reason - %s", gst_flow_get_name (fret)), (NULL)); + } + gst_pad_pause_task (submux->srcpad); + GST_DEBUG_OBJECT (submux, "Exiting from lopp in last"); + return; +} + +//////////////////////////////////////////////////////// +// Plugin Utility Functions // +//////////////////////////////////////////////////////// +/* +** +** Description : De-Initializing the submux private structure +** Params : (1) submux instance +** return : TRUE +** Comments : +** +*/ +static gboolean +gst_submux_deinit_private_values(Gstsubmux *submux) +{ + guint idx = 0; + GST_DEBUG_OBJECT (submux, "deinit priv values"); + + submux->priv->first_buffer = FALSE; + submux->priv->parser_type = 0; + if (submux->priv->lang_list && !submux->priv->is_internal) { + g_list_free (submux->priv->lang_list); + submux->priv->lang_list = NULL; + } + for (idx = 0; idx < submux->priv->stream_count; idx++) { + submux->cur_buf_array[idx] = NULL; + } + if (submux->cur_buf_array) { + g_free (submux->cur_buf_array); + submux->cur_buf_array = NULL; + } + + submux->priv->is_internal = FALSE; + submux->priv->stream_count = 0; + + return TRUE; +} + +static gboolean +gst_submux_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "submux", GST_RANK_PRIMARY, GST_TYPE_SUBMUX); +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,GST_VERSION_MINOR,"submux","submux",gst_submux_plugin_init,"0.10.36","Proprietary","Samsung Electronics Co","http://www.samsung.com") diff --git a/submux/src/gstsubmux.h b/submux/src/gstsubmux.h new file mode 100755 index 0000000..696b8b6 --- /dev/null +++ b/submux/src/gstsubmux.h @@ -0,0 +1,171 @@ +/* + * N-Project + * Copyright (c) 2008 Samsung Electronics, Inc. + * All rights reserved. + * + * This software is a confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung Electronics. + */ + +/* + * This file defines the functions of Gstreamer plug-in for submux + * + * @file + * @author Deepak Singh (deep.singh@samsung.com) + * @version 1.0 + * @usage + * @brief This plug-in is targeted to be used for ARM MP4ASP decoding. + */ + +/*! Revision History: + *! --------------------------------------------------------------------------- + *! DATE | AUTHOR | COMMENTS + *! --------------------------------------------------------------------------- + *! 17-Jan-2014 deep.singh@samsung.com created + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +G_BEGIN_DECLS + +#define GST_TYPE_SUBMUX (gst_submux_get_type()) +#define GST_SUBMUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUBMUX,Gstsubmux)) +#define GST_SUBMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUBMUX,GstsubmuxClass)) +#define GST_SUBMUX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_SUBMUX,GstsubmuxClass)) +#define GST_IS_SUBMUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUBMUX)) +#define GST_IS_SUBMUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUBMUX)) +#define GST_SUBMUX_CAST(obj) ((Gstsubmux *)(obj)) +#define MAX_LANG 10 + +typedef struct _Gstsubmux Gstsubmux; +typedef struct _GstsubmuxClass GstsubmuxClass; +typedef struct _GstsubmuxPrivate GstsubmuxPrivate; +typedef struct _LanguageStruct GstLangStruct; +typedef struct _GstSubMuxStream GstSubmuxStream; +typedef struct _GstSubMuxPipe SubMuxPipe; + +typedef enum +{ + GST_SUB_PARSE_FORMAT_UNKNOWN = 0, + GST_SUB_PARSE_FORMAT_MDVDSUB = 1, + GST_SUB_PARSE_FORMAT_SUBRIP = 2, + GST_SUB_PARSE_FORMAT_MPSUB = 3, + GST_SUB_PARSE_FORMAT_SAMI = 4, + GST_SUB_PARSE_FORMAT_TMPLAYER = 5, + GST_SUB_PARSE_FORMAT_MPL2 = 6, + GST_SUB_PARSE_FORMAT_SUBVIEWER = 7, + GST_SUB_PARSE_FORMAT_DKS = 8, + GST_SUB_PARSE_FORMAT_QTTEXT = 9 +} GstSubMuxFormat; +typedef enum +{ + GST_SUB_PARSE_REGEX_UNKNOWN = 0, + GST_SUB_PARSE_REGEX_MDVDSUB = 1, + GST_SUB_PARSE_REGEX_SUBRIP = 2, + GST_SUB_PARSE_REGEX_DKS = 3, +} GstSubMuxRegex; +struct _GstSubMuxPipe +{ + GstElement *pipe; + GstElement *appsrc; + GstElement *appsink; + GstElement *parser; + GstPad *app_sinkpad; +}; +struct _GstSubMuxStream +{ + void *parent; + gboolean need_segment; + gboolean discont_came; + gboolean flushing; + SubMuxPipe pipe_struc; + gboolean eos_sent; + gboolean eos_came; + GstClockTime duration; + GstClockTime last_ts; /* last timestamp of subtitle present in subtitle file*/ + GstClockTime eos_ts; + GstClockTime seek_ts; + GstBuffer *buffer; + GQueue *queue; + GMutex *queue_lock; + GCond *queue_empty; + gboolean flush_done; +}; +struct _Gstsubmux +{ + GstElement element; + + /*< private >*/ + GstsubmuxPrivate *priv; + + /* pads */ + guint sinkpads_count; + gboolean external_sinkpad; + gboolean stop_loop; + GstPad *srcpad; + GList *sinkpad; + gboolean pipeline_made; + //GstPad *sinkpad; + GList *buffer_list; + gboolean init_done; + GList *msl_streams; + GList *streams; + gboolean flushing; + gboolean need_segment; + GstSubmuxStream muxed_stream; + gchar *encoding; + gchar *detected_encoding; + gint fps_n, fps_d; + GstSegment segment; + GstTask *loop_task; + GstSeekFlags segment_flags; + gboolean seek_came ; + gboolean finalize; + gboolean langlist_msg_posted; + GstBuffer **cur_buf_array; + gchar* external_filepath; +}; + +struct _GstsubmuxPrivate +{ + gboolean first_buffer; + GstSubMuxFormat parser_type; + GList *lang_list; + gboolean is_internal; + guint stream_count; +}; + + +struct _LanguageStruct +{ + gchar *language_code; + gchar *language_key; + gboolean active; +}; + +struct _GstsubmuxClass +{ + GstElementClass parent_class; +}; + +GType gst_submux_get_type (void); + +G_END_DECLS + + diff --git a/mobile/drmsrc/Makefile.am b/toggle/Makefile.am similarity index 100% rename from mobile/drmsrc/Makefile.am rename to toggle/Makefile.am diff --git a/wearable/toggle/src/Makefile.am b/toggle/src/Makefile.am similarity index 100% rename from wearable/toggle/src/Makefile.am rename to toggle/src/Makefile.am diff --git a/wearable/toggle/src/gsttoggle.c b/toggle/src/gsttoggle.c similarity index 100% rename from wearable/toggle/src/gsttoggle.c rename to toggle/src/gsttoggle.c diff --git a/wearable/toggle/src/gsttoggle.h b/toggle/src/gsttoggle.h similarity index 100% rename from wearable/toggle/src/gsttoggle.h rename to toggle/src/gsttoggle.h diff --git a/wearable/uninstall.sh b/uninstall.sh similarity index 100% rename from wearable/uninstall.sh rename to uninstall.sh diff --git a/wearable/LICENSE.LGPLv2.1 b/wearable/LICENSE.LGPLv2.1 deleted file mode 100644 index 8add30a..0000000 --- a/wearable/LICENSE.LGPLv2.1 +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library 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.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/wearable/avsystem/Makefile.am b/wearable/avsystem/Makefile.am deleted file mode 100644 index af437a6..0000000 --- a/wearable/avsystem/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = src diff --git a/wearable/avsystem/src/Makefile.am b/wearable/avsystem/src/Makefile.am deleted file mode 100644 index dd1576e..0000000 --- a/wearable/avsystem/src/Makefile.am +++ /dev/null @@ -1,60 +0,0 @@ - -# plugindir is set in configure - -plugin_LTLIBRARIES = libgstavsysaudiosrc.la - -# sources used to compile this plug-in -libgstavsysaudiosrc_la_SOURCES = gstavsyssrc.c \ - gstavsysaudiosrc.c - -libgstavsysaudiosrc_la_CFLAGS = $(GST_CFLAGS) \ - $(GST_BASE_CFLAGS) \ - $(AVSYSTEM_CFLAGS) \ - $(GST_VIDEO_FLAGS) \ - -I$(includedir)/mmf \ - $(MMTA_CFLAGS) \ - $(GST_AUDIO_CFLAGS) \ - $(VCONF_CFLAGS) \ - $(AVSYSAUDIO_CFLAGS) - -libgstavsysaudiosrc_la_LIBADD = $(GST_LIBS) \ - $(GST_BASE_LIBS) \ - $(DATACOMLIB_LIBS) \ - $(HTTPLIB_LIBS) \ - $(AVSYSTEM_LIBS) \ - $(GST_VIDEO_LIBS) \ - -lgstaudio-0.10 \ - $(MMTA_LIBS) \ - $(GST_AUDIO_LIBS) \ - -ldl \ - $(VCONF_LIBS) \ - $(AVSYSAUDIO_LIBS) - -libgstavsysaudiosrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -if IS_I386 -libgstavsysaudiosrc_la_CFLAGS += -DI386_SIMULATOR -else -endif - -plugin_LTLIBRARIES += libgstavsyssink.la - -## sources used to compile this plug-in -libgstavsyssink_la_SOURCES = gstavsyssink.c \ - gstavsysmemsink.c - -libgstavsyssink_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(AVSYSVIDEO_CFLAGS) $(AVSYSTEM_CFLAGS) -I$(includedir)/mmf -libgstavsyssink_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(DATACOMLIB_LIBS) $(HTTPLIB_LIBS) $(AVSYSVIDEO_LIBS) $(AVSYSTEM_LIBS) $(GST_VIDEO_LIBS) -lgstaudio-0.10 -ldl -libgstavsyssink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - - -libgstavsyssink_la_SOURCES += gstavsysaudiosink.c -libgstavsyssink_la_CFLAGS += $(AVSYSAUDIO_CFLAGS) -libgstavsyssink_la_LIBADD += $(AVSYSAUDIO_LIBS) - -if IS_I386 -libgstavsyssink_la_CFLAGS += -DI386_SIMULATOR -else -endif - - diff --git a/wearable/avsystem/src/gstavsysaudiosink.c b/wearable/avsystem/src/gstavsysaudiosink.c deleted file mode 100755 index 90c4921..0000000 --- a/wearable/avsystem/src/gstavsysaudiosink.c +++ /dev/null @@ -1,1196 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - - -#include -#include - -#include - -#include "gstavsysaudiosink.h" - -#define _ALSA_DAPM_ -#define __REPLACE_RESET_WITH_CLOSE_AND_REOPEN__ - -#define CONVERT_MUTE_VALUE(_mute) ((_mute) ? AVSYS_AUDIO_MUTE : AVSYS_AUDIO_UNMUTE) - -GST_DEBUG_CATEGORY_EXTERN (avsystem_sink_debug); -#define GST_CAT_DEFAULT avsystem_sink_debug - -#define DEFAULT_USER_ROUTE AVSYSAUDIOSINK_USERROUTE_AUTO -#define DEFAULT_AUDIO_ROUTE AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING -#define DEFAULT_VOLUME_TYPE AVSYS_AUDIO_VOLUME_TYPE_MEDIA -#define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE -#define DEFAULT_FADEUP_VOLUME FALSE -#define DEFAULT_AUDIO_MUTE AVSYSAUDIOSINK_AUDIO_UNMUTE -#define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSINK_LATENCY_MID -#define DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE FALSE -#define DEFAULT_AUDIO_OPEN_FORCEDLY FALSE - -//GST_DEBUG_CATEGORY_STATIC (gst_avsystemsink_debug); - -/* element factory information */ -static const GstElementDetails gst_avsysaudiosink_details = - GST_ELEMENT_DETAILS ("AV-system Audio OUT", - "Sink/Audio", - "Output to AV System", - "Samsung Electronics co., ltd"); - -static const avsys_audio_channel_pos_t gst_pos_to_avsys[GST_AUDIO_CHANNEL_POSITION_NUM] = { - [GST_AUDIO_CHANNEL_POSITION_FRONT_MONO] = AVSYS_AUDIO_CHANNEL_POSITION_MONO, - [GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT] = AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT, - [GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT] = AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, - [GST_AUDIO_CHANNEL_POSITION_REAR_CENTER] = AVSYS_AUDIO_CHANNEL_POSITION_REAR_CENTER, - [GST_AUDIO_CHANNEL_POSITION_REAR_LEFT] = AVSYS_AUDIO_CHANNEL_POSITION_REAR_LEFT, - [GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT] = AVSYS_AUDIO_CHANNEL_POSITION_REAR_RIGHT, - [GST_AUDIO_CHANNEL_POSITION_LFE] = AVSYS_AUDIO_CHANNEL_POSITION_LFE, - [GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER] = AVSYS_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - [GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, - [GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, - [GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT] = AVSYS_AUDIO_CHANNEL_POSITION_SIDE_LEFT, - [GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT] = AVSYS_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, - [GST_AUDIO_CHANNEL_POSITION_NONE] = AVSYS_AUDIO_CHANNEL_POSITION_INVALID -}; - -enum -{ - PROP_0, - PROP_AUDIO_MUTE, - PROP_AUDIO_VOLUME_TYPE, - PROP_AUDIO_PRIORITY, - PROP_AUDIO_FADEUPVOLUME, - PROP_AUDIO_ROUTE_POLICY, - PROP_AUDIO_USER_ROUTE, - PROP_AUDIO_LATENCY, - PROP_AUDIO_HANDLE, - PROP_AUDIO_CALLBACK, - PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE, - PROP_AUDIO_OPEN_FORCEDLY, -#ifdef USE_PA_AUDIO_FILTER - PROP_SPEED, - PROP_FILTER_ACTION, - PROP_FILTER_OUTPUT_MODE, - PROP_PRESET_MODE, - PROP_CUSTOM_EQ, - PROP_CUSTOM_EXT, -#endif -}; - -#ifdef USE_PA_AUDIO_FILTER -#define AUDIOVSP_DEFAULT_PLAYBACK_RATE 1.0 -#define AUDIOVSP_MIN_PLAYBACK_RATE 0.5 -#define AUDIOVSP_MAX_PLAYBACK_RATE 2.0 - -#define DEFAULT_FILTER_ACTION FILTER_NONE -#define DEFAULT_FILTER_OUTPUT_MODE OUTPUT_SPK -#define DEFAULT_PRESET_MODE PRESET_NORMAL - -enum FilterActionType -{ - FILTER_NONE, - FILTER_PRESET, - FILTER_ADVANCED_SETTING -}; - -enum OutputMode -{ - OUTPUT_SPK, - OUTPUT_EAR, - OUTPUT_OTHERS, - OUTPUT_NUM -}; - -enum PresetMode -{ - PRESET_NORMAL, - PRESET_POP, - PRESET_ROCK, - PRESET_DANCE, - PRESET_JAZZ, - PRESET_CLASSIC, - PRESET_VOCAL, - PRESET_BASS_BOOST, - PRESET_TREBLE_BOOST, - PRESET_MTHEATER, - PRESET_EXTERNALIZATION, - PRESET_CAFE, - PRESET_CONCERT_HALL, - PRESET_VOICE, - PRESET_MOVIE, - PRESET_VIRT51, - PRESET_HIPHOP, - PRESET_RNB, - PRESET_FLAT, - PRESET_TUBE, - - PRESET_NUM -}; -#endif - -GType -gst_avsysaudiosink_audio_mute_get_type (void) -{ - static GType avaudio_mute_type = 0; - static const GEnumValue avaudio_mute[] = { - {AVSYSAUDIOSINK_AUDIO_UNMUTE, "Unmute", "unmute"}, - {AVSYSAUDIOSINK_AUDIO_MUTE, "Mute immediately", "mute"}, - {AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, "Mute with fadedown effect", "fadedown"}, - {0, NULL, NULL}, - }; - - if (!avaudio_mute_type) { - avaudio_mute_type = - g_enum_register_static ("GstAvsysAudioSinkAudioMute", avaudio_mute); - } - return avaudio_mute_type; -} - -GType -gst_avsysaudiosink_user_route_get_type (void) -{ - static GType user_route_type = 0; - static const GEnumValue user_route[] = { - {AVSYSAUDIOSINK_USERROUTE_AUTO, "Route automatically", "auto"}, - {AVSYSAUDIOSINK_USERROUTE_PHONE, "Route to phone only", "phone"}, - {AVSYSAUDIOSINK_USERROUTE_ALL, "Route to all", "all"}, - {0, NULL, NULL}, - }; - - if (!user_route_type) { - user_route_type = - g_enum_register_static ("GstAvsysAudioSinkUserRoutePolicy",user_route); - } - return user_route_type; -} - -GType -gst_avsysaudiosink_audio_route_get_type (void) -{ - static GType playback_audio_route_type = 0; - static const GEnumValue playback_audio_route[] = { - {AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING, "Use external sound path", "external"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, "Auto change between speaker & earphone", "normal"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, "Play via both speaker & earphone", "alert"}, - {AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY, "Play via earphone only", "headset"}, - {0, NULL, NULL}, - }; - - if (!playback_audio_route_type) { - playback_audio_route_type = - g_enum_register_static ("GstAvsysAudioSinkAudioRoutePolicy", playback_audio_route); - } - return playback_audio_route_type; -} - -GType -gst_avsysaudiosink_latency_get_type (void) -{ - static GType avsysaudio_latency_type = 0; - static const GEnumValue avsysaudio_latency[] = { - {AVSYSAUDIOSINK_LATENCY_LOW, "Low latency", "low"}, - {AVSYSAUDIOSINK_LATENCY_MID, "Mid latency", "mid"}, - {AVSYSAUDIOSINK_LATENCY_HIGH, "High latency", "high"}, - {0, NULL, NULL}, - }; - - if (!avsysaudio_latency_type) { - avsysaudio_latency_type = - g_enum_register_static ("GstAvsysAudioSinkLatency", avsysaudio_latency); - } - return avsysaudio_latency_type; -} - -static void gst_avsysaudiosink_init_interfaces (GType type); - -//#define GST_BOILERPLATE_FULL(type, type_as_function, parent_type, parent_type_macro, additional_initializations) - -GST_BOILERPLATE_FULL (GstAvsysAudioSink, gst_avsysaudiosink, GstAudioSink, - GST_TYPE_AUDIO_SINK, gst_avsysaudiosink_init_interfaces); - - -static void gst_avsysaudiosink_finalise (GObject * object); -static void gst_avsysaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_avsysaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -#if 0 /*not use*/ -static GstCaps *gst_avsysaudiosink_getcaps (GstBaseSink * bsink); -#endif - -static gboolean gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio); -static gboolean gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio); - -static gboolean gst_avsysaudiosink_open (GstAudioSink * asink); -static gboolean gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec); -static gboolean gst_avsysaudiosink_unprepare (GstAudioSink * asink); -static gboolean gst_avsysaudiosink_close (GstAudioSink * asink); -static guint gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length); -static guint gst_avsysaudiosink_delay (GstAudioSink * asink); -static void gst_avsysaudiosink_reset (GstAudioSink * asink); -static gboolean avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode); - - -#define AVSYS_AUDIO_FACTORY_ENDIANNESS "LITTLE_ENDIAN" - - -static GstStaticPadTemplate avsysaudiosink_sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw-int, " - "endianness = (int) { " AVSYS_AUDIO_FACTORY_ENDIANNESS " }, " - "signed = (boolean) { TRUE }, " - "width = (int) 16, " - "depth = (int) 16, " - "rate = (int) 44100, " - "channels = (int) [ 1, 6 ]; " - "audio/x-raw-int, " - "signed = (boolean) { FALSE }, " - "width = (int) 8, " - "depth = (int) 8, " - "rate = (int) 44100, " - "channels = (int) [ 1, 6 ] " - ) - ); -/* -static inline guint _time_to_sample(GstAvsysAudioSink * asink, GstClockTime diff) -{ - guint result = 0; - result =(GST_TIME_AS_USECONDS(diff) * asink->audio_param.samplerate)/1000000; - return result; -} -*/ - -static void -gst_avsysaudiosink_finalise (GObject * object) -{ - GstAvsysAudioSink *sink = NULL; - sink = GST_AVSYS_AUDIO_SINK (object); - - GST_WARNING(">> Start(%d)", sink->audio_handle); - - GST_AVSYS_AUDIO_SINK_LOCK(sink); - gst_avsysaudiosink_avsys_close(sink); - GST_AVSYS_AUDIO_SINK_UNLOCK(sink); - g_mutex_free (sink->avsys_audio_lock); - g_mutex_free (sink->avsys_audio_delay_lock); - g_mutex_free (sink->avsys_audio_reset_lock); - - GST_WARNING("<< End(%d)", sink->audio_handle); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_avsysaudiosink_init_interfaces (GType type) -{ - /* None */ -} - -static void -gst_avsysaudiosink_base_init (gpointer g_class) -{ - GstElementClass *element_class = NULL; - - element_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_set_details (element_class, &gst_avsysaudiosink_details); - gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&avsysaudiosink_sink_factory)); -} - -static GstStateChangeReturn -gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition); - - -static void -gst_avsysaudiosink_class_init (GstAvsysAudioSinkClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - GstBaseAudioSinkClass *gstbaseaudiosink_class; - GstAudioSinkClass *gstaudiosink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass; - gstaudiosink_class = (GstAudioSinkClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_avsyssudiosink_change_state); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_finalise); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_get_property); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_set_property); - - // gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_getcaps); - - gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_open); - gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_prepare); - gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_unprepare); - gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_close); - gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_write); - gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_delay); - gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosink_reset); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_VOLUME_TYPE, - g_param_spec_int ("volumetype", "Avsystem Volume Type", - "Select avsystem audio software volume type", 0, G_MAXINT, - DEFAULT_VOLUME_TYPE, G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_PRIORITY, - g_param_spec_int ("priority", "Avsystem Sound Priority", "Avsystem sound priority", - AVSYS_AUDIO_PRIORITY_NORMAL, AVSYS_AUDIO_PRIORITY_MAX - 1, - AVSYS_AUDIO_PRIORITY_NORMAL, G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_HANDLE, - g_param_spec_pointer("audio-handle", "Avsystem handle", - "Avsystem audio handle", - G_PARAM_READWRITE)); - - g_object_class_install_property ( gobject_class, PROP_AUDIO_CALLBACK, - g_param_spec_pointer("audio-callback", "Avsystem callback", - "Avsystem audio callback", - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_AUDIO_FADEUPVOLUME, - g_param_spec_boolean ("fadeup", "Avsystem fadeup volume", - "Enable avsystem audio fadeup volume when pause to play", - DEFAULT_FADEUP_VOLUME, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_MUTE, - g_param_spec_enum("mute", "Avsystem mute", - "Avsystem audio mute", - GST_AVSYS_AUDIO_SINK_MUTE, DEFAULT_AUDIO_MUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_ROUTE_POLICY, - g_param_spec_enum("audio-route", "Audio Route Policy", - "Audio route policy of system", - GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE, DEFAULT_AUDIO_ROUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_USER_ROUTE, - g_param_spec_enum("user-route", "User Route Policy", - "User route policy", - GST_AVSYS_AUDIO_SINK_USER_ROUTE, DEFAULT_USER_ROUTE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY, - g_param_spec_enum("latency", "Audio Backend Latency", - "Audio backend latency", - GST_AVSYS_AUDIO_SINK_LATENCY_TYPE, DEFAULT_AUDIO_LATENCY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); - - g_object_class_install_property (gobject_class, PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE, - g_param_spec_boolean ("close-handle-on-prepare", "Close Handle on Prepare", - "Close Handle on Prepare", - DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_AUDIO_OPEN_FORCEDLY, - g_param_spec_boolean ("open-audio", "Open Audio", - "Open Audio dev", - DEFAULT_AUDIO_OPEN_FORCEDLY, G_PARAM_READWRITE)); - -#ifdef USE_PA_AUDIO_FILTER - g_object_class_install_property(gobject_class, PROP_SPEED, - g_param_spec_float("speed", "speed", "speed", - AUDIOVSP_MIN_PLAYBACK_RATE, - AUDIOVSP_MAX_PLAYBACK_RATE, - AUDIOVSP_DEFAULT_PLAYBACK_RATE, - G_PARAM_READWRITE)); - - g_object_class_install_property(gobject_class, PROP_FILTER_ACTION, - g_param_spec_uint("filter-action", "filter action", "(0)none (1)preset (2)advanced setting", - 0, 2, DEFAULT_FILTER_ACTION, G_PARAM_READWRITE)); - - g_object_class_install_property(gobject_class, PROP_FILTER_OUTPUT_MODE, - g_param_spec_uint("filter-output-mode", "filter output mode", "(0)Speaker (1)Ear (2)Others", - 0, 2, DEFAULT_FILTER_OUTPUT_MODE, G_PARAM_READWRITE)); - - g_object_class_install_property(gobject_class, PROP_PRESET_MODE, - g_param_spec_uint("preset-mode", "preset mode", "(0)normal (1)pop (2)rock (3)dance (4)jazz (5)classic (6)vocal (7)bass boost (8)treble boost (9)mtheater (10)externalization (11)cafe (12)concert hall (13)voice (14)movie (15)virt 5.1 (16)hip-hop (17)R&B (18)flat (19)tube", - 0, 19, DEFAULT_PRESET_MODE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_CUSTOM_EQ, - g_param_spec_pointer("custom-eq", "custom eq level array", - "pointer for array of EQ bands level", G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_CUSTOM_EXT, - g_param_spec_pointer("custom-ext", "custom ext level array", - "pointer for array of custom effect level", G_PARAM_READWRITE)); -#endif -} - -static void -gst_avsysaudiosink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSink *sink = NULL; - int nvalue = 0; - gboolean nbool = FALSE; -#ifdef USE_PA_AUDIO_FILTER - gshort *pointer; -#endif - - sink = GST_AVSYS_AUDIO_SINK (object); - - switch (prop_id) { - case PROP_AUDIO_VOLUME_TYPE: - nvalue = g_value_get_int(value); - sink->volume_type = nvalue; - if (sink->audio_handle != (avsys_handle_t)-1) { - avsys_audio_update_volume_config(sink->audio_handle, sink->volume_type); - } - break; - case PROP_AUDIO_PRIORITY: - nvalue = g_value_get_int(value); - sink->sound_priority = nvalue; - GST_INFO_OBJECT(sink, "Set audio priority(%d)", nvalue); - if (sink->audio_handle != (avsys_handle_t)-1) { - int error = AVSYS_STATE_ERR_UNKNOWN; - int handle_route = 0; - sink->audio_param.priority = sink->sound_priority; - error = avsys_audio_handle_update_priority(sink->audio_handle, nvalue, handle_route, AVSYS_AUDIO_SET_PRIORITY); - if (AVSYS_FAIL(error)) { - GST_ERROR_OBJECT(sink, "Failed to set audio priority(%d) to audio handle(%d)", nvalue, sink->audio_handle); - break; - } - } - break; - case PROP_AUDIO_MUTE: - nvalue = g_value_get_enum(value); - if (sink->audio_handle != (avsys_handle_t)-1) { - if (nvalue == AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT) { - if(AVSYS_SUCCESS(avsys_audio_set_mute_fadedown(sink->audio_handle))) - sink->mute = nvalue; - } else { - if(AVSYS_SUCCESS(avsys_audio_set_mute(sink->audio_handle, nvalue))) - sink->mute = nvalue; - } - } else { - sink->mute = nvalue; - } - break; - case PROP_AUDIO_FADEUPVOLUME: - nbool = g_value_get_boolean(value); - sink->use_fadeup_volume = nbool; - break; - case PROP_AUDIO_ROUTE_POLICY: - nvalue = g_value_get_enum(value); - sink->audio_route_policy = nvalue; - switch (sink->audio_route_policy) { - case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING: - GST_INFO_OBJECT(sink, "use external audio route setting"); - break; - default: - g_print("AVSYSAUDIOSINK :: Unknown audio route option %d\n", sink->audio_route_policy); - GST_ERROR_OBJECT(sink, "Unknown audio route option %d", sink->audio_route_policy); - break; - } - break; - case PROP_AUDIO_USER_ROUTE: - nvalue = g_value_get_enum(value); - sink->user_route_policy = nvalue; - break; - case PROP_AUDIO_LATENCY: - nvalue = g_value_get_enum(value); - sink->latency = nvalue; - break; - case PROP_AUDIO_HANDLE: - sink->cbHandle = g_value_get_pointer(value); - break; - case PROP_AUDIO_CALLBACK: - sink->audio_stream_cb = g_value_get_pointer(value); - break; - case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE: - nbool = g_value_get_boolean(value); - sink->close_handle_on_prepare = nbool; - break; - case PROP_AUDIO_OPEN_FORCEDLY: - nbool = g_value_get_boolean(value); - if (nbool) { - GST_AVSYS_AUDIO_SINK_LOCK(sink); - if (gst_avsysaudiosink_avsys_open(sink) == FALSE) { - GST_ERROR_OBJECT(sink, "gst_avsysaudiosink_avsys_open() failed"); - } - GST_AVSYS_AUDIO_SINK_UNLOCK (sink); - } - break; -#ifdef USE_PA_AUDIO_FILTER - case PROP_SPEED: - GST_INFO_OBJECT(sink, "request setting filter speed:%f (current:%f)", - g_value_get_float(value), sink->playback_rate); - sink->playback_rate = g_value_get_float(value); - if (sink->audio_handle != -1) { - avsys_audio_set_vsp_speed(sink->audio_handle, (guint)(sink->playback_rate * 1000)); - } - break; - case PROP_FILTER_ACTION: - sink->filter_action = g_value_get_uint(value); - if (sink->audio_handle != -1) { - avsys_audio_set_soundalive_filter_action(sink->audio_handle, sink->filter_action); - if (sink->filter_action == FILTER_ADVANCED_SETTING) { - avsys_audio_set_soundalive_eq(sink->audio_handle, sink->custom_eq); - avsys_audio_set_soundalive_ext(sink->audio_handle, sink->custom_ext); - } - } - break; - case PROP_FILTER_OUTPUT_MODE: - GST_INFO_OBJECT(sink, "request setting filter_output_mode:%d (current:%d)", - g_value_get_uint(value), sink->filter_output_mode); - sink->filter_output_mode = g_value_get_uint(value); - if (sink->audio_handle != -1) - avsys_audio_set_soundalive_device(sink->audio_handle, sink->filter_output_mode); - break; - case PROP_PRESET_MODE: - sink->preset_mode = g_value_get_uint(value); - if (sink->audio_handle != -1) - avsys_audio_set_soundalive_preset_mode(sink->audio_handle, sink->preset_mode); - break; - case PROP_CUSTOM_EQ: - pointer = g_value_get_pointer(value); - if (pointer) { - gint *custom_eq = (gint *)pointer; - GST_INFO_OBJECT(sink, "request setting custom_eq:%d,%d,%d,%d,%d,%d,%d (current:%d,%d,%d,%d,%d,%d,%d)", - custom_eq[0], custom_eq[1], custom_eq[2], custom_eq[3], custom_eq[4], custom_eq[5], custom_eq[6], - sink->custom_eq[0], sink->custom_eq[1], sink->custom_eq[2], sink->custom_eq[3], - sink->custom_eq[4], sink->custom_eq[5], sink->custom_eq[6]); - memcpy(sink->custom_eq, pointer, sizeof(gint) * CUSTOM_EQ_BAND_MAX); - if ((sink->audio_handle != -1) && (sink->filter_action == FILTER_ADVANCED_SETTING)) { - avsys_audio_set_soundalive_eq(sink->audio_handle, sink->custom_eq); - } - } - break; - case PROP_CUSTOM_EXT: - pointer = g_value_get_pointer(value); - if (pointer) { - gint *custom_ext = (gint *)pointer; - GST_INFO_OBJECT(sink, "request setting custom_ext:%d,%d,%d,%d,%d (current:%d,%d,%d,%d,%d)", - custom_ext[CUSTOM_EXT_3D_LEVEL], custom_ext[CUSTOM_EXT_BASS_LEVEL], - custom_ext[CUSTOM_EXT_CONCERT_HALL_LEVEL], custom_ext[CUSTOM_EXT_CONCERT_HALL_VOLUME], - custom_ext[CUSTOM_EXT_CLARITY_LEVEL], - sink->custom_ext[CUSTOM_EXT_3D_LEVEL], sink->custom_ext[CUSTOM_EXT_BASS_LEVEL], - sink->custom_ext[CUSTOM_EXT_CONCERT_HALL_LEVEL], sink->custom_ext[CUSTOM_EXT_CONCERT_HALL_VOLUME], - sink->custom_ext[CUSTOM_EXT_CLARITY_LEVEL]); - memcpy(sink->custom_ext, pointer, sizeof(gint) * CUSTOM_EXT_PARAM_MAX); - if ((sink->audio_handle != -1) && (sink->filter_action == FILTER_ADVANCED_SETTING)) { - avsys_audio_set_soundalive_ext(sink->audio_handle, sink->custom_ext); - } - } - break; -#endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosink_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSink *sink = NULL; - - sink = GST_AVSYS_AUDIO_SINK (object); - - switch (prop_id) { - case PROP_AUDIO_VOLUME_TYPE: - g_value_set_int(value, sink->volume_type); - break; - case PROP_AUDIO_PRIORITY: - g_value_set_int(value, sink->sound_priority); - break; - case PROP_AUDIO_MUTE: - g_value_set_enum(value, sink->mute); - break; - case PROP_AUDIO_FADEUPVOLUME: - g_value_set_boolean(value, sink->use_fadeup_volume); - break; - case PROP_AUDIO_ROUTE_POLICY: - g_value_set_enum(value, sink->audio_route_policy); - break; - case PROP_AUDIO_USER_ROUTE: - g_value_set_enum(value, sink->user_route_policy); - break; - case PROP_AUDIO_LATENCY: - g_value_set_enum(value, sink->latency); - break; - case PROP_AUDIO_HANDLE: - g_value_set_pointer(value, sink->cbHandle); - break; - case PROP_AUDIO_CALLBACK: - g_value_set_pointer(value, sink->audio_stream_cb); - break; - case PROP_AUDIO_CLOSE_HANDLE_ON_PREPARE: - g_value_set_boolean(value, sink->close_handle_on_prepare); - break; - case PROP_AUDIO_OPEN_FORCEDLY: - break; -#ifdef USE_PA_AUDIO_FILTER - case PROP_SPEED: - g_value_set_float(value, sink->playback_rate); - break; - case PROP_FILTER_ACTION: - g_value_set_uint(value, sink->filter_action); - break; - case PROP_FILTER_OUTPUT_MODE: - g_value_set_uint(value, sink->filter_output_mode); - break; - case PROP_PRESET_MODE: - g_value_set_uint(value, sink->preset_mode); - break; - case PROP_CUSTOM_EQ: - g_value_set_pointer(value, sink->custom_eq); - break; - case PROP_CUSTOM_EXT: - g_value_set_pointer(value, sink->custom_ext); - break; -#endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosink_init (GstAvsysAudioSink * avsysaudiosink, GstAvsysAudioSinkClass * g_class) -{ - GST_DEBUG_OBJECT (avsysaudiosink, "initializing avsysaudiosink"); - - avsysaudiosink->audio_handle = (avsys_handle_t)-1; - avsysaudiosink->cached_caps = NULL; - avsysaudiosink->avsys_audio_lock = g_mutex_new (); - avsysaudiosink->avsys_audio_delay_lock = g_mutex_new (); - avsysaudiosink->avsys_audio_reset_lock = g_mutex_new (); - avsysaudiosink->volume_type = DEFAULT_VOLUME_TYPE; - avsysaudiosink->sound_priority = AVSYS_AUDIO_PRIORITY_NORMAL; - avsysaudiosink->mute = DEFAULT_AUDIO_MUTE; - avsysaudiosink->use_fadeup_volume = DEFAULT_FADEUP_VOLUME; - avsysaudiosink->latency = DEFAULT_AUDIO_LATENCY; - avsysaudiosink->audio_route_policy = DEFAULT_AUDIO_ROUTE; - avsysaudiosink->bytes_per_sample = 1; - avsysaudiosink->close_handle_on_prepare = DEFAULT_AUDIO_CLOSE_HANDLE_ON_PREPARE; - avsysaudiosink->first_write = FALSE; -#if defined (LPCM_DUMP_SUPPORT) - avsysaudiosink->dumpFp = NULL; -#endif - avsysaudiosink->audio_param.format = AVSYS_AUDIO_FORMAT_UNKNOWN; -#ifdef USE_PA_AUDIO_FILTER - avsysaudiosink->filter_action = DEFAULT_FILTER_ACTION; - avsysaudiosink->filter_output_mode = DEFAULT_FILTER_OUTPUT_MODE; - avsysaudiosink->preset_mode = DEFAULT_PRESET_MODE; - memset(avsysaudiosink->custom_eq, 0x00, sizeof(gint) * CUSTOM_EQ_BAND_MAX); - memset(avsysaudiosink->custom_ext, 0x00, sizeof(gint) * CUSTOM_EXT_PARAM_MAX); - avsysaudiosink->playback_rate = AUDIOVSP_DEFAULT_PLAYBACK_RATE; -#endif -} -#if 0 -static GstCaps * -gst_avsysaudiosink_getcaps (GstBaseSink * bsink) -{ - GstElementClass *element_class = NULL; - GstPadTemplate *pad_template = NULL; - GstAvsysAudioSink *sink = GST_AVSYS_AUDIO_SINK (bsink); - GstCaps *caps; - -// debug_fenter(); - - sink = GST_AVSYS_AUDIO_SINK (bsink); - if (sink->audio_handle == -1) - { - GST_DEBUG_OBJECT (sink, "avsystem audio not open, using template caps"); - return NULL; /* base class will get template caps for us */ - } - - if (sink->cached_caps) - { - GST_LOG_OBJECT (sink, "Returning cached caps"); - return gst_caps_ref (sink->cached_caps); - } - - element_class = GST_ELEMENT_GET_CLASS (sink); - pad_template = gst_element_class_get_pad_template (element_class, "sink"); - g_return_val_if_fail (pad_template != NULL, NULL); - - // todo : get supported format. - //caps = gst_avsysaudio_probe_supported_formats (GST_OBJECT (sink), sink->, - //gst_pad_template_get_caps (pad_template)); - - //if (caps) { - //sink->cached_caps = gst_caps_ref (caps); - //} - - GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps); - - return caps; -} -#endif - -static avsys_audio_channel_pos_t * -gst_avsysaudiosink_gst_to_channel_map (avsys_audio_channel_pos_t * map, - const GstRingBufferSpec * spec) -{ - int i; - GstAudioChannelPosition *pos; - - for (i = 0; i < AVSYS_CHANNEL_MAX; i++) { - map[i] = AVSYS_AUDIO_CHANNEL_POSITION_INVALID; - } - - if (!(pos = gst_audio_get_channel_positions (gst_caps_get_structure (spec->caps, 0)))) { - return NULL; - } - - for (i = 0; i < spec->channels; i++) { - if (pos[i] == GST_AUDIO_CHANNEL_POSITION_NONE) { - g_free (pos); - return NULL; - } else if (pos[i] < GST_AUDIO_CHANNEL_POSITION_NUM) { - map[i] = gst_pos_to_avsys[pos[i]]; - } else { - map[i] = AVSYS_AUDIO_CHANNEL_POSITION_INVALID; - } - } - - g_free (pos); - - return map; -} - -static gboolean -avsysaudiosink_parse_spec (GstAvsysAudioSink * avsys_audio, GstRingBufferSpec * spec) -{ - /* Check param */ - if (spec->type != GST_BUFTYPE_LINEAR || - spec->channels > 6 || spec->channels < 1 || - !(spec->format == GST_S8 || spec->format == GST_S16_LE) ) - return FALSE; - - switch (spec->format) { - case GST_S8: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT; - avsys_audio->bytes_per_sample = 1; - break; - case GST_S16_LE: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT; - avsys_audio->bytes_per_sample = 2; - break; - default: - return FALSE; - } - - /// set audio parameter for avsys audio open - switch (avsys_audio->latency) { - case AVSYSAUDIOSINK_LATENCY_LOW: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_VIDEO; - break; - case AVSYSAUDIOSINK_LATENCY_MID: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT; - break; - case AVSYSAUDIOSINK_LATENCY_HIGH: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT_CLOCK; - break; - } - - avsys_audio->audio_param.priority = 0; - avsys_audio->audio_param.samplerate = spec->rate; - avsys_audio->audio_param.channels = spec->channels; - avsys_audio->bytes_per_sample *= spec->channels; - gst_avsysaudiosink_gst_to_channel_map (avsys_audio->audio_param.map, spec); - - /* set software volume table type */ - avsys_audio->audio_param.vol_type = avsys_audio->volume_type; - avsys_audio->audio_param.priority = avsys_audio->sound_priority; - avsys_audio->audio_param.handle_route = avsys_audio->user_route_policy; - - return TRUE; -} - -static gboolean -gst_avsysaudiosink_open (GstAudioSink * asink) -{ - return TRUE; -} - -static gboolean -gst_avsysaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec) -{ - guint p_time = 0, b_time = 0; - gboolean ret = FALSE; - gboolean close_on_exit = FALSE; - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - - GST_WARNING(">> Start(%d)", avsys_audio->audio_handle); - - GST_AVSYS_AUDIO_SINK_LOCK(avsys_audio); - - // set avsys audio param - if (!avsysaudiosink_parse_spec (avsys_audio, spec)) { - GST_ELEMENT_ERROR (avsys_audio, RESOURCE, SETTINGS, (NULL), - ("Setting of swparams failed: " )); - goto exit; - } - - /* Open Handle */ - if (gst_avsysaudiosink_avsys_open(avsys_audio) == FALSE) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_open() failed"); - goto OPEN_FAILED; - } - - /* Ring buffer size */ - if (AVSYS_STATE_SUCCESS == - avsys_audio_get_period_buffer_time(avsys_audio->audio_handle, &p_time, &b_time)) { - if(p_time == 0 || b_time == 0) { - GST_WARNING_OBJECT(avsys_audio, ""); - close_on_exit = TRUE; - goto exit; - } - spec->latency_time = (guint64)p_time; - spec->buffer_time = (guint64)b_time; - } else { - GST_WARNING_OBJECT(avsys_audio, ""); - close_on_exit = TRUE; - goto exit; - } - spec->segsize = avsys_audio->avsys_size; /* '/16' see avsys_audio_open */ - spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0); - //spec->segtotal+2; - GST_WARNING ("latency time %u, buffer time %u, seg total %u\n", - (unsigned int)(spec->latency_time/1000), (unsigned int)(spec->buffer_time/1000), spec->segtotal); - - /* Close if needed */ - close_on_exit = avsys_audio->close_handle_on_prepare; - - ret = TRUE; - -exit: - if (close_on_exit) { - if (gst_avsysaudiosink_avsys_close(avsys_audio) == FALSE) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed"); - } - } - - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - GST_WARNING("<< End(%d), ret=%d", avsys_audio->audio_handle, ret); - return ret; - -OPEN_FAILED: - avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ); - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - GST_WARNING("<< End(%d), ret=%d", avsys_audio->audio_handle, ret); - return ret; -} - -static gboolean -gst_avsysaudiosink_unprepare (GstAudioSink * asink) -{ - gboolean ret = TRUE; - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - - GST_WARNING(">> Start(%d)", avsys_audio->audio_handle); - GST_AVSYS_AUDIO_SINK_LOCK(avsys_audio); - if(!gst_avsysaudiosink_avsys_close(avsys_audio)) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed"); - ret = FALSE; - } - GST_AVSYS_AUDIO_SINK_UNLOCK(avsys_audio); - GST_WARNING("<< End(%d), ret=%d", avsys_audio->audio_handle, ret); - - return ret; -} - -static gboolean -gst_avsysaudiosink_close (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - gst_caps_replace (&avsys_audio->cached_caps, NULL); - - return TRUE; -} - - -/* - * Underrun and suspend recovery - */ - -static guint -gst_avsysaudiosink_write (GstAudioSink * asink, gpointer data, guint length) -{ - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - gint write_len = 0; - guint ret = 0; - - GST_AVSYS_AUDIO_SINK_LOCK (asink); - - if (avsys_audio->audio_stream_cb == NULL) { -#if defined (LPCM_DUMP_SUPPORT) - fwrite(data, 1, write_len, avsys_audio->dumpFp); //This is for original data (no volume convert) -#endif - write_len = avsys_audio_write(avsys_audio->audio_handle, data, length); - if(write_len == length) { - ret = write_len; - } else { - if(AVSYS_FAIL(write_len)) { - GST_ERROR_OBJECT(avsys_audio, "avsys_audio_write() failed with %d\n", write_len); - } - ret = length; /* skip one period */ - } - } else { - if(!avsys_audio->audio_stream_cb(data, length, avsys_audio->cbHandle)) { - GST_ERROR_OBJECT(avsys_audio,"auido stream callback failed\n"); - } - ret = length; - } - - if (avsys_audio->first_write) { - GST_WARNING("First write (%d/%d)", ret, length); - avsys_audio->first_write = FALSE; - } - - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - return ret; - -} - -static guint -gst_avsysaudiosink_delay (GstAudioSink * asink) -{ - GstAvsysAudioSink *avsys_audio = NULL; - int delay = 0; - guint retValue = 0; - - avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - GST_AVSYS_AUDIO_SINK_DELAY_LOCK (asink); - if ((int)avsys_audio->audio_handle != -1) { - if (AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) { - retValue = delay; - } - } - GST_AVSYS_AUDIO_SINK_DELAY_UNLOCK (asink); - return retValue; -} - -static void -gst_avsysaudiosink_reset (GstAudioSink * asink) -{ - int avsys_result = AVSYS_STATE_SUCCESS; - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (asink); - - GST_WARNING(">> Start(%d)", avsys_audio->audio_handle); - GST_AVSYS_AUDIO_SINK_LOCK (asink); - -#if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__) - if(!gst_avsysaudiosink_avsys_close(avsys_audio)) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_close() failed"); - } -#else - if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle)) { - GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: "); - } -#endif - - GST_AVSYS_AUDIO_SINK_UNLOCK (asink); - GST_WARNING("<< End(%d)", avsys_audio->audio_handle); - - return; -} - - -static gboolean -gst_avsysaudiosink_avsys_open(GstAvsysAudioSink *avsys_audio) -{ - gboolean ret = TRUE; - int avsys_result; - int available = FALSE; - - if (avsys_audio->audio_handle == (avsys_handle_t)-1) { - GST_LOG_OBJECT (avsys_audio, "avsys_audio_open() with user policy [%d] ", avsys_audio->user_route_policy); - - /* workaround for PA audio filter */ - if (avsys_audio->latency == AVSYSAUDIOSINK_LATENCY_HIGH) { - avsys_audio_is_available_high_latency(&available); - if (available == FALSE) { - avsys_audio->latency = AVSYSAUDIOSINK_LATENCY_MID; - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_OUTPUT; - } - } - - avsys_result = avsys_audio_open(&avsys_audio->audio_param, &avsys_audio->audio_handle, &avsys_audio->avsys_size); - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_ERROR_OBJECT(avsys_audio, "avsys_audio_open() failed with 0x%x", avsys_result); - avsysaudiosink_post_message(avsys_audio, GST_RESOURCE_ERROR_OPEN_READ); - ret = FALSE; - } else { - GST_WARNING("avsys_audio_open() success [%d]", avsys_audio->audio_handle); - avsys_audio->first_write = TRUE; - -#ifdef USE_PA_AUDIO_FILTER - avsys_audio_set_vsp_speed(avsys_audio->audio_handle, (guint)(avsys_audio->playback_rate * 1000)); -#endif - - // check audio handle was already muted. - if(avsys_audio->mute == TRUE) { - if(AVSYS_SUCCESS(avsys_audio_set_mute(avsys_audio->audio_handle, AVSYS_AUDIO_MUTE))) - GST_DEBUG("avsys_audio_set_mute() success. mute handle open success.\n"); - else - GST_DEBUG("avsys_audio_set mute() fail.\n"); - } - } - } else { - GST_WARNING("audio handle has already opened"); - ret = FALSE; - } -#if defined (LPCM_DUMP_SUPPORT) - if (avsys_audio->dumpFp == NULL) { - avsys_audio->dumpFp = fopen("/root/dump.lpcm","w"); - } -#endif - return ret; -} - -static gboolean -gst_avsysaudiosink_avsys_close(GstAvsysAudioSink *avsys_audio) -{ - gboolean ret = TRUE; - int avsys_result = AVSYS_STATE_SUCCESS; - - if (avsys_audio->audio_handle != (avsys_handle_t)-1 ) { - avsys_result = avsys_audio_close(avsys_audio->audio_handle); - if (AVSYS_FAIL(avsys_result)) { - GST_ERROR_OBJECT(avsys_audio, "avsys_audio_close() failed with 0x%x", avsys_result); - ret = FALSE; - } else { - GST_WARNING("avsys_audio_close(%d) success", avsys_audio->audio_handle); - avsys_audio->audio_handle = (avsys_handle_t) -1; - } - } else { - GST_INFO("audio handle has already closed"); - } - -#if defined (LPCM_DUMP_SUPPORT) - if(avsys_audio->dumpFp != NULL) - { - fclose(avsys_audio->dumpFp); - avsys_audio->dumpFp = NULL; - } -#endif - return ret; -} - -static GstStateChangeReturn -gst_avsyssudiosink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstAvsysAudioSink *avsys_audio = GST_AVSYS_AUDIO_SINK (element); - - int avsys_result = AVSYS_STATE_SUCCESS; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: -#if defined(_ALSA_DAPM_) - switch(avsys_audio->audio_route_policy) { - case AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING: - GST_INFO_OBJECT(avsys_audio, "audio route uses external setting"); - break; - default: - GST_ERROR_OBJECT(avsys_audio, "Unknown audio route option %d\n", avsys_audio->audio_route_policy); - break; - } -#endif - GST_AVSYS_AUDIO_SINK_LOCK (avsys_audio); -#if defined(__REPLACE_RESET_WITH_CLOSE_AND_REOPEN__) - if (avsys_audio->audio_handle == (avsys_handle_t)-1 && - avsys_audio->audio_param.format != AVSYS_AUDIO_FORMAT_UNKNOWN) { - if (gst_avsysaudiosink_avsys_open(avsys_audio) == FALSE) { - GST_ERROR_OBJECT(avsys_audio, "gst_avsysaudiosink_avsys_open() failed"); - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - return GST_STATE_CHANGE_FAILURE; - } - } -#endif - if (avsys_audio->use_fadeup_volume) { - GST_INFO_OBJECT(avsys_audio, "Set fadeup volume"); - avsys_audio_set_volume_fadeup(avsys_audio->audio_handle); - } - GST_AVSYS_AUDIO_SINK_UNLOCK (avsys_audio); - -#if 0 - if(AVSYS_STATE_SUCCESS != avsys_audio_set_mute(avsys_audio->audio_handle, CONVERT_MUTE_VALUE(avsys_audio->mute))) - { - GST_ERROR_OBJECT(avsys_audio, "Set mute failed %d", CONVERT_MUTE_VALUE(avsys_audio->mute)); - } -#endif - break; - default: - break; - } - ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) { - return ret; - } - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - return ret; -} - - -static gboolean -avsysaudiosink_post_message(GstAvsysAudioSink* self,int errorcode) -{ - GST_DEBUG("avsysaudiosink_post_message\n"); - gboolean ret = TRUE; - GstMessage *Msg = NULL; - GQuark domain; - gboolean status = FALSE; - GError *error = NULL; - gint error_code; - /* - if(errorcode>0) - error_code = errorcode; - else - error_code = GST_STREAM_ERROR_TYPE_NOT_FOUND; */ - error_code = errorcode; - domain = gst_resource_error_quark(); - error = g_error_new (domain, error_code, "AVSYSAUDIOSINK_RESOURCE_ERROR"); - Msg = gst_message_new_error(GST_ELEMENT(self), error, "AVSYSAUDIOSINK_ERROR"); - status = gst_element_post_message (GST_ELEMENT(self), Msg); - if (status == FALSE) - { - GST_ERROR("Error in posting message on the bus ...\n"); - ret = FALSE; - } - - return ret; -} diff --git a/wearable/avsystem/src/gstavsysaudiosink.h b/wearable/avsystem/src/gstavsysaudiosink.h deleted file mode 100644 index cc77557..0000000 --- a/wearable/avsystem/src/gstavsysaudiosink.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef __GST_AVSYSAUDIOSINK_H__ -#define __GST_AVSYSAUDIOSINK_H__ - -#include -#include -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_AUDIO_SINK (gst_avsysaudiosink_get_type()) -#define GST_AVSYS_AUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_AUDIO_SINK,GstAvsysAudioSink)) -#define GST_AVSYS_AUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_AUDIO_SINK,GstAvsysAudioSinkClass)) -#define GST_IS_AVSYS_AUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_AUDIO_SINK)) -#define GST_IS_AVSYS_AUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_AUDIO_SINK)) -//#define GST_AVSYS_AUDIO_SINK_CAST(obj) ((GstAvsysAudioSink *) (obj)) - -typedef struct _GstAvsysAudioSink GstAvsysAudioSink; -typedef struct _GstAvsysAudioSinkClass GstAvsysAudioSinkClass; - -#define GST_AVSYS_AUDIO_SINK_GET_LOCK(obj) (GST_AVSYS_AUDIO_SINK (obj)->avsys_audio_lock) -#define GST_AVSYS_AUDIO_SINK_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SINK_GET_LOCK(obj))) -#define GST_AVSYS_AUDIO_SINK_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SINK_GET_LOCK(obj))) - -#define GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj) (GST_AVSYS_AUDIO_SINK (obj)->avsys_audio_reset_lock) -#define GST_AVSYS_AUDIO_SINK_RESET_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj))) -#define GST_AVSYS_AUDIO_SINK_RESET_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SINK_GET_RESET_LOCK(obj))) - -#define GST_AVSYS_AUDIO_SINK_GET_DELAY_LOCK(obj) (GST_AVSYS_AUDIO_SINK (obj)->avsys_audio_delay_lock) -#define GST_AVSYS_AUDIO_SINK_DELAY_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SINK_GET_DELAY_LOCK(obj))) -#define GST_AVSYS_AUDIO_SINK_DELAY_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SINK_GET_DELAY_LOCK(obj))) - -typedef enum { - AVSYSAUDIOSINK_AUDIO_UNMUTE = 0, - AVSYSAUDIOSINK_AUDIO_MUTE, - AVSYSAUDIOSINK_AUDIO_MUTE_WITH_FADEDOWN_EFFECT, -}GstAvsysAudioSinkAudioMute; - - -typedef enum { - AVSYSAUDIOSINK_AUDIOROUTE_USE_EXTERNAL_SETTING = -1, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_NORMAL, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_ALERT, - AVSYSAUDIOSINK_AUDIOROUTE_PLAYBACK_HEADSET_ONLY -}GstAvsysAudioSinkAudioRoutePolicy; - - -typedef enum { - AVSYSAUDIOSINK_USERROUTE_AUTO = 0, - AVSYSAUDIOSINK_USERROUTE_PHONE, - AVSYSAUDIOSINK_USERROUTE_ALL -}GstAvsysAudioSinkUserRoutePolicy; - -typedef enum { - AVSYSAUDIOSINK_LATENCY_LOW = 0, - AVSYSAUDIOSINK_LATENCY_MID, - AVSYSAUDIOSINK_LATENCY_HIGH, -}GstAvsysAudioSinkLatency; - -#define GST_AVSYS_AUDIO_SINK_USER_ROUTE (gst_avsysaudiosink_user_route_get_type ()) -#define GST_AVSYS_AUDIO_SINK_AUDIO_ROUTE (gst_avsysaudiosink_audio_route_get_type ()) -#define GST_AVSYS_AUDIO_SINK_MUTE (gst_avsysaudiosink_audio_mute_get_type()) -#define GST_AVSYS_AUDIO_SINK_LATENCY_TYPE (gst_avsysaudiosink_latency_get_type ()) - -//this define if for debugging -//#define LPCM_DUMP_SUPPORT -#define USE_PA_AUDIO_FILTER -#ifdef USE_PA_AUDIO_FILTER -#define CUSTOM_EQ_BAND_MAX 9 -enum { - CUSTOM_EXT_3D_LEVEL, - CUSTOM_EXT_BASS_LEVEL, - CUSTOM_EXT_CONCERT_HALL_VOLUME, - CUSTOM_EXT_CONCERT_HALL_LEVEL, - CUSTOM_EXT_CLARITY_LEVEL, - CUSTOM_EXT_PARAM_MAX -}; -#endif -struct _GstAvsysAudioSink { - GstAudioSink sink; - - avsys_handle_t audio_handle; - avsys_audio_param_t audio_param; - gint avsys_size; - gint mute; - gint use_fadeup_volume; - gint close_handle_on_prepare; - gint audio_route_policy; - gint user_route_policy; - gint latency; - - GstCaps *cached_caps; - - GMutex *avsys_audio_lock; - GMutex *avsys_audio_reset_lock; - GMutex *avsys_audio_delay_lock; - gint volume_type; - gint sound_priority; - gint bytes_per_sample; - - gboolean first_write; - - gpointer cbHandle; - gboolean (*audio_stream_cb) (void *stream, int stream_size, void *user_param); - -#ifdef USE_PA_AUDIO_FILTER - guint filter_action; - guint filter_output_mode; - guint preset_mode; - gint custom_eq[CUSTOM_EQ_BAND_MAX]; - gint custom_ext[CUSTOM_EXT_PARAM_MAX]; - guint custom_eq_band_num; - gint custom_eq_band_freq[CUSTOM_EQ_BAND_MAX]; - gint custom_eq_band_width[CUSTOM_EQ_BAND_MAX]; - float playback_rate; -#endif -}; - - -struct _GstAvsysAudioSinkClass { - GstAudioSinkClass parent_class; -}; - -GType gst_avsysaudiosink_get_type (void); -GType gst_avsysaudiosink_audio_route_get_type (void); -GType gst_avsysaudiosink_audio_mute_get_type(void); -GType gst_avsysaudiosink_latency_get_type (void); - -G_END_DECLS - -#endif /* __GST_AVSYSAUDIOSINK_H__ */ diff --git a/wearable/avsystem/src/gstavsysaudiosrc.c b/wearable/avsystem/src/gstavsysaudiosrc.c deleted file mode 100644 index 3a4fdc0..0000000 --- a/wearable/avsystem/src/gstavsysaudiosrc.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include - -#include -#include -//#include - -#include /*gettimeofday*/ -#include - -#include "gstavsysaudiosrc.h" - -/** - * Define for Release - * - * _ENABLE_FAKE_READ: enable fake read instead of avsys_audio_read(). (default: 0) - */ -#define _ENABLE_FAKE_READ 0 -//#define USE_GPT8 - - -#define _MIN_RATE 8000 -#define _MAX_RATE 48000 -#define _MIN_CHANNEL 1 -#define _MAX_CHANNEL 2 - - -#define DEFAULT_GPT8_FREQ 26 - -#if _ENABLE_FAKE_READ -static long g_delay_time; -#endif - -#define DEFAULT_MEDIACALL_MODE AVSYS_AUDIO_ECHO_MODE_NONE -#define DEFAULT_AUDIO_LATENCY AVSYSAUDIOSRC_LATENCY_MID - -GST_DEBUG_CATEGORY_EXTERN (avsystem_src_debug); -#define GST_CAT_DEFAULT avsystem_src_debug - -/* elementfactory information */ -static const GstElementDetails gst_avsysaudiosrc_details = - GST_ELEMENT_DETAILS ("AV system source", - "Source/Audio", - "Read from a AV system audio in", - "Samsung Electronics co., ltd."); - - -enum { - PROP_0, -#if 0 -#if !defined(I386_SIMULATOR) - PROP_AUDIO_MEDIA_CALL, -#endif -#endif - PROP_AUDIO_LATENCY, -}; - -enum { - CAPTURE_UNCORK = 0, - CAPTURE_CORK, -}; - -GType -gst_avsysaudiosrc_audio_latency_get_type (void) -{ - static GType capture_audio_latency_type = 0; - static const GEnumValue capture_audio_latency[] = { - {AVSYSAUDIOSRC_LATENCY_LOW, "Set capture latency as low", "low"}, - {AVSYSAUDIOSRC_LATENCY_MID, "Set capture latency as mid", "mid"}, - {AVSYSAUDIOSRC_LATENCY_HIGH, "Set capture latency as high", "high"}, - {0, NULL, NULL}, - }; - - if (!capture_audio_latency_type) { - capture_audio_latency_type = - g_enum_register_static ("GstAvsysAudioSrcAudioLatency", capture_audio_latency); - } - return capture_audio_latency_type; -} - - -GST_BOILERPLATE (GstAvsysAudioSrc, gst_avsysaudiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC); - -#if _ENABLE_FAKE_READ -static unsigned long fake_delay (unsigned long usec); -#endif - -static guint gst_avsysaudiosrc_delay (GstAudioSrc *asrc); - -static void gst_avsysaudiosrc_finalize (GObject * object); -static void gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); - -static GstCaps* gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc); - -static gboolean gst_avsysaudiosrc_open (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec); -static gboolean gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_close (GstAudioSrc * asrc); -static guint gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length); -static void gst_avsysaudiosrc_reset (GstAudioSrc * asrc); -static gboolean gst_avsysaudiosrc_avsys_close (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork); -static gboolean gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *src); -static gboolean gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *src); -#if defined(_USE_CAPS_) -static GstCaps *gst_avsysaudiosrc_detect_rates (GstObject * obj, avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_detect_channels (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_detect_formats (GstObject * obj,avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps); -static GstCaps *gst_avsysaudiosrc_probe_supported_formats (GstObject * obj, avsys_handle_t handle, const GstCaps * template_caps); -#endif -static GstStateChangeReturn gst_avsys_src_change_state (GstElement * element, GstStateChange transition) ; - - - -/* AvsysAudioSrc signals and args */ -enum { - LAST_SIGNAL -}; - -# define AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS "LITTLE_ENDIAN" - -static GstStaticPadTemplate avsysaudiosrc_src_factory = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ( - "audio/x-raw-int, " - "endianness = (int) { " AVSYS_AUDIO_SRC_FACTORY_ENDIANNESS " }, " - "signed = (boolean) { TRUE }, " - "width = (int) 16, " - "depth = (int) 16, " - "rate = (int) [ 8000, 48000 ], " - "channels = (int) [ 1, 2 ]; " - "audio/x-raw-int, " - "signed = (boolean) { FALSE }, " - "width = (int) 8, " - "depth = (int) 8, " - "rate = (int) [ 8000, 48000 ], " - "channels = (int) [ 1, 2 ]") - ); - -static inline guint _time_to_sample(GstAvsysAudioSrc *avsyssrc, GstClockTime diff) -{ - guint result = 0; - // sample rate : asrc->audio_param.samplerate - result =(GST_TIME_AS_USECONDS(diff) * avsyssrc->audio_param.samplerate)/1000000; - return result; -} - - -static void -gst_avsysaudiosrc_finalize (GObject * object) -{ - GstAvsysAudioSrc *src = NULL; - - - src = GST_AVSYS_AUDIO_SRC (object); - g_mutex_free (src->avsysaudio_lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_avsysaudiosrc_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (element_class, &gst_avsysaudiosrc_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&avsysaudiosrc_src_factory)); -} - -static void -gst_avsysaudiosrc_class_init (GstAvsysAudioSrcClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; - GstBaseAudioSrcClass *gstbaseaudiosrc_class; - GstAudioSrcClass *gstaudiosrc_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; - gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass; - gstaudiosrc_class = (GstAudioSrcClass *) klass; - - gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_avsys_src_change_state); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_finalize); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_get_property); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_set_property); -#if defined(_USE_CAPS_) - gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_getcaps); -#endif - gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_open); - gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_prepare); - gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_unprepare); - gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_close); - gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_read); - gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_delay); - gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_avsysaudiosrc_reset); - - g_object_class_install_property (gobject_class ,PROP_AUDIO_LATENCY, - g_param_spec_enum("latency", "Audio Latency", - "Audio latency", - GST_AVSYS_AUDIO_SRC_LATENCY, DEFAULT_AUDIO_LATENCY, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS )); -} - - - -/** - *@note useful range 0 - 1000000 microsecond - */ -#if _ENABLE_FAKE_READ -static unsigned long -fake_delay (unsigned long usec) -{ - struct timeval s_time; - struct timeval c_time; - long s_sec = 0L; - long s_usec = 0L; - long c_sec = 0L; - long c_usec = 0L; - long t_sec = 0L; - long t_usec = 0L; - unsigned long total_usec = 0UL; - unsigned long t = 0UL; - - if (usec == 0UL) { - usleep (0); - return 0; - } - - /*get start time*/ - if (gettimeofday ((struct timeval *)&s_time, NULL) == 0) { - s_sec = s_time.tv_sec; - s_usec = s_time.tv_usec; - } else { - return 0; - } - - for (;;) { - /*get current time*/ - if (gettimeofday ((struct timeval *)&c_time, NULL) == 0) { - c_sec = c_time.tv_sec; - c_usec = c_time.tv_usec; - } else { - return 0; - } - - /*get elasped sec*/ - t_sec = c_sec - s_sec; - - /*get elapsed usec*/ - if ((s_usec) > (c_usec)) { - t_usec = 1000000L - (s_usec) + (c_usec); - t_sec--; - } else { - t_usec = (c_usec) - (s_usec); - } - - /*get total elapsed time*/ - total_usec = (t_sec * 1000000UL) + t_usec; - - t = usec - total_usec; - - if (total_usec >= usec) { - break; - } else { - if (t > 10000UL) { - /*this function does not work in precision*/ - usleep (1); - } - } - } - - return total_usec; -} -#endif - -static guint -gst_avsysaudiosrc_delay (GstAudioSrc *asrc) -{ - GstAvsysAudioSrc *avsys_audio = NULL; - int delay; - guint retValue = 0; - - avsys_audio = GST_AVSYS_AUDIO_SRC (asrc); - if(AVSYS_STATE_SUCCESS == avsys_audio_delay(avsys_audio->audio_handle, &delay)) - retValue = delay; - - return retValue; -} - - - -static void -gst_avsysaudiosrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSrc *src = NULL; -// gint getvalue = 0; - src = GST_AVSYS_AUDIO_SRC (object); - - if (src->cached_caps == NULL) - { - switch (prop_id) - { - case PROP_AUDIO_LATENCY: - src->latency = g_value_get_enum(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } -} - -static void -gst_avsysaudiosrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstAvsysAudioSrc *src; - - src = GST_AVSYS_AUDIO_SRC (object); - - switch (prop_id) - { - case PROP_AUDIO_LATENCY: - g_value_set_enum(value, src->latency); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_avsysaudiosrc_init (GstAvsysAudioSrc * avsysaudiosrc, GstAvsysAudioSrcClass * g_class) -{ - GST_DEBUG_OBJECT (avsysaudiosrc, "initializing"); - - avsysaudiosrc->cached_caps = NULL; - avsysaudiosrc->audio_handle = (avsys_handle_t)-1; - avsysaudiosrc->buffer_size = 0; - avsysaudiosrc->avsysaudio_lock = g_mutex_new (); - avsysaudiosrc->latency = DEFAULT_AUDIO_LATENCY; -} - -#if defined(_USE_CAPS_) -static GstCaps * -gst_avsysaudiosrc_getcaps (GstBaseSrc * bsrc) -{ - GstElementClass *element_class; - GstPadTemplate *pad_template; - GstAvsysAudioSrc *src; - GstCaps *caps = NULL; - - src = GST_AVSYS_AUDIO_SRC (bsrc); - - if(src->audio_handle==(avsys_handle_t)-1){ - GST_DEBUG_OBJECT(src,"device not open, using template caps"); - return NULL; - } - - if (src->cached_caps) - { - GST_LOG_OBJECT (src, "Returning cached caps"); - return gst_caps_ref(src->cached_caps); - } - element_class = GST_ELEMENT_GET_CLASS (src); - pad_template = gst_element_class_get_pad_template (element_class, "src"); - g_return_val_if_fail (pad_template != NULL, NULL); - - caps = gst_avsysaudiosrc_probe_supported_formats (GST_OBJECT (src), src->audio_handle, - gst_pad_template_get_caps (pad_template)); - - if (caps) { - src->cached_caps = gst_caps_ref (caps); - } - - GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps); - - return caps; -} -#endif -static gboolean -gst_avsysaudiosrc_open (GstAudioSrc * asrc) -{ - return TRUE; -} - -static gboolean -avsysaudiosrc_parse_spec (GstAvsysAudioSrc *avsys_audio, GstRingBufferSpec * spec) -{ - /* Check param */ - if (spec->type != GST_BUFTYPE_LINEAR || - spec->channels > 2 || spec->channels < 1 || - !(spec->format == GST_S8 || spec->format == GST_S16_LE) ) - return FALSE; - - switch(spec->format) - { - case GST_S8: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_8BIT; - avsys_audio->bytes_per_sample = 1; - break; - case GST_S16_LE: - avsys_audio->audio_param.format = AVSYS_AUDIO_FORMAT_16BIT; - avsys_audio->bytes_per_sample = 2; - break; - default: - GST_DEBUG_OBJECT(avsys_audio, "Only support S8, S16LE format"); - return FALSE; - } - - // set audio parameter for avsys audio open - - switch(avsys_audio->latency) - { - case AVSYSAUDIOSRC_LATENCY_LOW: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY; - break; - case AVSYSAUDIOSRC_LATENCY_MID: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT; - break; - case AVSYSAUDIOSRC_LATENCY_HIGH: - avsys_audio->audio_param.mode = AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY; - break; - default: - break; - } - - avsys_audio->audio_param.priority = 0; - avsys_audio->audio_param.samplerate = spec->rate; - avsys_audio->audio_param.channels = spec->channels; - - if(spec->channels == 2) - avsys_audio->bytes_per_sample *= 2; - else if(spec->channels > 2) - { - GST_ERROR_OBJECT(avsys_audio,"Unsupported channel number %d", spec->channels); - return FALSE; - } - - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - guint p_time = 0, b_time = 0; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - if (!avsysaudiosrc_parse_spec(avsysaudiosrc, spec)) - { - GST_ERROR("avsysaudiosrc_parse_spec failed"); - return FALSE; - } - - /*open avsys audio*/ - if (!gst_avsysaudiosrc_avsys_open (avsysaudiosrc)) - { - GST_ERROR("gst_avsysaudiosrc_avsys_open failed"); - return FALSE; - } - - /* Ring buffer size */ - if (AVSYS_STATE_SUCCESS == - avsys_audio_get_period_buffer_time(avsysaudiosrc->audio_handle, &p_time, &b_time)) - { - if(p_time == 0 || b_time == 0) - return FALSE; - - spec->latency_time = (guint64)p_time; - spec->buffer_time = (guint64)b_time; - } - else - { - return FALSE; - } - spec->segsize = avsysaudiosrc->buffer_size; - spec->segtotal = (b_time / p_time) + (((b_time % p_time)/p_time > 0.5) ? 1: 0); - spec->segtotal += 2; - - GST_INFO_OBJECT(avsysaudiosrc, "audio buffer spec : latency_time(%llu), buffer_time(%llu), segtotal(%d), segsize(%d)\n", - spec->latency_time, spec->buffer_time, spec->segtotal, spec->segsize); - - - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_unprepare (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - gboolean ret = TRUE; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - /*close*/ - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - - if(!gst_avsysaudiosrc_avsys_close(avsysaudiosrc)) - { - GST_ERROR_OBJECT(avsysaudiosrc, "gst_avsysaudiosrc_avsys_close failed"); - ret = FALSE; - } - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - - - - return ret; -} - -static gboolean -gst_avsysaudiosrc_close (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - gst_caps_replace (&avsysaudiosrc->cached_caps, NULL); - - return TRUE; -} - -static void -gst_avsysaudiosrc_reset (GstAudioSrc * asrc) -{ - GstAvsysAudioSrc *avsys_audio = NULL; - - avsys_audio = GST_AVSYS_AUDIO_SRC (asrc); - GST_AVSYS_AUDIO_SRC_LOCK (asrc); - - if(AVSYS_STATE_SUCCESS != avsys_audio_reset(avsys_audio->audio_handle)) - { - GST_ERROR_OBJECT (avsys_audio, "avsys-reset: internal error: "); - } - - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - - return; -} - - -static GstStateChangeReturn -gst_avsys_src_change_state (GstElement * element, GstStateChange transition) -{ - GstAvsysAudioSrc *avsys = NULL; - GstStateChangeReturn ret ; - - avsys = GST_AVSYS_AUDIO_SRC (element); - GST_DEBUG("gst_avsys_src_change_state"); - - switch (transition) - { - case GST_STATE_CHANGE_NULL_TO_READY: - { - GST_DEBUG ("GST_STATE_CHANGE_NULL_TO_READY\n") ; - break ; - } - case GST_STATE_CHANGE_READY_TO_PAUSED: - { - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_PAUSED\n") ; - break ; - } - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - { - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_PLAYING\n") ; - /* Capture Start */ - if (!gst_avsysaudiosrc_avsys_start (avsys)) { - GST_ERROR("gst_avsysaudiosrc_avsys_start failed"); - } - break ; - } - default: - break ; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - GST_DEBUG ("After parent_class->change_state...\n") ; - switch (transition) - { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - { - GST_DEBUG ("GST_STATE_CHANGE_PLAYING_TO_PAUSED\n") ; - /* Capture Stop */ - if (!gst_avsysaudiosrc_avsys_stop (avsys)) { - GST_ERROR("gst_avsysaudiosrc_avsys_stop failed"); - } - break ; - } - case GST_STATE_CHANGE_PAUSED_TO_READY: - { - GST_DEBUG ("GST_STATE_CHANGE_PAUSED_TO_READY\n") ; - break ; - } - case GST_STATE_CHANGE_READY_TO_NULL: - { - GST_DEBUG ("GST_STATE_CHANGE_READY_TO_NULL\n") ; - break ; - } - default: - break ; - } - - return ret; -} - - - -static guint -gst_avsysaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length) -{ - GstAvsysAudioSrc *avsysaudiosrc = NULL; - gint readed = 0; - gpointer ptr = NULL; - guint used_length = 0; - - avsysaudiosrc = GST_AVSYS_AUDIO_SRC (asrc); - - ptr = data; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); -#if _ENABLE_FAKE_READ - readed = avsysaudiosrc->buffer_size; - memset (ptr, 10, avsysaudiosrc->buffer_size); /*maybe can't hear*/ - fake_delay (1000000UL / g_delay_time); -#else - ptr = data; - readed = avsys_audio_read (avsysaudiosrc->audio_handle, ptr, length); - if (readed < 0) - goto _READ_ERROR; -#endif //_ENABLE_FAKE_READ - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return readed; - -_READ_ERROR: - { - GST_AVSYS_AUDIO_SRC_UNLOCK (asrc); - return length; /* skip one period */ - } -} - -static gboolean -gst_avsysaudiosrc_avsys_cork (GstAvsysAudioSrc *avsysaudiosrc, int cork) -{ - int avsys_result = avsys_audio_cork (avsysaudiosrc->audio_handle, cork); - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_cork() error. [0x%x]\n", avsys_result); - return FALSE; - } - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_avsys_start (GstAvsysAudioSrc *avsysaudiosrc) -{ - gboolean result; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_UNCORK); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return result; -} - -static gboolean -gst_avsysaudiosrc_avsys_stop (GstAvsysAudioSrc *avsysaudiosrc) -{ - gboolean result; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - result = gst_avsysaudiosrc_avsys_cork(avsysaudiosrc, CAPTURE_CORK); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - - return result; -} - -static gboolean -gst_avsysaudiosrc_avsys_open (GstAvsysAudioSrc *avsysaudiosrc) -{ - int avsys_result = 0; - - GST_AVSYS_AUDIO_SRC_LOCK (avsysaudiosrc); - - avsys_result = avsys_audio_open(&avsysaudiosrc->audio_param, &avsysaudiosrc->audio_handle, &avsysaudiosrc->buffer_size); - - if (avsys_result != AVSYS_STATE_SUCCESS) { - GST_ERROR_OBJECT(avsysaudiosrc, "avsys_audio_open() error. [0x%x]\n", avsys_result); - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - return FALSE; - } - -#if _ENABLE_FAKE_READ - g_delay_time = (unsigned long)((avsysaudiosrc->samplerate * (avsysaudiosrc->format / 8) * avsysaudiosrc->channels) / avsysaudiosrc->buffer_size); -#endif - - GST_AVSYS_AUDIO_SRC_UNLOCK (avsysaudiosrc); - return TRUE; -} - -static gboolean -gst_avsysaudiosrc_avsys_close(GstAvsysAudioSrc *src) -{ - int ret; - - if (src->audio_handle != (avsys_handle_t)-1) - { - /*close avsys audio*/ - ret = avsys_audio_close (src->audio_handle); - if (AVSYS_FAIL(ret)) - { - GST_ERROR_OBJECT(src, "avsys_audio_close() error 0x%x", ret); - return FALSE; - } - src->audio_handle = (avsys_handle_t)-1; - GST_DEBUG_OBJECT(src, "AVsys audio handle closed"); - } - else - { - GST_WARNING_OBJECT(src,"avsys audio handle has already closed"); - } - - return TRUE; -} -#if defined(_USE_CAPS_) -static GstCaps * -gst_avsysaudiosrc_detect_rates(GstObject *obj, - avsys_pcm_hw_params_t *hw_params, GstCaps *in_caps) -{ - GstCaps *caps; - guint min, max; - gint err, dir, min_rate, max_rate, i; - - GST_LOG_OBJECT(obj, "probing sample rates ..."); - - if ((err = avsys_pcm_hw_params_get_rate_min(hw_params, &min, &dir)) < 0) - goto min_rate_err; - - if ((err = avsys_pcm_hw_params_get_rate_max(hw_params, &max, &dir)) < 0) - goto max_rate_err; - - min_rate = min; - max_rate = max; - - if (min_rate < _MIN_RATE) - min_rate = _MIN_RATE; /* random 'sensible minimum' */ - - if (max_rate <= 0) - max_rate = _MAX_RATE; /* or maybe just use 192400 or so? */ - else if (max_rate > 0 && max_rate < _MIN_RATE) - max_rate = MAX (_MIN_RATE, min_rate); - - GST_DEBUG_OBJECT(obj, "Min. rate = %u (%d)", min_rate, min); - GST_DEBUG_OBJECT(obj, "Max. rate = %u (%d)", max_rate, max); - - caps = gst_caps_make_writable(in_caps); - - for (i = 0; i < gst_caps_get_size(caps); ++i) - { - GstStructure *s; - - s = gst_caps_get_structure(caps, i); - if (min_rate == max_rate) - { - gst_structure_set(s, "rate", G_TYPE_INT, min_rate, NULL); - } - else - { - gst_structure_set(s, "rate", GST_TYPE_INT_RANGE, min_rate, - max_rate, NULL); - } - } - - return caps; - /* ERRORS */ - min_rate_err: - { - GST_ERROR_OBJECT(obj, "failed to query minimum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } - max_rate_err: - { - GST_ERROR_OBJECT(obj, "failed to query maximum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } -} - - -static GstCaps * -gst_avsysaudiosrc_detect_formats(GstObject * obj, - avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps) -{ - avsys_pcm_format_mask_t *mask; - GstStructure *s; - GstCaps *caps; - gint i; - - avsys_pcm_format_mask_malloc(&mask); - avsys_pcm_hw_params_get_format_mask(hw_params, mask); - - caps = gst_caps_new_empty(); - - for (i = 0; i < gst_caps_get_size(in_caps); ++i) - { - GstStructure *scopy; - //gint w; - gint width = 0, depth = 0; - gint sndformat; - - s = gst_caps_get_structure(in_caps, i); - if (!gst_structure_has_name(s, "audio/x-raw-int")) - { - GST_WARNING_OBJECT(obj, "skipping non-int format"); - continue; - } - if (!gst_structure_get_int(s, "width", &width) - || !gst_structure_get_int(s, "depth", &depth)) - continue; - - GST_DEBUG_OBJECT(obj, "width = %d height = %d", width, depth); - if (width == 8) - sndformat = 0;//SND_PCM_FORMAT_S8 - else - //width==16 - sndformat = 2; //SND_PCM_FORMAT_S16_LE - if (avsys_pcm_format_mask_test(mask, sndformat)) - { //must be implemented - /* template contains { true, false } or just one, leave it as it is */ - scopy = gst_structure_copy(s); - - } - else - { - scopy = NULL; - } - if (scopy) - { - /* TODO: proper endianness detection, for now it's CPU endianness only */ - gst_structure_set(scopy, "signed", G_TYPE_BOOLEAN, TRUE, NULL); - gst_structure_set(scopy, "endianness", G_TYPE_INT, G_BYTE_ORDER, - NULL); - gst_caps_append_structure(caps, scopy); - } - - } - - avsys_pcm_format_mask_free(mask); - gst_caps_unref(in_caps); - return caps; -} - - -static GstCaps * -gst_avsysaudiosrc_detect_channels(GstObject * obj, - avsys_pcm_hw_params_t * hw_params, GstCaps * in_caps) -{ - GstCaps *caps; - guint min, max; - gint err, min_channel, max_channel, i; -// gint dir; - - GST_LOG_OBJECT(obj, "probing sample rates ..."); - - if ((err = avsys_pcm_hw_params_get_channels_min(hw_params, &min)) < 0) - goto min_chan_err; - - if ((err = avsys_pcm_hw_params_get_channels_max(hw_params, &max)) < 0) - goto max_chan_err; - - min_channel = min; - max_channel = max; - - if (min_channel < _MIN_CHANNEL) - min_channel = _MIN_CHANNEL; /* random 'sensible minimum' */ - - if (max_channel <= 0) - max_channel = _MAX_CHANNEL; /* or maybe just use 192400 or so? */ - else if (max_channel > 0 && max_channel < _MIN_CHANNEL) - max_channel = MAX (_MAX_CHANNEL, min_channel); - - GST_DEBUG_OBJECT(obj, "Min. channel = %u (%d)", min_channel, min); - GST_DEBUG_OBJECT(obj, "Max. channel = %u (%d)", max_channel, max); - - caps = gst_caps_make_writable(in_caps); - - for (i = 0; i < gst_caps_get_size(caps); ++i) - { - GstStructure *s; - - s = gst_caps_get_structure(caps, i); - if (min_channel == max_channel) - { - gst_structure_set(s, "channels", G_TYPE_INT, _MIN_CHANNEL, NULL); - } - else - { - gst_structure_set(s, "channels", GST_TYPE_INT_RANGE, min_channel, - max_channel, NULL); - } - } - - return caps; - - /* ERRORS */ - min_chan_err: - { - GST_ERROR_OBJECT(obj, "failed to query minimum sample rate"); - gst_caps_unref(in_caps); - return NULL; - } - max_chan_err: - { - GST_ERROR_OBJECT(obj, "failed to query maximum sample rate:"); - gst_caps_unref(in_caps); - return NULL; - } -} - -/* - * gst_avsys_probe_supported_formats: - * - * Takes the template caps and returns the subset which is actually - * supported by this device. - * - */ - -static GstCaps * -gst_avsysaudiosrc_probe_supported_formats(GstObject * obj, - avsys_handle_t handle, const GstCaps * template_caps) -{ - - avsys_pcm_hw_params_t *hw_params; - GstCaps *caps; - gint err; - - avsys_pcm_hw_params_malloc(&hw_params); - if ((err = avsys_pcm_hw_params_any(handle, hw_params)) < 0) - goto error; - - caps = gst_caps_copy(template_caps); - - if (!(caps = gst_avsysaudiosrc_detect_formats(obj, hw_params, caps))) - goto subroutine_error; - - if (!(caps = gst_avsysaudiosrc_detect_rates(obj, hw_params, caps))) - goto subroutine_error; - - if (!(caps = gst_avsysaudiosrc_detect_channels(obj, hw_params, caps))) - goto subroutine_error; - - avsys_pcm_hw_params_free(hw_params); - return caps; - - /* ERRORS */ - error: - { - GST_ERROR_OBJECT(obj, "failed to query formats"); - return NULL; - } - subroutine_error: - { - GST_ERROR_OBJECT(obj, "failed to query formats"); - return NULL; - } -} -#endif diff --git a/wearable/avsystem/src/gstavsysaudiosrc.h b/wearable/avsystem/src/gstavsysaudiosrc.h deleted file mode 100644 index 4031e04..0000000 --- a/wearable/avsystem/src/gstavsysaudiosrc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_AVSYS_AUDIO_SRC_H__ -#define __GST_AVSYS_AUDIO_SRC_H__ - -//#undef _MMCAMCORDER_MERGE_TEMP - -#include -#include - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_AUDIO_SRC (gst_avsysaudiosrc_get_type()) -#define GST_AVSYS_AUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_AUDIO_SRC,GstAvsysAudioSrc)) -#define GST_AVSYS_AUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_AUDIO_SRC,GstAvsysAudioSrcClass)) -#define GST_IS_AVSYS_AUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_AUDIO_SRC)) -#define GST_IS_AVSYS_AUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_AUDIO_SRC)) -#define GST_AVSYS_AUDIO_SRC_CAST(obj) ((GstAvsysAudioSrc *)(obj)) - -#define GST_AVSYS_AUDIO_SRC_GET_LOCK(obj) (GST_AVSYS_AUDIO_SRC_CAST (obj)->avsysaudio_lock) -#define GST_AVSYS_AUDIO_SRC_LOCK(obj) (g_mutex_lock (GST_AVSYS_AUDIO_SRC_GET_LOCK (obj))) -#define GST_AVSYS_AUDIO_SRC_UNLOCK(obj) (g_mutex_unlock (GST_AVSYS_AUDIO_SRC_GET_LOCK (obj))) - -typedef struct _GstAvsysAudioSrc GstAvsysAudioSrc; -typedef struct _GstAvsysAudioSrcClass GstAvsysAudioSrcClass; - -typedef enum { - AVSYSAUDIOSRC_LATENCY_LOW = 0, - AVSYSAUDIOSRC_LATENCY_MID, - AVSYSAUDIOSRC_LATENCY_HIGH, -}GstAvsysAudioSrcAudioLatency; - -#define GST_AVSYS_AUDIO_SRC_LATENCY (gst_avsysaudiosrc_audio_latency_get_type()) - - - -/** - * GstAvsysAudioSrc: - * - * Opaque data structure - */ -struct _GstAvsysAudioSrc { - GstAudioSrc src; - - avsys_handle_t audio_handle; - avsys_audio_param_t audio_param; - - gint buffer_size; - GstCaps *cached_caps; - GMutex *avsysaudio_lock; - - gint media_call; - gint bytes_per_sample; - gint latency; - -}; - -struct _GstAvsysAudioSrcClass { - GstAudioSrcClass parent_class; -}; - - -GType gst_avsysaudiosrc_get_type (void); -GType gst_avsysaudiosrc_audio_latency_get_type(void); - -G_END_DECLS - -#endif /* __GST_AVSYS_AUDIO_SRC_H__ */ diff --git a/wearable/avsystem/src/gstavsysmemsink.c b/wearable/avsystem/src/gstavsysmemsink.c deleted file mode 100644 index 718afb4..0000000 --- a/wearable/avsystem/src/gstavsysmemsink.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#if defined(_MM_PROJECT_FLOATER) || defined(_MM_PROJECT_PROTECTOR) || defined(_MM_PROJECT_VOLANS) -#define VERSION "0.10.19" // sec -#define PACKAGE "gstreamer" -#elif defined(_MM_PROJECT_ADORA) -#define VERSION "0.10.9" // mavell -#define PACKAGE "gstreamer" -#else -#include -#endif - -#include -#include - -#include "gstavsysmemsink.h" - -#define debug_enter g_print -#define debug_leave g_print -#define debug_fenter() g_print("enter: %s\n",__FUNCTION__) -#define debug_fleave() g_print("leave: %s\n",__FUNCTION__) -#define debug_msg g_print -#define debug_verbose g_print -#define debug_warning g_print -#define debug_error g_print - -#define GST_CAT_DEFAULT avsysmemsink_debug - -#define DISABLE_YUV_FORMAT_ON_SINK_CAPS - -GST_DEBUG_CATEGORY_STATIC (avsysmemsink_debug); - -enum -{ - SIGNAL_VIDEO_STREAM, - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ROTATE, -}; - -static GstStaticPadTemplate sink_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ( -#ifndef DISABLE_YUV_FORMAT_ON_SINK_CAPS - "video/x-raw-yuv, " - "format = (fourcc){YV12}, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " - "video/x-raw-yuv, " - "format = (fourcc){I420}, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " - "video/x-raw-rgb, " - "bpp = (int)32, " - "depth = (int)24; " -#else /* BGRA */ - "video/x-raw-rgb, " - "bpp = (int)32, " - "endianness = (int)4321, " - "red_mask = (int)65280, " - "green_mask = (int)16711680, " - "blue_mask = (int)-16777216, " - "alpha_mask = (int)255, " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ], " - "framerate = (fraction) [ 0, MAX ]; " -#endif - ) - ); - -static GstElementDetails AvsysMemSink_details = { - "AV-system Stream callback", - "Sink/Video", - "Stream sink for AV-System GStreamer Plug-in", - "" -}; - -static guint gst_avsysmemsink_signals[LAST_SIGNAL] = { 0 }; - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#else /* !G_ENABLE_DEBUG */ -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -#define GET_PIXEL(buf, x, y, stride) (*((unsigned char*)(buf) + (x) + (y)*(stride))) - -#define GET_RED(Y,U,V) ((9535 * (Y - 16) + 13074 * (V - 128)) >> 13) -#define GET_GREEN(Y,U,V) ((9535 * (Y - 16) - 6660 * (V - 128) - 3203 * (U - 128)) >> 13 ) -#define GET_BLUE(Y,U,V) ((9535 * (Y - 16) + 16531 * (U - 128)) >> 13 ) - -#define UCLIP(a) (((a)<0)?0:((a)>255)?255:(a)) - - -static void -yuv420toargb(unsigned char *src, unsigned char *dst, int width, int height) -{ - int h,w; - int y=0,u=0,v=0; - int a=0,r=0,g=0,b=0; - - unsigned char* pixel; - - int index=0; - - unsigned char *pY; - unsigned char *pU; - unsigned char *pV; - - GST_DEBUG ("converting yuv420 to argb"); - - pY = src ; - pU = src + (width * height) ; - pV = src + (width * height) + (width * height /4) ; - - a = 255; - - for(h = 0 ; h < height; h++) - { - for(w = 0 ; w < width; w++) - { - y = GET_PIXEL(pY,w,h,width); - u = GET_PIXEL(pU,w/2,h/2,width/2); - v = GET_PIXEL(pV,w/2,h/2,width/2); - - r = GET_RED(y,u,v); - g = GET_GREEN(y,u,v); - b = GET_BLUE(y,u,v); - - r = UCLIP(r); - g = UCLIP(g); - b = UCLIP(b); - - index = (w + (h* width)) * 4; - dst[index] = r; - dst[index+1] = g; - dst[index+2] = b; - dst[index+3] = a; - } - } -} - -static void -rotate_pure(unsigned char *src, unsigned char *dst, int width,int height,int angle,int bpp) -{ - - int size; - int new_x,new_y; - int org_x,org_y; - int dst_width; - int src_idx, dst_idx; - - size = width * height * bpp; - - if(angle == 0) - { - memcpy(dst,src,size); - return; - } - - for(org_y =0; org_y < height; org_y++) - { - for(org_x = 0; org_x < width ; org_x++) - { - if(angle == 90) - { - new_x = height - org_y; - new_y = org_x; - - dst_width = height; - } - else if(angle == 180) - { - new_x = width - org_x; - new_y = height - org_y; - dst_width = width; - } - else if(angle == 270) - { - new_x = org_y; - new_y = width - org_x; - dst_width = height; - } - else - { - g_print("Not support Rotate : %d\n",angle); - return; - } - - src_idx = org_x + (org_y * width); - dst_idx = new_x + (new_y * dst_width); - - memcpy(dst + (dst_idx*bpp), src+(src_idx *bpp),bpp); - } - } - -} - -static void -resize_pure(unsigned char *src, unsigned char *dst, int src_width, int src_height, int dst_width,int dst_height, int bpp) -{ - float xFactor,yFactor; - - float org_fx,org_fy; - int org_x,org_y; - - int x,y; - - int src_index,dst_index; - - unsigned short *pshortSrc; - unsigned short *pshortDst; - - if(bpp == 2) - { - pshortSrc = (unsigned short*)src; - pshortDst = (unsigned short*)dst; - } - - xFactor = (float)((dst_width<<16) / src_width); - yFactor = (float)((dst_height<<16) / src_height); - - for(y = 0; y < dst_height; y++) - { - for(x = 0; x < dst_width; x++) - { - org_fx = (float)((x<<16)/xFactor); - org_fy = (float)((y<<16)/yFactor); - - org_x = (int)(org_fx); - org_y = (int)(org_fy); - - src_index = org_x + (org_y * src_width); - dst_index = x + (y*dst_width); - - memcpy(dst+(dst_index *bpp ),src+(src_index *bpp),bpp); - } - } -} - -/* BOOLEAN:POINTER,INT,INT (avsysvideosink.c:1) */ -void -gst_avsysmemsink_BOOLEAN__POINTER_INT_INT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_INT_INT) (gpointer data1, - gpointer arg_1, - gint arg_2, - gint arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__POINTER_INT_INT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__POINTER_INT_INT) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_pointer (param_values + 1), - g_marshal_value_peek_int (param_values + 2), - g_marshal_value_peek_int (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -static void gst_avsysmemsink_init_interfaces (GType type); - - -GST_BOILERPLATE_FULL (GstAvsysMemSink, gst_avsysmemsink, GstVideoSink, GST_TYPE_VIDEO_SINK, gst_avsysmemsink_init_interfaces); - - -static void -gst_avsysmemsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (object); - switch (prop_id) { - case PROP_0: - break; - case PROP_WIDTH: - if(AvsysMemSink->dst_width != g_value_get_int (value)) - { - AvsysMemSink->dst_width = g_value_get_int (value); - AvsysMemSink->dst_changed = 1; - } - break; - case PROP_HEIGHT: - if(AvsysMemSink->dst_height != g_value_get_int (value)) - { - AvsysMemSink->dst_height = g_value_get_int (value); - AvsysMemSink->dst_changed = 1; - } - break; - case PROP_ROTATE: - if(AvsysMemSink->rotate != g_value_get_int(value)) - { - AvsysMemSink->rotate = g_value_get_int(value); - AvsysMemSink->dst_changed = 1; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - g_print ("invalid property id\n"); - break; - }; -} - -static void -gst_avsysmemsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (object); - - switch (prop_id) { - case PROP_0: - break; - case PROP_WIDTH: - g_value_set_int (value, AvsysMemSink->dst_width); - break; - case PROP_HEIGHT: - g_value_set_int (value, AvsysMemSink->dst_height); - break; - case PROP_ROTATE: - g_value_set_int (value, AvsysMemSink->rotate); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - debug_warning ("invalid property id\n"); - break; - } -} - -static void -free_buffer(GstAvsysMemSink *AvsysMemSink) -{ - if(AvsysMemSink->con_buf) - free(AvsysMemSink->con_buf); - - if(AvsysMemSink->rot_buf) - free(AvsysMemSink->rot_buf); - - if(AvsysMemSink->rsz_buf) - free(AvsysMemSink->rsz_buf); - - AvsysMemSink->con_buf = NULL; - AvsysMemSink->rot_buf = NULL; - AvsysMemSink->rsz_buf = NULL; - -} -static GstStateChangeReturn -gst_avsysmemsink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (element); - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - debug_msg ("GST AVSYS DISPLAY SINK: NULL -> READY\n"); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - debug_msg ("GST AVSYS DISPLAY SINK: READY -> PAUSED\n"); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - debug_msg ("GST AVSYS DISPLAY SINK: PAUSED -> PLAYING\n"); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS(parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) { - return ret; - } - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - debug_msg ("GST AVSYS MEM SINK: PLAYING -> PAUSED\n"); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - debug_msg ("GST AVSYS MEM SINK: PAUSED -> READY\n"); - free_buffer(AvsysMemSink); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - debug_msg ("GST AVSYS MEM SINK: READY -> NULL\n"); - break; - default: - break; - } - - return ret; - - -} - - -static gboolean -gst_avsysmemsink_set_caps (GstBaseSink * bs, GstCaps * caps) -{ - GstAvsysMemSink *s = GST_AVSYS_MEM_SINK (bs); - GstStructure *structure; - gint width = 0; - gint height = 0; - - if (caps != NULL) - { - guint32 fourcc; - char *name = NULL; - int bpp = 0, depth = 0; - - structure = gst_caps_get_structure (caps, 0); - - /**/ - name = (char *) gst_structure_get_name (structure); - GST_DEBUG_OBJECT (s, "CAPS NAME: %s", name); - - if (gst_structure_has_name (structure, "video/x-raw-rgb")) - { - s->is_rgb = TRUE; - } - else if (gst_structure_has_name (structure, "video/x-raw-yuv")) - { - s->is_rgb = FALSE; - } - - /* get source size */ - gst_structure_get_int (structure, "height", &height); - gst_structure_get_int (structure, "width", &width); - - if (gst_structure_get_fourcc (structure, "format", &fourcc)) - { - switch (fourcc) - { - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - debug_warning("set format AVSYS_VIDEO_FORMAT_UYVY\n"); - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '6'): - case GST_MAKE_FOURCC ('Y', '4', '2', 'B'): - debug_warning("set format AVSYS_VIDEO_FORMAT_YUV422\n"); - break; - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - debug_warning("set format AVSYS_VIDEO_FORMAT_YUV420\n"); - break; - case GST_MAKE_FOURCC ('R', 'G', 'B', ' '): - debug_warning("set format AVSYS_VIDEO_FORMAT_RGB565\n"); - break; - default: - debug_warning("set default format AVSYS_VIDEO_FORMAT_RGB565\n"); - break; - } - } - - if( s->src_width != width || - s->src_height != height) - { - debug_warning ("DISPLAY: Video Source Changed! [%d x %d] -> [%d x %d]\n", - s->src_width, s->src_height, width, height); - s->src_changed = TRUE; - } - - s->src_width = width; - s->src_height = height; - - if(s->dst_width ==0) - { - s->dst_width = width; - s->dst_changed = 1; - } - - if(s->dst_height == 0) - { - s->dst_height = height; - s->dst_changed = 1; - } - debug_msg ("SRC CAPS: width:%d, height:%d \n", width, height); - } - else - { - debug_warning ("caps is NULL.\n"); - } - - debug_fleave (); - - return TRUE; -} - -static GstFlowReturn -gst_avsysmemsink_preroll (GstBaseSink * bsink, GstBuffer * buf) -{ - GstAvsysMemSink *AvsysMemSink = GST_AVSYS_MEM_SINK (bsink); - - AvsysMemSink->src_length = GST_BUFFER_SIZE (buf); - debug_msg ("SRC LENGTH: %d\n", AvsysMemSink->src_length); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_avsysmemsink_show_frame (GstBaseSink * bsink, GstBuffer * buf) -{ - GstAvsysMemSink *s = GST_AVSYS_MEM_SINK (bsink); - gboolean res = FALSE; - int f_size; - f_size = GST_BUFFER_SIZE (buf); - unsigned char *dst_buf; - - if ( ! s->is_rgb ) - { - GST_DEBUG_OBJECT (s, "src format is not rgb"); - if (s->dst_changed == TRUE) - { - if(s->con_buf) - { - free(s->con_buf); - s->con_buf = NULL; - } - - if(s->rot_buf) - { - free(s->rot_buf); - s->rot_buf = NULL; - } - - if(s->rsz_buf) - { - free(s->rsz_buf); - s->rsz_buf = NULL; - } - - s->con_buf = malloc(s->src_width * s->src_height * 4); - if(s->rotate != 0) - { - s->rot_buf = malloc(s->src_width * s->src_height * 4); - } - - s->rsz_buf = malloc(s->dst_width * s->dst_height *4); - - s->dst_changed = FALSE; - } - - yuv420toargb(GST_BUFFER_DATA (buf),s->con_buf,s->src_width, s->src_height); - if(s->rotate != 0) - { - rotate_pure(s->con_buf,s->rot_buf,s->src_width, s->src_height,s->rotate,4); - if(s->rotate == 90 || s->rotate == 270) - { - resize_pure(s->rot_buf,s->rsz_buf,s->src_height,s->src_width, - s->dst_width, s->dst_height,4); - } - else - { - resize_pure(s->rot_buf,s->rsz_buf,s->src_width,s->src_height, - s->dst_width, s->dst_height,4); - } - } - else - { - resize_pure(s->con_buf,s->rsz_buf,s->src_width,s->src_height, - s->dst_width, s->dst_height,4); - } - - /* emit signal for video-stream */ - g_signal_emit (s,gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM], - 0,s->rsz_buf, - s->dst_width,s->dst_height, - &res); - } - else - { - GST_DEBUG_OBJECT (s, "src format is rgb"); - - /* NOTE : video can be resized by convert plugin's set caps on running time. - * So, it should notice it to application through callback func. - */ - g_signal_emit (s, gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM], - 0, GST_BUFFER_DATA (buf), - s->src_width, s->src_height, - &res); - - } - GST_DEBUG_OBJECT (s, "g_signal_emit : src_width=%d, src_height=%d, GST_BUFFER_SIZE=%d", s->src_width,s->src_height,GST_BUFFER_SIZE(buf)); - - /*check video stream callback result.*/ - if (res) - { - //debug_verbose("Video stream is called.\n"); - return GST_FLOW_OK; - } - - return GST_FLOW_OK; -} - -static void -gst_avsysmemsink_init_interfaces (GType type) -{ - /*void*/ -} - - -static void -gst_avsysmemsink_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details (element_class, &AvsysMemSink_details); -} - -static void -gst_avsysmemsink_class_init (GstAvsysMemSinkClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*) klass; - GstElementClass *gstelement_class = (GstElementClass*) klass; - GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass; - - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_avsysmemsink_set_property; - gobject_class->get_property = gst_avsysmemsink_get_property; - - - g_object_class_install_property (gobject_class, PROP_WIDTH, - g_param_spec_int ("width", - "Width", - "Width of display", - 0, G_MAXINT, 176, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - g_object_class_install_property (gobject_class, PROP_HEIGHT, - g_param_spec_int ("height", - "Height", - "Height of display", - 0, G_MAXINT, 144, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_ROTATE, - g_param_spec_int ("rotate", - "Rotate", - "Rotate of display", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - /** - * GstAvsysVideoSink::video-stream: - */ - gst_avsysmemsink_signals[SIGNAL_VIDEO_STREAM] = g_signal_new ( - "video-stream", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - gst_avsysmemsink_BOOLEAN__POINTER_INT_INT, - G_TYPE_BOOLEAN, - 3, - G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT); - - gstelement_class->change_state = gst_avsysmemsink_change_state; - - gstbasesink_class->set_caps = gst_avsysmemsink_set_caps; - gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_avsysmemsink_preroll); - gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_avsysmemsink_show_frame); - - - GST_DEBUG_CATEGORY_INIT (avsysmemsink_debug, - "avsysmemsink", - 0, - "AV system based GStreamer Plug-in"); -} - - -static void -gst_avsysmemsink_init (GstAvsysMemSink *AvsysMemSink, GstAvsysMemSinkClass *klass) -{ - /*private*/ - AvsysMemSink->src_width = 0; - AvsysMemSink->src_height = 0; - - AvsysMemSink->src_changed = 0; - - /*property*/ - AvsysMemSink->dst_width = 0; - AvsysMemSink->dst_height = 0; - - AvsysMemSink->dst_changed = 0; - - AvsysMemSink->rotate = 0; - - AvsysMemSink->con_buf = NULL; - AvsysMemSink->rot_buf = NULL; - AvsysMemSink->rsz_buf = NULL; - - AvsysMemSink->is_rgb = FALSE; -} - - -/* EOF */ diff --git a/wearable/avsystem/src/gstavsysmemsink.h b/wearable/avsystem/src/gstavsysmemsink.h deleted file mode 100644 index bc28029..0000000 --- a/wearable/avsystem/src/gstavsysmemsink.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef __GST_AVSYSMEMSINK_H__ -#define __GST_AVSYSMEMSINK_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_AVSYS_MEM_SINK (gst_avsysmemsink_get_type()) -#define GST_AVSYS_MEM_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AVSYS_MEM_SINK, GstAvsysMemSink)) -#define GST_AVSYS_MEM_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AVSYS_MEM_SINK, GstAvsysMemSinkClass)) -#define GST_IS_AVSYS_MEM_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AVSYS_MEM_SINK)) -#define GST_IS_AVSYS_MEM_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AVSYS_MEM_SINK)) - - -typedef struct _GstAvsysMemSink GstAvsysMemSink; -typedef struct _GstAvsysMemSinkClass GstAvsysMemSinkClass; - -struct _GstAvsysMemSink -{ - GstVideoSink videosink; - - int src_width; - int src_height; - - int src_changed; - int src_length; - - - int dst_width; - int dst_height; - - int dst_length; - int dst_changed; - - unsigned char *con_buf; - unsigned char *rot_buf; - unsigned char *rsz_buf; - - int rotate; - - int is_rgb; -}; - -struct _GstAvsysMemSinkClass -{ - GstVideoSinkClass parent_class; -}; - -GType gst_avsysmemsink_get_type (void); - -G_END_DECLS - - -#endif /* __GST_AVSYSMEMSINK_H__ */ - -/* EOF */ diff --git a/wearable/avsystem/src/gstavsyssink.c b/wearable/avsystem/src/gstavsyssink.c deleted file mode 100644 index a1ab29e..0000000 --- a/wearable/avsystem/src/gstavsyssink.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "gstavsysaudiosink.h" -#include "gstavsysmemsink.h" - -GST_DEBUG_CATEGORY (avsystem_sink_debug); - -static gboolean -plugin_init (GstPlugin *plugin) -{ - gboolean error; - /*register the exact name you can find in the framework*/ - error = gst_element_register (plugin, "avsysaudiosink", - GST_RANK_PRIMARY + 100, - GST_TYPE_AVSYS_AUDIO_SINK); - - error = gst_element_register (plugin, "avsysmemsink", - GST_RANK_NONE, - GST_TYPE_AVSYS_MEM_SINK); - - if (!error) - goto failed; - - GST_DEBUG_CATEGORY_INIT (avsystem_sink_debug, "avsystemsink", 0, "avsystem sink plugins"); - return TRUE; - -failed: - - return FALSE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "avsyssink", - "AV system video/audio sink plug-in", - plugin_init, - PACKAGE_VERSION, - "LGPL", - "AV System Sink", - "http://www.samsung.com") diff --git a/wearable/avsystem/src/gstavsyssrc.c b/wearable/avsystem/src/gstavsyssrc.c deleted file mode 100644 index adde8df..0000000 --- a/wearable/avsystem/src/gstavsyssrc.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * avsystem - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: JongHyuk Choi - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "gstavsysaudiosrc.h" - -GST_DEBUG_CATEGORY (avsystem_src_debug); - -static gboolean -plugin_init (GstPlugin *plugin) -{ - gboolean error; - /*register the exact name you can find in the framework*/ - error = gst_element_register (plugin, "avsysaudiosrc", - GST_RANK_NONE, - GST_TYPE_AVSYS_AUDIO_SRC); - if (!error) - goto failed; - - GST_DEBUG_CATEGORY_INIT (avsystem_src_debug, "avsystemsrc", 0, "avsystem src plugins"); - return TRUE; - -failed: - - return FALSE; -} - - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "avsysaudiosrc", - "AV system audio source plug-in", - plugin_init, - PACKAGE_VERSION, - "LGPL", - "AV System Source", - "http://www.samsung.com") - diff --git a/wearable/configure.ac b/wearable/configure.ac deleted file mode 100755 index 9239bfc..0000000 --- a/wearable/configure.ac +++ /dev/null @@ -1,487 +0,0 @@ - -AC_INIT(extension, 1.0) - -dnl versions of gstreamer and plugins-base -GST_MAJORMINOR=0.10 -GST_REQUIRED=0.10.0 -GSTPB_REQUIRED=0.10.0 -EFL_REQUIRED=1.0.0 - -dnl fill in your package name and version here -dnl the fourth (nano) number should be 0 for a release, 1 for CVS, -dnl and 2... for a prerelease - -dnl when going to/from release please set the nano correctly ! -dnl releases only do Wall, cvs and prerelease does Werror too -AS_VERSION(gst-plugin, GST_PLUGIN_VERSION, 0, 10, 0, 1, - GST_PLUGIN_CVS="no", GST_PLUGIN_CVS="yes") - -dnl AM_MAINTAINER_MODE provides the option to enable maintainer mode -AM_MAINTAINER_MODE - -#AM_INIT_AUTOMAKE($PACKAGE, $VERSION) -AM_INIT_AUTOMAKE - -#AC_CONFIG_MACRO_DIR([m4]) - -dnl make aclocal work in maintainer mode -dnl AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") - -dnl Add parameters for aclocal -AC_SUBST(ACLOCAL_AMFLAGS, "-I m4 -I common/m4") - -AM_CONFIG_HEADER(config.h) - -dnl check for tools -AC_PROG_CC -AC_PROG_CXX -AC_PROG_LIBTOOL - -dnl decide on error flags -AS_COMPILER_FLAG(-Wall, GST_WALL="yes", GST_WALL="no") - -if test "x$GST_WALL" = "xyes"; then - GST_ERROR="$GST_ERROR -Wall" - -# if test "x$GST_PLUGIN_CVS" = "xyes"; then -# AS_COMPILER_FLAG(-Werror,GST_ERROR="$GST_ERROR -Werror",GST_ERROR="$GST_ERROR") -# fi -fi - -dnl Check for pkgconfig first -AC_CHECK_PROG(HAVE_PKGCONFIG, pkg-config, yes, no) - -dnl Give error and exit if we don't have pkgconfig -if test "x$HAVE_PKGCONFIG" = "xno"; then - AC_MSG_ERROR(you need to have pkgconfig installed !) -fi - -dnl Now we're ready to ask for gstreamer libs and cflags -dnl And we can also ask for the right version of gstreamer -AM_CONDITIONAL([IS_VODA_SDK], [test "x$DISTRO" = "xvodafone-sdk"]) -AM_CONDITIONAL([ISPROTECTOR_VODA_SDK], [test "x$DISTRO" = "xvodafone-sdk" && test "x$MACHINE" = "xprotector"]) -AM_CONDITIONAL([ISVOLANS_VODA_SDK], [test "x$DISTRO" = "xvodafone-sdk" && test "x$MACHINE" = "xvolans"]) -AM_CONDITIONAL([ISPROTECTOR_TARGET], [test "x$ARCH" = "xarm" && test "x$MACHINE" = "xprotector"]) -AM_CONDITIONAL([ISVOLANS_TARGET], [test "x$ARCH" = "xarm" && test "x$MACHINE" = "xvolans"]) - -PKG_CHECK_MODULES(GST, \ - gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED, - HAVE_GST=yes,HAVE_GST=no) - -dnl Give error and exit if we don't have gstreamer -if test "x$HAVE_GST" = "xno"; then - AC_MSG_ERROR(you need gstreamer development packages installed !) -fi - -dnl append GST_ERROR cflags to GST_CFLAGS -GST_CFLAGS="$GST_CFLAGS $GST_ERROR" - -dnl make GST_CFLAGS and GST_LIBS available -PKG_CHECK_MODULES(GST, gstreamer-0.10 >= 0.10) -AC_SUBST(GST_CFLAGS) -AC_SUBST(GST_LIBS) - -dnl make GST_MAJORMINOR available in Makefile.am -AC_SUBST(GST_MAJORMINOR) - -dnl If we need them, we can also use the base class libraries -PKG_CHECK_MODULES(GST_BASE, gstreamer-base-$GST_MAJORMINOR >= $GST_REQUIRED, - HAVE_GST_BASE=yes, HAVE_GST_BASE=no) - -dnl Give a warning if we don't have gstreamer libs -dnl you can turn this into an error if you need them -if test "x$HAVE_GST_BASE" = "xno"; then - AC_MSG_NOTICE(no GStreamer base class libraries found (gstreamer-base-$GST_MAJORMINOR)) -fi - -dnl make _CFLAGS and _LIBS available -AC_SUBST(GST_BASE_CFLAGS) -AC_SUBST(GST_BASE_LIBS) - -dnl If we need them, we can also use the gstreamer-plugins-base libraries -PKG_CHECK_MODULES(GSTPB_BASE, - gstreamer-plugins-base-$GST_MAJORMINOR >= $GSTPB_REQUIRED, - HAVE_GSTPB_BASE=yes, HAVE_GSTPB_BASE=no) - -dnl Give a warning if we don't have gstreamer libs -dnl you can turn this into an error if you need them -if test "x$HAVE_GSTPB_BASE" = "xno"; then - AC_MSG_NOTICE(no GStreamer Plugins Base libraries found (gstreamer-plugins-base-$GST_MAJORMINOR)) -fi - -dnl make _CFLAGS and _LIBS available -AC_SUBST(GSTPB_BASE_CFLAGS) -AC_SUBST(GSTPB_BASE_LIBS) - -dnl If we need them, we can also use the gstreamer-controller libraries -PKG_CHECK_MODULES(GSTCTRL, - gstreamer-controller-$GST_MAJORMINOR >= $GSTPB_REQUIRED, - HAVE_GSTCTRL=yes, HAVE_GSTCTRL=no) - -dnl Give a warning if we don't have gstreamer-controller -dnl you can turn this into an error if you need them -if test "x$HAVE_GSTCTRL" = "xno"; then - AC_MSG_NOTICE(no GStreamer Controller libraries found (gstreamer-controller-$GST_MAJORMINOR)) -fi - -dnl make _CFLAGS and _LIBS available -AC_SUBST(GSTCTRL_CFLAGS) -AC_SUBST(GSTCTRL_LIBS) - -dnl set the plugindir where plugins should be installed -if test "x${prefix}" = "x$HOME"; then - plugindir="$HOME/.gstreamer-$GST_MAJORMINOR/plugins" -else - plugindir="\$(libdir)/gstreamer-$GST_MAJORMINOR" -fi -AC_SUBST(plugindir) - -dnl set proper LDFLAGS for plugins -#GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).*' -GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\|FIR_\|arkamys_malloc\|arkamys_free\).*' -#GST_PLUGIN_LDFLAGS='-module -avoid-version' -AC_SUBST(GST_PLUGIN_LDFLAGS) - - -PKG_CHECK_MODULES(GST_AUDIO, gstreamer-audio-$GST_MAJORMINOR >= $GST_REQUIRED ) - - -dnl make _CFLAGS and _LIBS available -AC_SUBST(GST_AUDIO_CFLAGS) -AC_SUBST(GST_AUDIO_LIBS) - -PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-$GST_MAJORMINOR >= $GST_REQUIRED) - -dnl make _CFLAGS and _LIBS available -AC_SUBST(GST_VIDEO_CFLAGS) -AC_SUBST(GST_VIDEO_LIBS) - -PKG_CHECK_MODULES(GST_INTERFACES, gstreamer-interfaces-$GST_MAJORMINOR >= $GST_REQUIRED) -AC_SUBST(GST_INTERFACES_CFLAGS) -AC_SUBST(GST_INTERFACES_LIBS) - -dnl xvimagesrc _CFLAGS and _LIB available - -PKG_CHECK_MODULES(DRI2, libdri2) -AC_SUBST(DRI2_CFLAGS) -AC_SUBST(DRI2_LIBS) - -PKG_CHECK_MODULES(X11, x11) -AC_SUBST(X11_CFLAGS) -AC_SUBST(X11_LIBS) - -PKG_CHECK_MODULES(XEXT, xext) -AC_SUBST(XEXT_CFLAGS) -AC_SUBST(XEXT_LIBS) - -PKG_CHECK_MODULES(XV, xv) -AC_SUBST(XV_CFLAGS) -AC_SUBST(XV_LIBS) - -PKG_CHECK_MODULES(XDAMAGE, xdamage) -AC_SUBST(XDAMAGE_CFLAGS) -AC_SUBST(XDAMAGE_LIBS) - -PKG_CHECK_MODULES(TBM, libtbm) -AC_SUBST(TBM_CFLAGS) -AC_SUBST(TBM_LIBS) - -dnl use time analysis module -PKG_CHECK_MODULES(MMTA, mm-ta) -AC_SUBST(MMTA_CFLAGS) -AC_SUBST(MMTA_LIBS) - -PKG_CHECK_MODULES(XML2, libxml-2.0) -AC_SUBST(XML2_CFLAGS) -AC_SUBST(XML2_LIBS) - -dnl required package for evasimagesink/evaspixmapsink -PKG_CHECK_MODULES(EFL, [ - evas >= $EFL_REQUIRED - ecore >= $EFL_REQUIRED - ecore-x >= $EFL_REQUIRED -], [ - AC_SUBST(EFL_CFLAGS) - AC_SUBST(EFL_LIBS) -], [ - AC_MSG_ERROR([ - You need to install or upgrade the EFL development - packages on your system. On debian-based systems these are - libevas-dev and libecore-dev. - The minimum version required is $EFL_REQUIRED. - ]) -]) - -dnl *** belows are related to evaspixmapsink plug-ins *** -AG_GST_ARG_WITH_PACKAGE_NAME -AG_GST_ARG_WITH_PACKAGE_ORIGIN - -dnl set license and copyright notice -GST_LICENSE="LGPL" -AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license]) -AC_SUBST(GST_LICENSE) - -echo -AC_MSG_NOTICE([Checking libraries for evaspixmapsink plugin]) -echo -dnl *** X11 *** -translit(dnm, m, l) AM_CONDITIONAL(USE_X, true) -AG_GST_CHECK_FEATURE(X, [X libraries and plugins], - [evaspixmapsink], [ - AC_PATH_XTRA - ac_cflags_save="$CFLAGS" - ac_cppflags_save="$CPPFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" - CPPFLAGS="$CPPFLAGS $X_CFLAGS" - - dnl now try to find the HEADER - AC_CHECK_HEADER(X11/Xlib.h, HAVE_X="yes", HAVE_X="no") - - if test "x$HAVE_X" = "xno" - then - AC_MSG_NOTICE([cannot find X11 development files]) - else - dnl this is much more than we want - X_LIBS="$X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS" - dnl AC_PATH_XTRA only defines the path needed to find the X libs, - dnl it does not add the libs; therefore we add them here - X_LIBS="$X_LIBS -lX11" - AC_SUBST(X_CFLAGS) - AC_SUBST(X_LIBS) - fi - AC_SUBST(HAVE_X) - CFLAGS="$ac_cflags_save" - CPPFLAGS="$ac_cppflags_save" -]) - -dnl Check for Xv extension -translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true) -AG_GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions], - [evaspixmapsink], [ -AG_GST_CHECK_XV -]) - -dnl check for X Shm -translit(dnm, m, l) AM_CONDITIONAL(USE_XSHM, true) -AG_GST_CHECK_FEATURE(XSHM, [X Shared Memory extension], , [ - if test x$HAVE_X = xyes; then - AC_CHECK_LIB(Xext, XShmAttach, - HAVE_XSHM="yes", HAVE_XSHM="no", - $X_LIBS) - if test "x$HAVE_XSHM" = "xyes"; then - XSHM_LIBS="-lXext" - else - dnl On AIX, it is in XextSam instead, but we still need -lXext - AC_CHECK_LIB(XextSam, XShmAttach, - HAVE_XSHM="yes", HAVE_XSHM="no", - $X_LIBS) - if test "x$HAVE_XSHM" = "xyes"; then - XSHM_LIBS="-lXext -lXextSam" - fi - fi - fi -], , [ - AC_SUBST(HAVE_XSHM) - AC_SUBST(XSHM_LIBS) -]) - -dnl use tbm -PKG_CHECK_MODULES(TBM, libtbm) -AC_SUBST(TBM_CFLAGS) -AC_SUBST(TBM_LIBS) - -dnl PKG_CHECK_MODULES(UDEVMGR, unified-dev-mgr) -dnl AC_SUBST(UDEVMGR_CFLAGS) -dnl AC_SUBST(UDEVMGR_LIBS) - -dnl use ext-encodebin -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-encodebin, AC_HELP_STRING([--enable-ext-encodebin], [using encodebin]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_ENCODEBIN=yes ;; - no) GST_EXT_USE_EXT_ENCODEBIN=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-encodebin) ;; - esac - ], - [GST_EXT_USE_EXT_ENCODEBIN=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_ENCODEBIN, test "x$GST_EXT_USE_EXT_ENCODEBIN" = "xyes") - -dnl use ext-avsystem -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-avsystem, AC_HELP_STRING([--enable-ext-avsystem], [using avsystem]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_AVSYSTEM=yes ;; - no) GST_EXT_USE_EXT_AVSYSTEM=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-avsystem) ;; - esac - ], - [GST_EXT_USE_EXT_AVSYSTEM=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AVSYSTEM, test "x$GST_EXT_USE_EXT_AVSYSTEM" = "xyes") - -dnl use ext-evasimagesink -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-evasimagesink, AC_HELP_STRING([--enable-ext-evasimagesink], [using evasimagesink]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_EVASIMAGESINK=yes ;; - no) GST_EXT_USE_EXT_EVASIMAGESINK=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-evasimagesink) ;; - esac - ], - [GST_EXT_USE_EXT_EVASIMAGESINK=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_EVASIMAGESINK, test "x$GST_EXT_USE_EXT_EVASIMAGESINK" = "xyes") - -dnl use evaspixmapsink --------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-evaspixmapsink, AC_HELP_STRING([--enable-ext-evaspixmapsink], [using evaspixmapsink]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_EVASPIXMAPSINK=yes ;; - no) GST_EXT_USE_EXT_EVASPIXMAPSINK=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-evaspixmapsink) ;; - esac - ], - [GST_EXT_USE_EXT_EVASPIXMAPSINK=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_EVASPIXMAPSINK, test "x$GST_EXT_USE_EXT_EVASPIXMAPSINK" = "xyes") - -AC_ARG_ENABLE([qc-specific], AC_HELP_STRING([--enable-qc-specific], [Enable QC changes for WFD]), - [ - case "${enableval}" in - yes) IS_QC_SPECIFIC=yes ;; - no) IS_QC_SPECIFIC=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-qc-specific) ;; - esac - ], - [IS_QC_SPECIFIC=no]) -AM_CONDITIONAL([IS_QC_SPECIFIC], [test "x$IS_QC_SPECIFIC" = "xyes"]) - -dnl use ext-xvimagesrc-------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-xvimagesrc, AC_HELP_STRING([--enable-ext-xvimagesrc], [using xvimagesrc]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_XVIMAGESRC=yes ;; - no) GST_EXT_USE_EXT_XVIMAGESRC=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-xvimagesrc) ;; - esac - ], - [GST_EXT_USE_EXT_XVIMAGESRC=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_XVIMAGESRC, test "x$GST_EXT_USE_EXT_XVIMAGESRC" = "xyes") - -dnl use ext-gstreamer-audio ------------------------------------------------------------------- -AC_ARG_ENABLE(ext-gstreamer-audio, AC_HELP_STRING([--enable-ext-gstreamer-audio], [using gstreamer-audio]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_AVSYSAUDIO=yes ;; - no) GST_EXT_USE_EXT_AVSYSAUDIO=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-gstreamer-audio) ;; - esac - ], - [GST_EXT_USE_EXT_AVSYSAUDIO=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AVSYSAUDIO, test "x$GST_EXT_USE_EXT_AVSYSAUDIO" = "xyes") - -if test "x$GST_EXT_USE_EXT_AVSYSAUDIO" = "xyes"; then - HAVE_AVSYSAUDIO=NO - PKG_CHECK_MODULES(AVSYSAUDIO, avsysaudio, HAVE_AVSYSAUDIO="yes", [ - HAVE_AVSYSAUDIO="no" - AC_MSG_RESULT(no) - ]) - if test "x$HAVE_AVSYSAUDIO" = "xno"; then - AC_MSG_ERROR(no avsysaudio package found) - fi - AC_SUBST(AVSYSAUDIO_CFLAGS) - AC_SUBST(AVSYSAUDIO_LIBS) -fi - -dnl use ext-toggle -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-toggle, AC_HELP_STRING([--enable-ext-toggle], [using toggle]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_TOGGLE=yes ;; - no) GST_EXT_USE_EXT_TOGGLE=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-toggle) ;; - esac - ], - [GST_EXT_USE_EXT_TOGGLE=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_TOGGLE, test "x$GST_EXT_USE_EXT_TOGGLE" = "xyes") - -dnl for i386 -------------------------------------------------------------------------- -AC_ARG_ENABLE(i386, AC_HELP_STRING([--enable-i386], [i386 build]), - [ - case "${enableval}" in - yes) IS_I386=yes ;; - no) IS_I386=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-i386) ;; - esac - ], - [IS_I386=no]) -AM_CONDITIONAL([IS_I386], [test "x$IS_I386" = "xyes"]) - -dnl use ext-pdpushsrc -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-pdpushsrc, AC_HELP_STRING([--enable-ext-pdpushsrc], [using pdpushsrc]), -[ - case "${enableval}" in - yes) GST_EXT_USE_EXT_PD_PUSHSRC=yes ;; - no) GST_EXT_USE_EXT_PD_PUSHSRC=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-pdpushsrc) ;; - esac - ], - [GST_EXT_USE_EXT_PD_PUSHSRC=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_PD_PUSHSRC, test "x$GST_EXT_USE_EXT_PD_PUSHSRC" = "xyes") -dnl use ext-audiotp -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-audiotp, AC_HELP_STRING([--enable-ext-audiotp], [using audiotp]), -[ - case "${enableval}" in - yes) GST_EXT_USE_EXT_AUDIOTP=yes ;; - no) GST_EXT_USE_EXT_AUDIOTP=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-audiotp) ;; - esac - ], - [GST_EXT_USE_EXT_AUDIOTP=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AUDIOTP, test "x$GST_EXT_USE_EXT_AUDIOTP" = "xyes") - -dnl use ext-audioeq -------------------------------------------------------------------------- -AC_ARG_ENABLE(ext-audioeq, AC_HELP_STRING([--enable-ext-audioeq], [using audioeq]), -[ - case "${enableval}" in - yes) GST_EXT_USE_EXT_AUDIOEQ=yes ;; - no) GST_EXT_USE_EXT_AUDIOEQ=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-audioeq) ;; - esac - ], - [GST_EXT_USE_EXT_AUDIOEQ=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_AUDIOEQ, test "x$GST_EXT_USE_EXT_AUDIOEQ" = "xyes") - -dnl use ext-dashdemux ----------------------------------------------------------------------- -AC_ARG_ENABLE(ext-dashdemux, AC_HELP_STRING([--enable-ext-dashdemux], [using dashdemux]), - [ - case "${enableval}" in - yes) GST_EXT_USE_EXT_DASHDEMUX=yes ;; - no) GST_EXT_USE_EXT_DASHDEMUX=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ext-dashdemux) ;; - esac - ], - [GST_EXT_USE_EXT_DASHDEMUX=yes]) -AM_CONDITIONAL(GST_EXT_USE_EXT_DASHDEMUX, test "x$GST_EXT_USE_EXT_DASHDEMUX" = "xyes") - -AC_OUTPUT( -Makefile -common/Makefile -common/m4/Makefile -avsystem/Makefile -pdpushsrc/Makefile -pdpushsrc/src/Makefile -avsystem/src/Makefile -encodebin/Makefile -encodebin/src/Makefile -evasimagesink/Makefile -evasimagesink/src/Makefile -evaspixmapsink/Makefile -xvimagesrc/Makefile -xvimagesrc/src/Makefile -toggle/Makefile -toggle/src/Makefile -audiotp/Makefile -audiotp/src/Makefile -audioeq/Makefile -audioeq/src/Makefile -dashdemux/Makefile -dashdemux/src/Makefile -) diff --git a/wearable/evasimagesink/src/gstevasimagesink.c b/wearable/evasimagesink/src/gstevasimagesink.c deleted file mode 100644 index 9a2fbd4..0000000 --- a/wearable/evasimagesink/src/gstevasimagesink.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * evasimagesink - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * SECTION:element-evasimagesink - * Gstreamer Evas Video Sink - draw video on the given Evas Image Object - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "gstevasimagesink.h" - -#define CAP_WIDTH "width" -#define CAP_HEIGHT "height" - -GST_DEBUG_CATEGORY_STATIC (gst_evas_image_sink_debug); -#define GST_CAT_DEFAULT gst_evas_image_sink_debug - -/* Enumerations */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_EVAS_OBJECT, - PROP_EVAS_OBJECT_SHOW -}; - -enum -{ - UPDATE_FALSE, - UPDATE_TRUE -}; - -#define COLOR_DEPTH 4 -#define GL_X11_ENGINE "gl_x11" -#define DO_RENDER_FROM_FIMC 1 -#define SIZE_FOR_UPDATE_VISIBILITY sizeof(gchar) - -#define EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \ -do \ -{ \ - if (x_evas_image_object) { \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event, x_usr_data); \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, x_usr_data); \ - } \ -}while(0) - -#define EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \ -do \ -{ \ - if (x_evas_image_object) { \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event); \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event); \ - } \ -}while(0) - -GMutex *instance_lock; -guint instance_lock_count; - -static inline gboolean -is_evas_image_object (Evas_Object *obj) -{ - const char *type; - if (!obj) { - return FALSE; - } - type = evas_object_type_get (obj); - if (!type) { - return FALSE; - } - if (strcmp (type, "image") == 0) { - return TRUE; - } - return FALSE; -} - -/* the capabilities of the inputs. - * - * BGRx format - */ -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)); - -GST_BOILERPLATE (GstEvasImageSink, gst_evas_image_sink, GstVideoSink, GST_TYPE_VIDEO_SINK); - -static void gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static gboolean gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps); -static GstFlowReturn gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf); -static gboolean gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event); -static GstStateChangeReturn gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition); -static void evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info); -static void evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info); - -static void -gst_evas_image_sink_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "EvasImageSink", - "VideoSink", - "Video sink element for evas image object", - "Samsung Electronics "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); -} - -static void -gst_evas_image_sink_class_init (GstEvasImageSinkClass *klass) -{ - GObjectClass *gobject_class; - GstBaseSinkClass *gstbasesink_class; - GstVideoSinkClass *gstvideosink_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstbasesink_class = GST_BASE_SINK_CLASS (klass); - gstvideosink_class = GST_VIDEO_SINK_CLASS (klass); - gstelement_class = (GstElementClass *) klass; - - gobject_class->set_property = gst_evas_image_sink_set_property; - gobject_class->get_property = gst_evas_image_sink_get_property; - - g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT, - g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT_SHOW, - g_param_spec_boolean ("visible", "Show Evas Object", "When disabled, evas object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gstvideosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evas_image_sink_show_frame); - gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evas_image_sink_set_caps); - gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evas_image_sink_event); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_evas_image_sink_change_state); -} - -static void -gst_evas_image_sink_fini (gpointer data, GObject *obj) -{ - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = GST_EVASIMAGESINK (obj); - if (!esink) { - return; - } - if (esink->oldbuf) { - gst_buffer_unref (esink->oldbuf); - } - - if (esink->eo) { - evas_object_image_data_set(esink->eo, NULL); - } - - g_mutex_lock (instance_lock); - instance_lock_count--; - g_mutex_unlock (instance_lock); - if (instance_lock_count == 0) { - g_mutex_free (instance_lock); - instance_lock = NULL; - } - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_image_sink_cb_pipe (void *data, void *buffer, unsigned int nbyte) -{ - GstBuffer *buf; - GstEvasImageSink *esink = data; - void *img_data; - - GST_DEBUG ("[ENTER]"); - - if (!esink || !esink->eo) { - return; - } - if (nbyte == SIZE_FOR_UPDATE_VISIBILITY) { - if(!esink->object_show) { - evas_object_hide(esink->eo); - GST_INFO ("object hide.."); - } else { - evas_object_show(esink->eo); - GST_INFO ("object show.."); - } - GST_DEBUG ("[LEAVE]"); - return; - } - if (!buffer || nbyte != sizeof (GstBuffer *)) { - return; - } - if (GST_STATE(esink) < GST_STATE_PAUSED) { - GST_WARNING ("WRONG-STATE(%d) for rendering, skip this frame", GST_STATE(esink)); - return; - } - - memcpy (&buf, buffer, sizeof (GstBuffer *)); - if (!buf) { - GST_ERROR ("There is no buffer"); - return; - } - if (esink->present_data_addr == -1) { - /* if present_data_addr is -1, we don't use this member variable */ - } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { - GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); - return; - } - - MMTA_ACUM_ITEM_BEGIN("eavsimagesink _cb_pipe total", FALSE); - - if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) { - evas_object_image_size_set (esink->eo, esink->w, esink->h); - GST_DEBUG("evas_object_image_size_set(), width(%d),height(%d)",esink->w,esink->h); - esink->is_evas_object_size_set = TRUE; - } - if (esink->gl_zerocopy) { - img_data = evas_object_image_data_get (esink->eo, EINA_TRUE); - if (!img_data || !GST_BUFFER_DATA(buf)) { - GST_WARNING ("Cannot get image data from evas object or cannot get gstbuffer data"); - evas_object_image_data_set(esink->eo, img_data); - } else { - GST_DEBUG ("img_data(%x), GST_BUFFER_DATA(buf):%x, esink->w(%d),esink->h(%d), esink->eo(%x)",img_data,GST_BUFFER_DATA(buf),esink->w,esink->h,esink->eo); - __ta__("evasimagesink memcpy in _cb_pipe", memcpy (img_data, GST_BUFFER_DATA (buf), esink->w * esink->h * COLOR_DEPTH);); - evas_object_image_pixels_dirty_set (esink->eo, 1); - evas_object_image_data_set(esink->eo, img_data); - } - gst_buffer_unref (buf); - } else { - GST_DEBUG ("GST_BUFFER_DATA(buf):%x, esink->eo(%x)",GST_BUFFER_DATA(buf),esink->eo); - evas_object_image_data_set (esink->eo, GST_BUFFER_DATA (buf)); - evas_object_image_pixels_dirty_set (esink->eo, 1); - if (esink->oldbuf) { - gst_buffer_unref(esink->oldbuf); - } - esink->oldbuf = buf; - } - - MMTA_ACUM_ITEM_END("eavsimagesink _cb_pipe total", FALSE); - - GST_DEBUG ("[LEAVE]"); -} - -static void -gst_evas_image_sink_init (GstEvasImageSink *esink, GstEvasImageSinkClass *gclass) -{ - GST_DEBUG ("[ENTER]"); - - esink->eo = NULL; - esink->epipe = NULL; - esink->object_show = FALSE; - esink->update_visibility = UPDATE_FALSE; - esink->gl_zerocopy = FALSE; - esink->is_evas_object_size_set = FALSE; - esink->present_data_addr = -1; - - if(!instance_lock) { - instance_lock = g_mutex_new(); - } - g_mutex_lock (instance_lock); - instance_lock_count++; - g_mutex_unlock (instance_lock); - - g_object_weak_ref (G_OBJECT (esink), gst_evas_image_sink_fini, NULL); - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = data; - if (!esink) { - return; - } - - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - if (esink->oldbuf) { - gst_buffer_unref (esink->oldbuf); - esink->oldbuf = NULL; - } - - if (esink->eo) { - evas_object_image_data_set(esink->eo, NULL); - esink->eo = NULL; - } - - GST_DEBUG ("[LEAVE]"); -} - -static void -evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - int w = 0; - int h = 0; - - GST_DEBUG ("[ENTER]"); - - GstEvasImageSink *esink = data; - if (!esink) { - return; - } - - evas_object_geometry_get(esink->eo, NULL, NULL, &w, &h); - if (!w || !h) { - GST_WARNING ("evas object size (w:%d,h:%d) was not set",w,h); - } else { - evas_object_image_fill_set(esink->eo, 0, 0, w, h); - GST_DEBUG ("evas object fill set (w:%d,h:%d)",w,h); - } - - GST_DEBUG ("[LEAVE]"); -} - -static int -evas_image_sink_get_size_from_caps (GstCaps *caps, int *w, int *h) -{ - gboolean r; - int width, height; - GstStructure *s; - - if (!caps || !w || !h) { - return -1; - } - s = gst_caps_get_structure (caps, 0); - if (!s) { - return -1; - } - - r = gst_structure_get_int (s, CAP_WIDTH, &width); - if (r == FALSE) { - return -1; - } - - r = gst_structure_get_int (s, CAP_HEIGHT, &height); - if (r == FALSE) { - return -1; - } - - *w = width; - *h = height; - return 0; -} - -static gboolean -is_zerocopy_supported (Evas *e) -{ - Eina_List *engines, *l; - int cur_id; - int id; - char *name; - - if (!e) { - return FALSE; - } - - engines = evas_render_method_list (); - if (!engines) { - return FALSE; - } - - cur_id = evas_output_method_get (e); - - EINA_LIST_FOREACH (engines, l, name) { - id = evas_render_method_lookup (name); - if (name && id == cur_id) { - if (!strcmp (name, GL_X11_ENGINE)) { - return TRUE; - } - break; - } - } - return FALSE; -} - -static int -evas_image_sink_event_parse_data (GstEvasImageSink *esink, GstEvent *event) -{ - const GstStructure *st; - guint st_data_addr = 0; - gint st_data_width = 0; - gint st_data_height = 0; - - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (esink != NULL, FALSE); - - if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM_OOB) { - GST_WARNING ("it's not a custom downstream oob event"); - return -1; - } - st = gst_event_get_structure (event); - if (st == NULL || !gst_structure_has_name (st, "GstStructureForCustomEvent")) { - GST_WARNING ("structure in a given event is not proper"); - return -1; - } - if (!gst_structure_get_uint (st, "data-addr", &st_data_addr)) { - GST_WARNING ("parsing data-addr failed"); - return -1; - } - esink->present_data_addr = st_data_addr; - - return 0; -} - -static gboolean -gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (sink); - GstMessage *msg; - gchar *str; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - GST_DEBUG ("GST_EVENT_FLUSH_START"); - break; - case GST_EVENT_FLUSH_STOP: - GST_DEBUG ("GST_EVENT_FLUSH_STOP"); - break; - case GST_EVENT_EOS: - GST_DEBUG ("GST_EVENT_EOS"); - break; - case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: - if(!evas_image_sink_event_parse_data(esink, event)) { - GST_DEBUG ("GST_EVENT_CUSTOM_DOWNSTREAM_OOB, present_data_addr:%x",esink->present_data_addr); - } else { - GST_ERROR ("evas_image_sink_event_parse_data() failed"); - } - break; - default: - break; - } - if (GST_BASE_SINK_CLASS (parent_class)->event) { - return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); - } else { - return TRUE; - } -} - -static GstStateChangeReturn -gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret_state = GST_STATE_CHANGE_SUCCESS; - GstEvasImageSink *esink = NULL; - esink = GST_EVASIMAGESINK(element); - int ret = 0; - - if(!esink) { - GST_ERROR("can not get evasimagesink from element"); - return GST_STATE_CHANGE_FAILURE; - } - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - GST_INFO ("*** STATE_CHANGE_NULL_TO_READY ***"); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_INFO ("*** STATE_CHANGE_READY_TO_PAUSED ***"); - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - GST_INFO ("*** STATE_CHANGE_PAUSED_TO_PLAYING ***"); - break; - default: - break; - } - - ret_state = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - GST_INFO ("*** STATE_CHANGE_PLAYING_TO_PAUSED ***"); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_INFO ("*** STATE_CHANGE_PAUSED_TO_READY ***"); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - GST_INFO ("*** STATE_CHANGE_READY_TO_NULL ***"); - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - if (esink->epipe) { - ecore_pipe_del (esink->epipe); - esink->epipe = NULL; - } - break; - default: - break; - } - - return ret_state; -} - -static void -gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (object); - Evas_Object *eo; - - g_mutex_lock (instance_lock); - - switch (prop_id) { - case PROP_EVAS_OBJECT: - eo = g_value_get_pointer (value); - if (is_evas_image_object (eo)) { - if (eo != esink->eo) { - Eina_Bool r; - - /* delete evas object callbacks registrated on a previous evas image object */ - EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo); - esink->eo = eo; - /* add evas object callbacks on a new evas image object */ - EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo, esink); - - esink->gl_zerocopy = is_zerocopy_supported (evas_object_evas_get (eo)); - if (esink->gl_zerocopy) { - evas_object_image_content_hint_set (esink->eo, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - GST_DEBUG("Enable gl zerocopy"); - } - GST_DEBUG("Evas Image Object(%x) is set",esink->eo); - esink->is_evas_object_size_set = FALSE; - esink->object_show = TRUE; - esink->update_visibility = UPDATE_TRUE; - if (esink->epipe) { - r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); - if (r == EINA_FALSE) { - GST_WARNING ("Failed to ecore_pipe_write() for updating visibility\n"); - } - } - } - } else { - GST_ERROR ("Cannot set evas-object property: value is not an evas image object"); - } - break; - - case PROP_EVAS_OBJECT_SHOW: - { - Eina_Bool r; - esink->object_show = g_value_get_boolean (value); - if( !is_evas_image_object(esink->eo) ) { - GST_WARNING ("Cannot apply visible(show-object) property: cannot get an evas object\n"); - break; - } - esink->update_visibility = UPDATE_TRUE; - if (esink->epipe) { - r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY); - if (r == EINA_FALSE) { - GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n"); - } - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - g_mutex_unlock (instance_lock); -} - -static void -gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (object); - - switch (prop_id) { - case PROP_EVAS_OBJECT: - g_value_set_pointer (value, esink->eo); - break; - case PROP_EVAS_OBJECT_SHOW: - g_value_set_boolean (value, esink->object_show); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps) -{ - int r; - int w, h; - GstEvasImageSink *esink = GST_EVASIMAGESINK (base_sink); - - esink->is_evas_object_size_set = FALSE; - r = evas_image_sink_get_size_from_caps (caps, &w, &h); - if (!r) { - esink->w = w; - esink->h = h; - GST_DEBUG ("set size w(%d), h(%d)", w, h); - } - return TRUE; -} - -static GstFlowReturn -gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf) -{ - GstEvasImageSink *esink = GST_EVASIMAGESINK (video_sink); - Eina_Bool r; - - g_mutex_lock (instance_lock); - if (esink->present_data_addr == -1) { - /* if present_data_addr is -1, we don't use this member variable */ - } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) { - GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC); - g_mutex_unlock (instance_lock); - return GST_FLOW_OK; - } - if (!esink->epipe) { - esink->epipe = ecore_pipe_add (evas_image_sink_cb_pipe, esink); - if (!esink->epipe) { - GST_ERROR ("ecore-pipe create failed"); - g_mutex_unlock (instance_lock); - return GST_FLOW_ERROR; - } - } - if (esink->object_show) { - gst_buffer_ref (buf); - __ta__("evasimagesink ecore_pipe_write", r = ecore_pipe_write (esink->epipe, &buf, sizeof (GstBuffer *));); - if (r == EINA_FALSE) { - gst_buffer_unref (buf); - } - GST_DEBUG ("ecore_pipe_write() was called with GST_BUFFER_DATA(buf):%x", GST_BUFFER_DATA(buf)); - } else { - GST_DEBUG ("skip ecore_pipe_write()"); - } - g_mutex_unlock (instance_lock); - return GST_FLOW_OK; -} - -static gboolean -evas_image_sink_init (GstPlugin *evasimagesink) -{ - GST_DEBUG_CATEGORY_INIT (gst_evas_image_sink_debug, "evasimagesink", 0, "Evas image object based videosink"); - - return gst_element_register (evasimagesink, "evasimagesink", GST_RANK_NONE, GST_TYPE_EVASIMAGESINK); -} - -#ifndef PACKAGE -#define PACKAGE "gstevasimagesink-plugin-package" -#endif - -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "evasimagesink", - "Evas image object based videosink", - evas_image_sink_init, - VERSION, - "LGPL", - "Samsung Electronics Co", - "http://www.samsung.com/" -) diff --git a/wearable/evasimagesink/src/gstevasimagesink.h b/wearable/evasimagesink/src/gstevasimagesink.h deleted file mode 100644 index 09c8102..0000000 --- a/wearable/evasimagesink/src/gstevasimagesink.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * evasimagesink - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_EVASIMAGESINK_H__ -#define __GST_EVASIMAGESINK_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -/* #defines don't like whitespacey bits */ -#define GST_TYPE_EVASIMAGESINK \ - (gst_evas_image_sink_get_type()) -#define GST_EVASIMAGESINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EVASIMAGESINK,GstEvasImageSink)) -#define GST_EVASIMAGESINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EVASIMAGESINK,GstEvasImageSinkClass)) -#define GST_IS_EVASIMAGESINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EVASIMAGESINK)) -#define GST_IS_EVASIMAGESINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EVASIMAGESINK)) - -typedef struct _GstEvasImageSink GstEvasImageSink; -typedef struct _GstEvasImageSinkClass GstEvasImageSinkClass; - -struct _GstEvasImageSink -{ - GstVideoSink element; - - Evas_Object *eo; - Ecore_Pipe *epipe; - Evas_Coord w; - Evas_Coord h; - gboolean object_show; - gchar update_visibility; - gboolean gl_zerocopy; - - GstBuffer *oldbuf; - - gboolean is_evas_object_size_set; - guint present_data_addr; -}; - -struct _GstEvasImageSinkClass -{ - GstVideoSinkClass parent_class; -}; - -GType gst_evas_image_sink_get_type (void); - -G_END_DECLS - -#endif /* __GST_EVASIMAGESINK_H__ */ diff --git a/wearable/evaspixmapsink/Makefile.am b/wearable/evaspixmapsink/Makefile.am deleted file mode 100644 index f05ccbd..0000000 --- a/wearable/evaspixmapsink/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -plugin_LTLIBRARIES = libgstevaspixmapsink.la - -libgstevaspixmapsink_la_SOURCES = evaspixmapsink.c -libgstevaspixmapsink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(EFL_CFLAGS) $(MMTA_CFLAGS) \ - $(XFIXES_CFLAGS) $(DRI2PROTO_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XDAMAGE_CFLAGS) $(XV_CFLAGS) $(TBM_CFLAGS) -libgstevaspixmapsink_la_LIBADD = \ - $(GST_LIBS) -lgstvideo-$(GST_MAJORMINOR) -lgstinterfaces-$(GST_MAJORMINOR) \ - $(X_LIBS) $(XVIDEO_LIBS) $(XSHM_LIBS) $(LIBM) \ - $(EFL_LIBS) \ - $(MMTA_LIBS) \ - $(XFIXES_LIBS) $(DRI2PROTO_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XDAMAGE_LIBS) $(XV_LIBS) $(TBM_LIBS) -libgstevaspixmapsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstxvimagesink_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = evaspixmapsink.h diff --git a/wearable/evaspixmapsink/evaspixmapsink.c b/wearable/evaspixmapsink/evaspixmapsink.c deleted file mode 100644 index 6e1552c..0000000 --- a/wearable/evaspixmapsink/evaspixmapsink.c +++ /dev/null @@ -1,4358 +0,0 @@ -/* - * EvasPixmapSink - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Our interfaces */ -#include -#include -#include -/* Helper functions */ -#include - -/* Object header */ -#include "evaspixmapsink.h" - -#include - -/* Samsung extension headers */ -/* For xv extension header for buffer transfer (output) */ -#include "xv_types.h" - -/* headers for drm */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* max channel count *********************************************************/ -#define SCMN_IMGB_MAX_PLANE (4) - -/* image buffer definition *************************************************** - - +------------------------------------------+ --- - | | ^ - | a[], p[] | | - | +---------------------------+ --- | | - | | | ^ | | - | |<---------- w[] ---------->| | | | - | | | | | | - | | | | - | | | h[] | e[] - | | | | - | | | | | | - | | | | | | - | | | v | | - | +---------------------------+ --- | | - | | v - +------------------------------------------+ --- - - |<----------------- s[] ------------------>| -*/ - -typedef struct -{ - /* width of each image plane */ - int w[SCMN_IMGB_MAX_PLANE]; - /* height of each image plane */ - int h[SCMN_IMGB_MAX_PLANE]; - /* stride of each image plane */ - int s[SCMN_IMGB_MAX_PLANE]; - /* elevation of each image plane */ - int e[SCMN_IMGB_MAX_PLANE]; - /* user space address of each image plane */ - void *a[SCMN_IMGB_MAX_PLANE]; - /* physical address of each image plane, if needs */ - void *p[SCMN_IMGB_MAX_PLANE]; - /* color space type of image */ - int cs; - /* left postion, if needs */ - int x; - /* top position, if needs */ - int y; - /* to align memory */ - int __dummy2; - /* arbitrary data */ - int data[16]; - /* dma buf fd */ - int dma_buf_fd[SCMN_IMGB_MAX_PLANE]; - /* buffer share method */ - int buf_share_method; - /* Y plane size in case of ST12 */ - int y_size; - /* UV plane size in case of ST12 */ - int uv_size; - /* Tizen buffer object */ - void *bo[SCMN_IMGB_MAX_PLANE]; - /* JPEG data */ - void *jpeg_data; - /* JPEG size */ - int jpeg_size; - /* TZ memory buffer */ - int tz_enable; -} SCMN_IMGB; - -/* Debugging category */ -#include -GST_DEBUG_CATEGORY_STATIC (gst_debug_evaspixmapsink); -#define GST_CAT_DEFAULT gst_debug_evaspixmapsink -GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE); - -enum { - DEGREE_0, - DEGREE_90, - DEGREE_180, - DEGREE_270, - DEGREE_NUM, -}; - -enum { - DISP_GEO_METHOD_LETTER_BOX = 0, - DISP_GEO_METHOD_ORIGIN_SIZE, - DISP_GEO_METHOD_FULL_SCREEN, - DISP_GEO_METHOD_CROPPED_FULL_SCREEN, - DISP_GEO_METHOD_CUSTOM_ROI, - DISP_GEO_METHOD_NUM, -}; - -enum { - FLIP_NONE = 0, - FLIP_HORIZONTAL, - FLIP_VERTICAL, - FLIP_BOTH, - FLIP_NUM, -}; - -#define DEF_DISPLAY_GEOMETRY_METHOD DISP_GEO_METHOD_LETTER_BOX -#define DEF_DISPLAY_FLIP FLIP_NONE -#define GST_TYPE_EVASPIXMAPSINK_FLIP (gst_evaspixmapsink_flip_get_type()) -#define GST_TYPE_EVASPIXMAPSINK_ROTATE_ANGLE (gst_evaspixmapsink_rotate_angle_get_type()) -#define GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD (gst_evaspixmapsink_display_geometry_method_get_type()) - - -/* macro ******************************************************/ -#define EVASPIXMAPSINK_SET_PIXMAP_ID_TO_GEM_INFO( x_evaspixmapsink, x_pixmap_id ) \ -do \ -{ \ - int i = 0; \ - XV_DATA_PTR data = (XV_DATA_PTR)x_evaspixmapsink->evas_pixmap_buf->xvimage->data; \ - if (data->YBuf > 0) { \ - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { \ - if (evaspixmapsink->gem_info[i].gem_name == data->YBuf) { \ - evaspixmapsink->gem_info[i].ref_pixmap = x_pixmap_id; \ - GST_LOG_OBJECT (x_evaspixmapsink,"pixmap(%d) is marked at index(%d) of gem_info(YBuf)->gem_handle(%d)", x_pixmap_id, i, evaspixmapsink->gem_info[i].gem_handle); \ - break; \ - } \ - } \ - } \ - if (data->CbBuf > 0) { \ - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { \ - if (evaspixmapsink->gem_info[i].gem_name == data->CbBuf) { \ - evaspixmapsink->gem_info[i].ref_pixmap = x_pixmap_id; \ - GST_LOG_OBJECT (x_evaspixmapsink,"pixmap(%d) is marked at index(%d) of gem_info(CbBuf)->gem_handle(%d)", x_pixmap_id, i, evaspixmapsink->gem_info[i].gem_handle); \ - break; \ - } \ - } \ - } \ - if (data->CrBuf > 0) { \ - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { \ - if (evaspixmapsink->gem_info[i].gem_name == data->CrBuf) { \ - evaspixmapsink->gem_info[i].ref_pixmap = x_pixmap_id; \ - GST_LOG_OBJECT (x_evaspixmapsink,"pixmap(%d) is marked at index(%d) of gem_info(CrBuf)->gem_handle(%d)", x_pixmap_id, i, evaspixmapsink->gem_info[i].gem_handle); \ - break; \ - } \ - } \ - } \ -}while(0) - -#define EVASPIXMAPSINK_SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \ -do \ -{ \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event, x_usr_data); \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, x_usr_data); \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_SHOW, evas_callback_show_event, x_usr_data); \ - evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_HIDE, evas_callback_hide_event, x_usr_data); \ -}while(0) - -#define EVASPIXMAPSINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \ -do \ -{ \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event); \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event); \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_SHOW, evas_callback_show_event); \ - evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_HIDE, evas_callback_hide_event); \ -}while(0) - -static GType -gst_evaspixmapsink_flip_get_type(void) -{ - static GType evaspixmapsink_flip_type = 0; - static const GEnumValue flip_type[] = { - { FLIP_NONE, "Flip NONE", "FLIP_NONE"}, - { FLIP_HORIZONTAL, "Flip HORIZONTAL", "FLIP_HORIZONTAL"}, - { FLIP_VERTICAL, "Flip VERTICAL", "FLIP_VERTICAL"}, - { FLIP_BOTH, "Flip BOTH", "FLIP_BOTH"}, - { FLIP_NUM, NULL, NULL}, - }; - - if (!evaspixmapsink_flip_type) { - evaspixmapsink_flip_type = g_enum_register_static("GstEvasPixmapSinkFlipType", flip_type); - } - - return evaspixmapsink_flip_type; -} - -static GType -gst_evaspixmapsink_rotate_angle_get_type(void) -{ - static GType evaspixmapsink_rotate_angle_type = 0; - static const GEnumValue rotate_angle_type[] = { - { 0, "No rotate", "DEGREE_0"}, - { 1, "Rotate 90 degree", "DEGREE_90"}, - { 2, "Rotate 180 degree", "DEGREE_180"}, - { 3, "Rotate 270 degree", "DEGREE_270"}, - { 4, NULL, NULL}, - }; - - if (!evaspixmapsink_rotate_angle_type) { - evaspixmapsink_rotate_angle_type = g_enum_register_static("GstEvasPixmapSinkRotateAngleType", rotate_angle_type); - } - - return evaspixmapsink_rotate_angle_type; -} - -static GType -gst_evaspixmapsink_display_geometry_method_get_type(void) -{ - static GType evaspixmapsink_display_geometry_method_type = 0; - static const GEnumValue display_geometry_method_type[] = { - { 0, "Letter box", "LETTER_BOX"}, - { 1, "Origin size", "ORIGIN_SIZE"}, - { 2, "Full-screen", "FULL_SCREEN"}, - { 3, "Cropped Full-screen", "CROPPED_FULL_SCREEN"}, - { 4, "Explicitely described destination ROI", "CUSTOM_ROI"}, - { 5, NULL, NULL}, - }; - - if (!evaspixmapsink_display_geometry_method_type) { - evaspixmapsink_display_geometry_method_type = g_enum_register_static("GstEvasPixmapSinkDisplayGeometryMethodType", display_geometry_method_type); - } - - return evaspixmapsink_display_geometry_method_type; -} - -typedef struct -{ - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} -MotifWmHints, MwmHints; - -#define MWM_HINTS_DECORATIONS (1L << 1) - -static void gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink); -static GstBufferClass *evaspixmap_buffer_parent_class = NULL; -static void gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf); -static void gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink); -static void gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap); -static void gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink, int idx); -static gboolean gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf); -static gboolean gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink); -static void gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap); -static gint gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps); -static void drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle); -static void drm_fini_close_gem_handle(GstEvasPixmapSink *evaspixmapsink, Pixmap pixmap_id); -static void evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info); -static void evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info); -static void evas_callback_show_event (void *data, Evas *e, Evas_Object *obj, void *event_info); -static void evas_callback_hide_event (void *data, Evas *e, Evas_Object *obj, void *event_info); - -/* Default template - initiated with class struct to allow gst-register to work - without X running */ -static GstStaticPadTemplate gst_evaspixmapsink_sink_template_factory = - GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("video/x-raw-rgb, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " - "height = (int) [ 1, MAX ]; " - "video/x-raw-yuv, " - "framerate = (fraction) [ 0, MAX ], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]") - ); - -enum -{ - PROP_0, - PROP_CONTRAST, - PROP_BRIGHTNESS, - PROP_HUE, - PROP_SATURATION, - PROP_DISPLAY, - PROP_SYNCHRONOUS, - PROP_PIXEL_ASPECT_RATIO, - PROP_DEVICE, - PROP_DEVICE_NAME, - PROP_DOUBLE_BUFFER, - PROP_AUTOPAINT_COLORKEY, - PROP_COLORKEY, - PROP_PIXMAP_WIDTH, - PROP_PIXMAP_HEIGHT, - PROP_FLIP, - PROP_ROTATE_ANGLE, - PROP_DISPLAY_GEOMETRY_METHOD, - PROP_ZOOM, - PROP_DST_ROI_X, - PROP_DST_ROI_Y, - PROP_DST_ROI_W, - PROP_DST_ROI_H, - PROP_STOP_VIDEO, - PROP_EVAS_OBJECT, - PROP_VISIBLE, - PROP_ORIGIN_SIZE, -}; - -static GstVideoSinkClass *parent_class = NULL; - -/* ============================================================= */ -/* */ -/* Private Methods */ -/* */ -/* ============================================================= */ - -/* evaspixmap buffers */ - -#define GST_TYPE_EVASPIXMAP_BUFFER (gst_evaspixmap_buffer_get_type()) - -#define GST_IS_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVASPIXMAP_BUFFER)) -#define GST_EVASPIXMAP_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVASPIXMAP_BUFFER, GstEvasPixmapBuffer)) - -static int get_millis_time() -{ - struct timespec tp; - clock_gettime(CLOCK_MONOTONIC, &tp); - return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L); -} - -static void -ecore_pipe_callback_handler (void *data, void *buffer, unsigned int nbyte) -{ - GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink*)data; - GST_DEBUG_OBJECT (evaspixmapsink,"[START] Evas_Object(0x%x)", evaspixmapsink->eo); - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink - ecore thread cb : TOTAL", FALSE); - int i = 0; - guint idx = 0; - GstXPixmap *xpixmap = NULL; - - if (!data ) { - GST_WARNING_OBJECT (evaspixmapsink,"data is NULL.."); - return; - } - if (!evaspixmapsink->eo) { - GST_WARNING_OBJECT (evaspixmapsink,"evas object is NULL.."); - return; - } - if (!evaspixmapsink->visible) { - GST_WARNING_OBJECT (evaspixmapsink,"visible is false.."); - return; - } - - /* mapping evas object with xpixmap */ - if (evaspixmapsink->do_link) { - GST_DEBUG_OBJECT (evaspixmapsink,"do link"); - evas_object_image_size_set(evaspixmapsink->eo, evaspixmapsink->w, evaspixmapsink->h); - if (evaspixmapsink->xpixmap[idx]->pixmap) { - Evas_Native_Surface surf; - surf.version = EVAS_NATIVE_SURFACE_VERSION; - surf.type = EVAS_NATIVE_SURFACE_X11; - surf.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); - surf.data.x11.pixmap = evaspixmapsink->xpixmap[idx]->pixmap; - __ta__("evaspixmapsink - ecore thread cb : _native_surface_set(LINK)", evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); ); - evaspixmapsink->do_link = FALSE; - } else { - GST_WARNING_OBJECT (evaspixmapsink,"pixmap is NULL.."); - return; - } - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]->prev_pixmap && evaspixmapsink->xpixmap[i]->prev_gc && evaspixmapsink->prev_damage[i]) { - GST_LOG_OBJECT (evaspixmapsink,"Free pixmap(%d), gc(%x), destroy previous damage(%d)", - evaspixmapsink->xpixmap[i]->prev_pixmap, evaspixmapsink->xpixmap[i]->prev_gc, evaspixmapsink->prev_damage[i]); - g_mutex_lock (evaspixmapsink->x_lock); - XFreePixmap(evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->prev_pixmap); - XFreeGC (evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[i]->prev_gc); - XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->prev_damage[i]); - XSync(evaspixmapsink->xcontext->disp, FALSE); - g_mutex_unlock (evaspixmapsink->x_lock); - evaspixmapsink->xpixmap[i]->prev_pixmap = 0; - evaspixmapsink->xpixmap[i]->prev_gc = 0; - evaspixmapsink->prev_damage[i] = NULL; - } - } - - } else { - GST_DEBUG_OBJECT (evaspixmapsink,"update"); - /* update evas image object size */ - if (evaspixmapsink->use_origin_size) { - evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evaspixmapsink->w, &evaspixmapsink->h); - } - - g_mutex_lock (evaspixmapsink->pixmap_ref_lock); - - /* find a oldest damaged pixmap */ - int temp_time = 0; - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->last_updated_idx == i) { - continue; - } else { - xpixmap = evaspixmapsink->xpixmap[i]; - if (xpixmap->ref > 0 && xpixmap->damaged_time) { - if (temp_time == 0) { - temp_time = xpixmap->damaged_time; - idx = i; - } else { - if (temp_time > xpixmap->damaged_time) { - temp_time = xpixmap->damaged_time; - idx = i; - } - } - } - } - } - - xpixmap = evaspixmapsink->xpixmap[idx]; - if (xpixmap->pixmap) { - if (evaspixmapsink->last_updated_idx != idx) { - Evas_Native_Surface surf; - surf.version = EVAS_NATIVE_SURFACE_VERSION; - surf.type = EVAS_NATIVE_SURFACE_X11; - surf.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); - surf.data.x11.pixmap = xpixmap->pixmap; - if (evaspixmapsink->eo) { - evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); - } - __ta__("evaspixmapsink - ecore thread cb : _native_surface_set", evas_object_image_native_surface_set(evaspixmapsink->eo, &surf); ); - GST_LOG_OBJECT (evaspixmapsink,"update, native_surface_set of xpixmap[%d]",idx); - if (evaspixmapsink->last_updated_idx == -1) { - xpixmap->damaged_time = 0; - GST_INFO_OBJECT (evaspixmapsink,"this is the first time to request to update(do not DECREASE ref-count) : pixmap(%d), refcount(%d), damaged_time(%d), idx(%d)", - xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time, idx); - } else { - xpixmap = evaspixmapsink->xpixmap[evaspixmapsink->last_updated_idx]; - xpixmap->ref--; - xpixmap->damaged_time = 0; - GST_INFO_OBJECT (evaspixmapsink,"pixmap ref-count DECREASED : pixmap(%d), refcount(%d), damaged_time(%d), idx(%d)", - xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time, evaspixmapsink->last_updated_idx); - } - evaspixmapsink->last_updated_idx = idx; - } - - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evas_object_image update", FALSE); - evas_object_image_pixels_dirty_set (evaspixmapsink->eo, 1); - evas_object_image_fill_set(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h); - evas_object_image_data_update_add(evaspixmapsink->eo, 0, 0, evaspixmapsink->w, evaspixmapsink->h); - MMTA_ACUM_ITEM_END("evaspixmapsink evas_object_image update", FALSE); - //GST_LOG_OBJECT (evaspixmapsink,"request to update : pixmap idx(%d), ref(%d)", idx, xpixmap->ref); - } else { - GST_ERROR_OBJECT (evaspixmapsink,"pixmap is NULL.."); - } - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); - } - - MMTA_ACUM_ITEM_END("evaspixmapsink - ecore thread cb : TOTAL", FALSE); - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); -} - -static inline gboolean -is_evas_image_object (Evas_Object *obj) -{ - const char *type; - if (!obj) { - GST_ERROR ("evas image object is NULL.."); - return FALSE; - } - type = evas_object_type_get (obj); - if (!type) { - GST_ERROR ("could not find type of the evas object.."); - return FALSE; - } - if (strcmp (type, "image") == 0) { - return TRUE; - } - return FALSE; -} - -static void -evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - int w = 0; - int h = 0; - float former_ratio = 0; - float ratio = 0; - float abs_margin = 0; - int i = 0; - - GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink *)data; - GST_DEBUG_OBJECT (evaspixmapsink,"[START] evas_image_object(%x), tid(%u)", obj, (unsigned int)pthread_self()); - - evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &w, &h); - GST_DEBUG_OBJECT (evaspixmapsink,"resized : w(%d), h(%d)", w, h); - if (!evaspixmapsink->use_origin_size && - (evaspixmapsink->w != w || evaspixmapsink->h != h)) { - former_ratio = (float)evaspixmapsink->w / evaspixmapsink->h; - ratio = (float)w / h; - evaspixmapsink->w = w; - evaspixmapsink->h = h; - -#ifdef COMPARE_RATIO - GST_DEBUG_OBJECT (evaspixmapsink,"resized : ratio(%.3f=>%.3f)", former_ratio, ratio); - if ( former_ratio >= ratio ) { - abs_margin = former_ratio - ratio; - } else { - abs_margin = ratio - former_ratio; - } - /* re-link_pixmap can only be set when ratio is changed */ - if ( abs_margin >= MARGIN_OF_ERROR ) { -#endif - if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) { - GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed..."); - return; - } - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { - if (evaspixmapsink->gem_info[i].ref_pixmap > 0) { - GST_LOG_OBJECT (evaspixmapsink,"set ref_pixmap(%d) to 0 in gem_info[%d]", evaspixmapsink->gem_info[i].ref_pixmap, i); - evaspixmapsink->gem_info[i].ref_pixmap = 0; - } - } -#ifdef COMPARE_RATIO - } -#endif - } - - if (GST_STATE(evaspixmapsink) == GST_STATE_PAUSED) { - gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf); - } - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); -} - -static void -evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - GstEvasPixmapSink *evaspixmapsink = data; - if (!evaspixmapsink) { - GST_WARNING ("evaspixmapsink is NULL.."); - return; - } - GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); - - EVASPIXMAPSINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( evaspixmapsink->eo ); - if (evaspixmapsink->eo) { - evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); - evaspixmapsink->eo = NULL; - } - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); -} - -static void -evas_callback_show_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink *)data; - GST_INFO_OBJECT (evaspixmapsink,"show evas_image_object(%x) from pid(%d), tid(%u)", obj, getpid(), (unsigned int)pthread_self()); -} - -static void -evas_callback_hide_event (void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - GstEvasPixmapSink *evaspixmapsink = (GstEvasPixmapSink *)data; - GST_INFO_OBJECT (evaspixmapsink,"hide evas_image_object(%x) from pid(%d), tid(%u)", obj, getpid(), (unsigned int)pthread_self()); -} - -/* X11 stuff */ -static gboolean error_caught = FALSE; - -static int -gst_evaspixmapsink_handle_xerror (Display * display, XErrorEvent * xevent) -{ - char error_msg[1024]; - - XGetErrorText (display, xevent->error_code, error_msg, 1024); - GST_DEBUG ("evaspixmapsink triggered an XError. error: %s", error_msg); - error_caught = TRUE; - return 0; -} - -#ifdef HAVE_XSHM -/* This function checks that it is actually really possible to create an image - using XShm */ -static gboolean -gst_evaspixmapsink_check_xshm_calls (GstXContext * xcontext) -{ - XvImage *xvimage; - XShmSegmentInfo SHMInfo; - gint size; - int (*handler) (Display *, XErrorEvent *); - gboolean result = FALSE; - gboolean did_attach = FALSE; - - g_return_val_if_fail (xcontext != NULL, FALSE); - - /* Sync to ensure any older errors are already processed */ - XSync (xcontext->disp, FALSE); - - /* Set defaults so we don't free these later unnecessarily */ - SHMInfo.shmaddr = ((void *) -1); - SHMInfo.shmid = -1; - - /* Setting an error handler to catch failure */ - error_caught = FALSE; - handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror); - - /* Trying to create a 1x1 picture */ - GST_DEBUG ("XvShmCreateImage of 1x1"); - xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id, - xcontext->im_format, NULL, 1, 1, &SHMInfo); - - /* Might cause an error, sync to ensure it is noticed */ - XSync (xcontext->disp, FALSE); - if (!xvimage || error_caught) { - GST_WARNING ("could not XvShmCreateImage a 1x1 image"); - goto beach; - } - size = xvimage->data_size; - - SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); - if (SHMInfo.shmid == -1) { - GST_WARNING ("could not get shared memory of %d bytes", size); - goto beach; - } - - SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0); - if (SHMInfo.shmaddr == ((void *) -1)) { - GST_WARNING ("Failed to shmat: %s", g_strerror (errno)); - /* Clean up the shared memory segment */ - shmctl (SHMInfo.shmid, IPC_RMID, NULL); - goto beach; - } - - xvimage->data = SHMInfo.shmaddr; - SHMInfo.readOnly = FALSE; - - if (XShmAttach (xcontext->disp, &SHMInfo) == 0) { - GST_WARNING ("Failed to XShmAttach"); - /* Clean up the shared memory segment */ - shmctl (SHMInfo.shmid, IPC_RMID, NULL); - goto beach; - } - - /* Sync to ensure we see any errors we caused */ - XSync (xcontext->disp, FALSE); - - /* Delete the shared memory segment as soon as everyone is attached. - * This way, it will be deleted as soon as we detach later, and not - * leaked if we crash. */ - shmctl (SHMInfo.shmid, IPC_RMID, NULL); - - if (!error_caught) { - GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid, - SHMInfo.shmseg); - - did_attach = TRUE; - /* store whether we succeeded in result */ - result = TRUE; - } else { - GST_WARNING ("MIT-SHM extension check failed at XShmAttach. " - "Not using shared memory."); - } - -beach: - /* Sync to ensure we swallow any errors we caused and reset error_caught */ - XSync (xcontext->disp, FALSE); - - error_caught = FALSE; - XSetErrorHandler (handler); - - if (did_attach) { - GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx", - SHMInfo.shmid, SHMInfo.shmseg); - XShmDetach (xcontext->disp, &SHMInfo); - XSync (xcontext->disp, FALSE); - } - if (SHMInfo.shmaddr != ((void *) -1)) - shmdt (SHMInfo.shmaddr); - if (xvimage) - XFree (xvimage); - return result; -} -#endif /* HAVE_XSHM */ - -/* This function destroys a GstEvasPixmap handling XShm availability */ -static void -gst_evaspixmap_buffer_destroy (GstEvasPixmapBuffer *evaspixmapbuf) -{ - GstEvasPixmapSink *evaspixmapsink; - - evaspixmapsink = evaspixmapbuf->evaspixmapsink; - if (G_UNLIKELY (evaspixmapsink == NULL)) { - goto no_sink; - } - GST_DEBUG_OBJECT (evaspixmapsink, "Destroying buffer"); - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - GST_OBJECT_LOCK (evaspixmapsink); - - /* We might have some buffers destroyed after changing state to NULL */ - if (evaspixmapsink->xcontext == NULL) { - GST_DEBUG_OBJECT (evaspixmapsink,"Destroying XvImage after Xcontext"); -#ifdef HAVE_XSHM - /* Need to free the shared memory segment even if the x context - * was already cleaned up */ - if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) { - shmdt (evaspixmapbuf->SHMInfo.shmaddr); - } -#endif - goto beach; - } - g_mutex_lock (evaspixmapsink->x_lock); - -#ifdef HAVE_XSHM - if (evaspixmapsink->xcontext->use_xshm) { - if (evaspixmapbuf->SHMInfo.shmaddr != ((void *) -1)) { - GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmDetaching from 0x%x id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg); - XShmDetach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo); - XSync (evaspixmapsink->xcontext->disp, FALSE); - shmdt (evaspixmapbuf->SHMInfo.shmaddr); - } - if (evaspixmapbuf->xvimage) - XFree (evaspixmapbuf->xvimage); - } else -#endif /* HAVE_XSHM */ - { - if (evaspixmapbuf->xvimage) { - if (evaspixmapbuf->xvimage->data) { - g_free (evaspixmapbuf->xvimage->data); - } - XFree (evaspixmapbuf->xvimage); - } - } - - XSync (evaspixmapsink->xcontext->disp, FALSE); - - g_mutex_unlock (evaspixmapsink->x_lock); - -beach: - GST_OBJECT_UNLOCK (evaspixmapsink); - evaspixmapbuf->evaspixmapsink = NULL; - gst_object_unref (evaspixmapsink); - - GST_MINI_OBJECT_CLASS (evaspixmap_buffer_parent_class)->finalize (GST_MINI_OBJECT(evaspixmapbuf)); - - return; - - no_sink: - { - GST_WARNING ("no sink found"); - return; - } -} - -static void -gst_evaspixmap_buffer_finalize (GstEvasPixmapBuffer *evaspixmapbuf) -{ - GstEvasPixmapSink *evaspixmapsink; - - evaspixmapsink = evaspixmapbuf->evaspixmapsink; - if (G_UNLIKELY (evaspixmapsink == NULL)) { - GST_WARNING_OBJECT (evaspixmapsink,"no sink found"); - return; - } - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - /* If our geometry changed we can't reuse that image. */ - GST_LOG_OBJECT (evaspixmapsink,"destroy image as sink is shutting down"); - gst_evaspixmap_buffer_destroy (evaspixmapbuf); -} - -static void -gst_evaspixmap_buffer_free (GstEvasPixmapBuffer *evaspixmapbuf) -{ - /* make sure it is not recycled */ - evaspixmapbuf->width = -1; - evaspixmapbuf->height = -1; - gst_buffer_unref (GST_BUFFER (evaspixmapbuf)); -} - -static void -gst_evaspixmap_buffer_init (GstEvasPixmapBuffer *evaspixmapbuf, gpointer g_class) -{ -#ifdef HAVE_XSHM - evaspixmapbuf->SHMInfo.shmaddr = ((void *) -1); - evaspixmapbuf->SHMInfo.shmid = -1; -#endif -} - -static void -gst_evaspixmap_buffer_class_init (gpointer g_class, gpointer class_data) -{ - GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class); - - evaspixmap_buffer_parent_class = g_type_class_peek_parent (g_class); - - mini_object_class->finalize = (GstMiniObjectFinalizeFunction) gst_evaspixmap_buffer_finalize; -} - -static GType -gst_evaspixmap_buffer_get_type (void) -{ - static GType _gst_evaspixmap_buffer_type; - - if (G_UNLIKELY (_gst_evaspixmap_buffer_type == 0)) { - static const GTypeInfo evaspixmap_buffer_info = { - sizeof (GstBufferClass), - NULL, - NULL, - gst_evaspixmap_buffer_class_init, - NULL, - NULL, - sizeof (GstEvasPixmapBuffer), - 0, - (GInstanceInitFunc) gst_evaspixmap_buffer_init, - NULL - }; - _gst_evaspixmap_buffer_type = g_type_register_static (GST_TYPE_BUFFER, - "GstEvasPixmapBuffer", &evaspixmap_buffer_info, 0); - } - return _gst_evaspixmap_buffer_type; -} - -/* This function handles GstEvasPixmapBuffer creation depending on XShm availability */ -static GstEvasPixmapBuffer* -gst_evaspixmap_buffer_new (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps) -{ - GstEvasPixmapBuffer *evaspixmapbuf = NULL; - GstStructure *structure = NULL; - gboolean succeeded = FALSE; - int (*handler) (Display *, XErrorEvent *); - - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL); - - if (caps == NULL) { - return NULL; - } - - evaspixmapbuf = (GstEvasPixmapBuffer*) gst_mini_object_new (GST_TYPE_EVASPIXMAP_BUFFER); - GST_DEBUG_OBJECT (evaspixmapsink,"Creating new EvasPixmapBuffer"); - - structure = gst_caps_get_structure (caps, 0); - - if (!gst_structure_get_int (structure, "width", &evaspixmapbuf->width) || !gst_structure_get_int (structure, "height", &evaspixmapbuf->height)) { - GST_WARNING_OBJECT (evaspixmapsink,"failed getting geometry from caps %" GST_PTR_FORMAT, caps); - } - - GST_LOG_OBJECT (evaspixmapsink,"creating %dx%d", evaspixmapbuf->width, evaspixmapbuf->height); - - GST_LOG_OBJECT (evaspixmapsink,"aligned size %dx%d", evaspixmapsink->aligned_width, evaspixmapsink->aligned_height); - if (evaspixmapsink->aligned_width == 0 || evaspixmapsink->aligned_height == 0) { - GST_INFO_OBJECT (evaspixmapsink,"aligned size is zero. set size of caps."); - evaspixmapsink->aligned_width = evaspixmapbuf->width; - evaspixmapsink->aligned_height = evaspixmapbuf->height; - } - - evaspixmapbuf->im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps); - if (evaspixmapbuf->im_format == -1) { - GST_WARNING_OBJECT (evaspixmapsink,"failed to get format from caps %"GST_PTR_FORMAT, caps); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels", - evaspixmapbuf->width, evaspixmapbuf->height), ("Invalid input caps")); - goto beach_unlocked; - } - - GST_INFO_OBJECT (evaspixmapsink, "FOURCC format : %c%c%c%c", evaspixmapbuf->im_format, evaspixmapbuf->im_format>>8, - evaspixmapbuf->im_format>>16, evaspixmapbuf->im_format>>24); - - evaspixmapbuf->evaspixmapsink = gst_object_ref (evaspixmapsink); - - g_mutex_lock (evaspixmapsink->x_lock); - - /* Sync to ensure we swallow any errors we caused and reset error_caught */ - XSync (evaspixmapsink->xcontext->disp, FALSE); - - /* Setting an error handler to catch failure */ - error_caught = FALSE; - handler = XSetErrorHandler (gst_evaspixmapsink_handle_xerror); - -#ifdef HAVE_XSHM - if (evaspixmapsink->xcontext->use_xshm) { - int expected_size; - evaspixmapbuf->xvimage = XvShmCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, evaspixmapbuf->im_format, NULL, - evaspixmapsink->aligned_width, evaspixmapsink->aligned_height, &evaspixmapbuf->SHMInfo); - if (!evaspixmapbuf->xvimage || error_caught) { - if (error_caught) { - GST_ERROR_OBJECT (evaspixmapsink,"error_caught!"); - } - if(!evaspixmapbuf->xvimage) { - GST_ERROR_OBJECT (evaspixmapsink,"XvShmCreateImage() failed"); - } - g_mutex_unlock (evaspixmapsink->x_lock); - /* Reset error handler */ - error_caught = FALSE; - XSetErrorHandler (handler); - /* Push an error */ - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE,("Failed to create output image buffer of %dx%d pixels",evaspixmapbuf->width, - evaspixmapbuf->height),("could not XvShmCreateImage a %dx%d image",evaspixmapbuf->width, evaspixmapbuf->height)); - goto beach_unlocked; - } - - /* we have to use the returned data_size for our shm size */ - evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size; - GST_LOG_OBJECT (evaspixmapsink,"XShm image size is %" G_GSIZE_FORMAT, evaspixmapbuf->size); - - /* calculate the expected size. This is only for sanity checking the - * number we get from X. */ - switch (evaspixmapbuf->im_format) { - case GST_MAKE_FOURCC ('I', '4', '2', '0'): - case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - { - gint pitches[3]; - gint offsets[3]; - guint plane; - - offsets[0] = 0; - pitches[0] = GST_ROUND_UP_4 (evaspixmapbuf->width); - offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (evaspixmapbuf->height); - pitches[1] = GST_ROUND_UP_8 (evaspixmapbuf->width) / 2; - offsets[2] = - offsets[1] + pitches[1] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2; - pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2; - - expected_size = offsets[2] + pitches[2] * GST_ROUND_UP_2 (evaspixmapbuf->height) / 2; - - for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) { - GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a expected pitch of %d bytes, " "offset of %d", - plane, pitches[plane], offsets[plane]); - } - break; - } - case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): - case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): - expected_size = evaspixmapbuf->height * GST_ROUND_UP_4 (evaspixmapbuf->width * 2); - break; - case GST_MAKE_FOURCC ('S', 'T', '1', '2'): - case GST_MAKE_FOURCC ('S', 'N', '1', '2'): - case GST_MAKE_FOURCC ('S', 'U', 'Y', 'V'): - case GST_MAKE_FOURCC ('S', 'U', 'Y', '2'): - case GST_MAKE_FOURCC ('S', '4', '2', '0'): - case GST_MAKE_FOURCC ('S', 'Y', 'V', 'Y'): - case GST_MAKE_FOURCC ('I', 'T', 'L', 'V'): - case GST_MAKE_FOURCC ('S', 'R', '3', '2'): - expected_size = sizeof(SCMN_IMGB); - break; - default: - expected_size = 0; - break; - } - if (expected_size != 0 && evaspixmapbuf->size != expected_size) { - GST_WARNING_OBJECT (evaspixmapsink,"unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)", evaspixmapbuf->size, expected_size); - } - - /* Be verbose about our XvImage stride */ - { - guint plane; - for (plane = 0; plane < evaspixmapbuf->xvimage->num_planes; plane++) { - GST_DEBUG_OBJECT (evaspixmapsink,"Plane %u has a pitch of %d bytes, ""offset of %d", plane, - evaspixmapbuf->xvimage->pitches[plane], evaspixmapbuf->xvimage->offsets[plane]); - } - } - - evaspixmapbuf->SHMInfo.shmid = shmget (IPC_PRIVATE, evaspixmapbuf->size,IPC_CREAT | 0777); - if (evaspixmapbuf->SHMInfo.shmid == -1) { - g_mutex_unlock (evaspixmapsink->x_lock); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, - ("Failed to create output image buffer of %dx%d pixels", evaspixmapbuf->width, evaspixmapbuf->height), - ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",evaspixmapbuf->size)); - goto beach_unlocked; - } - - evaspixmapbuf->SHMInfo.shmaddr = shmat (evaspixmapbuf->SHMInfo.shmid, NULL, 0); - if (evaspixmapbuf->SHMInfo.shmaddr == ((void *) -1)) { - g_mutex_unlock (evaspixmapsink->x_lock); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, - ("Failed to create output image buffer of %dx%d pixels", - evaspixmapbuf->width, evaspixmapbuf->height), - ("Failed to shmat: %s", g_strerror (errno))); - /* Clean up the shared memory segment */ - shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL); - goto beach_unlocked; - } - - evaspixmapbuf->xvimage->data = evaspixmapbuf->SHMInfo.shmaddr; - evaspixmapbuf->SHMInfo.readOnly = FALSE; - - if (XShmAttach (evaspixmapsink->xcontext->disp, &evaspixmapbuf->SHMInfo) == 0) { - /* Clean up the shared memory segment */ - shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL); - - g_mutex_unlock (evaspixmapsink->x_lock); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, - ("Failed to create output image buffer of %dx%d pixels", - evaspixmapbuf->width, evaspixmapbuf->height), ("Failed to XShmAttach")); - goto beach_unlocked; - } - - XSync (evaspixmapsink->xcontext->disp, FALSE); - - /* Delete the shared memory segment as soon as we everyone is attached. - * This way, it will be deleted as soon as we detach later, and not - * leaked if we crash. */ - shmctl (evaspixmapbuf->SHMInfo.shmid, IPC_RMID, NULL); - - GST_DEBUG_OBJECT (evaspixmapsink,"XServer ShmAttached to 0x%x, id 0x%lx", evaspixmapbuf->SHMInfo.shmid, evaspixmapbuf->SHMInfo.shmseg); - } else -#endif /* HAVE_XSHM */ - { - evaspixmapbuf->xvimage = XvCreateImage (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, - evaspixmapbuf->im_format, NULL, evaspixmapsink->aligned_width, evaspixmapsink->aligned_height); - if (!evaspixmapbuf->xvimage || error_caught) { - g_mutex_unlock (evaspixmapsink->x_lock); - /* Reset error handler */ - error_caught = FALSE; - XSetErrorHandler (handler); - /* Push an error */ - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, - ("Failed to create outputimage buffer of %dx%d pixels", - evaspixmapbuf->width, evaspixmapbuf->height), - ("could not XvCreateImage a %dx%d image", - evaspixmapbuf->width, evaspixmapbuf->height)); - goto beach_unlocked; - } - - /* we have to use the returned data_size for our image size */ - evaspixmapbuf->size = evaspixmapbuf->xvimage->data_size; - evaspixmapbuf->xvimage->data = g_malloc (evaspixmapbuf->size); - - XSync (evaspixmapsink->xcontext->disp, FALSE); - } - - /* Reset error handler */ - error_caught = FALSE; - XSetErrorHandler (handler); - - succeeded = TRUE; - - GST_BUFFER_DATA (evaspixmapbuf) = (guchar *) evaspixmapbuf->xvimage->data; - GST_BUFFER_SIZE (evaspixmapbuf) = evaspixmapbuf->size; - - g_mutex_unlock (evaspixmapsink->x_lock); - -beach_unlocked: - if (!succeeded) { - gst_evaspixmap_buffer_free (evaspixmapbuf); - evaspixmapbuf = NULL; - } - - return evaspixmapbuf; -} - -/* This function puts a GstEvasPixmapBuffer on a GstEvasPixmapSink's pixmap. Returns FALSE - * if no pixmap was available */ -static gboolean -gst_evaspixmap_buffer_put (GstEvasPixmapSink *evaspixmapsink, GstEvasPixmapBuffer *evaspixmapbuf) -{ - GstVideoRectangle result; - - GstVideoRectangle src_origin = { 0, 0, 0, 0}; - GstVideoRectangle src_input = { 0, 0, 0, 0}; - GstVideoRectangle src = { 0, 0, 0, 0}; - GstVideoRectangle dst = { 0, 0, 0, 0}; - int rotate = 0; - int ret = 0; - int idx = 0; - GstXPixmap *xpixmap = NULL; - - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink evaspixmap_buffer_put()", FALSE); - - /* We take the flow_lock. If expose is in there we don't want to run - concurrently from the data flow thread */ - g_mutex_lock (evaspixmapsink->flow_lock); - - if (G_UNLIKELY (evaspixmapsink->xpixmap[idx] == NULL)) { - GST_WARNING_OBJECT (evaspixmapsink, "xpixmap is NULL. Skip buffer_put." ); - g_mutex_unlock(evaspixmapsink->flow_lock); - return FALSE; - } - if (evaspixmapsink->visible == FALSE) { - GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. Skip buffer_put." ); - g_mutex_unlock(evaspixmapsink->flow_lock); - return TRUE; - } - if (!evaspixmapbuf) { - GST_WARNING_OBJECT (evaspixmapsink, "evaspixmapbuf is NULL. Skip buffer_put." ); - g_mutex_unlock(evaspixmapsink->flow_lock); - return TRUE; - } - - g_mutex_lock (evaspixmapsink->pixmap_ref_lock); - if (evaspixmapsink->last_updated_idx == -1) { - /* if it has never been updated any frame in Ecore thread, do below */ - idx = 0; - xpixmap = evaspixmapsink->xpixmap[idx]; - xpixmap->ref = 1; - GST_LOG_OBJECT (evaspixmapsink, "last_updated_idx(%d), we use index[%d] of pixmap buffers : pixmap(%d), ref(%d)", - evaspixmapsink->last_updated_idx, idx, xpixmap->pixmap, xpixmap->ref); - } else { - for (idx = 0; idx < evaspixmapsink->num_of_pixmaps; idx++) { - if (idx == evaspixmapsink->last_updated_idx) { - continue; - } else { - xpixmap = evaspixmapsink->xpixmap[idx]; - if (xpixmap->ref == 0 && xpixmap->damaged_time == 0) { - xpixmap->ref++; - GST_LOG_OBJECT (evaspixmapsink, "found an available pixmap(%d) : xpixmap[%d]", xpixmap->pixmap, idx); - GST_INFO_OBJECT (evaspixmapsink,"pixmap ref-count INCREASED : pixmap(%d), refcount(%d)", xpixmap->pixmap, xpixmap->ref); - break; - } - } - } - if (idx == evaspixmapsink->num_of_pixmaps) { - GST_LOG_OBJECT (evaspixmapsink, "Could not find a pixmap with idle state, skip buffer_put." ); - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); - g_mutex_unlock(evaspixmapsink->flow_lock); - return TRUE; - } - } - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); - - gst_evaspixmapsink_xpixmap_update_geometry(evaspixmapsink, idx); - - src.x = src.y = 0; - src_origin.x = src_origin.y = src_input.x = src_input.y = 0; - src_input.w = src_origin.w = evaspixmapsink->video_width; - src_input.h = src_origin.h = evaspixmapsink->video_height; - if (evaspixmapsink->use_origin_size || - (evaspixmapsink->rotate_angle == DEGREE_0 || - evaspixmapsink->rotate_angle == DEGREE_180)) { - src.w = src_origin.w; - src.h = src_origin.h; - } else { - src.w = src_origin.h; - src.h = src_origin.w; - } - - dst.w = evaspixmapsink->render_rect.w; /* pixmap width */ - dst.h = evaspixmapsink->render_rect.h; /* pixmap height */ - - if (!evaspixmapsink->use_origin_size) { - static Atom atom_rotation = None; - static Atom atom_hflip = None; - static Atom atom_vflip = None; - gboolean set_hflip = FALSE; - gboolean set_vflip = FALSE; - - /* compensation of size information (between evas image object's and pixmap's) */ - if (evaspixmapsink->sizediff_width > 1) { - if (evaspixmapsink->sizediff_height > 1) { - dst.w -= (evaspixmapsink->sizediff_width >> 1) << 1; - dst.h -= (evaspixmapsink->sizediff_height >> 1) << 1; - } else { - dst.w -= (evaspixmapsink->sizediff_width >> 1) << 1; - } - } else if (evaspixmapsink->sizediff_height > 1) { - dst.h -= (evaspixmapsink->sizediff_height >> 1) << 1; - } - - switch (evaspixmapsink->display_geometry_method) { - case DISP_GEO_METHOD_LETTER_BOX: - gst_video_sink_center_rect (src, dst, &result, TRUE); - result.x += evaspixmapsink->render_rect.x; - result.y += evaspixmapsink->render_rect.y; - GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : letter box"); - break; - case DISP_GEO_METHOD_ORIGIN_SIZE: - gst_video_sink_center_rect (src, dst, &result, FALSE); - gst_video_sink_center_rect (dst, src, &src_input, FALSE); - GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : origin size"); - if (evaspixmapsink->rotate_angle == DEGREE_90 || - evaspixmapsink->rotate_angle == DEGREE_270) { - src_input.x = src_input.x ^ src_input.y; - src_input.y = src_input.x ^ src_input.y; - src_input.x = src_input.x ^ src_input.y; - src_input.w = src_input.w ^ src_input.h; - src_input.h = src_input.w ^ src_input.h; - src_input.w = src_input.w ^ src_input.h; - } - break; - case DISP_GEO_METHOD_FULL_SCREEN: - result.x = result.y = 0; - result.w = evaspixmapsink->xpixmap[idx]->width; - result.h = evaspixmapsink->xpixmap[idx]->height; - GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : full screen"); - break; - case DISP_GEO_METHOD_CROPPED_FULL_SCREEN: - GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : cropped full screen"); - gst_video_sink_center_rect(dst, src, &src_input, TRUE); - result.x = result.y = 0; - result.w = dst.w; - result.h = dst.h; - if (evaspixmapsink->rotate_angle == DEGREE_90 || - evaspixmapsink->rotate_angle == DEGREE_270) { - src_input.x = src_input.x ^ src_input.y; - src_input.y = src_input.x ^ src_input.y; - src_input.x = src_input.x ^ src_input.y; - src_input.w = src_input.w ^ src_input.h; - src_input.h = src_input.w ^ src_input.h; - src_input.w = src_input.w ^ src_input.h; - } - break; - case DISP_GEO_METHOD_CUSTOM_ROI: - switch (evaspixmapsink->rotate_angle) { - case DEGREE_90: - result.w = evaspixmapsink->dst_roi.h; - result.h = evaspixmapsink->dst_roi.w; - result.x = evaspixmapsink->dst_roi.y; - result.y = evaspixmapsink->xpixmap[idx]->height - evaspixmapsink->dst_roi.x - evaspixmapsink->dst_roi.w; - break; - case DEGREE_180: - result.w = evaspixmapsink->dst_roi.w; - result.h = evaspixmapsink->dst_roi.h; - result.x = evaspixmapsink->xpixmap[idx]->width - result.w - evaspixmapsink->dst_roi.x; - result.y = evaspixmapsink->xpixmap[idx]->height - result.h - evaspixmapsink->dst_roi.y; - break; - case DEGREE_270: - result.w = evaspixmapsink->dst_roi.h; - result.h = evaspixmapsink->dst_roi.w; - result.x = evaspixmapsink->xpixmap[idx]->width - evaspixmapsink->dst_roi.y - evaspixmapsink->dst_roi.h; - result.y = evaspixmapsink->dst_roi.x; - break; - default: - result.x = evaspixmapsink->dst_roi.x; - result.y = evaspixmapsink->dst_roi.y; - result.w = evaspixmapsink->dst_roi.w; - result.h = evaspixmapsink->dst_roi.h; - break; - } - GST_LOG_OBJECT(evaspixmapsink, "rotate[%d], ROI input[%d,%d,%dx%d] > result[%d,%d,%dx%d]", - evaspixmapsink->rotate_angle, - evaspixmapsink->dst_roi.x, evaspixmapsink->dst_roi.y, evaspixmapsink->dst_roi.w, evaspixmapsink->dst_roi.h, - result.x, result.y, result.w, result.h); - break; - default: - break; - } - GST_DEBUG_OBJECT (evaspixmapsink, "GEO_METHOD : src(%dx%d), dst(%dx%d), result(%dx%d), result_x(%d), result_y(%d)", - src.w,src.h,dst.w,dst.h,result.w,result.h,result.x,result.y); - - switch( evaspixmapsink->rotate_angle ) { - case DEGREE_0: - break; - case DEGREE_90: - rotate = 270; - break; - case DEGREE_180: - rotate = 180; - break; - case DEGREE_270: - rotate = 90; - break; - default: - GST_WARNING_OBJECT( evaspixmapsink, "Unsupported rotation [%d]... set DEGREE 0.", - evaspixmapsink->rotate_angle ); - break; - } - - /* set display rotation */ - if (atom_rotation == None) { - atom_rotation = XInternAtom(evaspixmapsink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_ROTATION", False); - } - - ret = XvSetPortAttribute(evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_rotation, rotate); - if (ret != Success) { - GST_ERROR_OBJECT( evaspixmapsink, "XvSetPortAttribute failed[%d]. disp[%x],xv_port_id[%d],atom[%x],rotate[%d]", - ret, evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_rotation, rotate ); - return FALSE; - } - - /* set display flip */ - if (atom_hflip == None) { - atom_hflip = XInternAtom(evaspixmapsink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_HFLIP", False); - } - if (atom_vflip == None) { - atom_vflip = XInternAtom(evaspixmapsink->xcontext->disp, "_USER_WM_PORT_ATTRIBUTE_VFLIP", False); - } - - switch (evaspixmapsink->flip) { - case FLIP_HORIZONTAL: - set_hflip = TRUE; - set_vflip = FALSE; - break; - case FLIP_VERTICAL: - set_hflip = FALSE; - set_vflip = TRUE; - break; - case FLIP_BOTH: - set_hflip = TRUE; - set_vflip = TRUE; - break; - case FLIP_NONE: - default: - set_hflip = FALSE; - set_vflip = FALSE; - break; - } - GST_INFO_OBJECT(evaspixmapsink, "set rotate %d HFLIP %d, VFLIP %d", rotate, set_hflip, set_vflip); - - ret = XvSetPortAttribute(evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_hflip, set_hflip); - if (ret != Success) { - GST_WARNING("set HFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],hflip[%d]", - ret, evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_hflip, set_hflip); - } - ret = XvSetPortAttribute(evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_vflip, set_vflip); - if (ret != Success) { - GST_WARNING("set VFLIP failed[%d]. disp[%x],xv_port_id[%d],atom[%x],vflip[%d]", - ret, evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, atom_vflip, set_vflip); - } - - } else { - result.x = result.y = 0; - result.w = evaspixmapsink->xpixmap[idx]->width; - result.h = evaspixmapsink->xpixmap[idx]->height; - GST_INFO_OBJECT (evaspixmapsink, "USE ORIGIN SIZE, no geometry method, no rotation/flip" ); - } - - g_mutex_lock (evaspixmapsink->x_lock); - - /* We scale to the pixmap's geometry */ -#ifdef HAVE_XSHM - if (evaspixmapsink->xcontext->use_xshm) { - GST_LOG_OBJECT (evaspixmapsink,"XvShmPutImage with image %dx%d and pixmap %dx%d, from xvimage %" - GST_PTR_FORMAT, - evaspixmapbuf->width, evaspixmapbuf->height, - evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h, evaspixmapbuf); - - /* Trim as proper size */ - if (src_input.w % 2 == 1) { - src_input.w += 1; - } - if (src_input.h % 2 == 1) { - src_input.h += 1; - } - - GST_LOG_OBJECT (evaspixmapsink, "screen[%dx%d],pixmap[%d,%d,%dx%d],method[%d],rotate[%d],src[%dx%d],dst[%d,%d,%dx%d],input[%d,%d,%dx%d],result[%d,%d,%dx%d]", - evaspixmapsink->scr_w, evaspixmapsink->scr_h, - evaspixmapsink->xpixmap[idx]->x, evaspixmapsink->xpixmap[idx]->y, evaspixmapsink->xpixmap[idx]->width, evaspixmapsink->xpixmap[idx]->height, - evaspixmapsink->display_geometry_method, rotate, - src_origin.w, src_origin.h, - dst.x, dst.y, dst.w, dst.h, - src_input.x, src_input.y, src_input.w, src_input.h, - result.x, result.y, result.w, result.h ); - - if (evaspixmapsink->visible) { - if (evaspixmapsink->buf_shared_type == BUF_SHARE_METHOD_FD) { - EVASPIXMAPSINK_SET_PIXMAP_ID_TO_GEM_INFO (evaspixmapsink, evaspixmapsink->xpixmap[idx]->pixmap); - } - ret = XvShmPutImage (evaspixmapsink->xcontext->disp, - evaspixmapsink->xcontext->xv_port_id, - evaspixmapsink->xpixmap[idx]->pixmap, - evaspixmapsink->xpixmap[idx]->gc, evaspixmapbuf->xvimage, - src_input.x, src_input.y, src_input.w, src_input.h, - result.x, result.y, result.w, result.h, FALSE); - GST_LOG_OBJECT (evaspixmapsink, "XvShmPutImage return value [%d]", ret ); - } else { - GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." ); - } - } else -#endif /* HAVE_XSHM */ - { - if (evaspixmapsink->visible) { - XvPutImage (evaspixmapsink->xcontext->disp, - evaspixmapsink->xcontext->xv_port_id, - evaspixmapsink->xpixmap[idx]->pixmap, - evaspixmapsink->xpixmap[idx]->gc, evaspixmapbuf->xvimage, - evaspixmapsink->disp_x, evaspixmapsink->disp_y, - evaspixmapsink->disp_width, evaspixmapsink->disp_height, - result.x, result.y, result.w, result.h); - } else { - GST_WARNING_OBJECT (evaspixmapsink, "visible is FALSE. skip this image..." ); - } - } - XSync (evaspixmapsink->xcontext->disp, FALSE); - - g_mutex_unlock (evaspixmapsink->x_lock); - g_mutex_unlock (evaspixmapsink->flow_lock); - - MMTA_ACUM_ITEM_END("evaspixmapsink evaspixmap_buffer_put()", FALSE); - - return TRUE; -} - -static int -drm_init(GstEvasPixmapSink *evaspixmapsink) -{ - Display *dpy; - int i = 0; - int eventBase = 0; - int errorBase = 0; - int dri2Major = 0; - int dri2Minor = 0; - char *driverName = NULL; - char *deviceName = NULL; - struct drm_auth auth_arg = {0}; - - evaspixmapsink->drm_fd = -1; - - dpy = XOpenDisplay(0); - - /* DRI2 */ - if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) { - GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryExtension()"); - goto ERROR_CASE; - } - - if (!DRI2QueryVersion(dpy, &dri2Major, &dri2Minor)) { - GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2QueryVersion"); - goto ERROR_CASE; - } - - if (!DRI2Connect(dpy, RootWindow(dpy, DefaultScreen(dpy)), &driverName, &deviceName)) { - GST_ERROR_OBJECT (evaspixmapsink,"failed to DRI2Connect"); - goto ERROR_CASE; - } - - if (!driverName || !deviceName) { - GST_ERROR_OBJECT (evaspixmapsink,"driverName or deviceName is not valid"); - goto ERROR_CASE; - } - - GST_INFO_OBJECT (evaspixmapsink,"Open drm device : %s", deviceName); - - /* get the drm_fd though opening the deviceName */ - evaspixmapsink->drm_fd = open(deviceName, O_RDWR); - if (evaspixmapsink->drm_fd < 0) { - GST_ERROR_OBJECT (evaspixmapsink,"cannot open drm device (%s)", deviceName); - goto ERROR_CASE; - } - - /* get magic from drm to authentication */ - if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GET_MAGIC, &auth_arg)) { - GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm auth magic"); - close(evaspixmapsink->drm_fd); - evaspixmapsink->drm_fd = -1; - goto ERROR_CASE; - } - - if (!DRI2Authenticate(dpy, RootWindow(dpy, DefaultScreen(dpy)), auth_arg.magic)) { - GST_ERROR_OBJECT (evaspixmapsink,"cannot get drm authentication from X"); - close(evaspixmapsink->drm_fd); - evaspixmapsink->drm_fd = -1; - goto ERROR_CASE; - } - - /* init gem handle */ - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { - evaspixmapsink->gem_info[i].dmabuf_fd = 0; - evaspixmapsink->gem_info[i].gem_handle = 0; - evaspixmapsink->gem_info[i].gem_name = 0; - evaspixmapsink->gem_info[i].bo = 0; - evaspixmapsink->gem_info[i].ref_pixmap = 0; - } - - XCloseDisplay(dpy); - free(driverName); - free(deviceName); - - return 0; - -ERROR_CASE: - XCloseDisplay(dpy); - if (driverName) { - free(driverName); - } - if (deviceName) { - free(deviceName); - } - - return -1; -} - -static void -drm_fini(GstEvasPixmapSink *evaspixmapsink) -{ - if (evaspixmapsink->drm_fd >= 0) { - GST_INFO_OBJECT (evaspixmapsink,"close drm_fd(%d)", evaspixmapsink->drm_fd); - close(evaspixmapsink->drm_fd); - evaspixmapsink->drm_fd = -1; - } -} - -static unsigned int -drm_init_convert_dmabuf_gemname(GstEvasPixmapSink *evaspixmapsink, int dmabuf_fd) -{ - struct drm_prime_handle prime_arg = {0,}; - struct drm_gem_flink flink_arg = {0,}; - int i = 0; - - if (evaspixmapsink->drm_fd < 0) { - GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened"); - return 0; - } - - if (dmabuf_fd <= 0) { - GST_DEBUG_OBJECT (evaspixmapsink,"Ignore wrong dmabuf fd(%d)", dmabuf_fd); /* temporarily change log level to DEBUG for reducing WARNING level log */ - return 0; - } - - /* check duplicated dmabuf fd */ - for (i = 0 ; i < MAX_GEM_BUFFER_NUM ; i++) { - if (evaspixmapsink->gem_info[i].dmabuf_fd == dmabuf_fd) { - GST_LOG_OBJECT (evaspixmapsink,"already got fd(%u) with name(%u)", dmabuf_fd, evaspixmapsink->gem_info[i].gem_name); - return evaspixmapsink->gem_info[i].gem_name; - } - - if (evaspixmapsink->gem_info[i].dmabuf_fd == 0) { - GST_LOG_OBJECT (evaspixmapsink,"empty gem_info[%d] found", i); - break; - } - } - - if (i == MAX_GEM_BUFFER_NUM) { - GST_WARNING_OBJECT (evaspixmapsink,"too many buffers[dmabuf_fd(%d). skip it]", dmabuf_fd); - return 0; - } - - evaspixmapsink->gem_info[i].dmabuf_fd = dmabuf_fd; - prime_arg.fd = dmabuf_fd; - if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_arg)) { - GST_ERROR_OBJECT (evaspixmapsink,"non dmabuf fd(%d)", dmabuf_fd); - return 0; - } - - evaspixmapsink->gem_info[i].gem_handle = prime_arg.handle; - GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_handle = %u", i, prime_arg.handle); - - flink_arg.handle = prime_arg.handle; - if (ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_FLINK, &flink_arg)) { - GST_ERROR_OBJECT (evaspixmapsink,"cannot convert drm handle to name"); - return 0; - } - - evaspixmapsink->gem_info[i].gem_name = flink_arg.name; - GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_name = %u", i, flink_arg.name); - - return flink_arg.name; -} - -static unsigned int -tbm_init_convert_bo_gemname(GstEvasPixmapSink *evaspixmapsink, unsigned int bo) -{ - int i = 0; - - if (bo <= 0) { - GST_DEBUG_OBJECT (evaspixmapsink,"Ignore wrong bo(%u)", bo); /* temporarily change log level to DEBUG for reducing WARNING level log */ - return 0; - } - - /* check duplicated dmabuf bo */ - for (i = 0 ; i < MAX_GEM_BUFFER_NUM ; i++) { - if (evaspixmapsink->gem_info[i].bo == bo) { - GST_LOG_OBJECT (evaspixmapsink,"already got bo(%u) with name(%u)", bo, evaspixmapsink->gem_info[i].gem_name); - return evaspixmapsink->gem_info[i].gem_name; - } - - if (evaspixmapsink->gem_info[i].bo == 0) { - GST_LOG_OBJECT (evaspixmapsink,"empty gem_info[%d] found", i); - break; - } - } - - if (i == MAX_GEM_BUFFER_NUM) { - GST_WARNING_OBJECT (evaspixmapsink,"too many buffers[dmabuf_bo(%d). skip it]", bo); - return 0; - } - - evaspixmapsink->gem_info[i].bo = bo; - evaspixmapsink->gem_info[i].gem_name = tbm_bo_export(bo); - GST_LOG_OBJECT (evaspixmapsink,"gem_info[%d].gem_name = %u", i, evaspixmapsink->gem_info[i].gem_name); - - return evaspixmapsink->gem_info[i].gem_name; -} - -static void -drm_fini_close_gem_handle(GstEvasPixmapSink *evaspixmapsink, Pixmap pixmap_id) -{ - int i = 0; - if (evaspixmapsink->drm_fd >= 0) { - if (pixmap_id == 0) { - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { - if (evaspixmapsink->gem_info[i].dmabuf_fd > 0) { - if (evaspixmapsink->buf_shared_type == BUF_SHARE_METHOD_FD) { - GST_INFO_OBJECT (evaspixmapsink,"close gem_handle(%u)", evaspixmapsink->gem_info[i].gem_handle); - drm_close_gem(evaspixmapsink, evaspixmapsink->gem_info[i].gem_handle); - } - evaspixmapsink->gem_info[i].dmabuf_fd = 0; - evaspixmapsink->gem_info[i].gem_handle = 0; - evaspixmapsink->gem_info[i].gem_name = 0; - evaspixmapsink->gem_info[i].bo = 0; - evaspixmapsink->gem_info[i].ref_pixmap = 0; - break; - } - } - } else { - for (i = 0; i < MAX_GEM_BUFFER_NUM; i++) { - if (evaspixmapsink->gem_info[i].dmabuf_fd > 0 && evaspixmapsink->gem_info[i].ref_pixmap == pixmap_id) { - if (evaspixmapsink->buf_shared_type == BUF_SHARE_METHOD_FD) { - GST_INFO_OBJECT (evaspixmapsink,"close gem_handle(%u) for pixmap_id(%d)", - evaspixmapsink->gem_info[i].gem_handle, pixmap_id); - drm_close_gem(evaspixmapsink, evaspixmapsink->gem_info[i].gem_handle); - } - evaspixmapsink->gem_info[i].dmabuf_fd = 0; - evaspixmapsink->gem_info[i].gem_handle = 0; - evaspixmapsink->gem_info[i].gem_name = 0; - evaspixmapsink->gem_info[i].bo = 0; - evaspixmapsink->gem_info[i].ref_pixmap = 0; - break; - } - } - } - } -} - -static void -drm_close_gem(GstEvasPixmapSink *evaspixmapsink, unsigned int gem_handle) -{ - struct drm_gem_close close_arg = {0,}; - - if (evaspixmapsink->drm_fd < 0) { - GST_ERROR_OBJECT (evaspixmapsink,"DRM is not opened"); - return; - } - - if (gem_handle == 0) { - GST_ERROR_OBJECT (evaspixmapsink,"invalid gem_handle(%d)",gem_handle); - return; - } - - close_arg.handle = gem_handle; - if (gem_handle > 0 && ioctl(evaspixmapsink->drm_fd, DRM_IOCTL_GEM_CLOSE, &close_arg)) { - GST_ERROR_OBJECT (evaspixmapsink,"cannot close drm gem handle(%d)", gem_handle); - return; - } - - return; -} - -/* This function destroys a GstXPixmap */ -static void -gst_evaspixmapsink_xpixmap_destroy (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap) -{ - g_return_if_fail (xpixmap != NULL); - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - g_mutex_lock (evaspixmapsink->x_lock); - - if(xpixmap->pixmap) { - GST_LOG_OBJECT (evaspixmapsink,"Free pixmap(%d)", xpixmap->pixmap); - XFreePixmap(evaspixmapsink->xcontext->disp, xpixmap->pixmap); - xpixmap->pixmap = 0; - } - - if (xpixmap->gc) { - XFreeGC (evaspixmapsink->xcontext->disp, xpixmap->gc); - } - - XSync (evaspixmapsink->xcontext->disp, FALSE); - - g_mutex_unlock (evaspixmapsink->x_lock); - - g_free (xpixmap); -} - -static void -gst_evaspixmapsink_xpixmap_update_geometry (GstEvasPixmapSink *evaspixmapsink, int idx) -{ - Window root_window; - XWindowAttributes root_attr; - - int cur_pixmap_x = 0; - int cur_pixmap_y = 0; - unsigned int cur_pixmap_width = 0; - unsigned int cur_pixmap_height = 0; - unsigned int cur_pixmap_border_width = 0; - unsigned int cur_pixmap_depth = 0; - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - /* Update the window geometry */ - g_mutex_lock (evaspixmapsink->x_lock); - if (G_UNLIKELY (evaspixmapsink->xpixmap[idx] == NULL)) { - g_mutex_unlock (evaspixmapsink->x_lock); - return; - } - - /* Get root window and size of current pixmap */ - XGetGeometry( evaspixmapsink->xcontext->disp, evaspixmapsink->xpixmap[idx]->pixmap, &root_window, - &cur_pixmap_x, &cur_pixmap_y, /* relative x, y, for pixmap these are alway 0 */ - &cur_pixmap_width, &cur_pixmap_height, - &cur_pixmap_border_width, &cur_pixmap_depth ); /* cur_pixmap_border_width, cur_pixmap_depth are not used */ - - evaspixmapsink->xpixmap[idx]->width = cur_pixmap_width; - evaspixmapsink->xpixmap[idx]->height = cur_pixmap_height; - - evaspixmapsink->xpixmap[idx]->x = cur_pixmap_x; - evaspixmapsink->xpixmap[idx]->y = cur_pixmap_y; - - /* Get size of root window == size of screen */ - XGetWindowAttributes(evaspixmapsink->xcontext->disp, root_window, &root_attr); - - evaspixmapsink->scr_w = root_attr.width; - evaspixmapsink->scr_h = root_attr.height; - - if (!evaspixmapsink->have_render_rect) { - evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = 0; - evaspixmapsink->render_rect.w = cur_pixmap_width; - evaspixmapsink->render_rect.h = cur_pixmap_height; - } - - GST_LOG_OBJECT (evaspixmapsink,"screen size %dx%d, current pixmap geometry %d,%d,%dx%d, render_rect %d,%d,%dx%d", - evaspixmapsink->scr_w, evaspixmapsink->scr_h, - evaspixmapsink->xpixmap[idx]->x, evaspixmapsink->xpixmap[idx]->y, - evaspixmapsink->xpixmap[idx]->width, evaspixmapsink->xpixmap[idx]->height, - evaspixmapsink->render_rect.x, evaspixmapsink->render_rect.y, - evaspixmapsink->render_rect.w, evaspixmapsink->render_rect.h); - - g_mutex_unlock (evaspixmapsink->x_lock); -} - -static void -gst_evaspixmapsink_xpixmap_clear (GstEvasPixmapSink *evaspixmapsink, GstXPixmap *xpixmap) -{ - g_return_if_fail (xpixmap != NULL); - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - if (!xpixmap->pixmap) { - GST_WARNING_OBJECT (evaspixmapsink,"pixmap was not created.."); - return; - } - - g_mutex_lock (evaspixmapsink->x_lock); - - if (!evaspixmapsink->xcontext) { - GST_WARNING_OBJECT (evaspixmapsink,"xcontext is null.."); - g_mutex_unlock (evaspixmapsink->x_lock); - return; - } - - if (evaspixmapsink->stop_video) { - XvStopVideo (evaspixmapsink->xcontext->disp, evaspixmapsink->xcontext->xv_port_id, xpixmap->pixmap); - } - XSync (evaspixmapsink->xcontext->disp, FALSE); - - g_mutex_unlock (evaspixmapsink->x_lock); - - g_mutex_lock (evaspixmapsink->pixmap_ref_lock); - evaspixmapsink->last_updated_idx = -1; - xpixmap->ref = 0; - xpixmap->damaged_time = 0; - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); -} - -/* This function commits our internal colorbalance settings to our grabbed Xv - port. If the xcontext is not initialized yet it simply returns */ -static void -gst_evaspixmapsink_update_colorbalance (GstEvasPixmapSink *evaspixmapsink) -{ - GList *channels = NULL; - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - /* If we haven't initialized the X context we can't update anything */ - if (evaspixmapsink->xcontext == NULL) - return; - - /* Don't set the attributes if they haven't been changed, to avoid - * rounding errors changing the values */ - if (!evaspixmapsink->cb_changed) - return; - - /* For each channel of the colorbalance we calculate the correct value - doing range conversion and then set the Xv port attribute to match our - values. */ - channels = evaspixmapsink->xcontext->channels_list; - - while (channels) { - if (channels->data && GST_IS_COLOR_BALANCE_CHANNEL (channels->data)) { - GstColorBalanceChannel *channel = NULL; - Atom prop_atom; - gint value = 0; - gdouble convert_coef; - - channel = GST_COLOR_BALANCE_CHANNEL (channels->data); - g_object_ref (channel); - - /* Our range conversion coef */ - convert_coef = (channel->max_value - channel->min_value) / 2000.0; - - if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) { - value = evaspixmapsink->hue; - } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) { - value = evaspixmapsink->saturation; - } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) { - value = evaspixmapsink->contrast; - } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) { - value = evaspixmapsink->brightness; - } else { - g_warning ("got an unknown channel %s", channel->label); - g_object_unref (channel); - return; - } - - /* Committing to Xv port */ - g_mutex_lock (evaspixmapsink->x_lock); - prop_atom = - XInternAtom (evaspixmapsink->xcontext->disp, channel->label, True); - if (prop_atom != None) { - int xv_value; - xv_value = - floor (0.5 + (value + 1000) * convert_coef + channel->min_value); - XvSetPortAttribute (evaspixmapsink->xcontext->disp, - evaspixmapsink->xcontext->xv_port_id, prop_atom, xv_value); - } - g_mutex_unlock (evaspixmapsink->x_lock); - - g_object_unref (channel); - } - channels = g_list_next (channels); - } -} - -static void -gst_lookup_xv_port_from_adaptor (GstXContext *xcontext, XvAdaptorInfo *adaptors, int adaptor_no) -{ - gint j; - gint res; - - /* Do we support XvImageMask ? */ - if (!(adaptors[adaptor_no].type & XvImageMask)) { - GST_DEBUG ("XV Adaptor %s has no support for XvImageMask", adaptors[adaptor_no].name); - return; - } - - /* We found such an adaptor, looking for an available port */ - for (j = 0; j < adaptors[adaptor_no].num_ports && !xcontext->xv_port_id; j++) { - /* We try to grab the port */ - res = XvGrabPort (xcontext->disp, adaptors[adaptor_no].base_id + j, 0); - if (Success == res) { - xcontext->xv_port_id = adaptors[adaptor_no].base_id + j; - GST_DEBUG ("XV Adaptor %s with %ld ports", adaptors[adaptor_no].name, adaptors[adaptor_no].num_ports); - } else { - GST_DEBUG ("GrabPort %d for XV Adaptor %s failed: %d", j, adaptors[adaptor_no].name, res); - } - } -} - -/* This function generates a caps with all supported format by the first - Xv grabable port we find. We store each one of the supported formats in a - format list and append the format to a newly created caps that we return - If this function does not return NULL because of an error, it also grabs - the port via XvGrabPort */ -static GstCaps* -gst_evaspixmapsink_get_xv_support (GstEvasPixmapSink *evaspixmapsink, GstXContext *xcontext) -{ - gint i; - XvAdaptorInfo *adaptors; - gint nb_formats; - XvImageFormatValues *formats = NULL; - guint nb_encodings; - XvEncodingInfo *encodings = NULL; - gulong max_w = G_MAXINT, max_h = G_MAXINT; - GstCaps *caps = NULL; - GstCaps *rgb_caps = NULL; - - g_return_val_if_fail (xcontext != NULL, NULL); - - /* First let's check that XVideo extension is available */ - if (!XQueryExtension (xcontext->disp, "XVideo", &i, &i, &i)) { - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS, - ("Could not initialise Xv output"), - ("XVideo extension is not available")); - return NULL; - } - - /* Then we get adaptors list */ - if (Success != XvQueryAdaptors (xcontext->disp, xcontext->root, - &xcontext->nb_adaptors, &adaptors)) { - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS, - ("Could not initialise Xv output"), - ("Failed getting XV adaptors list")); - return NULL; - } - - xcontext->xv_port_id = 0; - - GST_DEBUG_OBJECT (evaspixmapsink,"Found %u XV adaptor(s)", xcontext->nb_adaptors); - - xcontext->adaptors = - (gchar **) g_malloc0 (xcontext->nb_adaptors * sizeof (gchar *)); - - /* Now fill up our adaptor name array */ - for (i = 0; i < xcontext->nb_adaptors; i++) { - xcontext->adaptors[i] = g_strdup (adaptors[i].name); - } - - if (evaspixmapsink->adaptor_no < xcontext->nb_adaptors) { - /* Find xv port from user defined adaptor */ - gst_lookup_xv_port_from_adaptor (xcontext, adaptors, evaspixmapsink->adaptor_no); - } - - if (!xcontext->xv_port_id) { - /* Now search for an adaptor that supports XvImageMask */ - for (i = 0; i < xcontext->nb_adaptors && !xcontext->xv_port_id; i++) { - gst_lookup_xv_port_from_adaptor (xcontext, adaptors, i); - evaspixmapsink->adaptor_no = i; - } - } - - XvFreeAdaptorInfo (adaptors); - - if (!xcontext->xv_port_id) { - evaspixmapsink->adaptor_no = -1; - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, BUSY, - ("Could not initialise Xv output"), ("No port available")); - return NULL; - } - - /* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */ - { - int count, todo = 3; - XvAttribute *const attr = XvQueryPortAttributes (xcontext->disp, - xcontext->xv_port_id, &count); - static const char autopaint[] = "XV_AUTOPAINT_COLORKEY"; - static const char dbl_buffer[] = "XV_DOUBLE_BUFFER"; - static const char colorkey[] = "XV_COLORKEY"; - - GST_DEBUG_OBJECT (evaspixmapsink,"Checking %d Xv port attributes", count); - - evaspixmapsink->have_autopaint_colorkey = FALSE; - evaspixmapsink->have_double_buffer = FALSE; - evaspixmapsink->have_colorkey = FALSE; - - for (i = 0; ((i < count) && todo); i++) - if (!strcmp (attr[i].name, autopaint)) { - const Atom atom = XInternAtom (xcontext->disp, autopaint, False); - - /* turn on autopaint colorkey */ - XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom, - (evaspixmapsink->autopaint_colorkey ? 1 : 0)); - todo--; - evaspixmapsink->have_autopaint_colorkey = TRUE; - } else if (!strcmp (attr[i].name, dbl_buffer)) { - const Atom atom = XInternAtom (xcontext->disp, dbl_buffer, False); - - XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom, - (evaspixmapsink->double_buffer ? 1 : 0)); - todo--; - evaspixmapsink->have_double_buffer = TRUE; - } else if (!strcmp (attr[i].name, colorkey)) { - /* Set the colorkey, default is something that is dark but hopefully - * won't randomly appear on the screen elsewhere (ie not black or greys) - * can be overridden by setting "colorkey" property - */ - const Atom atom = XInternAtom (xcontext->disp, colorkey, False); - guint32 ckey = 0; - gboolean set_attr = TRUE; - guint cr, cg, cb; - - /* set a colorkey in the right format RGB565/RGB888 - * We only handle these 2 cases, because they're the only types of - * devices we've encountered. If we don't recognise it, leave it alone - */ - cr = (evaspixmapsink->colorkey >> 16); - cg = (evaspixmapsink->colorkey >> 8) & 0xFF; - cb = (evaspixmapsink->colorkey) & 0xFF; - switch (xcontext->depth) { - case 16: /* RGB 565 */ - cr >>= 3; - cg >>= 2; - cb >>= 3; - ckey = (cr << 11) | (cg << 5) | cb; - break; - case 24: - case 32: /* RGB 888 / ARGB 8888 */ - ckey = (cr << 16) | (cg << 8) | cb; - break; - default: - GST_DEBUG_OBJECT (evaspixmapsink,"Unknown bit depth %d for Xv Colorkey - not adjusting", xcontext->depth); - set_attr = FALSE; - break; - } - - if (set_attr) { - ckey = CLAMP (ckey, (guint32) attr[i].min_value, - (guint32) attr[i].max_value); - GST_LOG_OBJECT (evaspixmapsink,"Setting color key for display depth %d to 0x%x", xcontext->depth, ckey); - - XvSetPortAttribute (xcontext->disp, xcontext->xv_port_id, atom, - (gint) ckey); - } - todo--; - evaspixmapsink->have_colorkey = TRUE; - } - - XFree (attr); - } - - /* Get the list of encodings supported by the adapter and look for the - * XV_IMAGE encoding so we can determine the maximum width and height - * supported */ - XvQueryEncodings (xcontext->disp, xcontext->xv_port_id, &nb_encodings, - &encodings); - - for (i = 0; i < nb_encodings; i++) { - GST_LOG_OBJECT (evaspixmapsink, - "Encoding %d, name %s, max wxh %lux%lu rate %d/%d", - i, encodings[i].name, encodings[i].width, encodings[i].height, - encodings[i].rate.numerator, encodings[i].rate.denominator); - if (strcmp (encodings[i].name, "XV_IMAGE") == 0) { - max_w = encodings[i].width; - max_h = encodings[i].height; - evaspixmapsink->scr_w = max_w; - evaspixmapsink->scr_h = max_h; - } - } - - XvFreeEncodingInfo (encodings); - - /* We get all image formats supported by our port */ - formats = XvListImageFormats (xcontext->disp, - xcontext->xv_port_id, &nb_formats); - caps = gst_caps_new_empty (); - for (i = 0; i < nb_formats; i++) { - GstCaps *format_caps = NULL; - gboolean is_rgb_format = FALSE; - - /* We set the image format of the xcontext to an existing one. This - is just some valid image format for making our xshm calls check before - caps negotiation really happens. */ - xcontext->im_format = formats[i].id; - - switch (formats[i].type) { - case XvRGB: - { - XvImageFormatValues *fmt = &(formats[i]); - gint endianness = G_BIG_ENDIAN; - - if (fmt->byte_order == LSBFirst) { - /* our caps system handles 24/32bpp RGB as big-endian. */ - if (fmt->bits_per_pixel == 24 || fmt->bits_per_pixel == 32) { - fmt->red_mask = GUINT32_TO_BE (fmt->red_mask); - fmt->green_mask = GUINT32_TO_BE (fmt->green_mask); - fmt->blue_mask = GUINT32_TO_BE (fmt->blue_mask); - - if (fmt->bits_per_pixel == 24) { - fmt->red_mask >>= 8; - fmt->green_mask >>= 8; - fmt->blue_mask >>= 8; - } - } else - endianness = G_LITTLE_ENDIAN; - } - - format_caps = gst_caps_new_simple ("video/x-raw-rgb", - "format", GST_TYPE_FOURCC, formats[i].id, - "endianness", G_TYPE_INT, endianness, - "depth", G_TYPE_INT, fmt->depth, - "bpp", G_TYPE_INT, fmt->bits_per_pixel, - "red_mask", G_TYPE_INT, fmt->red_mask, - "green_mask", G_TYPE_INT, fmt->green_mask, - "blue_mask", G_TYPE_INT, fmt->blue_mask, - "width", GST_TYPE_INT_RANGE, 1, max_w, - "height", GST_TYPE_INT_RANGE, 1, max_h, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - - is_rgb_format = TRUE; - break; - } - case XvYUV: - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC, formats[i].id, - "width", GST_TYPE_INT_RANGE, 1, max_w, - "height", GST_TYPE_INT_RANGE, 1, max_h, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - break; - default: - g_assert_not_reached (); - break; - } - - if (format_caps) { - GstEvasPixmapFormat *format = NULL; - - format = g_new0 (GstEvasPixmapFormat, 1); - if (format) { - format->format = formats[i].id; - format->caps = gst_caps_copy (format_caps); - xcontext->formats_list = g_list_append (xcontext->formats_list, format); - } - - if (is_rgb_format) { - if (rgb_caps == NULL) - rgb_caps = format_caps; - else - gst_caps_append (rgb_caps, format_caps); - } else - gst_caps_append (caps, format_caps); - } - } - - /* Collected all caps into either the caps or rgb_caps structures. - * Append rgb_caps on the end of YUV, so that YUV is always preferred */ - if (rgb_caps) - gst_caps_append (caps, rgb_caps); - - if (formats) - XFree (formats); - - GST_DEBUG_OBJECT (evaspixmapsink,"Generated the following caps: %" GST_PTR_FORMAT, caps); - - if (gst_caps_is_empty (caps)) { - gst_caps_unref (caps); - XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0); - GST_ELEMENT_ERROR (evaspixmapsink, STREAM, WRONG_TYPE, (NULL), - ("No supported format found")); - return NULL; - } - - return caps; -} - -static gpointer -gst_evaspixmapsink_event_thread (GstEvasPixmapSink * evaspixmapsink) -{ - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL); - int damage_base = 0; - int damage_err_base = 0; - int damage_case = 0; - XEvent e; - int i = 0; - Display *disp = NULL; - - GST_OBJECT_LOCK (evaspixmapsink); - - if (evaspixmapsink->xcontext && evaspixmapsink->xcontext->disp) { - disp = evaspixmapsink->xcontext->disp; - } else { - GST_ERROR_OBJECT (evaspixmapsink,"evaspixmapsink->xcontext(->disp) is not ready"); - return NULL; - } - - if (!XDamageQueryExtension(evaspixmapsink->xcontext->disp, &damage_base, &damage_err_base)) { - GST_ERROR_OBJECT (evaspixmapsink,"XDamageQueryExtension() failed"); - return NULL; - } - damage_case = (int)damage_base + XDamageNotify; - - while (evaspixmapsink->running) { - GST_OBJECT_UNLOCK (evaspixmapsink); - - g_mutex_lock (evaspixmapsink->x_lock); - while (XPending (disp)) { - XNextEvent (disp, &e); - if (e.type == damage_case ) { - XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&e; - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - GstXPixmap *xpixmap = evaspixmapsink->xpixmap[i]; - if (xpixmap && damage_ev->drawable == xpixmap->pixmap) { - g_mutex_lock(evaspixmapsink->pixmap_ref_lock); - if (xpixmap->ref) { - /* set it only if damage event comes from _buffer_put() */ - xpixmap->damaged_time = (gint)get_millis_time(); - } - GST_LOG_OBJECT (evaspixmapsink,"event_handler : got a damage event for pixmap(%d), refcount(%d), damaged_time(%d)", - xpixmap->pixmap, xpixmap->ref, xpixmap->damaged_time); - g_mutex_unlock(evaspixmapsink->pixmap_ref_lock); - - __ta__("evaspixmapsink ecore_pipe_write", ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink));); - GST_DEBUG_OBJECT (evaspixmapsink,"event_handler : after call ecore_pipe_write() for pixmap(%d)", xpixmap->pixmap); - XDamageSubtract (evaspixmapsink->xcontext->disp, evaspixmapsink->damage[i], None, None ); - - if (evaspixmapsink->buf_shared_type == BUF_SHARE_METHOD_FD) { - if (GST_STATE(evaspixmapsink) == GST_STATE_PLAYING) { - drm_fini_close_gem_handle(evaspixmapsink, xpixmap->pixmap); - } - } - break; - } - } - if (i == evaspixmapsink->num_of_pixmaps) { - GST_WARNING_OBJECT (evaspixmapsink,"event_handler : could not find corresponding pixmap with this damage event(%d)", damage_ev->drawable); - } - } else { - GST_LOG_OBJECT (evaspixmapsink,"event_handler : unidentified event(%d)", e.type); - continue; - } - } - //XSync (disp, FALSE); - g_mutex_unlock (evaspixmapsink->x_lock); - - g_usleep (G_USEC_PER_SEC / 40); - GST_OBJECT_LOCK (evaspixmapsink); - } - GST_OBJECT_UNLOCK (evaspixmapsink); - return NULL; -} - -static void -gst_evaspixmapsink_manage_event_thread (GstEvasPixmapSink *evaspixmapsink) -{ - /* don't start the thread too early */ - if (evaspixmapsink->xcontext == NULL) { - GST_ERROR_OBJECT (evaspixmapsink,"xcontext is NULL.."); - return; - } - - GST_OBJECT_LOCK (evaspixmapsink); - - if (!evaspixmapsink->event_thread) { - /* Setup our event listening thread */ - GST_DEBUG_OBJECT (evaspixmapsink,"run xevent thread"); - evaspixmapsink->running = TRUE; - evaspixmapsink->event_thread = g_thread_create ( (GThreadFunc) gst_evaspixmapsink_event_thread, evaspixmapsink, TRUE, NULL); - } else { - GST_WARNING_OBJECT (evaspixmapsink,"there already existed the event_thread.. keep going"); - /* Do not finalize the thread in here, Only finalize the thread by calling gst_evaspixmapsink_reset() */ - } - - GST_OBJECT_UNLOCK (evaspixmapsink); -} - - -/* This function calculates the pixel aspect ratio based on the properties - * in the xcontext structure and stores it there. */ -static void -gst_evaspixmapsink_calculate_pixel_aspect_ratio (GstXContext *xcontext) -{ - static const gint par[][2] = { - {1, 1}, /* regular screen */ - {16, 15}, /* PAL TV */ - {11, 10}, /* 525 line Rec.601 video */ - {54, 59}, /* 625 line Rec.601 video */ - {64, 45}, /* 1280x1024 on 16:9 display */ - {5, 3}, /* 1280x1024 on 4:3 display */ - {4, 3} /* 800x600 on 16:9 display */ - }; - gint i; - gint index; - gdouble ratio; - gdouble delta; - -#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1]))) - - /* first calculate the "real" ratio based on the X values; - * which is the "physical" w/h divided by the w/h in pixels of the display */ - ratio = (gdouble) (xcontext->widthmm * xcontext->height) - / (xcontext->heightmm * xcontext->width); - - /* DirectFB's X in 720x576 reports the physical dimensions wrong, so - * override here */ - if (xcontext->width == 720 && xcontext->height == 576) { - ratio = 4.0 * 576 / (3.0 * 720); - } - GST_DEBUG ("calculated pixel aspect ratio: %f", ratio); - /* now find the one from par[][2] with the lowest delta to the real one */ - delta = DELTA (0); - index = 0; - - for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) { - gdouble this_delta = DELTA (i); - - if (this_delta < delta) { - index = i; - delta = this_delta; - } - } - - GST_DEBUG ("Decided on index %d (%d/%d)", index, - par[index][0], par[index][1]); - - g_free (xcontext->par); - xcontext->par = g_new0 (GValue, 1); - g_value_init (xcontext->par, GST_TYPE_FRACTION); - gst_value_set_fraction (xcontext->par, par[index][0], par[index][1]); - GST_DEBUG ("set xcontext PAR to %d/%d", - gst_value_get_fraction_numerator (xcontext->par), - gst_value_get_fraction_denominator (xcontext->par)); -} - -/* This function gets the X Display and global info about it. Everything is - stored in our object and will be cleaned when the object is disposed. Note - here that caps for supported format are generated without any window or - image creation */ -static GstXContext* -gst_evaspixmapsink_xcontext_get (GstEvasPixmapSink *evaspixmapsink) -{ - GstXContext *xcontext = NULL; - XPixmapFormatValues *px_formats = NULL; - gint nb_formats = 0, i, j, N_attr; - XvAttribute *xv_attr; - Atom prop_atom; - const char *channels[4] = { "XV_HUE", "XV_SATURATION", "XV_BRIGHTNESS", "XV_CONTRAST"}; - - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL); - - xcontext = g_new0 (GstXContext, 1); - xcontext->im_format = 0; - - g_mutex_lock (evaspixmapsink->x_lock); - - xcontext->disp = XOpenDisplay (evaspixmapsink->display_name); - - if (!xcontext->disp) { - g_mutex_unlock (evaspixmapsink->x_lock); - g_free (xcontext); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Could not initialise Xv output"), ("Could not open display")); - return NULL; - } - - xcontext->screen = DefaultScreenOfDisplay (xcontext->disp); - xcontext->screen_num = DefaultScreen (xcontext->disp); - xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num); - xcontext->root = DefaultRootWindow (xcontext->disp); - xcontext->white = XWhitePixel (xcontext->disp, xcontext->screen_num); - xcontext->black = XBlackPixel (xcontext->disp, xcontext->screen_num); - xcontext->depth = DefaultDepthOfScreen (xcontext->screen); - - xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num); - xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num); - xcontext->widthmm = DisplayWidthMM (xcontext->disp, xcontext->screen_num); - xcontext->heightmm = DisplayHeightMM (xcontext->disp, xcontext->screen_num); - - GST_DEBUG_OBJECT (evaspixmapsink,"X reports %dx%d pixels and %d mm x %d mm", xcontext->width, xcontext->height, xcontext->widthmm, xcontext->heightmm); - - gst_evaspixmapsink_calculate_pixel_aspect_ratio (xcontext); - /* We get supported pixmap formats at supported depth */ - px_formats = XListPixmapFormats (xcontext->disp, &nb_formats); - - if (!px_formats) { - XCloseDisplay (xcontext->disp); - g_mutex_unlock (evaspixmapsink->x_lock); - g_free (xcontext->par); - g_free (xcontext); - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, SETTINGS, - ("Could not initialise Xv output"), ("Could not get pixel formats")); - return NULL; - } - - /* We get bpp value corresponding to our running depth */ - for (i = 0; i < nb_formats; i++) { - if (px_formats[i].depth == xcontext->depth) - xcontext->bpp = px_formats[i].bits_per_pixel; - } - - XFree (px_formats); - - xcontext->endianness = (ImageByteOrder (xcontext->disp) == LSBFirst) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN; - - /* our caps system handles 24/32bpp RGB as big-endian. */ - if ((xcontext->bpp == 24 || xcontext->bpp == 32) && xcontext->endianness == G_LITTLE_ENDIAN) { - xcontext->endianness = G_BIG_ENDIAN; - xcontext->visual->red_mask = GUINT32_TO_BE (xcontext->visual->red_mask); - xcontext->visual->green_mask = GUINT32_TO_BE (xcontext->visual->green_mask); - xcontext->visual->blue_mask = GUINT32_TO_BE (xcontext->visual->blue_mask); - if (xcontext->bpp == 24) { - xcontext->visual->red_mask >>= 8; - xcontext->visual->green_mask >>= 8; - xcontext->visual->blue_mask >>= 8; - } - } - - xcontext->caps = gst_evaspixmapsink_get_xv_support (evaspixmapsink, xcontext); - - if (!xcontext->caps) { - XCloseDisplay (xcontext->disp); - g_mutex_unlock (evaspixmapsink->x_lock); - g_free (xcontext->par); - g_free (xcontext); - /* GST_ELEMENT_ERROR is thrown by gst_evaspixmapsink_get_xv_support */ - return NULL; - } -#ifdef HAVE_XSHM - /* Search for XShm extension support */ - if (XShmQueryExtension (xcontext->disp) && gst_evaspixmapsink_check_xshm_calls (xcontext)) { - xcontext->use_xshm = TRUE; - GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is using XShm extension"); - } else -#endif /* HAVE_XSHM */ - { - xcontext->use_xshm = FALSE; - GST_DEBUG_OBJECT (evaspixmapsink,"evaspixmapsink is not using XShm extension"); - } - - xv_attr = XvQueryPortAttributes (xcontext->disp, xcontext->xv_port_id, &N_attr); - - /* Generate the channels list */ - for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) { - XvAttribute *matching_attr = NULL; - - /* Retrieve the property atom if it exists. If it doesn't exist, - * the attribute itself must not either, so we can skip */ - prop_atom = XInternAtom (xcontext->disp, channels[i], True); - if (prop_atom == None) { - continue; - } - - if (xv_attr != NULL) { - for (j = 0; j < N_attr && matching_attr == NULL; ++j) { - if (!g_ascii_strcasecmp (channels[i], xv_attr[j].name)) { - matching_attr = xv_attr + j; - } - } - } - - if (matching_attr) { - GstColorBalanceChannel *channel; - channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL); - channel->label = g_strdup (channels[i]); - channel->min_value = matching_attr->min_value; - channel->max_value = matching_attr->max_value; - - xcontext->channels_list = g_list_append (xcontext->channels_list, channel); - - /* If the colorbalance settings have not been touched we get Xv values - as defaults and update our internal variables */ - if (!evaspixmapsink->cb_changed) { - gint val; - XvGetPortAttribute (xcontext->disp, xcontext->xv_port_id, prop_atom, &val); - /* Normalize val to [-1000, 1000] */ - val = floor (0.5 + -1000 + 2000 * (val - channel->min_value) / (double) (channel->max_value - channel->min_value)); - - if (!g_ascii_strcasecmp (channels[i], "XV_HUE")) { - evaspixmapsink->hue = val; - } else if (!g_ascii_strcasecmp (channels[i], "XV_SATURATION")) { - evaspixmapsink->saturation = val; - } else if (!g_ascii_strcasecmp (channels[i], "XV_BRIGHTNESS")) { - evaspixmapsink->brightness = val; - } else if (!g_ascii_strcasecmp (channels[i], "XV_CONTRAST")) { - evaspixmapsink->contrast = val; - } - } - } - } - - if (xv_attr) { - XFree (xv_attr); - } - - g_mutex_unlock (evaspixmapsink->x_lock); - - return xcontext; -} - -/* This function cleans the X context. Closing the Display, releasing the XV - port and unrefing the caps for supported formats. */ -static void -gst_evaspixmapsink_xcontext_clear (GstEvasPixmapSink *evaspixmapsink) -{ - GList *formats_list, *channels_list; - GstXContext *xcontext; - gint i = 0; - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - - GST_OBJECT_LOCK (evaspixmapsink); - if (evaspixmapsink->xcontext == NULL) { - GST_OBJECT_UNLOCK (evaspixmapsink); - return; - } - - /* Take the XContext from the sink and clean it up */ - xcontext = evaspixmapsink->xcontext; - evaspixmapsink->xcontext = NULL; - - GST_OBJECT_UNLOCK (evaspixmapsink); - - formats_list = xcontext->formats_list; - - while (formats_list) { - GstEvasPixmapFormat *format = formats_list->data; - - gst_caps_unref (format->caps); - g_free (format); - formats_list = g_list_next (formats_list); - } - - if (xcontext->formats_list) - g_list_free (xcontext->formats_list); - - channels_list = xcontext->channels_list; - - while (channels_list) { - GstColorBalanceChannel *channel = channels_list->data; - - g_object_unref (channel); - channels_list = g_list_next (channels_list); - } - - if (xcontext->channels_list) - g_list_free (xcontext->channels_list); - - gst_caps_unref (xcontext->caps); - - for (i = 0; i < xcontext->nb_adaptors; i++) { - g_free (xcontext->adaptors[i]); - } - - g_free (xcontext->adaptors); - - g_free (xcontext->par); - - g_mutex_lock (evaspixmapsink->x_lock); - - GST_DEBUG_OBJECT (evaspixmapsink,"Closing display and freeing X Context"); - - XvUngrabPort (xcontext->disp, xcontext->xv_port_id, 0); - - XCloseDisplay (xcontext->disp); - - g_mutex_unlock (evaspixmapsink->x_lock); - - g_free (xcontext); -} - -/* Element stuff */ - -/* This function tries to get a format matching with a given caps in the - supported list of formats we generated in gst_evaspixmapsink_get_xv_support */ -static gint -gst_evaspixmapsink_get_format_from_caps (GstEvasPixmapSink *evaspixmapsink, GstCaps *caps) -{ - GList *list = NULL; - - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0); - - list = evaspixmapsink->xcontext->formats_list; - - while (list) { - GstEvasPixmapFormat *format = list->data; - - if (format) { - if (gst_caps_can_intersect (caps, format->caps)) { - return format->format; - } - } - list = g_list_next (list); - } - - return -1; -} - -static GstCaps * -gst_evaspixmapsink_getcaps (GstBaseSink *bsink) -{ - GstEvasPixmapSink *evaspixmapsink; - - evaspixmapsink = GST_EVASPIXMAPSINK (bsink); - - if (evaspixmapsink->xcontext) - return gst_caps_ref (evaspixmapsink->xcontext->caps); - - return - gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD - (evaspixmapsink))); -} - -static gboolean -gst_evaspixmapsink_setcaps (GstBaseSink *bsink, GstCaps *caps) -{ - GstEvasPixmapSink *evaspixmapsink; - GstStructure *structure; - guint32 im_format = 0; - gboolean ret; - gint video_width, video_height; - gint disp_x, disp_y; - gint disp_width, disp_height; - gint video_par_n, video_par_d; /* video's PAR */ - gint display_par_n, display_par_d; /* display's PAR */ - const GValue *caps_par; - const GValue *caps_disp_reg; - const GValue *fps; - guint num, den; - gboolean enable_last_buffer; - - evaspixmapsink = GST_EVASPIXMAPSINK (bsink); - - GST_DEBUG_OBJECT (evaspixmapsink,"In setcaps. Possible caps %" GST_PTR_FORMAT ", setting caps %" GST_PTR_FORMAT, evaspixmapsink->xcontext->caps, caps); - - if (!gst_caps_can_intersect (evaspixmapsink->xcontext->caps, caps)) { - goto incompatible_caps; - } - - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &video_width); - ret &= gst_structure_get_int (structure, "height", &video_height); - fps = gst_structure_get_value (structure, "framerate"); - ret &= (fps != NULL); - - if (!ret) { - goto incomplete_caps; - } - - evaspixmapsink->aligned_width = video_width; - evaspixmapsink->aligned_height = video_height; - - /* get enable-last-buffer */ - g_object_get(G_OBJECT(evaspixmapsink), "enable-last-buffer", &enable_last_buffer, NULL); - GST_INFO_OBJECT (evaspixmapsink,"current enable-last-buffer : %d", enable_last_buffer); - /* flush if enable-last-buffer is TRUE */ - if (enable_last_buffer) { - GST_INFO_OBJECT (evaspixmapsink,"flush last-buffer"); - g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", FALSE, NULL); - g_object_set(G_OBJECT(evaspixmapsink), "enable-last-buffer", TRUE, NULL); - } - - evaspixmapsink->fps_n = gst_value_get_fraction_numerator (fps); - evaspixmapsink->fps_d = gst_value_get_fraction_denominator (fps); - - evaspixmapsink->video_width = video_width; - evaspixmapsink->video_height = video_height; - - im_format = gst_evaspixmapsink_get_format_from_caps (evaspixmapsink, caps); - if (im_format == -1) { - goto invalid_format; - } - - /* get aspect ratio from caps if it's present, and - * convert video width and height to a display width and height - * using wd / hd = wv / hv * PARv / PARd */ - - /* get video's PAR */ - caps_par = gst_structure_get_value (structure, "pixel-aspect-ratio"); - if (caps_par) { - video_par_n = gst_value_get_fraction_numerator (caps_par); - video_par_d = gst_value_get_fraction_denominator (caps_par); - } else { - video_par_n = 1; - video_par_d = 1; - } - /* get display's PAR */ - if (evaspixmapsink->par) { - display_par_n = gst_value_get_fraction_numerator (evaspixmapsink->par); - display_par_d = gst_value_get_fraction_denominator (evaspixmapsink->par); - } else { - display_par_n = 1; - display_par_d = 1; - } - - /* get the display region */ - caps_disp_reg = gst_structure_get_value (structure, "display-region"); - if (caps_disp_reg) { - disp_x = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 0)); - disp_y = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 1)); - disp_width = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 2)); - disp_height = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 3)); - } else { - disp_x = disp_y = 0; - disp_width = video_width; - disp_height = video_height; - } - - if (!gst_video_calculate_display_ratio (&num, &den, video_width, video_height, video_par_n, video_par_d, display_par_n, display_par_d)) { - goto no_disp_ratio; - } - - evaspixmapsink->disp_x = disp_x; - evaspixmapsink->disp_y = disp_y; - evaspixmapsink->disp_width = disp_width; - evaspixmapsink->disp_height = disp_height; - - GST_DEBUG_OBJECT (evaspixmapsink,"video width/height: %dx%d, calculated display ratio: %d/%d", video_width, video_height, num, den); - - /* now find a width x height that respects this display ratio. - * prefer those that have one of w/h the same as the incoming video - * using wd / hd = num / den */ - - /* start with same height, because of interlaced video */ - /* check hd / den is an integer scale factor, and scale wd with the PAR */ - if (video_height % den == 0) { - GST_DEBUG_OBJECT (evaspixmapsink,"keeping video height"); - GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den); - GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height; - } else if (video_width % num == 0) { - GST_DEBUG_OBJECT (evaspixmapsink,"keeping video width"); - GST_VIDEO_SINK_WIDTH (evaspixmapsink) = video_width; - GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_width, den, num); - } else { - GST_DEBUG_OBJECT (evaspixmapsink,"approximating while keeping video height"); - GST_VIDEO_SINK_WIDTH (evaspixmapsink) = (guint) gst_util_uint64_scale_int (video_height, num, den); - GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = video_height; - } - GST_DEBUG_OBJECT (evaspixmapsink,"scaling to %dx%d", GST_VIDEO_SINK_WIDTH (evaspixmapsink), GST_VIDEO_SINK_HEIGHT (evaspixmapsink)); - - /* Creating our window and our image with the display size in pixels */ - if (GST_VIDEO_SINK_WIDTH (evaspixmapsink) <= 0 || GST_VIDEO_SINK_HEIGHT (evaspixmapsink) <= 0) { - goto no_display_size; - } - - g_mutex_lock (evaspixmapsink->flow_lock); - - /* We renew our evaspixmap buffer only if size or format changed; - * the evaspixmap buffer is the same size as the video pixel size */ - if ((evaspixmapsink->evas_pixmap_buf) && ((im_format != evaspixmapsink->evas_pixmap_buf->im_format) - || (video_width != evaspixmapsink->evas_pixmap_buf->width) || (video_height != evaspixmapsink->evas_pixmap_buf->height))) { - GST_DEBUG_OBJECT (evaspixmapsink,"old format %" GST_FOURCC_FORMAT ", new format %" GST_FOURCC_FORMAT, - GST_FOURCC_ARGS (evaspixmapsink->evas_pixmap_buf->im_format), GST_FOURCC_ARGS (im_format)); - GST_DEBUG_OBJECT (evaspixmapsink,"renewing evaspixmap buffer"); - gst_buffer_unref (GST_BUFFER (evaspixmapsink->evas_pixmap_buf)); - evaspixmapsink->evas_pixmap_buf = NULL; - } - - g_mutex_unlock (evaspixmapsink->flow_lock); - - if (evaspixmapsink->eo) { - if (!gst_evaspixmapsink_xpixmap_link (evaspixmapsink)) { - GST_ERROR_OBJECT (evaspixmapsink,"link evas image object with pixmap failed..."); - return FALSE; - } else { - gst_evaspixmapsink_manage_event_thread (evaspixmapsink); - } - } else { - GST_ERROR_OBJECT (evaspixmapsink,"setcaps success, but there is no evas image object.."); - return FALSE; - } - - return TRUE; - - /* ERRORS */ - incompatible_caps: - { - GST_ERROR_OBJECT (evaspixmapsink,"caps incompatible"); - return FALSE; - } - incomplete_caps: - { - GST_DEBUG_OBJECT (evaspixmapsink,"Failed to retrieve either width, ""height or framerate from intersected caps"); - return FALSE; - } - invalid_format: - { - GST_DEBUG_OBJECT (evaspixmapsink,"Could not locate image format from caps %" GST_PTR_FORMAT, caps); - return FALSE; - } - no_disp_ratio: - { - GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video.")); - return FALSE; - } - no_display_size: - { - GST_ELEMENT_ERROR (evaspixmapsink, CORE, NEGOTIATION, (NULL), ("Error calculating the output display ratio of the video.")); - return FALSE; - } -} - -static GstStateChangeReturn -gst_evaspixmapsink_change_state (GstElement *element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstEvasPixmapSink *evaspixmapsink; - - evaspixmapsink = GST_EVASPIXMAPSINK (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - g_mutex_lock (evaspixmapsink->flow_lock); - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_NULL_TO_READY"); - - /* open drm to use gem */ - if (drm_init(evaspixmapsink)) { - GST_ERROR_OBJECT (evaspixmapsink,"drm_init() failure"); - g_mutex_unlock (evaspixmapsink->flow_lock); - return GST_STATE_CHANGE_FAILURE; - } - - /* check if there exist evas image object, need to write code related to making internal evas image object */ - if (!is_evas_image_object (evaspixmapsink->eo)) { - GST_ERROR_OBJECT (evaspixmapsink,"There is no evas image object.."); - g_mutex_unlock (evaspixmapsink->flow_lock); - return GST_STATE_CHANGE_FAILURE; - } - - /* Set xcontext and display */ - if (!evaspixmapsink->xcontext) { - evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink); - if (!evaspixmapsink->xcontext) { - GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext.."); - g_mutex_unlock (evaspixmapsink->flow_lock); - return GST_STATE_CHANGE_FAILURE; - } - } - - /* update object's par with calculated one if not set yet */ - if (!evaspixmapsink->par) { - evaspixmapsink->par = g_new0 (GValue, 1); - gst_value_init_and_copy (evaspixmapsink->par, evaspixmapsink->xcontext->par); - GST_DEBUG_OBJECT (evaspixmapsink,"set calculated PAR on object's PAR"); - } - - /* call XSynchronize with the current value of synchronous */ - GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE"); - XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous); - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - - g_mutex_unlock (evaspixmapsink->flow_lock); - break; - - case GST_STATE_CHANGE_READY_TO_PAUSED: - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_PAUSED"); - break; - - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_PLAYING"); - break; - - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PLAYING_TO_PAUSED"); - break; - - case GST_STATE_CHANGE_PAUSED_TO_READY: - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_PAUSED_TO_READY"); - evaspixmapsink->fps_n = 0; - evaspixmapsink->fps_d = 1; - GST_VIDEO_SINK_WIDTH (evaspixmapsink) = 0; - GST_VIDEO_SINK_HEIGHT (evaspixmapsink) = 0; - drm_fini_close_gem_handle(evaspixmapsink, 0); - break; - - case GST_STATE_CHANGE_READY_TO_NULL: - GST_WARNING_OBJECT (evaspixmapsink,"GST_STATE_CHANGE_READY_TO_NULL"); - gst_evaspixmapsink_reset(evaspixmapsink); - /* close drm */ - drm_fini(evaspixmapsink); - break; - - default: - break; - } - return ret; -} - -static void -gst_evaspixmapsink_get_times (GstBaseSink *bsink, GstBuffer *buf, GstClockTime *start, GstClockTime *end) -{ - GstEvasPixmapSink *evaspixmapsink; - - evaspixmapsink = GST_EVASPIXMAPSINK (bsink); - - if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { - *start = GST_BUFFER_TIMESTAMP (buf); - if (GST_BUFFER_DURATION_IS_VALID (buf)) { - *end = *start + GST_BUFFER_DURATION (buf); - } else { - if (evaspixmapsink->fps_n > 0) { - *end = *start + - gst_util_uint64_scale_int (GST_SECOND, evaspixmapsink->fps_d, - evaspixmapsink->fps_n); - } - } - } -} - -static GstFlowReturn -gst_evaspixmapsink_show_frame (GstVideoSink *vsink, GstBuffer *buf) -{ - GstEvasPixmapSink *evaspixmapsink; - XV_DATA_PTR img_data = NULL; - SCMN_IMGB *scmn_imgb = NULL; - gint format = 0; - - MMTA_ACUM_ITEM_BEGIN("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); - - evaspixmapsink = GST_EVASPIXMAPSINK (vsink); - - if( evaspixmapsink->stop_video ) { - GST_INFO_OBJECT (evaspixmapsink, "Stop video is TRUE. so skip show frame..." ); - return GST_FLOW_OK; - } - - if (!evaspixmapsink->evas_pixmap_buf) { - GST_DEBUG_OBJECT (evaspixmapsink,"creating our evaspixmap buffer"); - format = gst_evaspixmapsink_get_format_from_caps(evaspixmapsink, GST_BUFFER_CAPS(buf)); - switch (format) { - case GST_MAKE_FOURCC('S', 'T', '1', '2'): - case GST_MAKE_FOURCC('S', 'N', '1', '2'): - case GST_MAKE_FOURCC('S', '4', '2', '0'): - case GST_MAKE_FOURCC('S', 'U', 'Y', '2'): - case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'): - case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'): - case GST_MAKE_FOURCC('I', 'T', 'L', 'V'): - case GST_MAKE_FOURCC('S', 'R', '3', '2'): - scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf); - if(scmn_imgb == NULL) { - GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." ); - return GST_FLOW_OK; - } - /* skip buffer if aligned size is smaller than size of caps */ - if (scmn_imgb->s[0] < evaspixmapsink->video_width || scmn_imgb->e[0] < evaspixmapsink->video_height) { - GST_WARNING_OBJECT (evaspixmapsink,"invalid size[caps:%dx%d,aligned:%dx%d]. Skip this buffer...", - evaspixmapsink->video_width, evaspixmapsink->video_height, scmn_imgb->s[0], scmn_imgb->e[0]); - return GST_FLOW_OK; - } - evaspixmapsink->aligned_width = scmn_imgb->s[0]; - evaspixmapsink->aligned_height = scmn_imgb->e[0]; - GST_DEBUG_OBJECT (evaspixmapsink,"video width,height[%dx%d]",evaspixmapsink->video_width, evaspixmapsink->video_height); - GST_INFO_OBJECT (evaspixmapsink,"Use aligned width,height[%dx%d]",evaspixmapsink->aligned_width, evaspixmapsink->aligned_height); - break; - default: - GST_INFO_OBJECT (evaspixmapsink,"Use original width,height of caps"); - break; - } - evaspixmapsink->evas_pixmap_buf = gst_evaspixmap_buffer_new (evaspixmapsink, GST_BUFFER_CAPS (buf)); - if (!evaspixmapsink->evas_pixmap_buf) { - /* The create method should have posted an informative error */ - goto no_image; - } - if (evaspixmapsink->evas_pixmap_buf->size < GST_BUFFER_SIZE (buf)) { - GST_ELEMENT_ERROR (evaspixmapsink, RESOURCE, WRITE, ("Failed to create output image buffer of %dx%d pixels", evaspixmapsink->evas_pixmap_buf->width, evaspixmapsink->evas_pixmap_buf->height),("XServer allocated buffer size did not match input buffer")); - gst_evaspixmap_buffer_destroy (evaspixmapsink->evas_pixmap_buf); - evaspixmapsink->evas_pixmap_buf = NULL; - goto no_image; - } - } - - switch (evaspixmapsink->evas_pixmap_buf->im_format) { - /* Cases for specified formats of Samsung extension */ - case GST_MAKE_FOURCC('S', 'T', '1', '2'): - case GST_MAKE_FOURCC('S', 'N', '1', '2'): - case GST_MAKE_FOURCC('S', '4', '2', '0'): - case GST_MAKE_FOURCC('S', 'U', 'Y', '2'): - case GST_MAKE_FOURCC('S', 'U', 'Y', 'V'): - case GST_MAKE_FOURCC('S', 'Y', 'V', 'Y'): - case GST_MAKE_FOURCC('I', 'T', 'L', 'V'): - case GST_MAKE_FOURCC('S', 'R', '3', '2'): - { - GST_DEBUG_OBJECT (evaspixmapsink,"Samsung extension display format activated. fourcc:%d", evaspixmapsink->evas_pixmap_buf->im_format); - - if (evaspixmapsink->evas_pixmap_buf->xvimage->data) { - img_data = (XV_DATA_PTR) evaspixmapsink->evas_pixmap_buf->xvimage->data; - XV_INIT_DATA(img_data); - scmn_imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buf); - if (scmn_imgb == NULL) { - GST_DEBUG_OBJECT (evaspixmapsink, "scmn_imgb is NULL. Skip buffer put..." ); - return GST_FLOW_OK; - } - - if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_PADDR) { - img_data->YBuf = (unsigned int)scmn_imgb->p[0]; - img_data->CbBuf = (unsigned int)scmn_imgb->p[1]; - img_data->CrBuf = (unsigned int)scmn_imgb->p[2]; - img_data->BufType = XV_BUF_TYPE_LEGACY; - - } else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_FD) { - /* set gem information to gem_info structure of handle and convert dma-buf fd into drm gem name */ - img_data->YBuf = drm_init_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[0]); - img_data->CbBuf = drm_init_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[1]); - img_data->CrBuf = drm_init_convert_dmabuf_gemname(evaspixmapsink, (int)scmn_imgb->dma_buf_fd[2]); - img_data->BufType = XV_BUF_TYPE_DMABUF; - if (evaspixmapsink->buf_shared_type != BUF_SHARE_METHOD_FD) { - evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_FD; - GST_WARNING_OBJECT (evaspixmapsink, "BUF SHARED TYPE : FD"); - } - - } else if (scmn_imgb->buf_share_method == BUF_SHARE_METHOD_TIZEN_BUFFER) { - img_data->bo[0] = scmn_imgb->bo[0]; - img_data->bo[1] = scmn_imgb->bo[1]; - img_data->bo[2] = scmn_imgb->bo[2]; - GST_DEBUG("TBM bo %p %p %p", img_data->bo[0], img_data->bo[1], img_data->bo[2]); - /* export bo */ - if (img_data->bo[0]) { - img_data->YBuf = tbm_init_convert_bo_gemname(evaspixmapsink, img_data->bo[0]); - } - if (img_data->bo[1]) { - img_data->CbBuf = tbm_init_convert_bo_gemname(evaspixmapsink, img_data->bo[1]); - } - if (img_data->bo[2]) { - img_data->CrBuf = tbm_init_convert_bo_gemname(evaspixmapsink, img_data->bo[2]); - } - if (evaspixmapsink->buf_shared_type != BUF_SHARE_METHOD_TIZEN_BUFFER) { - evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_TIZEN_BUFFER; - GST_WARNING_OBJECT (evaspixmapsink, "BUF SHARED TYPE : TIZEN BUFFER"); - } - } else { - GST_WARNING_OBJECT (evaspixmapsink, "Not supported, buf_share_method(%d)", scmn_imgb->buf_share_method); - return GST_FLOW_OK; - } - if (!img_data->YBuf) { - GST_WARNING_OBJECT (evaspixmapsink, "img_data->YBuf is NULL. skip buffer put..." ); - return GST_FLOW_OK; - } - GST_LOG_OBJECT(evaspixmapsink, "YBuf[%d], CbBuf[%d], CrBuf[%d]", - img_data->YBuf, img_data->CbBuf, img_data->CrBuf ); - } else { - GST_WARNING_OBJECT (evaspixmapsink, "xvimage->data is NULL. skip buffer put..." ); - return GST_FLOW_OK; - } - break; - } - default: - { - if (evaspixmapsink->buf_shared_type != BUF_SHARE_METHOD_NONE) { - evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_NONE; - } - GST_DEBUG_OBJECT (evaspixmapsink,"Normal format activated. fourcc = %d", evaspixmapsink->evas_pixmap_buf->im_format); - __ta__("evaspixmapsink memcpy in _show_frame", memcpy (evaspixmapsink->evas_pixmap_buf->xvimage->data, GST_BUFFER_DATA (buf), - MIN (GST_BUFFER_SIZE (buf), evaspixmapsink->evas_pixmap_buf->size));); - break; - } - } - if (!gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf)) { - MMTA_ACUM_ITEM_END("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); - return GST_FLOW_OK; - } - - MMTA_ACUM_ITEM_END("evaspixmapsink gst_evaspixmapsink_show_frame()", FALSE); - - return GST_FLOW_OK; - - /* ERRORS */ - no_image: - { - /* No image available. That's very bad ! */ - GST_WARNING_OBJECT (evaspixmapsink,"could not create image"); - return GST_FLOW_ERROR; - } -} - -static gboolean -gst_evaspixmapsink_event (GstBaseSink *sink, GstEvent *event) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (sink); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_START: - GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_START"); - break; - case GST_EVENT_FLUSH_STOP: - GST_DEBUG_OBJECT (evaspixmapsink,"GST_EVENT_FLUSH_STOP"); - break; - default: - break; - } - if (GST_BASE_SINK_CLASS (parent_class)->event) { - return GST_BASE_SINK_CLASS (parent_class)->event (sink, event); - } else { - return TRUE; - } -} - -/* Interfaces stuff */ - -static gboolean -gst_evaspixmapsink_interface_supported (GstImplementsInterface *iface, GType type) -{ - g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_COLOR_BALANCE || type == GST_TYPE_PROPERTY_PROBE); - return TRUE; -} - -static void -gst_evaspixmapsink_interface_init (GstImplementsInterfaceClass *klass) -{ - klass->supported = gst_evaspixmapsink_interface_supported; -} - -static void -gst_evaspixmapsink_navigation_send_event (GstNavigation *navigation, GstStructure *structure) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (navigation); - GstPad *peer; - int i = 0; - - if ((peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (evaspixmapsink)))) { - GstEvent *event; - GstVideoRectangle result; - gdouble x, y, xscale = 1.0, yscale = 1.0; - - event = gst_event_new_navigation (structure); - - /* We take the flow_lock while we look at the window */ - g_mutex_lock (evaspixmapsink->flow_lock); - - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i ++) { - if (!evaspixmapsink->xpixmap[i]) { - g_mutex_unlock (evaspixmapsink->flow_lock); - return; - } - } - - memcpy (&result, &evaspixmapsink->render_rect, sizeof (GstVideoRectangle)); - - g_mutex_unlock (evaspixmapsink->flow_lock); - - /* We calculate scaling using the original video frames geometry to include - pixel aspect ratio scaling. */ - xscale = (gdouble) evaspixmapsink->video_width / result.w; - yscale = (gdouble) evaspixmapsink->video_height / result.h; - - /* Converting pointer coordinates to the non scaled geometry */ - if (gst_structure_get_double (structure, "pointer_x", &x)) { - x = MIN (x, result.x + result.w); - x = MAX (x - result.x, 0); - gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, - (gdouble) x * xscale, NULL); - } - if (gst_structure_get_double (structure, "pointer_y", &y)) { - y = MIN (y, result.y + result.h); - y = MAX (y - result.y, 0); - gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, - (gdouble) y * yscale, NULL); - } - - gst_pad_send_event (peer, event); - gst_object_unref (peer); - } -} - -static void -gst_evaspixmapsink_navigation_init (GstNavigationInterface *iface) -{ - iface->send_event = gst_evaspixmapsink_navigation_send_event; -} - -static const GList* -gst_evaspixmapsink_colorbalance_list_channels (GstColorBalance *balance) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance); - - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), NULL); - - if (evaspixmapsink->xcontext) - return evaspixmapsink->xcontext->channels_list; - else - return NULL; -} - -static void -gst_evaspixmapsink_colorbalance_set_value (GstColorBalance *balance, GstColorBalanceChannel *channel, gint value) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance); - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink)); - g_return_if_fail (channel->label != NULL); - - evaspixmapsink->cb_changed = TRUE; - - /* Normalize val to [-1000, 1000] */ - value = floor (0.5 + -1000 + 2000 * (value - channel->min_value) / - (double) (channel->max_value - channel->min_value)); - - if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) { - evaspixmapsink->hue = value; - } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) { - evaspixmapsink->saturation = value; - } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) { - evaspixmapsink->contrast = value; - } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) { - evaspixmapsink->brightness = value; - } else { - g_warning ("got an unknown channel %s", channel->label); - return; - } - - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); -} - -static gint -gst_evaspixmapsink_colorbalance_get_value (GstColorBalance *balance, GstColorBalanceChannel *channel) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (balance); - gint value = 0; - - g_return_val_if_fail (GST_IS_EVASPIXMAPSINK (evaspixmapsink), 0); - g_return_val_if_fail (channel->label != NULL, 0); - - if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) { - value = evaspixmapsink->hue; - } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) { - value = evaspixmapsink->saturation; - } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) { - value = evaspixmapsink->contrast; - } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) { - value = evaspixmapsink->brightness; - } else { - g_warning ("got an unknown channel %s", channel->label); - } - - /* Normalize val to [channel->min_value, channel->max_value] */ - value = channel->min_value + (channel->max_value - channel->min_value) * (value + 1000) / 2000; - - return value; -} - -static void -gst_evaspixmapsink_colorbalance_init (GstColorBalanceClass *iface) -{ - GST_COLOR_BALANCE_TYPE (iface) = GST_COLOR_BALANCE_HARDWARE; - iface->list_channels = gst_evaspixmapsink_colorbalance_list_channels; - iface->set_value = gst_evaspixmapsink_colorbalance_set_value; - iface->get_value = gst_evaspixmapsink_colorbalance_get_value; -} - -static const GList * -gst_evaspixmapsink_probe_get_properties (GstPropertyProbe *probe) -{ - GObjectClass *klass = G_OBJECT_GET_CLASS (probe); - static GList *list = NULL; - - if (!list) { - list = g_list_append (NULL, g_object_class_find_property (klass, "device")); - list = g_list_append (list, g_object_class_find_property (klass, "autopaint-colorkey")); - list = g_list_append (list, g_object_class_find_property (klass, "double-buffer")); - list = g_list_append (list, g_object_class_find_property (klass, "colorkey")); - } - - return list; -} - -static void -gst_evaspixmapsink_probe_probe_property (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe); - - switch (prop_id) { - case PROP_DEVICE: - case PROP_AUTOPAINT_COLORKEY: - case PROP_DOUBLE_BUFFER: - case PROP_COLORKEY: - GST_DEBUG_OBJECT (evaspixmapsink,"probing device list and get capabilities"); - if (!evaspixmapsink->xcontext) { - GST_DEBUG_OBJECT (evaspixmapsink,"generating xcontext"); - evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink); - if (!evaspixmapsink->xcontext) { - GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext.."); - } - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } -} - -static gboolean -gst_evaspixmapsink_probe_needs_probe (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe); - gboolean ret = FALSE; - - switch (prop_id) { - case PROP_DEVICE: - case PROP_AUTOPAINT_COLORKEY: - case PROP_DOUBLE_BUFFER: - case PROP_COLORKEY: - if (evaspixmapsink->xcontext != NULL) { - ret = FALSE; - } else { - ret = TRUE; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - - return ret; -} - -static GValueArray * -gst_evaspixmapsink_probe_get_values (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) -{ - GstEvasPixmapSink *evaspixmapsink = GST_EVASPIXMAPSINK (probe); - GValueArray *array = NULL; - - if (G_UNLIKELY (!evaspixmapsink->xcontext)) { - GST_WARNING_OBJECT (evaspixmapsink,"we don't have any xcontext, can't " - "get values"); - goto beach; - } - - switch (prop_id) { - case PROP_DEVICE: - { - guint i; - GValue value = { 0 }; - - array = g_value_array_new (evaspixmapsink->xcontext->nb_adaptors); - g_value_init (&value, G_TYPE_STRING); - - for (i = 0; i < evaspixmapsink->xcontext->nb_adaptors; i++) { - gchar *adaptor_id_s = g_strdup_printf ("%u", i); - - g_value_set_string (&value, adaptor_id_s); - g_value_array_append (array, &value); - g_free (adaptor_id_s); - } - g_value_unset (&value); - break; - } - case PROP_AUTOPAINT_COLORKEY: - if (evaspixmapsink->have_autopaint_colorkey) { - GValue value = { 0 }; - - array = g_value_array_new (2); - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, FALSE); - g_value_array_append (array, &value); - g_value_set_boolean (&value, TRUE); - g_value_array_append (array, &value); - g_value_unset (&value); - } - break; - case PROP_DOUBLE_BUFFER: - if (evaspixmapsink->have_double_buffer) { - GValue value = { 0 }; - - array = g_value_array_new (2); - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, FALSE); - g_value_array_append (array, &value); - g_value_set_boolean (&value, TRUE); - g_value_array_append (array, &value); - g_value_unset (&value); - } - break; - case PROP_COLORKEY: - if (evaspixmapsink->have_colorkey) { - GValue value = { 0 }; - - array = g_value_array_new (1); - g_value_init (&value, GST_TYPE_INT_RANGE); - gst_value_set_int_range (&value, 0, 0xffffff); - g_value_array_append (array, &value); - g_value_unset (&value); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); - break; - } - -beach: - return array; -} - -static void -gst_evaspixmapsink_property_probe_interface_init (GstPropertyProbeInterface *iface) -{ - iface->get_properties = gst_evaspixmapsink_probe_get_properties; - iface->probe_property = gst_evaspixmapsink_probe_probe_property; - iface->needs_probe = gst_evaspixmapsink_probe_needs_probe; - iface->get_values = gst_evaspixmapsink_probe_get_values; -} - -static gboolean -gst_evaspixmapsink_xpixmap_link (GstEvasPixmapSink *evaspixmapsink) -{ - Display *dpy; - Pixmap *pixmap_id[NUM_OF_PIXMAP]; - int evas_object_width = 0; - int evas_object_height = 0; - int pixmap_width = 0; - int pixmap_height = 0; - unsigned int xw = 0; - unsigned int xh = 0; - int i = 0; - - GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); - - if (!evaspixmapsink) { - GST_ERROR_OBJECT (evaspixmapsink,"could not get evaspixmapsink.."); - return FALSE; - } - g_mutex_lock (evaspixmapsink->flow_lock); - - /* Set xcontext and display */ - if (!evaspixmapsink->xcontext) { - GST_WARNING_OBJECT (evaspixmapsink,"there's no xcontext, try to get one.."); - evaspixmapsink->xcontext = gst_evaspixmapsink_xcontext_get (evaspixmapsink); - if (!evaspixmapsink->xcontext) { - GST_ERROR_OBJECT (evaspixmapsink,"could not get xcontext.."); - return FALSE; - } - } - - /* Set evas image object size */ - evas_object_geometry_get(evaspixmapsink->eo, NULL, NULL, &evas_object_width, &evas_object_height); - - /* check if it is redundant request */ - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]) { - if (!evaspixmapsink->use_origin_size && evaspixmapsink->xpixmap[i]->width && evaspixmapsink->xpixmap[i]->height) { - if (evaspixmapsink->xpixmap[i]->width == evas_object_width && evaspixmapsink->xpixmap[i]->height == evas_object_height) { - GST_WARNING_OBJECT (evaspixmapsink,"pixmap was already created(w:%d, h:%d), skip it..", - evaspixmapsink->xpixmap[i]->width, evaspixmapsink->xpixmap[i]->height); - goto SKIP_LINK; - } - } - } - } - - dpy = evaspixmapsink->xcontext->disp; - - if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) { - pixmap_width = evaspixmapsink->video_width; - pixmap_height = evaspixmapsink->video_height; - GST_INFO_OBJECT (evaspixmapsink,"set size to media src size(%dx%d)", pixmap_width, pixmap_height); - } - - g_mutex_lock (evaspixmapsink->x_lock); - evaspixmapsink->sizediff_width = 0; - evaspixmapsink->sizediff_height = 0; - if (evaspixmapsink->use_origin_size || !evas_object_width || !evas_object_height) { - XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, pixmap_width, pixmap_height, &xw, &xh); - if (!evas_object_width || !evas_object_height) { - evaspixmapsink->w = xw; - evaspixmapsink->h = xh; - } else { - evaspixmapsink->w = evas_object_width; - evaspixmapsink->h = evas_object_height; - } - GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, pixmap_width, pixmap_height, xw, xh); - } else { - XvQueryBestSize(dpy, evaspixmapsink->xcontext->xv_port_id,0,0,0, evas_object_width, evas_object_height, &xw, &xh); - GST_DEBUG_OBJECT (evaspixmapsink,"XvQueryBestSize : xv_port_id(%d), w(%d),h(%d) => xw(%d),xh(%d)", evaspixmapsink->xcontext->xv_port_id, evas_object_width, evas_object_height, xw, xh); - evaspixmapsink->w = xw; - evaspixmapsink->h = xh; - /* update difference of size information (between evas image object's and pixmap's) */ - evaspixmapsink->sizediff_width = xw - evas_object_width; - evaspixmapsink->sizediff_height = xh - evas_object_height; - } - - /* create xpixmap structure */ - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (!evaspixmapsink->xpixmap[i]) { - /* xpixmap can be created in this function only */ - evaspixmapsink->xpixmap[i] = g_new0 (GstXPixmap, 1); - if(!evaspixmapsink->xpixmap[i]) { - GST_ERROR_OBJECT (evaspixmapsink,"xpixmap is not valid.."); - int j = 0; - for (j = 0; j < i; j++) { - g_free(evaspixmapsink->xpixmap[j]); - } - goto GO_OUT_OF_FUNC; - } - } - } - - /* create pixmap */ - if (!xw || !xh) { - GST_WARNING_OBJECT (evaspixmapsink,"skip creating pixmap..xw(%d),xh(%d)",xw,xh); - goto GO_OUT_OF_FUNC; - } else { - /* multiple pixmaps creation */ - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - pixmap_id[i] = XCreatePixmap(dpy, DefaultRootWindow(dpy), xw, xh, DefaultDepth(dpy, DefaultScreen(dpy))); - if ( (int)pixmap_id[i] == BadAlloc || (int)pixmap_id[i] == BadDrawable || (int)pixmap_id[i] == BadValue ) { - GST_ERROR_OBJECT (evaspixmapsink,"pixmap[%d] allocation error..", i); - int j = 0; - for (j = 0; j < i; j++) { - XFreePixmap(dpy, pixmap_id[j]); - } - goto GO_OUT_OF_FUNC; - } - GST_INFO_OBJECT (evaspixmapsink,"creation pixmap_id[%d]:%d success", i, pixmap_id[i]); - GST_DEBUG_OBJECT (evaspixmapsink,"evas_object_width(%d),evas_object_height(%d),pixmap:%d,depth:%d", - evas_object_width,evas_object_height,pixmap_id[i],DefaultDepth(dpy, DefaultScreen(dpy))); - } - } - - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]->pixmap && pixmap_id[i] != evaspixmapsink->xpixmap[i]->pixmap) { - g_mutex_unlock (evaspixmapsink->x_lock); - g_mutex_lock (evaspixmapsink->pixmap_ref_lock); - /* If we reset another pixmap, do below */ - evaspixmapsink->xpixmap[i]->prev_pixmap = evaspixmapsink->xpixmap[i]->pixmap; - evaspixmapsink->xpixmap[i]->prev_gc = evaspixmapsink->xpixmap[i]->gc; - evaspixmapsink->xpixmap[i]->pixmap = 0; - evaspixmapsink->xpixmap[i]->ref = 0; - evaspixmapsink->xpixmap[i]->damaged_time = 0; - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); - g_mutex_lock (evaspixmapsink->x_lock); - } - } - - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - /* Set pixmap id and create GC */ - evaspixmapsink->xpixmap[i]->pixmap = pixmap_id[i]; - evaspixmapsink->xpixmap[i]->gc = XCreateGC(dpy, evaspixmapsink->xpixmap[i]->pixmap, 0,0); - evaspixmapsink->xpixmap[i]->width = xw; - evaspixmapsink->xpixmap[i]->height = xh; - - /* Create XDamage */ - if (evaspixmapsink->damage[i]) { - evaspixmapsink->prev_damage[i] = evaspixmapsink->damage[i]; - } - evaspixmapsink->damage[i] = XDamageCreate (dpy, evaspixmapsink->xpixmap[i]->pixmap, XDamageReportRawRectangles); - - GST_WARNING_OBJECT (evaspixmapsink,"xpixmap[%d]->(pixmap:%d,gc:%p), damage[%d]:%d", - i, evaspixmapsink->xpixmap[i]->pixmap, evaspixmapsink->xpixmap[i]->gc, i, evaspixmapsink->damage[i]); - } - - XSync(dpy, FALSE); - - /* Set flag for mapping evas object with xpixmap */ - evaspixmapsink->do_link = TRUE; - ecore_pipe_write(evaspixmapsink->epipe, evaspixmapsink, sizeof(GstEvasPixmapSink)); - - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - - g_mutex_unlock (evaspixmapsink->x_lock); - - -SKIP_LINK: - g_mutex_lock (evaspixmapsink->pixmap_ref_lock); - evaspixmapsink->last_updated_idx = -1; - g_mutex_unlock (evaspixmapsink->pixmap_ref_lock); - - g_mutex_unlock (evaspixmapsink->flow_lock); - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); - - return TRUE; - -GO_OUT_OF_FUNC: - g_mutex_unlock (evaspixmapsink->x_lock); - g_mutex_unlock (evaspixmapsink->flow_lock); - return FALSE; -} - -static void -gst_evaspixmapsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - GstEvasPixmapSink *evaspixmapsink; - g_return_if_fail (GST_IS_EVASPIXMAPSINK (object)); - evaspixmapsink = GST_EVASPIXMAPSINK (object); - - switch (prop_id) { - case PROP_HUE: - evaspixmapsink->hue = g_value_get_int (value); - evaspixmapsink->cb_changed = TRUE; - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - break; - case PROP_CONTRAST: - evaspixmapsink->contrast = g_value_get_int (value); - evaspixmapsink->cb_changed = TRUE; - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - break; - case PROP_BRIGHTNESS: - evaspixmapsink->brightness = g_value_get_int (value); - evaspixmapsink->cb_changed = TRUE; - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - break; - case PROP_SATURATION: - evaspixmapsink->saturation = g_value_get_int (value); - evaspixmapsink->cb_changed = TRUE; - gst_evaspixmapsink_update_colorbalance (evaspixmapsink); - break; - case PROP_DISPLAY: - evaspixmapsink->display_name = g_strdup (g_value_get_string (value)); - break; - case PROP_SYNCHRONOUS: - evaspixmapsink->synchronous = g_value_get_boolean (value); - if (evaspixmapsink->xcontext) { - XSynchronize (evaspixmapsink->xcontext->disp, evaspixmapsink->synchronous); - GST_DEBUG_OBJECT (evaspixmapsink,"XSynchronize called with %s", evaspixmapsink->synchronous ? "TRUE" : "FALSE"); - } - break; - case PROP_PIXEL_ASPECT_RATIO: - g_free (evaspixmapsink->par); - evaspixmapsink->par = g_new0 (GValue, 1); - g_value_init (evaspixmapsink->par, GST_TYPE_FRACTION); - if (!g_value_transform (value, evaspixmapsink->par)) { - g_warning ("Could not transform string to aspect ratio"); - gst_value_set_fraction (evaspixmapsink->par, 1, 1); - } - GST_DEBUG_OBJECT (evaspixmapsink,"set PAR to %d/%d", gst_value_get_fraction_numerator (evaspixmapsink->par), gst_value_get_fraction_denominator (evaspixmapsink->par)); - break; - case PROP_DEVICE: - evaspixmapsink->adaptor_no = atoi (g_value_get_string (value)); - break; - case PROP_DOUBLE_BUFFER: - evaspixmapsink->double_buffer = g_value_get_boolean (value); - break; - case PROP_AUTOPAINT_COLORKEY: - evaspixmapsink->autopaint_colorkey = g_value_get_boolean (value); - break; - case PROP_COLORKEY: - evaspixmapsink->colorkey = g_value_get_int (value); - break; - case PROP_PIXMAP_WIDTH: - { - /* To do : code related to pixmap re-link */ - GST_LOG_OBJECT (evaspixmapsink, "Not supported"); - break; - } - case PROP_PIXMAP_HEIGHT: - { - /* To do : code related to pixmap re-link */ - GST_LOG_OBJECT (evaspixmapsink, "Not supported"); - break; - } - case PROP_DISPLAY_GEOMETRY_METHOD: - { - guint new_val = g_value_get_enum (value); - if (evaspixmapsink->display_geometry_method != new_val) { - evaspixmapsink->display_geometry_method = new_val; - GST_INFO_OBJECT (evaspixmapsink,"Overlay geometry method update, display_geometry_method(%d)",evaspixmapsink->display_geometry_method); - if( evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_FULL_SCREEN && - evaspixmapsink->display_geometry_method != DISP_GEO_METHOD_CROPPED_FULL_SCREEN ) { - if( evaspixmapsink->xcontext ) { - g_mutex_lock( evaspixmapsink->flow_lock ); - int i = 0; - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]) { - gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap[i]); - } - } - g_mutex_unlock( evaspixmapsink->flow_lock ); - } - } - if (evaspixmapsink->xcontext) { - gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf); - } - } - break; - } - case PROP_DST_ROI_X: - evaspixmapsink->dst_roi.x = g_value_get_int (value); - GST_INFO_OBJECT (evaspixmapsink, "ROI_X(%d)",evaspixmapsink->dst_roi.x ); - break; - case PROP_DST_ROI_Y: - evaspixmapsink->dst_roi.y = g_value_get_int (value); - GST_INFO_OBJECT (evaspixmapsink, "ROI_Y(%d)",evaspixmapsink->dst_roi.y ); - break; - case PROP_DST_ROI_W: - evaspixmapsink->dst_roi.w = g_value_get_int (value); - GST_INFO_OBJECT (evaspixmapsink, "ROI_W(%d)",evaspixmapsink->dst_roi.w ); - break; - case PROP_DST_ROI_H: - evaspixmapsink->dst_roi.h = g_value_get_int (value); - GST_INFO_OBJECT (evaspixmapsink, "ROI_H(%d)",evaspixmapsink->dst_roi.h ); - break; - case PROP_STOP_VIDEO: - evaspixmapsink->stop_video = g_value_get_int (value); - g_mutex_lock( evaspixmapsink->flow_lock ); - if( evaspixmapsink->stop_video ) { - GST_INFO_OBJECT (evaspixmapsink, "XPixmap CLEAR when set video-stop property" ); - int i = 0; - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]) { - gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap[i]); - } - } - } - GST_INFO_OBJECT (evaspixmapsink, "video-stop property(%d)", evaspixmapsink->stop_video); - - g_mutex_unlock( evaspixmapsink->flow_lock ); - break; - case PROP_EVAS_OBJECT: - { - Evas_Object *eo = g_value_get_pointer (value); - if ( is_evas_image_object (eo)) { - if (!evaspixmapsink->epipe) { - evaspixmapsink->epipe = ecore_pipe_add (ecore_pipe_callback_handler, evaspixmapsink); - if (!evaspixmapsink->epipe) { - GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: ecore_pipe_add() failed"); - break; - } - } - if (evaspixmapsink->eo == NULL) { - evaspixmapsink->eo = eo; - /* add evas object callbacks on a new evas image object */ - EVASPIXMAPSINK_SET_EVAS_OBJECT_EVENT_CALLBACK (eo, evaspixmapsink); - if (GST_STATE(evaspixmapsink) < GST_STATE_PAUSED) { - GST_INFO_OBJECT (evaspixmapsink,"It's the first time the new evas image object(%x) is set, skip gst_evaspixmapsink_xpixmap_link()..", eo); - break; - } else { - if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) { - GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed..."); - evaspixmapsink->eo = NULL; - break; - } - } - } - if (eo == evaspixmapsink->eo) { - GST_LOG_OBJECT (evaspixmapsink,"new evas image object(%x) is same as the previous one(%x)", eo, evaspixmapsink->eo); - } else { - GST_INFO_OBJECT (evaspixmapsink,"new evas image object(%x), previous one(%x)", eo, evaspixmapsink->eo); - /* delete evas object callbacks registrated on a former evas image object */ - EVASPIXMAPSINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (evaspixmapsink->eo); - evaspixmapsink->eo = eo; - if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) { - GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed..."); - evaspixmapsink->eo = NULL; - break; - } - /* add evas object callbacks on a new evas image object */ - EVASPIXMAPSINK_SET_EVAS_OBJECT_EVENT_CALLBACK (eo, evaspixmapsink); - } - GST_INFO_OBJECT (evaspixmapsink,"Evas image object(%x) is set", evaspixmapsink->eo); - } else { - GST_ERROR_OBJECT (evaspixmapsink,"Cannot set evas-object property: value is not an evas image object"); - } - break; - } - case PROP_FLIP: - evaspixmapsink->flip = g_value_get_enum(value); - break; - case PROP_ROTATE_ANGLE: - evaspixmapsink->rotate_angle = g_value_get_enum (value); - break; - case PROP_VISIBLE: - { - gboolean visible = g_value_get_boolean (value); - if (evaspixmapsink->visible != visible) { - evaspixmapsink->visible = visible; - if (evaspixmapsink->eo) { - if (!visible) { - int i = 0; - g_mutex_lock( evaspixmapsink->flow_lock ); - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if (evaspixmapsink->xpixmap[i]) { - gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap[i]); - } - } - g_mutex_unlock( evaspixmapsink->flow_lock ); - evas_object_hide(evaspixmapsink->eo); - GST_INFO_OBJECT (evaspixmapsink,"object hide.."); - } else { - evas_object_show(evaspixmapsink->eo); - GST_INFO_OBJECT (evaspixmapsink,"object show.."); - gst_evaspixmap_buffer_put (evaspixmapsink, evaspixmapsink->evas_pixmap_buf); - } - } else { - GST_WARNING_OBJECT (evaspixmapsink,"evas image object was not set"); - } - } - break; - } - case PROP_ORIGIN_SIZE: - evaspixmapsink->use_origin_size = g_value_get_boolean (value); - GST_INFO_OBJECT (evaspixmapsink,"set origin-size (%d)",evaspixmapsink->use_origin_size); - if (evaspixmapsink->previous_origin_size != evaspixmapsink->use_origin_size) { - if (!gst_evaspixmapsink_xpixmap_link(evaspixmapsink)) { - GST_WARNING_OBJECT (evaspixmapsink,"link evas image object with pixmap failed..."); - } - evaspixmapsink->previous_origin_size = evaspixmapsink->use_origin_size; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_evaspixmapsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - GstEvasPixmapSink *evaspixmapsink; - - g_return_if_fail (GST_IS_EVASPIXMAPSINK (object)); - - evaspixmapsink = GST_EVASPIXMAPSINK (object); - - switch (prop_id) { - case PROP_HUE: - g_value_set_int (value, evaspixmapsink->hue); - break; - case PROP_CONTRAST: - g_value_set_int (value, evaspixmapsink->contrast); - break; - case PROP_BRIGHTNESS: - g_value_set_int (value, evaspixmapsink->brightness); - break; - case PROP_SATURATION: - g_value_set_int (value, evaspixmapsink->saturation); - break; - case PROP_DISPLAY: - g_value_set_string (value, evaspixmapsink->display_name); - break; - case PROP_SYNCHRONOUS: - g_value_set_boolean (value, evaspixmapsink->synchronous); - break; - case PROP_PIXEL_ASPECT_RATIO: - if (evaspixmapsink->par) { - if (!g_value_transform (evaspixmapsink->par, value)) { - g_warning ("g_value_transform() failure"); - } - } - break; - case PROP_DEVICE: - { - char *adaptor_no_s = g_strdup_printf ("%u", evaspixmapsink->adaptor_no); - g_value_set_string (value, adaptor_no_s); - g_free (adaptor_no_s); - break; - } - case PROP_DEVICE_NAME: - if (evaspixmapsink->xcontext && evaspixmapsink->xcontext->adaptors) { - g_value_set_string (value, - evaspixmapsink->xcontext->adaptors[evaspixmapsink->adaptor_no]); - } else { - g_value_set_string (value, NULL); - } - break; - case PROP_DOUBLE_BUFFER: - g_value_set_boolean (value, evaspixmapsink->double_buffer); - break; - case PROP_AUTOPAINT_COLORKEY: - g_value_set_boolean (value, evaspixmapsink->autopaint_colorkey); - break; - case PROP_COLORKEY: - g_value_set_int (value, evaspixmapsink->colorkey); - break; - case PROP_PIXMAP_WIDTH: - { - GST_LOG_OBJECT (evaspixmapsink, "Not supported"); - break; - } - case PROP_PIXMAP_HEIGHT: - { - GST_LOG_OBJECT (evaspixmapsink, "Not supported"); - break; - } - case PROP_DISPLAY_GEOMETRY_METHOD: - g_value_set_enum (value, evaspixmapsink->display_geometry_method); - break; - case PROP_DST_ROI_X: - g_value_set_int (value, evaspixmapsink->dst_roi.x); - break; - case PROP_DST_ROI_Y: - g_value_set_int (value, evaspixmapsink->dst_roi.y); - break; - case PROP_DST_ROI_W: - g_value_set_int (value, evaspixmapsink->dst_roi.w); - break; - case PROP_DST_ROI_H: - g_value_set_int (value, evaspixmapsink->dst_roi.h); - break; - case PROP_STOP_VIDEO: - g_value_set_int (value, evaspixmapsink->stop_video); - break; - case PROP_EVAS_OBJECT: - g_value_set_pointer (value, evaspixmapsink->eo); - break; - case PROP_FLIP: - g_value_set_enum(value, evaspixmapsink->flip); - break; - case PROP_ROTATE_ANGLE: - g_value_set_enum (value, evaspixmapsink->rotate_angle); - break; - case PROP_VISIBLE: - g_value_set_boolean (value, evaspixmapsink->visible); - break; - case PROP_ORIGIN_SIZE: - g_value_set_boolean (value, evaspixmapsink->use_origin_size); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_evaspixmapsink_reset (GstEvasPixmapSink *evaspixmapsink) -{ - GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); - - GThread *thread; - GST_OBJECT_LOCK (evaspixmapsink); - evaspixmapsink->running = FALSE; - int i = 0; - - /* grab thread and mark it as NULL */ - thread = evaspixmapsink->event_thread; - evaspixmapsink->event_thread = NULL; - GST_OBJECT_UNLOCK (evaspixmapsink); - - /* Wait for our event thread to finish before we clean up our stuff. */ - if (thread) { - g_thread_join (thread); - } - - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - if(evaspixmapsink->damage[i]) { - XDamageDestroy(evaspixmapsink->xcontext->disp, evaspixmapsink->damage[i]); - evaspixmapsink->damage[i] = NULL; - } - } - EVASPIXMAPSINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( evaspixmapsink->eo ); - - if (evaspixmapsink->evas_pixmap_buf) { - gst_buffer_unref (GST_BUFFER_CAST (evaspixmapsink->evas_pixmap_buf)); - evaspixmapsink->evas_pixmap_buf = NULL; - } - - for (i = 0; i < evaspixmapsink->num_of_pixmaps; i++) { - gst_evaspixmapsink_xpixmap_clear (evaspixmapsink, evaspixmapsink->xpixmap[i]); - gst_evaspixmapsink_xpixmap_destroy (evaspixmapsink, evaspixmapsink->xpixmap[i]); - evaspixmapsink->xpixmap[i] = NULL; - } - if (evaspixmapsink->eo) { - evas_object_image_native_surface_set(evaspixmapsink->eo, NULL); - evaspixmapsink->eo = NULL; - } - - evaspixmapsink->render_rect.x = evaspixmapsink->render_rect.y = - evaspixmapsink->render_rect.w = evaspixmapsink->render_rect.h = 0; - evaspixmapsink->have_render_rect = FALSE; - - gst_evaspixmapsink_xcontext_clear (evaspixmapsink); - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); -} - -/* Finalize is called only once, dispose can be called multiple times. - * We use mutexes and don't reset stuff to NULL here so let's register - * as a finalize. */ -static void -gst_evaspixmapsink_finalize (GObject *object) -{ - GstEvasPixmapSink *evaspixmapsink; - evaspixmapsink = GST_EVASPIXMAPSINK (object); - GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); - - if (evaspixmapsink->display_name) { - g_free (evaspixmapsink->display_name); - evaspixmapsink->display_name = NULL; - } - if (evaspixmapsink->par) { - g_free (evaspixmapsink->par); - evaspixmapsink->par = NULL; - } - if (evaspixmapsink->x_lock) { - g_mutex_free (evaspixmapsink->x_lock); - evaspixmapsink->x_lock = NULL; - } - if (evaspixmapsink->flow_lock) { - g_mutex_free (evaspixmapsink->flow_lock); - evaspixmapsink->flow_lock = NULL; - } - if (evaspixmapsink->pixmap_ref_lock) { - g_mutex_free (evaspixmapsink->pixmap_ref_lock); - evaspixmapsink->pixmap_ref_lock = NULL; - } - if (evaspixmapsink->epipe) { - ecore_pipe_del (evaspixmapsink->epipe); - evaspixmapsink->epipe = NULL; - } - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); - - G_OBJECT_CLASS (parent_class)->finalize (object); - - MMTA_ACUM_ITEM_SHOW_RESULT_TO(MMTA_SHOW_FILE); - MMTA_RELEASE(); -} - -static void -gst_evaspixmapsink_init (GstEvasPixmapSink *evaspixmapsink) -{ - int i = 0; - - GST_DEBUG_OBJECT (evaspixmapsink,"[START]"); - - evaspixmapsink->display_name = NULL; - evaspixmapsink->adaptor_no = 0; - evaspixmapsink->xcontext = NULL; - - for (i = 0; i < NUM_OF_PIXMAP; i++) { - evaspixmapsink->xpixmap[i] = NULL; - evaspixmapsink->damage[i] = 0; - } - - evaspixmapsink->evas_pixmap_buf = NULL; - - evaspixmapsink->hue = evaspixmapsink->saturation = 0; - evaspixmapsink->contrast = evaspixmapsink->brightness = 0; - evaspixmapsink->cb_changed = FALSE; - - evaspixmapsink->fps_n = 0; - evaspixmapsink->fps_d = 0; - evaspixmapsink->video_width = 0; - evaspixmapsink->video_height = 0; - - evaspixmapsink->x_lock = g_mutex_new (); - evaspixmapsink->flow_lock = g_mutex_new (); - evaspixmapsink->pixmap_ref_lock = g_mutex_new(); - - evaspixmapsink->synchronous = FALSE; - evaspixmapsink->double_buffer = TRUE; - evaspixmapsink->par = NULL; - evaspixmapsink->autopaint_colorkey = TRUE; - evaspixmapsink->running = FALSE; - - /* on 16bit displays this becomes r,g,b = 1,2,3 - * on 24bit displays this becomes r,g,b = 8,8,16 - * as a port atom value - */ - evaspixmapsink->colorkey = (8 << 16) | (8 << 8) | 16; - - evaspixmapsink->display_geometry_method = DEF_DISPLAY_GEOMETRY_METHOD; - evaspixmapsink->dst_roi.x = 0; - evaspixmapsink->dst_roi.y = 0; - evaspixmapsink->dst_roi.w = 0; - evaspixmapsink->dst_roi.h = 0; - evaspixmapsink->scr_w = 0; - evaspixmapsink->scr_h = 0; - evaspixmapsink->aligned_width = 0; - evaspixmapsink->aligned_height = 0; - evaspixmapsink->stop_video = FALSE; - evaspixmapsink->eo = NULL; - evaspixmapsink->epipe = NULL; - evaspixmapsink->do_link = FALSE; - evaspixmapsink->flip = DEF_DISPLAY_FLIP; - evaspixmapsink->rotate_angle = DEGREE_0; - evaspixmapsink->visible = TRUE; - evaspixmapsink->use_origin_size = FALSE; - evaspixmapsink->previous_origin_size = FALSE; - - evaspixmapsink->num_of_pixmaps = NUM_OF_PIXMAP; - - evaspixmapsink->buf_shared_type = BUF_SHARE_METHOD_NONE; - - MMTA_INIT(); - - GST_DEBUG_OBJECT (evaspixmapsink,"[END]"); - } - -static void -gst_evaspixmapsink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details_simple (element_class, - "EvasPixmapSink", "Sink/Video", - "evas image object videosink based on Xv extension", "Sangchul Lee "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_evaspixmapsink_sink_template_factory)); -} - -static void -gst_evaspixmapsink_class_init (GstEvasPixmapSinkClass *klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSinkClass *gstbasesink_class; - GstVideoSinkClass *videosink_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasesink_class = (GstBaseSinkClass *) klass; - videosink_class = (GstVideoSinkClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_evaspixmapsink_set_property; - gobject_class->get_property = gst_evaspixmapsink_get_property; - - g_object_class_install_property (gobject_class, PROP_CONTRAST, - g_param_spec_int ("contrast", "Contrast", "The contrast of the video", - -1000, 1000, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_BRIGHTNESS, - g_param_spec_int ("brightness", "Brightness", - "The brightness of the video", -1000, 1000, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_HUE, - g_param_spec_int ("hue", "Hue", "The hue of the video", -1000, 1000, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_SATURATION, - g_param_spec_int ("saturation", "Saturation", - "The saturation of the video", -1000, 1000, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DISPLAY, - g_param_spec_string ("display", "Display", "X Display name", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_SYNCHRONOUS, - g_param_spec_boolean ("synchronous", "Synchronous", - "When enabled, runs " - "the X display in synchronous mode. (used only for debugging)", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO, - g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio", - "The pixel aspect ratio of the device", "1/1", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DEVICE, - g_param_spec_string ("device", "Adaptor number", - "The number of the video adaptor", "0", - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_DEVICE_NAME, - g_param_spec_string ("device-name", "Adaptor name", - "The name of the video adaptor", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:double-buffer - * - * Whether to double-buffer the output. - * - * Since: 0.10.14 - */ - g_object_class_install_property (gobject_class, PROP_DOUBLE_BUFFER, - g_param_spec_boolean ("double-buffer", "Double-buffer", - "Whether to double-buffer the output", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstEvasPixmapSink:autopaint-colorkey - * - * Whether to autofill overlay with colorkey - * - * Since: 0.10.21 - */ - g_object_class_install_property (gobject_class, PROP_AUTOPAINT_COLORKEY, - g_param_spec_boolean ("autopaint-colorkey", "Autofill with colorkey", - "Whether to autofill overlay with colorkey", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * GstEvasPixmapSink:colorkey - * - * Color to use for the overlay mask. - * - * Since: 0.10.21 - */ - g_object_class_install_property (gobject_class, PROP_COLORKEY, - g_param_spec_int ("colorkey", "Colorkey", - "Color to use for the overlay mask", G_MININT, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:pixmap-width - * - * Actual width of the pixmap. - */ - g_object_class_install_property (gobject_class, PROP_PIXMAP_WIDTH, - g_param_spec_uint64 ("pixmap-width", "pixmap-width", "Width of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:pixmap-height - * - * Actual height of the pixmap. - */ - g_object_class_install_property (gobject_class, PROP_PIXMAP_HEIGHT, - g_param_spec_uint64 ("pixmap-height", "pixmap-height", "Height of the pixmap", 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:display-geometry-method - * - * Display geometrical method setting - */ - g_object_class_install_property(gobject_class, PROP_DISPLAY_GEOMETRY_METHOD, - g_param_spec_enum("display-geometry-method", "Display geometry method", - "Geometrical method for display", - GST_TYPE_EVASPIXMAPSINK_DISPLAY_GEOMETRY_METHOD, DEF_DISPLAY_GEOMETRY_METHOD, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:dst-roi-x - * - * X value of Destination ROI - */ - g_object_class_install_property (gobject_class, PROP_DST_ROI_X, - g_param_spec_int ("dst-roi-x", "Dst-ROI-X", - "X value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:dst-roi-y - * - * Y value of Destination ROI - */ - g_object_class_install_property (gobject_class, PROP_DST_ROI_Y, - g_param_spec_int ("dst-roi-y", "Dst-ROI-Y", - "Y value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:dst-roi-w - * - * W value of Destination ROI - */ - g_object_class_install_property (gobject_class, PROP_DST_ROI_W, - g_param_spec_int ("dst-roi-w", "Dst-ROI-W", - "W value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_WIDTH, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:dst-roi-h - * - * H value of Destination ROI - */ - g_object_class_install_property (gobject_class, PROP_DST_ROI_H, - g_param_spec_int ("dst-roi-h", "Dst-ROI-H", - "H value of Destination ROI(only effective \"CUSTOM_ROI\")", 0, XV_SCREEN_SIZE_HEIGHT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:stop-video - * - * Stop video for releasing video source buffer - */ - g_object_class_install_property (gobject_class, PROP_STOP_VIDEO, - g_param_spec_int ("stop-video", "Stop-Video", "Stop video for releasing video source buffer", 0, 1, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:evas-object - * - * Evas image object for rendering - */ - g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT, - g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:display-flip - * - * Display flip setting - */ - g_object_class_install_property(gobject_class, PROP_FLIP, - g_param_spec_enum("flip", "Display flip", - "Flip for display", - GST_TYPE_EVASPIXMAPSINK_FLIP, DEF_DISPLAY_FLIP, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:rotate - * - * draw rotation angle setting - */ - g_object_class_install_property(gobject_class, PROP_ROTATE_ANGLE, - g_param_spec_enum("rotate", "Rotate angle", "Rotate angle of display output",GST_TYPE_EVASPIXMAPSINK_ROTATE_ANGLE, DEGREE_0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:visible - * - * visible setting for a evas image object - */ - g_object_class_install_property (gobject_class, PROP_VISIBLE, - g_param_spec_boolean ("visible", "Visible", "When setting it false, evas image object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - /** - * GstEvasPixmapSink:origin-size - * - * Set pixmap size with media source's width and height - */ - g_object_class_install_property (gobject_class, PROP_ORIGIN_SIZE, - g_param_spec_boolean ("origin-size", "Origin-Size", "When setting it true, pixmap will be created with media source's width and height", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gobject_class->finalize = gst_evaspixmapsink_finalize; - - gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_change_state); - gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_getcaps); - gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_setcaps); - gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_get_times); - gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_event); - videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evaspixmapsink_show_frame); -} - -/* Object typing & Creation */ -GType -gst_evaspixmapsink_get_type (void) -{ - static GType evaspixmapsink_type = 0; - - if (!evaspixmapsink_type) { - static const GTypeInfo evaspixmapsink_info = { - sizeof (GstEvasPixmapSinkClass), - gst_evaspixmapsink_base_init, - NULL, - (GClassInitFunc) gst_evaspixmapsink_class_init, - NULL, - NULL, - sizeof (GstEvasPixmapSink), - 0, - (GInstanceInitFunc) gst_evaspixmapsink_init, - }; - static const GInterfaceInfo iface_info = { - (GInterfaceInitFunc) gst_evaspixmapsink_interface_init, - NULL, - NULL, - }; - static const GInterfaceInfo navigation_info = { - (GInterfaceInitFunc) gst_evaspixmapsink_navigation_init, - NULL, - NULL, - }; - static const GInterfaceInfo colorbalance_info = { - (GInterfaceInitFunc) gst_evaspixmapsink_colorbalance_init, - NULL, - NULL, - }; - static const GInterfaceInfo propertyprobe_info = { - (GInterfaceInitFunc) gst_evaspixmapsink_property_probe_interface_init, - NULL, - NULL, - }; - evaspixmapsink_type = g_type_register_static (GST_TYPE_VIDEO_SINK, "GstEvasPixmapSink", &evaspixmapsink_info, 0); - - g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info); - g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_NAVIGATION, &navigation_info); - g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_COLOR_BALANCE, &colorbalance_info); - g_type_add_interface_static (evaspixmapsink_type, GST_TYPE_PROPERTY_PROBE, &propertyprobe_info); - - /* register type and create class in a more safe place instead of at - * runtime since the type registration and class creation is not - * threadsafe. */ - g_type_class_ref (gst_evaspixmap_buffer_get_type ()); - } - - return evaspixmapsink_type; -} - -static gboolean -plugin_init (GstPlugin *plugin) -{ - if (!gst_element_register (plugin, "evaspixmapsink", GST_RANK_NONE, GST_TYPE_EVASPIXMAPSINK)) { - return FALSE; - } - GST_DEBUG_CATEGORY_INIT (gst_debug_evaspixmapsink, "evaspixmapsink", 0, "evaspixmapsink element"); - GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - "evaspixmapsink","Evas image object render plugin using Xv extension", plugin_init, - VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/wearable/evaspixmapsink/evaspixmapsink.h b/wearable/evaspixmapsink/evaspixmapsink.h deleted file mode 100644 index 12dc839..0000000 --- a/wearable/evaspixmapsink/evaspixmapsink.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * EvasPixmapSink - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sangchul Lee - * - * This library 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.1 of the License, or (at your option) - * any later version. - * - * This library 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 library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __GST_EVASPIXMAPSINK_H__ -#define __GST_EVASPIXMAPSINK_H__ - -#include -#include - -#ifdef HAVE_XSHM -#include -#include -#include -#endif /* HAVE_XSHM */ - -#include -#include - -#ifdef HAVE_XSHM -#include -#endif /* HAVE_XSHM */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#define MAX_PLANE_NUM 3 -#define MAX_BUFFER_NUM 20 -#define MAX_GEM_BUFFER_NUM (MAX_PLANE_NUM * MAX_BUFFER_NUM) -typedef struct _gem_info_t { - int dmabuf_fd; - unsigned int gem_handle; - unsigned int gem_name; - unsigned int bo; - Pixmap ref_pixmap; -} gem_info_t; - -typedef enum { - BUF_SHARE_METHOD_NONE = -1, - BUF_SHARE_METHOD_PADDR = 0, - BUF_SHARE_METHOD_FD, - BUF_SHARE_METHOD_TIZEN_BUFFER -} buf_share_method_t; - -G_BEGIN_DECLS - -#define GST_TYPE_EVASPIXMAPSINK \ - (gst_evaspixmapsink_get_type()) -#define GST_EVASPIXMAPSINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSink)) -#define GST_EVASPIXMAPSINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_EVASPIXMAPSINK, GstEvasPixmapSinkClass)) -#define GST_IS_EVASPIXMAPSINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_EVASPIXMAPSINK)) -#define GST_IS_EVASPIXMAPSINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_EVASPIXMAPSINK)) - -#define XV_SCREEN_SIZE_WIDTH 4096 -#define XV_SCREEN_SIZE_HEIGHT 4096 - -#define MARGIN_OF_ERROR 0.005 -#define NUM_OF_PIXMAP 3 - -typedef struct _GstXContext GstXContext; -typedef struct _GstXPixmap GstXPixmap; -typedef struct _GstEvasPixmapFormat GstEvasPixmapFormat; -typedef struct _GstEvasPixmapBuffer GstEvasPixmapBuffer; -typedef struct _GstEvasPixmapBufferClass GstEvasPixmapBufferClass; -typedef struct _GstEvasPixmapSink GstEvasPixmapSink; -typedef struct _GstEvasPixmapSinkClass GstEvasPixmapSinkClass; - -/* - * GstXContext: - * @disp: the X11 Display of this context - * @screen: the default Screen of Display @disp - * @screen_num: the Screen number of @screen - * @visual: the default Visual of Screen @screen - * @root: the root Window of Display @disp - * @white: the value of a white pixel on Screen @screen - * @black: the value of a black pixel on Screen @screen - * @depth: the color depth of Display @disp - * @bpp: the number of bits per pixel on Display @disp - * @endianness: the endianness of image bytes on Display @disp - * @width: the width in pixels of Display @disp - * @height: the height in pixels of Display @disp - * @widthmm: the width in millimeters of Display @disp - * @heightmm: the height in millimeters of Display @disp - * @par: the pixel aspect ratio calculated from @width, @widthmm and @height, - * @heightmm ratio - * @use_xshm: used to known wether of not XShm extension is usable or not even - * if the Extension is present - * @xv_port_id: the XVideo port ID - * @im_format: used to store at least a valid format for XShm calls checks - * @formats_list: list of supported image formats on @xv_port_id - * @channels_list: list of #GstColorBalanceChannels - * @caps: the #GstCaps that Display @disp can accept - * - * Structure used to store various informations collected/calculated for a - * Display. - */ -struct _GstXContext { - Display *disp; - - Screen *screen; - gint screen_num; - - Visual *visual; - - Window root; - - gulong white, black; - - gint depth; - gint bpp; - gint endianness; - - gint width, height; - gint widthmm, heightmm; - GValue *par; /* calculated pixel aspect ratio */ - - gboolean use_xshm; - - XvPortID xv_port_id; - guint nb_adaptors; - gchar ** adaptors; - gint im_format; - - GList *formats_list; - GList *channels_list; - - GstCaps *caps; -}; - -/* - * GstXPixmap: - * @pixmap: the pixmap ID of this X11 pixmap - * @width: the width in pixels of Pixmap @pixmap - * @height: the height in pixels of Pixmap @pixmap - * @gc: the Graphical Context of Pixmap @pixmap - * - * Structure used to store informations about a Pixmap. - */ -struct _GstXPixmap { - Pixmap pixmap; - gint x, y; - gint width, height; - GC gc; - guint ref; - gint damaged_time; - Pixmap prev_pixmap; - GC prev_gc; -}; - -/** - * GstEvasPixmapFormat: - * @format: the image format - * @caps: generated #GstCaps for this image format - * - * Structure storing image format to #GstCaps association. - */ -struct _GstEvasPixmapFormat { - gint format; - GstCaps *caps; -}; - -/** - * GstEvasPixmapBuffer: - * @evaspixmapsink: a reference to our #GstEvasPixmapSink - * @xvimage: the XvImage of this buffer - * @width: the width in pixels of XvImage @xvimage - * @height: the height in pixels of XvImage @xvimage - * @im_format: the image format of XvImage @xvimage - * @size: the size in bytes of XvImage @xvimage - * - * Subclass of #GstBuffer containing additional information about an XvImage. - */ -struct _GstEvasPixmapBuffer { - GstBuffer buffer; - - /* Reference to the evaspixmapsink we belong to */ - GstEvasPixmapSink *evaspixmapsink; - XvImage *xvimage; - -#ifdef HAVE_XSHM - XShmSegmentInfo SHMInfo; -#endif /* HAVE_XSHM */ - - gint width, height; - gint im_format; - size_t size; -}; - -/** - * GstEvasPixmapSink: - * @display_name: the name of the Display we want to render to - * @xcontext: our instance's #GstXContext - * @xpixmap: the #GstXPixmap we are rendering to - * @fps_n: the framerate fraction numerator - * @fps_d: the framerate fraction denominator - * @x_lock: used to protect X calls as we are not using the XLib in threaded - * mode - * @flow_lock: used to protect data flow routines from external calls such as - * methods from the #GstXOverlay interface - * @par: used to override calculated pixel aspect ratio from @xcontext - * @synchronous: used to store if XSynchronous should be used or not (for - * debugging purpose only) - * @keep_aspect: used to remember if reverse negotiation scaling should respect - * aspect ratio - * @brightness: used to store the user settings for color balance brightness - * @contrast: used to store the user settings for color balance contrast - * @hue: used to store the user settings for color balance hue - * @saturation: used to store the user settings for color balance saturation - * @cb_changed: used to store if the color balance settings where changed - * @video_width: the width of incoming video frames in pixels - * @video_height: the height of incoming video frames in pixels - * - * The #GstEvasPixmapSink data structure. - */ -struct _GstEvasPixmapSink { - /* Our element stuff */ - GstVideoSink videosink; - - char *display_name; - guint adaptor_no; - - GstXContext *xcontext; - GstXPixmap *xpixmap[NUM_OF_PIXMAP]; - GstEvasPixmapBuffer *evas_pixmap_buf; - - GThread *event_thread; - gboolean running; - - gint fps_n; - gint fps_d; - - GMutex *x_lock; - GMutex *flow_lock; - GMutex *pixmap_ref_lock; - - /* object-set pixel aspect ratio */ - GValue *par; - - gboolean synchronous; - gboolean double_buffer; - - gint brightness; - gint contrast; - gint hue; - gint saturation; - gboolean cb_changed; - - /* size of incoming video, used as the size for XvImage */ - guint video_width, video_height; - - /* display sizes, used for clipping the image */ - gint disp_x, disp_y; - gint disp_width, disp_height; - - /* port attributes */ - gboolean autopaint_colorkey; - gint colorkey; - - /* port features */ - gboolean have_autopaint_colorkey; - gboolean have_colorkey; - gboolean have_double_buffer; - - /* target video rectagle */ - GstVideoRectangle render_rect; - gboolean have_render_rect; - - /* display */ - guint flip; - guint rotate_angle; - guint display_geometry_method; - GstVideoRectangle dst_roi; - guint scr_w, scr_h; - /* needed if fourcc is one if S series */ - guint aligned_width; - guint aligned_height; - - gboolean stop_video; - buf_share_method_t buf_shared_type; - - /* ecore & evas object */ - Evas_Object *eo; - Evas_Coord w; - Evas_Coord h; - gboolean visible; - gint last_updated_idx; - - /* pixmap */ - gboolean do_link; - gboolean use_origin_size; - gboolean previous_origin_size; - gint sizediff_width; - gint sizediff_height; - guint num_of_pixmaps; - - /* damage event */ - Damage damage[NUM_OF_PIXMAP]; - Damage prev_damage[NUM_OF_PIXMAP]; - int damage_case; - Ecore_Pipe *epipe; - - gint drm_fd; - gem_info_t gem_info[MAX_GEM_BUFFER_NUM]; -}; - -/* max plane count *********************************************************/ -#define MPLANE_IMGB_MAX_COUNT (4) - -/* image buffer definition *************************************************** - - +------------------------------------------+ --- - | | ^ - | uaddr[], index[] | | - | +---------------------------+ --- | | - | | | ^ | | - | |<-------- width[] -------->| | | | - | | | | | | - | | | | - | | |height[]|elevation[] - | | | | - | | | | | | - | | | | | | - | | | v | | - | +---------------------------+ --- | | - | | v - +------------------------------------------+ --- - - |<----------------- stride[] ------------------>| -*/ -typedef struct _GstMultiPlaneImageBuffer GstMultiPlaneImageBuffer; -struct _GstMultiPlaneImageBuffer -{ - GstBuffer buffer; - - /* width of each image plane */ - gint width[MPLANE_IMGB_MAX_COUNT]; - /* height of each image plane */ - gint height[MPLANE_IMGB_MAX_COUNT]; - /* stride of each image plane */ - gint stride[MPLANE_IMGB_MAX_COUNT]; - /* elevation of each image plane */ - gint elevation[MPLANE_IMGB_MAX_COUNT]; - /* user space address of each image plane */ - gpointer uaddr[MPLANE_IMGB_MAX_COUNT]; - /* Index of real address of each image plane, if needs */ - gpointer index[MPLANE_IMGB_MAX_COUNT]; - /* left postion, if needs */ - gint x; - /* top position, if needs */ - gint y; - /* to align memory */ - gint __dummy2; - /* arbitrary data */ - gint data[16]; -}; - -struct _GstEvasPixmapSinkClass { - GstVideoSinkClass parent_class; -}; - -GType gst_evaspixmapsink_get_type(void); - -G_END_DECLS - -#endif /* __GST_EVASPIXMAPSINK_H__ */ diff --git a/wearable/xvimagesrc/Makefile.am b/xvimagesrc/Makefile.am similarity index 100% rename from wearable/xvimagesrc/Makefile.am rename to xvimagesrc/Makefile.am diff --git a/wearable/xvimagesrc/src/Makefile.am b/xvimagesrc/src/Makefile.am similarity index 95% rename from wearable/xvimagesrc/src/Makefile.am rename to xvimagesrc/src/Makefile.am index 8482d9d..eff56f2 100644 --- a/wearable/xvimagesrc/src/Makefile.am +++ b/xvimagesrc/src/Makefile.am @@ -19,9 +19,6 @@ libgstxvimagesrc_la_SOURCES = gstxvimagesrc.c # flags used to compile this plugin # add other _CFLAGS and _LIBS as needed libgstxvimagesrc_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(TBM_CFLAGS) $(DRI2_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS) $(XV_CFLAGS) $(XDAMAGE_CFLAGS) $(DRM_DEVEL_CFLAGS) $(DRM_CFLAGS) -if IS_QC_SPECIFIC -libgstxvimagesrc_la_CFLAGS += -DENABLE_QC_SPECIFIC -endif libgstxvimagesrc_la_LIBADD = $(GST_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(TBM_LIBS) $(DRI2_LIBS) $(X11_LIBS) $(XEXT_LIBS) $(XV_LIBS) $(XDAMAGE_LIBS) $(DRM_LIBS) $(DRM_DEVEL_LIBS) $(DRM_SLP_MSM) libgstxvimagesrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/wearable/xvimagesrc/src/gstxvimagesrc.c b/xvimagesrc/src/gstxvimagesrc.c similarity index 81% rename from wearable/xvimagesrc/src/gstxvimagesrc.c rename to xvimagesrc/src/gstxvimagesrc.c index 26938f8..759e9f2 100755 --- a/wearable/xvimagesrc/src/gstxvimagesrc.c +++ b/xvimagesrc/src/gstxvimagesrc.c @@ -49,12 +49,11 @@ #include #include #include +#include #include #include #include -#ifndef ENABLE_QC_SPECIFIC #include -#endif GST_DEBUG_CATEGORY_STATIC (xvimagesrc_debug); #define GST_CAT_DEFAULT xvimagesrc_debug @@ -86,27 +85,28 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", enum { PROP_0, - PROP_SECURE_MODE + PROP_AUDIO_LATENCY, + PROP_SECURE_MODE, + PROP_DISPLAY_ROTATE, }; enum { + VIDEO_TYPE_UI, VIDEO_TYPE_VIDEO_WITH_UI, VIDEO_TYPE_VIDEO_ONLY, }; enum { - SIGNAL_VIDEO_WITH_UI = 0, + SIGNAL_UI_ONLY = 0, + SIGNAL_VIDEO_WITH_UI, SIGNAL_VIDEO_ONLY, + SIGNAL_SELECTION_NOTIFY, SIGNAL_LAST }; -#ifndef ENABLE_QC_SPECIFIC #define GEM_NAME_MAX 10 -#else -#define GEM_NAME_MAX 3 -#endif #define SCMN_CS_YUV420 1 /* Y:U:V 4:2:0 */ #define SCMN_CS_I420 SCMN_CS_YUV420 /* Y:U:V */ @@ -185,7 +185,7 @@ typedef struct /* tzmem buffer */ int tz_enable; } SCMN_IMGB; -#ifndef ENABLE_QC_SPECIFIC + typedef struct { void *address[GEM_NAME_MAX]; @@ -194,15 +194,7 @@ typedef struct gint32 fd[GEM_NAME_MAX]; gint32 handle[GEM_NAME_MAX]; } GEM_MMAP; -#else -typedef struct -{ - void *virtual_add[GEM_NAME_MAX]; - int gem_name[GEM_NAME_MAX]; - gint32 ion_fd[GEM_NAME_MAX]; - void *Ybo[GEM_NAME_MAX]; -} MSM_GEM_MMAP; -#endif + typedef enum { BUF_SHARE_METHOD_PADDR = 0, BUF_SHARE_METHOD_FD @@ -221,6 +213,19 @@ struct GstXvImageOutBuffer { #define DEFAULT_USER_AGENT "GStreamer xvimagesrc " +//#define _MAKE_DUMP +#ifdef _MAKE_DUMP +#define YUV_FRAME_SIZE 3110400 +#define YUV_720_FRAME_SIZE 1382400 +#define YUV_VGA_FRAME_SIZE 460800 + +static int g_prev_frame[YUV_FRAME_SIZE] = {0,}; +static int g_dump_frame[100][YUV_720_FRAME_SIZE]; +//static int g_dump_frame[200][YUV_VGA_FRAME_SIZE]; +static int f_idx = 0; +static int f_done = 0; +#endif + static guint gst_xv_image_src_signals[SIGNAL_LAST] = { 0 }; //#define COUNT_FRAMES @@ -265,9 +270,7 @@ static void* gst_xv_image_src_update_thread (void * asrc); static gboolean xvimagesrc_thread_start(GstXVImageSrc *src); static void drm_init(GstXVImageSrc *src); static void drm_finalize(GstXVImageSrc *src); -#ifndef ENABLE_QC_SPECIFIC static gint32 drm_convert_gem_to_fd(int * gemname_cnt, int drm_fd, unsigned int name, void * data, void **virtual_address); -#endif static void gst_xv_get_image_sleep(void *asrc, long duration); static void @@ -330,9 +333,13 @@ gst_xv_image_src_change_state (GstElement * element, GstStateChange transition) g_cond_signal(src->pause_cond); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + GST_WARNING("GST_STATE_CHANGE_PLAYING_TO_PAUSED: START"); src->pause_cond_var = TRUE; + g_cond_wait(src->pause_resp, src->pause_resp_lock); + GST_WARNING("GST_STATE_CHANGE_PLAYING_TO_PAUSED: End"); break; case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_WARNING("GST_STATE_CHANGE_PAUSED_TO_READY"); src->thread_return = TRUE; g_cond_signal(src->pause_cond); g_cond_signal(src->queue_cond); @@ -350,6 +357,11 @@ gst_xv_image_src_change_state (GstElement * element, GstStateChange transition) static void gst_xv_image_out_buffer_finalize(GstXvImageOutBuffer *buffer) { Atom atom_retbuf = 0; + if (buffer->xvimagesrc->thread_return) { + GST_INFO("xvimagesrc is being shutdown"); + return; + } + g_mutex_lock (buffer->xvimagesrc->dpy_lock); atom_retbuf = XInternAtom (buffer->xvimagesrc->dpy, "_USER_WM_PORT_ATTRIBUTE_RETURN_BUFFER", False); XvSetPortAttribute (buffer->xvimagesrc->dpy, buffer->xvimagesrc->p, atom_retbuf, buffer->YBuf); //data->YBuf is gemname, refer to drm_convert_gem_to_fd @@ -424,13 +436,17 @@ gst_xv_image_src_class_init (GstXVImageSrcClass * klass) gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_xv_image_src_setcaps); gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_xv_image_src_create); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_xv_image_src_change_state); -#ifdef ENABLE_QC_SPECIFIC - g_object_class_install_property (gobject_class, PROP_SECURE_MODE, - g_param_spec_boolean ("secure-mode", - "secure mode session", - "HDCP enabled", - 0, G_PARAM_READWRITE)); -#endif + g_object_class_install_property (gobject_class, PROP_DISPLAY_ROTATE, + g_param_spec_uint64 ("display-rotate", + "display-rotate", + "Display rotate info", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + + gst_xv_image_src_signals[SIGNAL_UI_ONLY] = + g_signal_new ("ui-only", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstXVImageSrcClass, ui_only), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + gst_xv_image_src_signals[SIGNAL_VIDEO_WITH_UI] = g_signal_new ("video-with-ui", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstXVImageSrcClass, video_with_ui), NULL, NULL, @@ -441,6 +457,10 @@ gst_xv_image_src_class_init (GstXVImageSrcClass * klass) G_STRUCT_OFFSET (GstXVImageSrcClass, video_only), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + gst_xv_image_src_signals[SIGNAL_SELECTION_NOTIFY] = + g_signal_new ("selection-notify", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstXVImageSrcClass, selection_notify), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); } static gboolean gst_xv_image_src_get_frame_size(int fourcc, int width, int height, unsigned int *outsize) @@ -583,6 +603,8 @@ gst_xv_image_src_init (GstXVImageSrc * src, GstXVImageSrcClass * g_class) src->buffer_cond_lock = g_mutex_new (); src->pause_cond = g_cond_new (); src->pause_cond_lock = g_mutex_new (); + src->pause_resp = g_cond_new (); + src->pause_resp_lock = g_mutex_new (); src->dpy_lock = g_mutex_new (); src->pause_cond_var = FALSE; src->drm_fd = -1; @@ -594,6 +616,7 @@ gst_xv_image_src_init (GstXVImageSrc * src, GstXVImageSrcClass * g_class) src->tz_enable = 0; src->sleep_base_time = 0; src->sleep_limit_time = 0; + src->switching_to_udp = FALSE; drm_init(src); gst_base_src_set_live (GST_BASE_SRC (src), TRUE); } @@ -661,7 +684,7 @@ static void drm_finalize(GstXVImageSrc *src) src->drm_fd = -1; } } -#ifndef ENABLE_QC_SPECIFIC + static gint32 drm_convert_gem_to_fd(int *gemname_cnt, int drm_fd, unsigned int name, void *data, void **virtual_address) { g_return_val_if_fail((data != NULL),0); @@ -767,74 +790,7 @@ PASS: GST_DEBUG("virtual_address = %p fd = %d", *virtual_address, fd); return fd; } -#else -static gint32 msm_convert_gem_to_fd(GstXVImageSrc *src, int *gemname_cnt, unsigned int gem_name, void *data) -{ - g_return_val_if_fail((data != NULL),0); - int count=0; - gint32 fd = 0; - tbm_bo_handle bo_handle; - count = *gemname_cnt; - GST_DEBUG("gamname_cnt = %d", count); - GST_DEBUG ("tbm_bo_import %d", gem_name); - MSM_GEM_MMAP *xv_gem_mmap = NULL; - xv_gem_mmap = (MSM_GEM_MMAP *) data; - if(count >=GEM_NAME_MAX) - goto PASS; - - if (count < GEM_NAME_MAX ) { - int i =0; - for ( i =0 ; i < GEM_NAME_MAX ; i++) { - if (gem_name == xv_gem_mmap->gem_name[i]) - goto PASS; - } - xv_gem_mmap->Ybo[count] = tbm_bo_import(src->bufmgr, gem_name); - if (!xv_gem_mmap->Ybo[count]) { - GST_ERROR ("[Error] : cannot import bo (key:%d)", gem_name); - return 0; - } - bo_handle = tbm_bo_get_handle (xv_gem_mmap->Ybo[count], TBM_DEVICE_2D); - if(!bo_handle.s32) - { - GST_ERROR ("[Error] : cannot get Ion FD"); - return 0; - } - xv_gem_mmap->ion_fd[count] = bo_handle.s32; - src->framesize = tbm_bo_size(xv_gem_mmap->Ybo[count]); -#if 0 //Its no more required with Meta mode Encoder, Need to remove after meta mode verification - tbm_bo_handle temp_virtual; - temp_virtual = tbm_bo_get_handle (xv_gem_mmap->Ybo[count], TBM_DEVICE_CPU); - xv_gem_mmap->virtual_add[count] = temp_virtual.ptr; - - if(!xv_gem_mmap->virtual_add[count]) - { - GST_ERROR ("[Error] : cannot map virtual address"); - return 0; - } -#endif - /*set name*/ - xv_gem_mmap->gem_name[count] = gem_name; - } - if (count < GEM_NAME_MAX) { - count ++; - *gemname_cnt = count; - } -PASS: - if (gem_name == xv_gem_mmap->gem_name[0]) { - //*virtual_address = xv_gem_mmap->virtual_add[0]; - fd = xv_gem_mmap->ion_fd[0]; - } else if (gem_name == xv_gem_mmap->gem_name[1]) { - //*virtual_address = xv_gem_mmap->virtual_add[1]; - fd = xv_gem_mmap->ion_fd[1]; - } else if (gem_name == xv_gem_mmap->gem_name[2]) { - //*virtual_address = xv_gem_mmap->virtual_add[2]; - fd = xv_gem_mmap->ion_fd[2]; - } - GST_DEBUG("ion_fd = %d", fd); - return fd; -} -#endif static void gst_xv_image_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -842,12 +798,10 @@ gst_xv_image_src_set_property (GObject * object, guint prop_id, GstXVImageSrc *src = GST_XV_IMAGE_SRC (object); GST_INFO ("set property function %x", src); switch (prop_id) { -#ifdef ENABLE_QC_SPECIFIC - case PROP_SECURE_MODE: - src->is_secured_mode = g_value_get_boolean (value); - GST_DEBUG("is_secured_mode %d", src->is_secured_mode); - break; -#endif + case PROP_DISPLAY_ROTATE: + src->display_rotate = g_value_get_uint64 (value); + GST_DEBUG("display_rotate [%d]", src->display_rotate); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -862,11 +816,9 @@ gst_xv_image_src_get_property (GObject * object, guint prop_id, GstXVImageSrc *src = GST_XV_IMAGE_SRC (object); GST_INFO ("get property function %x", src); switch (prop_id) { -#ifdef ENABLE_QC_SPECIFIC - case PROP_SECURE_MODE: - g_value_set_boolean (value, src->is_secured_mode); - break; -#endif + case PROP_DISPLAY_ROTATE: + g_value_set_uint64 (value, src->display_rotate); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -883,6 +835,56 @@ static inline GstClockTime xvimagesrc_clock (GstXVImageSrc *src) return (GstClockTime)(GST_TIMEVAL_TO_TIME(tv) - src->base_time); } +static gboolean gst_xv_image_src_get_timeinfo2(GstXVImageSrc *src, GstClockTime *time, GstClockTime *dur) +{ + int fps_nu = 0; + int fps_de = 0; + GstClockTime timestamp = GST_CLOCK_TIME_NONE; + GstClockTime duration = GST_CLOCK_TIME_NONE; + static GstClockTime prev_timestamp = 0; + + GstClock *clock; + if (!src) { + GST_WARNING("Invalid pointer [handle:%p]", src); + return FALSE; + } + clock = gst_element_get_clock (GST_ELEMENT (src)); + if (clock) { + timestamp = gst_clock_get_time (clock); + if(!gst_element_get_base_time (GST_ELEMENT(src))) + timestamp = GST_CLOCK_TIME_NONE; + else timestamp -= gst_element_get_base_time (GST_ELEMENT (src)); + gst_object_unref (clock); + } else { + /* not an error not to have a clock */ + timestamp = GST_CLOCK_TIME_NONE; + } + + if ((timestamp - prev_timestamp <= 30000000) || (timestamp-prev_timestamp >=36000000)) { + //GST_ERROR("Gap is below 30ms or over 36ms!!"); + } + + /* if we have a framerate adjust timestamp for frame latency */ + if ((int)((float)src->rate_numerator / (float)src->rate_denominator) <= 0) { + /*if fps is zero, auto fps mode*/ + fps_nu = 0; + fps_de = 1; + } else { + fps_nu = 1; + fps_de = (int)((float)src->rate_numerator / (float)src->rate_denominator); + } + if (fps_nu > 0 && fps_de > 0) { + GstClockTime latency; + latency = gst_util_uint64_scale_int(GST_SECOND, fps_nu, fps_de); + duration = latency; + } + timestamp+=src->initial_audio_latency; + *time = timestamp; + *dur = duration; + prev_timestamp = timestamp; + return TRUE; +} + static gboolean gst_xv_image_src_get_timeinfo(GstXVImageSrc *src, GstBuffer *buffer) { int fps_nu = 0; @@ -950,21 +952,29 @@ static void gst_xv_get_image_sleep(void *asrc, long duration) g_return_if_fail(src != NULL); long sleep_time = 0; sleep_time = src->sleep_base_time - duration; + if (sleep_time < 0) { - src->get_image_overtime_cnt ++; - src->get_image_overtime += sleep_time; - if (src->get_image_overtime_cnt > 2) - src->get_image_overtime = 0; - if (src->get_image_overtime <= src->sleep_limit_time) - src->get_image_overtime = 0; + src->get_image_overtime_cnt ++; + src->get_image_overtime += sleep_time; + if (src->get_image_overtime_cnt > 2) + src->get_image_overtime = 0; + if (src->get_image_overtime <= src->sleep_limit_time) + src->get_image_overtime = 0; + //GST_WARNING("Over Time[%d] : %d", src->get_image_overtime_cnt, src->get_image_overtime); } else if (sleep_time > 0) { - src->get_image_overtime_cnt = 0; - sleep_time = sleep_time + src->get_image_overtime; - src->get_image_overtime = (sleep_time < 0) ? sleep_time : 0; - if (sleep_time >0) { - GST_INFO("end_time : sleep_time = %d", sleep_time); - usleep(sleep_time); - } + src->get_image_overtime_cnt = 0; + sleep_time = sleep_time + src->get_image_overtime; + + if (src->get_image_overtime < 0) { + //GST_WARNING("Over Time : %d, So sleep time : %d", src->get_image_overtime, sleep_time); + } + + src->get_image_overtime = (sleep_time < 0) ? sleep_time : 0; + + if (sleep_time >0) { + GST_INFO("end_time : sleep_time = %d", sleep_time); + usleep(sleep_time); + } } } static GstFlowReturn @@ -982,6 +992,17 @@ gst_xv_image_src_create (GstPushSrc * psrc, GstBuffer ** buffer) g_cond_wait(src->queue_cond, src->cond_lock); if(src->pause_cond_var) return GST_FLOW_WRONG_STATE; g_mutex_lock (src->queue_lock); + + if(src->switching_to_udp == TRUE) { + GstStructure *structure; + structure = gst_structure_new("Switch_udp", "switch_to_udp", G_TYPE_BOOLEAN, NULL, NULL); + GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, structure); + GstPad *srcpad = gst_element_get_static_pad(src, "src"); + gst_pad_push_event(srcpad, event); + GST_INFO("sending the event"); + src->switching_to_udp = FALSE; + } + outbuf = (GstXvImageOutBuffer *)g_queue_pop_head(src->queue); GST_INFO("g_queue_pop_head"); g_mutex_unlock (src->queue_lock); @@ -1033,14 +1054,28 @@ gst_xv_image_src_start (GstBaseSrc * bsrc) gboolean signal_emit_func(void *asrc) { GstXVImageSrc *src = (GstXVImageSrc *)asrc; - if (src->current_data_type == VIDEO_TYPE_VIDEO_ONLY) { - g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_VIDEO_ONLY] , 0, NULL); + + if (src->current_data_type == VIDEO_TYPE_UI) { + src->switching_to_udp = TRUE; + g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_UI_ONLY] , 0, NULL); + } else if (src->current_data_type == VIDEO_TYPE_VIDEO_ONLY) { + g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_VIDEO_ONLY] , 0, NULL); } else if (src->current_data_type == VIDEO_TYPE_VIDEO_WITH_UI) { g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_VIDEO_WITH_UI] , 0, NULL); } + return FALSE; } +gboolean signal_selection_emit_func(void *asrc) +{ + GstXVImageSrc *src = (GstXVImageSrc *)asrc; + + g_signal_emit (src, gst_xv_image_src_signals[SIGNAL_SELECTION_NOTIFY] , 0, NULL); + + return FALSE; +} + static int gst_xvimagesrc_handle_xerror (Display * display, XErrorEvent * xevent) { @@ -1062,21 +1097,13 @@ static void* gst_xv_image_src_update_thread (void * asrc) Atom atom_fps = 0; g_return_val_if_fail((src != NULL),NULL); int i=0; -#ifdef ENABLE_QC_SPECIFIC - Atom atom_rotate=0; - MSM_GEM_MMAP *xv_gem_mmap = NULL; - xv_gem_mmap = (MSM_GEM_MMAP *)malloc(sizeof(MSM_GEM_MMAP)); - g_return_val_if_fail((xv_gem_mmap != NULL),NULL); - - memset(xv_gem_mmap, 0, sizeof(MSM_GEM_MMAP)); -#else struct drm_gem_close gem_close; GEM_MMAP *xv_gem_mmap = NULL; xv_gem_mmap = (GEM_MMAP *)malloc(sizeof(GEM_MMAP)); g_return_val_if_fail((xv_gem_mmap != NULL),NULL); memset(xv_gem_mmap, 0, sizeof(GEM_MMAP)); -#endif + GST_LOG_OBJECT (src, "The thread function start"); { int damage_err_base = 0; @@ -1101,29 +1128,39 @@ static void* gst_xv_image_src_update_thread (void * asrc) atom_format = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_FORMAT", False); atom_capture = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False); atom_display = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_DISPLAY", False); -#ifdef ENABLE_QC_SPECIFIC - atom_rotate = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_ROTATE_OFF", False); -#endif + /*get data type*/ atom_data_type = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_DATA_TYPE", False); /* _USER_WM_PORT_ATTRIBUTE_STREAM_OFF is removed */ //src->atom_stream_off = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False); + XvSetPortAttribute (src->dpy, src->p, atom_format, src->format_id); XvSetPortAttribute (src->dpy, src->p, atom_capture, 2); XvSetPortAttribute (src->dpy, src->p, atom_display, 1); -#ifdef ENABLE_QC_SPECIFIC - XvSetPortAttribute (src->dpy, src->p, atom_rotate, 0); -#endif -#ifdef ENABLE_QC_SPECIFIC - /* To be enabled for secure mode when msm is delivered */ - if(src->is_secured_mode) { - atom_secure = XInternAtom (src->dpy, "_USER_WM_PORT_ATTRIBUTE_SECURE", False); - XvSetPortAttribute (src->dpy, src->p, atom_secure, 1); - } -#endif XvSelectPortNotify (src->dpy, src->p, 1); XvGetPortAttribute (src->dpy, src->p, atom_data_type, &(src->new_data_type)); + + + /* Set display type */ + Atom atom_select_display=0; + Atom atom_select_display_type=0; + Atom atom_encoding=0; + XTextProperty xtp; + const char *display_type = "WFD"; + + atom_select_display = XInternAtom(src->dpy, "SEL_EXT_DISPLAY", False); + atom_select_display_type = XInternAtom(src->dpy, "SEL_EXT_DISPLAY_TYPE", False); + atom_encoding = XInternAtom(src->dpy, "UTF8_STRING", False); + src->win = DefaultRootWindow(src->dpy); + + XSetSelectionOwner(src->dpy, atom_select_display, src->win, 0); + + xtp.value = (unsigned char *)display_type; + xtp.format = 8; + xtp.encoding = atom_encoding; + xtp.nitems = strlen(display_type); + XSetTextProperty(src->dpy, src->win, &xtp, atom_select_display_type); } struct timeval start_time, end_time; @@ -1132,41 +1169,64 @@ static void* gst_xv_image_src_update_thread (void * asrc) GTimeVal timeout; XEvent ev; int eventcount = 0; + int refresh = 1; void *virtual_address = NULL; int (*handler) (Display *, XErrorEvent *); GstXvImageOutBuffer *outbuf = NULL; + GstClockTime ts_putstill = 0; + GstClockTime dur_putstill = 0; + + gboolean got_display_select_req = FALSE; + while(!src->thread_return) { if(src->pause_cond_var == TRUE) { + GST_WARNING("PAUSED in thread"); + g_cond_signal(src->pause_resp); g_cond_wait(src->pause_cond,src->pause_cond_lock); } - duration = 0; - starttime =0; - endtime = 0; - start_time.tv_sec = 0; - start_time.tv_usec = 0; - end_time.tv_sec = 0; - end_time.tv_usec = 0; - gettimeofday(&start_time, NULL); + if (src->thread_return) { + GST_WARNING("Thread return"); + break; + } + + if (refresh == 1) { + duration = 0; + starttime =0; + endtime = 0; + start_time.tv_sec = 0; + start_time.tv_usec = 0; + end_time.tv_sec = 0; + end_time.tv_usec = 0; + gettimeofday(&start_time, NULL); + refresh = 0; + } eventcount = 0; virtual_address = NULL; duration = 0; outbuf = NULL; g_mutex_lock (src->dpy_lock); + GST_DEBUG("[XCALL] call XSync"); XSync(src->dpy, 0); GST_INFO ("gst_xv_image_src_update_thread XSync@@ !!"); g_mutex_unlock (src->dpy_lock); error_caught = FALSE; - GST_DEBUG ("gst_xv_image_src_update_thread XSetErrorHandler in !!"); + //GST_DEBUG ("gst_xv_image_src_update_thread XSetErrorHandler in !!"); handler = XSetErrorHandler (gst_xvimagesrc_handle_xerror); - GST_INFO ("gst_xv_image_src_update_thread XSetErrorHandler !!"); - GST_INFO ("gst_xv_image_src_update_thread XvPutStill in !!"); + //GST_INFO ("gst_xv_image_src_update_thread XSetErrorHandler !!"); + //GST_INFO ("gst_xv_image_src_update_thread XvPutStill in !!"); g_mutex_lock (src->dpy_lock); + GST_DEBUG("[XCALL] call XvPutStill"); XvPutStill (src->dpy, src->p, src->pixmap, src->gc, 0, 0, src->width, src->height, 0, 0, src->width, src->height); - GST_INFO ("gst_xv_image_src_update_thread XvPutStill !!"); + + gst_xv_image_src_get_timeinfo2(src, &ts_putstill, &dur_putstill); + + //GST_INFO ("gst_xv_image_src_update_thread XvPutStill !!"); + GST_DEBUG("[XCALL] call 2nd XSync"); XSync (src->dpy, 0); + GST_DEBUG("[XCALL] call 2nd XSync done"); g_mutex_unlock (src->dpy_lock); if (error_caught) { GST_ERROR("gst_xv_image_src_update_thread error_caught is TRUE, X is out of buffers"); @@ -1185,14 +1245,14 @@ static void* gst_xv_image_src_update_thread (void * asrc) error_caught = FALSE; XSetErrorHandler(handler); - GST_INFO ("gst_xv_image_src_update_thread XSync !!"); + //GST_INFO ("gst_xv_image_src_update_thread XSync !!"); next_event: g_mutex_lock (src->dpy_lock); - GST_INFO("XNextEvent in"); + //GST_INFO("XNextEvent in"); XNextEvent (src->dpy, &ev); /* wating for x event */ - GST_INFO("XNextEvent out"); + //GST_INFO("XNextEvent out"); g_mutex_unlock (src->dpy_lock); - GST_INFO ("gst_xv_image_src_update_thread XNextEvent !!"); + //GST_INFO ("gst_xv_image_src_update_thread XNextEvent !!"); if (ev.type == (src->damage_base + XDamageNotify)) { XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev; GST_INFO ("gst_xv_image_src_update_thread XDamageNotifyEvent"); @@ -1209,22 +1269,53 @@ next_event: g_mutex_unlock (src->dpy_lock); GST_INFO ("gst_xv_image_src_update_thread XDamageSubtract"); } + /* Added to handle display selection notify */ + else if (ev.type == SelectionClear) { + XSelectionEvent *selection_ev = (XSelectionEvent*)&ev; + + GST_ERROR("ev.type : %d SelectionClear", ev.type); + //g_timeout_add(1, signal_selection_emit_func, src); + } + else if (ev.type == SelectionRequest) { + XSelectionRequestEvent *selection_ev = (XSelectionRequestEvent*)&ev; + + GST_ERROR("ev.type : %d SelectionRequest", ev.type); + src->requestor = selection_ev->requestor; + src->selection = selection_ev->selection; + src->target = selection_ev->target; + src->property = selection_ev->property; + + got_display_select_req = TRUE; + g_timeout_add(1, signal_selection_emit_func, src); + } + else if (ev.type == SelectionNotify) { + XSelectionEvent *selection_ev = (XSelectionEvent*)&ev; + + GST_ERROR("ev.type : %d SelectionNotify", ev.type); + //g_timeout_add(1, signal_selection_emit_func, src); + } else if (ev.type == (src->evt_base + XvPortNotify)) { XvPortNotifyEvent *notify_ev = (XvPortNotifyEvent*)&ev; -#ifndef ENABLE_QC_SPECIFIC if (notify_ev->attribute == atom_secure) { GST_WARNING ("secure attr changed : %s \n", ((int)notify_ev->value)?"Secure":"Normal"); src->tz_enable = (int)notify_ev->value; GST_ERROR("src->tz_enable = %d", src->tz_enable); } - else -#endif + else if (notify_ev->attribute == atom_data_type) { /* got a port notify, data_type */ src->new_data_type = (int)notify_ev->value; if (src->current_data_type != src->new_data_type) { src->current_data_type = src->new_data_type; - GST_WARNING("current_data_type : %s \n", (src->current_data_type)?"Video":"UI+Video"); + //GST_WARNING("current_data_type : %s \n", (src->current_data_type)?"Video":"UI+Video"); + if (src->current_data_type == VIDEO_TYPE_UI) { + GST_WARNING("current_data_type : UI\n"); + } else if (src->current_data_type == VIDEO_TYPE_VIDEO_WITH_UI) { + GST_WARNING("current_data_type : Video+UI\n"); + } else if (src->current_data_type == VIDEO_TYPE_VIDEO_ONLY) { + GST_WARNING("current_data_type : VideoOnly\n"); + } + g_timeout_add(1, signal_emit_func, src); } } @@ -1267,11 +1358,6 @@ next_event: psimgb->a[1] = NULL; } else if (data->BufType == XV_BUF_TYPE_DMABUF) { -#ifdef ENABLE_QC_SPECIFIC - psimgb->fd[0] = msm_convert_gem_to_fd(src, &src->gemname_cnt, data->YBuf, xv_gem_mmap); - GST_DEBUG("YBuf gem=%d to fd[0]=%d", data->YBuf, psimgb->fd[0]); - psimgb->buf_share_method = 1;//BUF_SHARE_METHOD_FD; -#else psimgb->fd[0] = drm_convert_gem_to_fd(&src->gemname_cnt, src->drm_fd, (void *)data->YBuf, xv_gem_mmap, &virtual_address); if(!virtual_address) continue; psimgb->a[0] = virtual_address; @@ -1287,7 +1373,6 @@ next_event: psimgb->e[1] = GST_ROUND_UP_16(psimgb->h[1]); psimgb->cs = SCMN_CS_NV12; psimgb->tz_enable = 0; -#endif } psimgb->w[0] = src->width; psimgb->h[0] = src->height; @@ -1312,20 +1397,51 @@ next_event: value_count = 0; } #endif + +#ifdef _MAKE_DUMP + if (f_idx < 100) { + if (src->running_time > 14000000000 && src->running_time < 20000000000) { + GST_ERROR("Mem copy"); + if (virtual_address == NULL) { + GST_ERROR("Mem virtual is NULL[%d]", f_idx); + } else { + memcpy(g_dump_frame[f_idx++], virtual_address, YUV_720_FRAME_SIZE); + //memcpy(g_dump_frame[f_idx++], virtual_address, YUV_VGA_FRAME_SIZE); + GST_ERROR("Mem copy done[%d]", f_idx); + } + } + } else { + if (f_done == 0) { + GST_ERROR("File DUMP!!"); + FILE *fp = NULL; + fp = fopen("/opt/usr/media/Videos/frame.yuv", "a"); + int i = 0; + for (i = 0; i < 100; i++) { + fwrite(g_dump_frame[i], YUV_720_FRAME_SIZE, 1, fp); + //fwrite(g_dump_frame[i], YUV_VGA_FRAME_SIZE, 1, fp); + } + fclose(fp); + f_done = 1; + GST_ERROR("File DUMP done!!"); + } + } +#endif } } if(!outbuf) continue; GST_BUFFER_SIZE (outbuf) = src->framesize; - gst_xv_image_src_get_timeinfo(src, GST_BUFFER_CAST(outbuf)); + //gst_xv_image_src_get_timeinfo(src, GST_BUFFER_CAST(outbuf)); + GST_BUFFER_TIMESTAMP(outbuf) = ts_putstill; + GST_BUFFER_DURATION(outbuf) = dur_putstill; src->running_time = GST_BUFFER_TIMESTAMP(outbuf); src->frame_duration = GST_BUFFER_DURATION(outbuf); //first_frame = FALSE; g_mutex_lock (src->queue_lock); g_queue_push_tail(src->queue, outbuf); - GST_INFO("g_queue_push_tail"); + //GST_INFO("g_queue_push_tail"); g_mutex_unlock (src->queue_lock); g_cond_signal(src->queue_cond); - GST_INFO("g_cond_signal"); + //GST_INFO("g_cond_signal"); update_done: if (src->virtual) tbm_bo_unmap(src->bo); @@ -1338,22 +1454,26 @@ next_event: gettimeofday(&end_time, NULL); starttime = start_time.tv_usec; endtime = end_time.tv_usec; - GST_INFO("star_time: %d, end_time:%d", starttime, endtime); + //GST_INFO("star_time: %d, end_time:%d", starttime, endtime); if (endtime > starttime) { - GST_INFO("end_time > start_time"); + //GST_INFO("end_time > start_time"); duration = endtime - starttime; - } else { - GST_INFO("end_time.tv_usec < start_time.tv_usec"); - endtime=endtime+1000000; - GST_INFO("end_time =%d", endtime); + } else { + //GST_INFO("end_time.tv_usec < start_time.tv_usec"); + endtime=endtime+1000000; + //GST_INFO("end_time =%d", endtime); duration = endtime -starttime; } + GST_INFO("end_time duration = %d", duration); - if (src->sleep_base_time > duration) + //if (src->sleep_base_time > duration) gst_xv_get_image_sleep (src, duration); + + refresh = 1; GST_INFO("gst_xv_image_src_update_thread cleanup !!"); } -#ifndef ENABLE_QC_SPECIFIC + GST_WARNING("gst_xv_image_src_update_thread loop ended"); + for ( i=0 ; i < GEM_NAME_MAX ; i++) { /*gem munmap*/ if (xv_gem_mmap->address[i]) { @@ -1376,18 +1496,6 @@ next_event: free(xv_gem_mmap); xv_gem_mmap = NULL; } -#else - for ( i=0 ; i < GEM_NAME_MAX ; i++) { - if (xv_gem_mmap->Ybo[i]) { - tbm_bo_unref(xv_gem_mmap->Ybo[i]); - xv_gem_mmap->Ybo[i] = NULL; - } - } - if (xv_gem_mmap) { - free(xv_gem_mmap); - xv_gem_mmap = NULL; - } -#endif GST_LOG_OBJECT (src, "The thread function cleanup"); XvStopVideo(src->dpy, src->p, src->pixmap); @@ -1400,6 +1508,30 @@ next_event: XvUngrabPort (src->dpy, src->p, 0); src->p = 0; } + + if (got_display_select_req) { + /* Notify miracast-destroyed to X */ + GST_WARNING_OBJECT (src, "There is display selection request"); + XEvent xev; + XSelectionEvent xnotify; + + xnotify.type = SelectionNotify; + xnotify.display = src->dpy; + xnotify.requestor = src->requestor; + xnotify.selection = src->selection; + xnotify.target = src->target; + xnotify.property = src->property; + xnotify.time = 0; + xnotify.send_event = True; + xnotify.serial = 0; + xev.xselection = xnotify; + if (XSendEvent(src->dpy, src->requestor, False, 0, &xev) < 0) { + GST_ERROR("XSendEvent failed!"); + } else { + GST_INFO("XSendEvent success!"); + } + } + if (src->gc) { XFreeGC (src->dpy, src->gc); src->gc = NULL; @@ -1412,6 +1544,7 @@ next_event: XCloseDisplay (src->dpy); src->dpy = NULL; } + GST_LOG_OBJECT (src, "The thread function stop"); return NULL; finish: @@ -1440,7 +1573,7 @@ static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap) tbm_bufmgr bufmgr; int eventBase, errorBase; int dri2Major, dri2Minor; - char *driverName, *deviceName; + char *driverName = NULL, *deviceName = NULL; drm_magic_t magic; screen = DefaultScreen(dpy); @@ -1458,6 +1591,7 @@ static tbm_bufmgr bufmgr_get (Display *dpy, Pixmap pixmap) if(deviceName) Xfree(deviceName); return NULL; } + if(driverName) Xfree(driverName); if(!deviceName) return NULL; @@ -1608,14 +1742,15 @@ static gboolean gst_xv_image_src_stop (GstBaseSrc * bsrc) { GstXVImageSrc *src = GST_XV_IMAGE_SRC (bsrc); - GST_DEBUG_OBJECT (src, "stop()"); + GST_WARNING ("stop()"); if(src->updates_thread) { src->thread_return = TRUE; + g_cond_signal(src->pause_cond); g_thread_join ( src->updates_thread); src->updates_thread = NULL; } - GST_DEBUG_OBJECT (src, "stop end "); + GST_WARNING ("stop end "); return TRUE; } diff --git a/wearable/xvimagesrc/src/gstxvimagesrc.h b/xvimagesrc/src/gstxvimagesrc.h similarity index 91% rename from wearable/xvimagesrc/src/gstxvimagesrc.h rename to xvimagesrc/src/gstxvimagesrc.h index 8ea8990..25783c4 100755 --- a/wearable/xvimagesrc/src/gstxvimagesrc.h +++ b/xvimagesrc/src/gstxvimagesrc.h @@ -109,27 +109,40 @@ struct _GstXVImageSrc { gboolean pause_cond_var; GCond *pause_cond; GMutex *pause_cond_lock; + GCond *pause_resp; + GMutex *pause_resp_lock; GMutex *buffer_cond_lock; GMutex *dpy_lock; gint drm_fd; gboolean is_secured_mode; int current_data_type; int new_data_type; - double get_image_overtime; + long get_image_overtime; int get_image_overtime_cnt; int gemname_cnt; int tz_enable; long sleep_base_time; long sleep_limit_time; - + gboolean switching_to_udp; + guint64 initial_audio_latency; + guint64 display_rotate; + + /* For display selection */ + Window win; + Atom requestor; + Atom selection; + Atom target; + Atom property; }; struct _GstXVImageSrcClass { GstPushSrcClass parent_class; /* signals */ + void (*ui_only) (void *data); void (*video_with_ui) (void *data); void (*video_only) (void *data); + void (*selection_notify) (void *data); }; GType gst_xv_image_src_get_type (void); diff --git a/wearable/xvimagesrc/src/xv_types.h b/xvimagesrc/src/xv_types.h similarity index 100% rename from wearable/xvimagesrc/src/xv_types.h rename to xvimagesrc/src/xv_types.h