debian/0000775000000000000000000000000013013177043007167 5ustar debian/control0000664000000000000000000003230212326430775010604 0ustar Source: gst-plugins-bad1.0 Section: libs Priority: extra Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Maintainers of GStreamer packages Uploaders: Sebastian Dröge , Sjoerd Simons Build-Depends: autoconf (>= 2.62), automake (>= 1.11), autopoint (>= 0.17), autotools-dev, cdbs (>= 0.4.93), debhelper (>= 9), dh-autoreconf, dpkg-dev (>= 1.15.1), flite-dev, libasound2-dev (>= 0.9.1) [linux-any], libcdaudio-dev [linux-any], libdc1394-22-dev (>= 2.0.0) [linux-any], libgudev-1.0-dev (>= 143) [linux-any], libusb-1.0-0-dev [linux-any], libbluetooth-dev (<< 5) [linux-any], libsbc-dev (>= 1.1) [linux-any], libgstreamer1.0-dev (>= 1.2.0), gstreamer1.0-doc, gstreamer1.0-plugins-base (>= 1.0.0), gstreamer1.0-plugins-base-doc, gtk-doc-tools (>= 1.12), ladspa-sdk, libass-dev (>= 0.9.4), libbz2-dev, libcairo2-dev, libchromaprint-dev, libcurl4-gnutls-dev (>= 7.21.0), libdca-dev, libdirac-dev (>= 0.10), libdirectfb-dev (>= 0.9.25), libdvdnav-dev (>= 4.1.2) [!hurd-any], libegl1-mesa-dev, libexempi-dev, libexif-dev (>= 0.6.16), libfaad-dev, libfluidsynth-dev (>= 1.0), libgles2-mesa-dev, libglib2.0-dev (>= 2.32), libgme-dev, libgnutls-dev (>= 2.11.3), libgsm1-dev, libgstreamer-plugins-base1.0-dev (>= 1.2.0), libgstreamer-plugins-good1.0-dev (>= 1.2.0), libgtk2.0-dev (>= 2.14.0), libiptcdata0-dev (>= 1.0.2), libjasper-dev, libkate-dev (>= 0.1.7), libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf], libmimic-dev (>= 1.0), libmms-dev (>= 0.4), libmodplug-dev, libmpcdec-dev, libmpg123-dev (>= 1.13), libofa0-dev (>= 0.9.3), libopenal-dev (>= 1:1.14), libopencv-dev (>= 2.0.0), libopenjpeg-dev, libopus-dev (>= 0.9.4), liborc-0.4-dev (>= 1:0.4.17), libplatform-api1-dev [i386 armhf], libpng-dev, librsvg2-dev (>= 2.36), librtmp-dev, libschroedinger-dev (>= 1.0.7), libslv2-dev (>= 0.6.6), libsndfile1-dev (>= 1.0.16), libsoundtouch-dev (>= 1.5.0), libspandsp-dev, libsrtp0-dev, libssl-dev, libtool (>= 2.2.6), libvo-aacenc-dev, libvo-amrwbenc-dev, libwebp-dev (>= 0.2.1), libwildmidi-dev (>= 0.2.3), libx11-dev, libxml2-dev (>= 2.4), libxvidcore-dev, libzbar-dev (>= 0.9), libzvbi-dev, pkg-config (>= 0.11.0) Standards-Version: 3.9.3 Vcs-Git: git://anonscm.debian.org/pkg-gstreamer/gst-plugins-bad1.0.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-gstreamer/gst-plugins-bad1.0.git;a=summary Homepage: http://gstreamer.freedesktop.org/modules/gst-plugins-bad.html Package: gstreamer1.0-plugins-bad-doc Architecture: all Section: doc Depends: ${misc:Depends}, gstreamer1.0-doc, gstreamer1.0-plugins-base-doc Description: GStreamer documentation for plugins from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the documentation for plugins from the "bad" set. Package: gstreamer1.0-hybris Architecture: i386 armhf Multi-Arch: same Depends: ${misc:Depends}, ${shlibs:Depends} Provides: ${gstreamer:Provides} XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer plugins from hybris GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . This package contains the GStreamer plugin for hybris, which provides a way to do hardware decode using both hybris and libstagefright from Android. Package: gstreamer1.0-plugins-bad Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer1.0-plugins-base, libgstreamer-plugins-bad1.0-0 (= ${binary:Version}), gstreamer1.0-plugins-bad-videoparsers (= ${binary:Version}), gstreamer1.0-plugins-bad-faad (= ${binary:Version}), Provides: ${gstreamer:Provides} Suggests: frei0r-plugins Replaces: gstreamer1.0-plugins-base (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Breaks: gstreamer1.0-plugins-base (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer plugins from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. Package: gstreamer1.0-plugins-bad-videoparsers Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer1.0-plugins-base, libgstreamer-plugins-bad1.0-0 (= ${binary:Version}), Provides: ${gstreamer:Provides} Replaces: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) Breaks: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer videoparsers plugin from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the "video parsers" plugin from the "bad" set. Package: gstreamer1.0-plugins-bad-faad Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer1.0-plugins-base, libgstreamer-plugins-bad1.0-0 (= ${binary:Version}), Provides: ${gstreamer:Provides} Replaces: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) Breaks: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer faad plugin from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the "faad" plugin from the "bad" set. Package: gstreamer1.0-plugins-bad-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: gstreamer1.0-hybris (= ${binary:Version}) [i386 armhf], gstreamer1.0-plugins-bad (= ${binary:Version}), ${misc:Depends} Replaces: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Breaks: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Description: GStreamer plugins from the "bad" set (debug symbols) GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . This package contains unstripped shared libraries. It is provided primarily to provide a backtrace with names in a debugger, this makes it somewhat easier to interpret core dumps. The libraries are installed in /usr/lib/debug and are automatically used by gdb. Package: libgstreamer-plugins-bad1.0-0 Architecture: any Section: libs Priority: extra Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, Description: GStreamer development files for libraries from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains shared GStreamer libraries from the "bad" set. The API is not guaranteed to be stable. Package: libgstreamer-plugins-bad1.0-dev Architecture: any Section: libdevel Priority: extra Depends: ${misc:Depends}, libgstreamer-plugins-bad1.0-0 (= ${binary:Version}), libgstreamer-plugins-good1.0-dev Description: GStreamer development files for libraries from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains development files for GStreamer libraries from the "bad" set. The API is not guaranteed to be stable. debian/gstreamer-plugins-bad-faad.install0000664000000000000000000000006712276646206015663 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfaad.so debian/gstreamer-faac.install0000664000000000000000000000006712324573056013453 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfaac.so debian/gstreamer-plugins-bad.install0000664000000000000000000001150612326431014014753 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstaccurip.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstadpcmdec.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstadpcmenc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstaiff.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstaudiofxbad.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstasfmux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstassrender.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstaudiovisualizers.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstautoconvert.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstbayer.so @bluez@ debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstbz2.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstchromaprint.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstcoloreffects.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstcurl.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdashdemux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdataurisrc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdebugutilsbad.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdtsdec.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdvbsuboverlay.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstdvdspu.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgsteglglessink.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfestival.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfieldanalysis.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfragmented.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfreeverb.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfrei0r.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstflite.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstfluidsynthmidi.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgaudieffects.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgdp.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgeometrictransform.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgme.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgsm.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstid3tag.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstinter.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstinterlace.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstivtc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstkate.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstladspa.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstliveadder.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmidi.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmimic.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmms.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmodplug.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpegpsdemux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpegtsdemux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpegpsmux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpegtsmux.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpg123.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmxf.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstofa.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstopenal.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstopencv.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstopenjpeg.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstopus.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstpcapparse.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstpnm.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstrawparse.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstremovesilence.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstrfbsrc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstrsvg.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstrtmp.so @sbc@ debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstschro.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsdpelem.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsegmentclip.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstshm.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsiren.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsmooth.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsmoothstreaming.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsoundtouch.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstspandsp.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstspeed.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsrtp.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsubenc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstvideofiltersbad.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstvoaacenc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstvoamrwbenc.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstwebp.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstwildmidi.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgsty4mdec.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstyadif.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstzbar.so debian/tmp/usr/share/locale debian/tmp/usr/share/gstreamer-@GST_ABI@/presets/ @dvb@ @resindvd@ @decklink@ @fbdev@ @uvch264@ debian/control.in0000664000000000000000000002440512324573056011214 0ustar Source: gst-plugins-bad@GST_ABI@ Section: libs Priority: extra Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Maintainers of GStreamer packages Uploaders: Sebastian Dröge , Sjoerd Simons Build-Depends: BUILDDEPS Standards-Version: 3.9.3 Vcs-Git: git://anonscm.debian.org/pkg-gstreamer/gst-plugins-bad@GST_ABI@.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-gstreamer/gst-plugins-bad@GST_ABI@.git;a=summary Homepage: http://gstreamer.freedesktop.org/modules/gst-plugins-bad.html Package: @GST_PKGNAME@-plugins-bad-doc Architecture: all Section: doc Depends: ${misc:Depends}, gstreamer@GST_ABI@-doc, gstreamer@GST_ABI@-plugins-base-doc Description: GStreamer documentation for plugins from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the documentation for plugins from the "bad" set. Package: @GST_PKGNAME@-hybris Architecture: i386 armhf Multi-Arch: same Depends: ${misc:Depends}, ${shlibs:Depends} Provides: ${gstreamer:Provides} XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer plugins from hybris GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . This package contains the GStreamer plugin for hybris, which provides a way to do hardware decode using both hybris and libstagefright from Android. Package: @GST_PKGNAME@-plugins-bad Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer@GST_ABI@-plugins-base, libgstreamer-plugins-bad@GST_DEB_ABI@ (= ${binary:Version}), @GST_PKGNAME@-plugins-bad-videoparsers (= ${binary:Version}), @GST_PKGNAME@-plugins-bad-faad (= ${binary:Version}), Provides: ${gstreamer:Provides} Suggests: frei0r-plugins Replaces: gstreamer1.0-plugins-base (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Breaks: gstreamer1.0-plugins-base (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer plugins from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. Package: @GST_PKGNAME@-plugins-bad-videoparsers Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer@GST_ABI@-plugins-base, libgstreamer-plugins-bad@GST_DEB_ABI@ (= ${binary:Version}), Provides: ${gstreamer:Provides} Replaces: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) Breaks: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer videoparsers plugin from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the "video parsers" plugin from the "bad" set. Package: @GST_PKGNAME@-plugins-bad-faad Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, gstreamer@GST_ABI@-plugins-base, libgstreamer-plugins-bad@GST_DEB_ABI@ (= ${binary:Version}), Provides: ${gstreamer:Provides} Replaces: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) Breaks: gstreamer1.0-plugins-bad (<< 1.2.3-0ubuntu2) XB-GStreamer-Version: ${gstreamer:Version} XB-GStreamer-Elements: ${gstreamer:Elements} XB-GStreamer-URI-Sources: ${gstreamer:URISources} XB-GStreamer-URI-Sinks: ${gstreamer:URISinks} XB-GStreamer-Encoders: ${gstreamer:Encoders} XB-GStreamer-Decoders: ${gstreamer:Decoders} Description: GStreamer faad plugin from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains the "faad" plugin from the "bad" set. Package: @GST_PKGNAME@-plugins-bad-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: @GST_PKGNAME@-hybris (= ${binary:Version}) [i386 armhf], @GST_PKGNAME@-plugins-bad (= ${binary:Version}), ${misc:Depends} Replaces: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Breaks: gstreamer1.0-plugins-base-dbg (<< 0.11.94), gstreamer1.0-plugins-good (<< 1.1.2) Description: GStreamer plugins from the "bad" set (debug symbols) GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . This package contains unstripped shared libraries. It is provided primarily to provide a backtrace with names in a debugger, this makes it somewhat easier to interpret core dumps. The libraries are installed in /usr/lib/debug and are automatically used by gdb. Package: libgstreamer-plugins-bad@GST_DEB_ABI@ Architecture: any Section: libs Priority: extra Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends}, Description: GStreamer development files for libraries from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains shared GStreamer libraries from the "bad" set. The API is not guaranteed to be stable. Package: libgstreamer-plugins-bad@GST_ABI@-dev Architecture: any Section: libdevel Priority: extra Depends: ${misc:Depends}, libgstreamer-plugins-bad@GST_DEB_ABI@ (= ${binary:Version}), libgstreamer-plugins-good@GST_ABI@-dev Description: GStreamer development files for libraries from the "bad" set GStreamer is a streaming media framework, based on graphs of filters which operate on media data. Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related. Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plug-ins. . GStreamer Bad Plug-ins is a set of plug-ins that aren't up to par compared to the rest. They might be close to being good quality, but they're missing something - be it a good code review, some documentation, a set of tests, a real live maintainer, or some actual wide use. . This package contains development files for GStreamer libraries from the "bad" set. The API is not guaranteed to be stable. debian/HACKING.Debian0000664000000000000000000001030212324573056011343 0ustar Hacking GStreamer for Debian ============================ An addition to the README.Debian that has Debian package hacking notes. Everything should now be versioned. - To update dependencies edit debian/build-deps.in - To rebuild package files from .in files: debian/rules maint - After a version update to check for missing files run: debian/maint missing debian/maint missing-libs debian/maint missing-so - To update package files edit gstreamer-foo then rebuild package files. This will generate the gstreamerX.Y-foo file. Also update debian/rules and debian/control.in as needed. - The packaging tries to stay close of upstream choice. gstreamerX.Y-misc has most of the files, extra packages are made for the sinks and by group of depends (gnome, x, ...) - Provide gstreamerX.Y-videosink and gstreamerX.Y-audiosink as needed. - All interfaces and generic libraries go in libgstreamer-plugins, libraries with external dependencies have their own package such as libgstreamer-gconf. - Applications go in gstreamerX.Y-plugins-base-apps File listing ------------ build-deps: - generated from "build-deps.in" abd "extra deps" in "rules debian/build-deps:": * "build-deps.in" lists build-depends for Debian main packages * "extra deps" is a shell script outputting additional build-depends if you are building additional plugins - serves generation with "control.in" and "mk.control" of "control" in "rules debian/control::" build-deps.in: - lists build-depends for Debian main packages - serves generation with "extra deps" of "build-deps" in "rules debian/build-deps:" changelog: handled classically compat: handled classically control: - generated for "rules maint" - generated from "control.in" and "build-deps" in "rules debian/control::": * "build-deps" lists build-depends to be inserted in "control Build-Depends:" * "control.in" serves of template for package descriptions of Debian main packages and makes use of special stanzas enclosed in "@" such as "@GST_ABI" which are replaced via sed in "rules debian/control::" * "extra deps" is a shell script outputting additional binary packages if you are building additional plugins control.in: - serves generation of "control" in "rules debian/control::" via "mk.control" called in "rules debian/control::" - template for package descriptions of Debian main packages and makes use of special stanzas enclosed in "@" such as "@GST_ABI" which are replaced via sed in "rules debian/control::" copyright: handled classically extra: - serves the generation of build-deps of additional packages not in Debian main in "rules debian/build-deps:" - serves the generation of additional binary packages if you are building additional plugins in "rules debian/control::" gstreamer-$plugin.install: - serves the generation of $gst_pkgname-$plugin.install (for example gstreamer-alsa.install serves the generation of gstreamerX.Y-alsa.install) in "rules pre-build::" via dynamic "@"-enclosed variables replacement - some plugins are handled specially and some special variables are available gstreamer-plugins-base-apps.install: this isn't really a plugin, but the gstreamerX.Y-plugins-base-apps package gstreamer-plugins-base-apps.manpages: man pages for the gstreamerX.Y-plugins-base-apps package HACKING.Debian: this file libgstreamer-plugins-base-dev.install libgstreamer-plugins-base.install: handled similarly has gstreamerX.Y-plugins-base-apps maint: makefile wrapping some targets of "rules" with some sh filtering mk.control: - Perl script serving the generation of "control" which reads "build-deps" and "control.in", and replaces the "BUILDDEPS" stanza with the build-deps patches: handled classically README.Debian: handled classically rules: handled classically, with special targets "maint:", and "debian/build-deps:" watch: handled classically This file is the initial work of: David I. Lehn Tue, 13 Apr 2004 21:28:55 -0400 and had some additions by: Loic Minier Sun, 19 Jun 2005 19:04:58 +0200 Sebastien Bacher Wed, 14 Dec 2005 17:00:21 +0100 debian/changelog0000664000000000000000000022400513013177043011044 0ustar gst-plugins-bad1.0 (1.2.4-1~ubuntu1.1) trusty-security; urgency=medium * SECURITY UPDATE: code execution via integer overflow in vmncdec - debian/patches/vmncdec_overflow.patch: sanity-check width/height before using it in gst/vmnc/vmncdec.c. - No CVE number -- Marc Deslauriers Wed, 16 Nov 2016 19:47:31 -0500 gst-plugins-bad1.0 (1.2.4-1~ubuntu1) trusty; urgency=medium * SRU Utopic update to trusty to get bugfix release 1.2.4 (LP: #1312305) + Don't hardcode /usr/share/sounds/sf2 path in fluiddec + hlsdemux: fails to compute media playlist URL if there is a query parameter + hlsdemux: fails to correctly parse CODECS and RESOLUTION * Don't enable mplex plugin. -- Iain Lane Fri, 25 Apr 2014 11:00:27 +0100 gst-plugins-bad1.0 (1.2.4-1ubuntu1) trusty; urgency=low * Merge with Debian unstable; remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) + Split videoparsers and faad out into their own packages. -- Iain Lane Fri, 25 Apr 2014 10:34:39 +0100 gst-plugins-bad1.0 (1.2.4-1) unstable; urgency=medium * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Enable mplex plugin (Closes: #726064). * New upstream bugfix release. -- Sebastian Dröge Fri, 18 Apr 2014 15:39:35 +0200 gst-plugins-bad1.0 (1.2.3-1ubuntu2) trusty; urgency=medium * Split videoparsers and faad out into their own packages. -- Iain Lane Mon, 03 Mar 2014 13:06:53 +0000 gst-plugins-bad1.0 (1.2.3-1ubuntu1) trusty; urgency=medium * Merge with Debian unstable for random bugfixes; remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) * debian/patches/bump_opencv_dep_version.patch: Dropped, no longer needed. -- Adam Conrad Sat, 22 Feb 2014 15:45:50 -0700 gst-plugins-bad1.0 (1.2.3-1) unstable; urgency=medium [ Iain Lane ] * Drop ltmain-as-needed patch and do the same with dh_autoreconf --as-needed. * Enable parallel builds. [ Sebastian Dröge ] * New upstream bugfix release. * debian/patches/02_opencv-linking.patch: + Fix linking of opencv plugin by working around yet again broken opencv pkg-config file. -- Sebastian Dröge Sun, 09 Feb 2014 11:37:09 +0100 gst-plugins-bad1.0 (1.2.2-1ubuntu4) trusty; urgency=medium * bump_opencv_dep_version.patch: bumping opencv as we're now building against opencv 2.4.8 -- Ricardo Salveti de Araujo Sun, 16 Feb 2014 06:07:14 -0300 gst-plugins-bad1.0 (1.2.2-1ubuntu3) trusty; urgency=medium * Refreshing adding-mirsink-and-android-media-over-hybris-support.patch: - Make the fill buffer compatible with Android 4.2 as well as 4.4+ - Add the divx variant for mpeg4 video - Adding color formats used by Exynos 5 (Nexus 10) -- Ricardo Salveti de Araujo Sun, 16 Feb 2014 00:05:47 -0300 gst-plugins-bad1.0 (1.2.2-1ubuntu2) trusty; urgency=medium * No-change rebuild for libwebp transition -- Iain Lane Mon, 20 Jan 2014 12:17:40 +0000 gst-plugins-bad1.0 (1.2.2-1ubuntu1) trusty; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) -- Iain Lane Fri, 10 Jan 2014 11:35:48 +0000 gst-plugins-bad1.0 (1.2.2-1) unstable; urgency=medium * New upstream bugfix release. -- Sebastian Dröge Fri, 27 Dec 2013 11:02:32 +0100 gst-plugins-bad1.0 (1.2.1-2) unstable; urgency=medium * debian/rules, debian/gstreamer-plugins-bad.install: + Enable the OpenCV plugin again, now that all the linking errors are gone. -- Sebastian Dröge Sun, 15 Dec 2013 15:11:34 +0100 gst-plugins-bad1.0 (1.2.1-1ubuntu2) trusty; urgency=medium * Refreshing adding-mirsink-and-android-media-over-hybris-support.patch: - Improved the CAPS for mirsink to use a cleaner method of constructing the caps, plus increased the formats it supports. - Adding a small delay to make sure we have the window id when doing hardware rendering - Fixing crash on EOS (LP: #1234506, LP: #1236599) * debian/build-deps.*: - Bumping dep version requirement for libmedia -- Ricardo Salveti de Araujo Mon, 23 Dec 2013 16:06:21 -0200 gst-plugins-bad1.0 (1.2.1-1ubuntu1) trusty; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) -- Iain Lane Fri, 15 Nov 2013 12:19:58 +0000 gst-plugins-bad1.0 (1.2.1-1) unstable; urgency=low [ Fabian Greffrath ] * Team upload. * Update Vcs-Browser field in debian/control{,.in}. * Turn versioned Conflicts into Breaks to simplify lockstep upgrades. [ Sebastian Dröge ] * New upstream bugfix release: + debian/patches/0001-bluez-Fix-compilation-on-big-endian-systems.patch: - Dropped, merged upstream. -- Sebastian Dröge Sat, 09 Nov 2013 17:10:09 +0100 gst-plugins-bad1.0 (1.2.0-4) unstable; urgency=low * debian/rules, debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Only enable sbc plugin on Linux, it's not available elsewhere. -- Sebastian Dröge Fri, 04 Oct 2013 10:06:43 +0200 gst-plugins-bad1.0 (1.2.0-3ubuntu5) saucy; urgency=low * Refreshing adding-mirsink-and-android-media-over-hybris-support.patch: - Improving texture_id sync handling when using mirsink - Extending mirsink caps (was just supporting NV12) - Disabling google software codecs (needed until we have software rendering support in mirsink) * debian/build-deps.*: - Bumping dep version requirement for libmedia -- Ricardo Salveti de Araujo Mon, 14 Oct 2013 17:14:27 -0300 gst-plugins-bad1.0 (1.2.0-3ubuntu4) saucy; urgency=low * Refreshing adding-mirsink-and-android-media-over-hybris-support.patch: - Increasing timeout before waiting for a valid texture id -- Ricardo Salveti de Araujo Mon, 14 Oct 2013 00:50:36 -0300 gst-plugins-bad1.0 (1.2.0-3ubuntu3) saucy; urgency=low * Refreshing adding-mirsink-and-android-media-over-hybris-support.patch: - Adding support for software rendering - Better input/out buffer handling * debian/build-deps.in: - Bumping dep version requirement for libmedia -- Ricardo Salveti de Araujo Sun, 13 Oct 2013 00:30:29 -0300 gst-plugins-bad1.0 (1.2.0-3ubuntu2) saucy; urgency=low * adding-mirsink-and-android-media-over-hybris-support.patch: - Improved the robustness of the decoding/rendering under heavy system IO load. - Porting fixes from the 1.2 based gstamcvideodec.c -- Ricardo Salveti de Araujo Wed, 02 Oct 2013 22:59:39 -0300 gst-plugins-bad1.0 (1.2.0-3ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) -- Ricardo Salveti de Araujo Wed, 02 Oct 2013 01:59:30 -0300 gst-plugins-bad1.0 (1.2.0-3) unstable; urgency=low * debian/rules, debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Only enable bluez plugin on Linux, it's not available elsewhere. -- Sebastian Dröge Fri, 27 Sep 2013 13:52:58 +0200 gst-plugins-bad1.0 (1.2.0-2) unstable; urgency=low * debian/patches/0001-bluez-Fix-compilation-on-big-endian-systems.patch: + Fix compilation on big endian systems. * debian/build-deps.in: + Tighten build dependency on libopenal-dev to >= 1:1.14 (Closes: #724669). -- Sebastian Dröge Thu, 26 Sep 2013 15:02:54 +0200 gst-plugins-bad1.0 (1.2.0-1ubuntu1) saucy; urgency=low [ Iain Lane ] * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. + debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can only work with android compatible archs) + debian/build-deps.in: - Adding mirsink/android decoder specific build dependencies for i386 and armhf (libplatform-api1-dev and libmedia-dev) -- Ricardo Salveti de Araujo Tue, 01 Oct 2013 15:35:17 -0300 gst-plugins-bad1.0 (1.2.0-1) unstable; urgency=low * New upstream stable release: + debian/rules, debian/build-deps.in: - Build depend on GStreamer and gst-plugins-base >= 1.2.0. -- Sebastian Dröge Tue, 24 Sep 2013 16:59:40 +0200 gst-plugins-bad1.0 (1.1.90-1) experimental; urgency=low * New upstream release candidate: + debian/rules, debian/build-deps.in: - Build depend on GStreamer and gst-plugins-base >= 1.1.90. -- Sebastian Dröge Thu, 19 Sep 2013 12:53:58 +0200 gst-plugins-bad1.0 (1.1.4-3) experimental; urgency=low * debian/patches/03_modplug-includes.patch: + Fix build with the new modplug version by including the modplug headers properly. Thanks to Iain Lane for the patch. * debian/patches/04_opencv-2.4.6.1.patch: + Fix build with OpenCV 2.4.6.1. * debian/gstreamer-plugins-bad.install: + Disable OpenCV plugin again for now until the libraries are --as-needed clean again. -- Sebastian Dröge Tue, 10 Sep 2013 11:12:25 +0200 gst-plugins-bad1.0 (1.1.4-2ubuntu6) saucy; urgency=low * adding-mirsink-and-android-media-over-hybris-support.patch: - Fixing platform-api related calls when not using texture_id (playbin use case) * debian/control: bumping libmedia-dev build-dep version due an extra function call to know when surface_texture is ready for rendering -- Ricardo Salveti de Araujo Mon, 30 Sep 2013 17:39:41 -0300 gst-plugins-bad1.0 (1.1.4-2ubuntu5) saucy; urgency=low * adding-mirsink-and-android-media-over-hybris-support.patch: - Refreshing patch to allow mirsink to create a session/surface to allow proper rendering with playbin (without giving a texture id) (LP: #1231727) * debian/control: adding libplatform-api1-dev as build-dep for i386 and armhf, as it's only relevant for the mirsink -- Ricardo Salveti de Araujo Fri, 27 Sep 2013 13:42:09 -0300 gst-plugins-bad1.0 (1.1.4-2ubuntu4) saucy; urgency=low * also drop missing deps from the dbg packages, keep -hybris for i386 and armhf in gstreamer1.0-plugins-bad-dbg -- Oliver Grawert Tue, 24 Sep 2013 12:28:51 +0200 gst-plugins-bad1.0 (1.1.4-2ubuntu3) saucy; urgency=low * drop gstreamer1.0-hybris from gstreamer1.0-plugins-bad dependencies -- Oliver Grawert Tue, 24 Sep 2013 11:32:53 +0200 gst-plugins-bad1.0 (1.1.4-2ubuntu2) saucy; urgency=low [ Ricardo Salveti de Araujo ] * debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch: - Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. * debian/control.in: - Making the hybris plugin as part of a separated package, and i386 and armhf only (can work with android compatible archs) [ Oliver Grawert ] * run update-maintainer to make sure bugs dont go to debian for this before it is merged there -- Ricardo Salveti de Araujo Tue, 17 Sep 2013 16:05:57 -0300 gst-plugins-bad1.0 (1.1.4-2ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. * debian/patches/0001-modplug-Specify-directory-when-including-stdafx.h.patch: Specify the directory when including modplug's stdafx.h, as its pcfile stopped giving us this in Cflags. -- Iain Lane Tue, 10 Sep 2013 09:12:49 +0000 gst-plugins-bad1.0 (1.1.4-2) experimental; urgency=low * debian/patches/02_soundtouch-int.patch: + Fix compilation on armel, where soundtouch is compiled as an integer version instead of floats as everywhere else. -- Sebastian Dröge Mon, 02 Sep 2013 10:38:03 +0200 gst-plugins-bad1.0 (1.1.4-1) experimental; urgency=low * New upstream development snapshot: + debian/rules, debian/build-deps.in: - Build depend on GStreamer and gst-plugins-base >= 1.1.4. + debian/build-deps.in, debian/gstreamer-plugins-bad.install: - Add webp plugin. -- Sebastian Dröge Fri, 30 Aug 2013 13:06:41 +0200 gst-plugins-bad1.0 (1.1.3-1ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing camerabin2 basecamerabin jpegformat - plugins which have moved to -good. + Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. + debian/patches/libtool-force-link-lc: Add a new patch to workaround libtool refusing to add -lc multiple times to link in the presence of circular dependencies. * Allow building with newer OpenCV. -- Iain Lane Wed, 31 Jul 2013 14:10:25 +0000 gst-plugins-bad1.0 (1.1.3-1) experimental; urgency=low * New upstream development snapshot: + debian/rules, debian/build-deps.in: - Build depend on GStreamer and gst-plugins-base >= 1.1.3. -- Sebastian Dröge Tue, 30 Jul 2013 08:51:10 +0200 gst-plugins-bad1.0 (1.1.2-1) experimental; urgency=low * New upstream development snapshot: + debian/rules, debian/build-deps.in: - Build depend on GStreamer and gst-plugins-base >= 1.1.2. - Build depend on orc >= 0.4.17. - Build depend on gnutls. - Build depend on rsvg >= 2.36. + debian/build-deps.in, debian/gstreamer-plugins-bad.install: - Add new bluez, fluidsynth, dash, smoothstreaming, opencv, openjpeg, sbc, srtp, accurip, audiofxbad, ivtc, midi, videofiltersbad, yadif, chromaprint plugins (Closes: #702341). - Add newly ported aiff, freeverbm, kate, ladspa, mxf, rsvg wildmidi, decklink, fbdev, uvch264, ofa, rfbsrc, openal plugins (Closes: #712966). + debian/libgstreamer-plugins-bad.install: - Add new EGL, insertbin, mpegts and uridownloader libs. - Remove removed basevideo library. -- Sebastian Dröge Sun, 14 Jul 2013 12:44:45 +0200 gst-plugins-bad1.0 (1.0.8-1ubuntu2) saucy; urgency=low * debian/patches/libtool-force-link-lc: Add a new patch to workaround libtool refusing to add -lc multiple times to link in the presence of circular dependencies. -- Iain Lane Mon, 15 Jul 2013 15:01:16 +0100 gst-plugins-bad1.0 (1.0.8-1ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing scapetempo rtpmux rtpvp8 camerabin2 basecamerabin jpegformat - plugins which have moved to -good. * Provide gstreamer-plugins-bad-1.0.pc with Requires on gstreamer-plugins-good-1.0 - the package we've moved the referenced library to. This maintains compatibility with upstream software and other distributions. (LP: #1170923) -- Iain Lane Mon, 15 Jul 2013 12:00:00 +0100 gst-plugins-bad1.0 (1.0.8-1) unstable; urgency=low * New upstream bugfix release. * debian/build-deps.in: + Build-depend on gst-plugins-base >= 1.0.8 for a macro fix. -- Sebastian Dröge Sat, 13 Jul 2013 11:33:12 +0200 gst-plugins-bad1.0 (1.0.7-1ubuntu1) saucy; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing gstreamer-plugins-bad-1.0.pc — the referenced library is in gst-plugins-good1.0 now. + Stop installing scapetempo rtpmux rtpvp8 camerabin2 basecamerabin jpegformat - plugins which have moved to -good. -- Iain Lane Fri, 26 Apr 2013 21:39:03 +0000 gst-plugins-bad1.0 (1.0.7-1) unstable; urgency=low * New upstream bugfix release. -- Sebastian Dröge Fri, 26 Apr 2013 14:10:58 +0200 gst-plugins-bad1.0 (1.0.6-1ubuntu1) raring; urgency=low * Merge with Debian unstable. Remaining changes: + Stop installing gstreamer-plugins-bad-1.0.pc — the referenced library is in gst-plugins-good1.0 now. + Stop installing scapetempo rtpmux rtpvp8 camerabin2 basecamerabin jpegformat - plugins which have moved to -good. -- Iain Lane Mon, 08 Apr 2013 17:29:17 +0100 gst-plugins-bad1.0 (1.0.6-1) unstable; urgency=low * New upstream bugfix release: + debian/gstreamer-plugins-bad.install, debian/build-deps.in: - Add newly ported OpenGLES2/EGL plugin. -- Sebastian Dröge Fri, 22 Mar 2013 18:24:57 +0100 gst-plugins-bad1.0 (1.0.5-1ubuntu1) raring; urgency=low * Merge from Debian unstable. Remaining changes: + Stop installing gstreamer-plugins-bad-1.0.pc — the referenced library is in gst-plugins-good1.0 now. + Stop installing scapetempo rtpmux rtpvp8 camerabin2 basecamerabin jpegformat - plugins which have moved to -good. -- Iain Lane Tue, 05 Feb 2013 12:23:45 +0000 gst-plugins-bad1.0 (1.0.5-1) unstable; urgency=low * New upstream bugfix release: + debian/gstreamer-plugins-bad.install: - Add newly ported mpegpsmux plugin. -- Sebastian Dröge Tue, 08 Jan 2013 13:56:44 +0100 gst-plugins-bad1.0 (1.0.4-1) unstable; urgency=low * New upstream bugfix release. -- Sebastian Dröge Wed, 19 Dec 2012 10:35:07 +0100 gst-plugins-bad1.0 (1.0.3-1ubuntu2) raring; urgency=low * Stop installing gstreamer-plugins-bad-1.0.pc — the referenced library is in gst-plugins-good1.0 now. -- Iain Lane Fri, 04 Jan 2013 16:20:30 +0000 gst-plugins-bad1.0 (1.0.3-1ubuntu1) raring; urgency=low * Stop installing scapetempo rtpmux rtpvp8 camerabin2 basecamerabin jpegformat - plugins which have moved to -good. -- Iain Lane Thu, 29 Nov 2012 15:25:38 +0000 gst-plugins-bad1.0 (1.0.3-1) unstable; urgency=low * New upstream bugfix release. -- Sebastian Dröge Wed, 21 Nov 2012 15:05:51 +0100 gst-plugins-bad1.0 (1.0.2-1) unstable; urgency=low * New upstream bugfix release: + debian/gstreamer-plugins-bad.install: - Add subenc and fieldanalysis plugins. -- Sebastian Dröge Thu, 25 Oct 2012 14:13:33 +0200 gst-plugins-bad1.0 (1.0.1-1) unstable; urgency=low * New upstream bugfix release: + debian/gstreamer-plugins-bad.install: - Add frei0r plugin. -- Sebastian Dröge Mon, 08 Oct 2012 11:12:00 +0200 gst-plugins-bad1.0 (1.0.0-1) unstable; urgency=low * New upstream release: + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 1.0.0. -- Sebastian Dröge Tue, 25 Sep 2012 00:29:02 +0200 gst-plugins-bad1.0 (0.11.99-1) experimental; urgency=low * New upstream release: + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 0.11.99. -- Sebastian Dröge Tue, 18 Sep 2012 11:26:04 +0200 gst-plugins-bad1.0 (0.11.94-1) experimental; urgency=low * New upstream release: + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 0.11.94. - Build depend on gtk-doc >= 1.12. + debian/gstreamer-plugins-bad.install, debian/rules: - Add the freeze, gdp, id3tag, inter, jpegformat, liveadder, pnm, siren, spandsp, speed, dvb, resindvd plugins. -- Sebastian Dröge Fri, 14 Sep 2012 11:30:28 +0200 gst-plugins-bad1.0 (0.11.93-1) experimental; urgency=low * New upstream release: + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 0.11.93. + debian/build-deps.in: - Build depend on libmpg123-dev (>= 1.13). - Build depend on GLIB >= 2.32. + debian/gstreamer-plugins-bad.install: - Add festival, interlace, mimic, mpegtsmux, mpg123 and soundtouch plugins. -- Sebastian Dröge Thu, 09 Aug 2012 11:40:32 +0200 gst-plugins-bad1.0 (0.11.92-1) experimental; urgency=low * debian/rules, debian/gstreamer-plugins-bad.install: + Build the cdaudio plugin on kfreebsd too. * New upstream release, "Shine On You Crazy Diamond": + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 0.11.92. + debian/build-deps.in: - Require orc >= 0.4.16. + debian/patches/0001-vp8enc-fix-target-bitrate-config-with-libvpx-1.1.0.patch: - Dropped, merged upstream. -- Sebastian Dröge Fri, 08 Jun 2012 13:13:33 +0200 gst-plugins-bad1.0 (0.11.91-3) experimental; urgency=low * debian/build-deps.in: + Drop unconditional libcdaudio build dependency. It's not available on hurd. -- Sebastian Dröge Mon, 04 Jun 2012 12:42:49 +0200 gst-plugins-bad1.0 (0.11.91-2) experimental; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Drop CELT plugin and add OPUS plugin. -- Sebastian Dröge Wed, 30 May 2012 15:11:21 +0200 gst-plugins-bad1.0 (0.11.91-1) experimental; urgency=low * New upstream release, "Be he alive, or be he dead": + debian/build-deps.in, debian/rules: - Build depend on GStreamer core/base >= 0.11.91. + debian/gstreamer-plugins-bad.install: - Re-add plugins that are ported now. * debian/control.in, debian/rules: + Update automake, autoconf, libtool, debhelper dependencies. + Update Standards-Version. * debian/build-deps.in: + Drop lv2core dependency, not needed anymore. * debian/patches/0001-vp8enc-fix-target-bitrate-config-with-libvpx-1.1.0.patch: + Patch from upstream GIT to fix vp8 encoder with libvpx 1.1.0. * debian/libgstreamer-plugins-bad-dev.install: + Drop .a files from the -dev package. * debian/rules: + Fix dh_gstscancodecs call. -- Sebastian Dröge Mon, 21 May 2012 16:00:47 +0200 gst-plugins-bad1.0 (0.11.90-1) experimental; urgency=low [ Olivier Naudan ] * Imported Upstream version 0.11.90 * Imported debian/ from gst-plugins-bad 0.10.23-1 * Updated debian/ for GStreamer 1.0 * Removed gstreamer-sdl, not ported to 0.11 * gstreamer-plugins-bad.install: Removed the plugins that have not been ported * gstreamer-plugins-bad.install: Removed schemas * gstreamer-plugins-bad.install: Added presets (.prs) * debian/rules: disable pvrvideosink, until it is ported to gst 0.11 [ Sebastian Dröge ] * Build-depend on GLib >= 2.31.14. * Remove obsolete Provides and Replaces * Merge changes from 0.10.23-2. * Update copyright -- Sebastian Dröge Thu, 03 May 2012 20:06:18 +0200 gst-plugins-bad0.11 (0.11.1-1~ppa1) oneiric; urgency=low * New upstream release, 0.11.1 -- Olivier Naudan Thu, 01 Mar 2012 13:02:01 +0100 gst-plugins-bad0.10 (0.10.23-1) unstable; urgency=low * New upstream stable release, "The Game Has Changed": + debian/rules, debian/build-deps.in: - (Build-) depend on GStreamer core/base >= 0.10.36. -- Sebastian Dröge Tue, 21 Feb 2012 10:58:52 +0100 gst-plugins-bad0.10 (0.10.22.3-2) experimental; urgency=low * debian/control.in, debian/gstreamer-plugins-bad.install, debian/libgstreamer-plugins-bad-dev.install, debian/libgstreamer-plugins-bad.install, debian/rules: + Split the libraries into their own package and add a -dev package. The API of the library is not guaranteed to be stable and as such the shlibs of the library package are very strict and will require dependant libraries to get a rebuild after every new upstream version. The libraries will be required by gstreamer-vaapi. Thanks to Timo Aaltonen for the patch. -- Sebastian Dröge Wed, 08 Feb 2012 09:45:25 +0100 gst-plugins-bad0.10 (0.10.22.3-1) experimental; urgency=low * New upstream pre-release: + debian/patches/01_dtsdec-libs.patch, debian/patches/02_teletextdec-subdirs.patch: - Dropped, merged upstream. -- Sebastian Dröge Mon, 06 Feb 2012 10:52:44 +0100 gst-plugins-bad0.10 (0.10.22.2-2) experimental; urgency=low * debian/control.in: + Build-depend on automake (>= 1.10), autoconf (>= 2.60) and libtool (>= 2.0) to make dh-autoreconf actually work. * debian/control.in: + Pre-depend on ${misc:Pre-Depends} for multi-arch. -- Sebastian Dröge Wed, 14 Dec 2011 10:18:38 +0100 gst-plugins-bad0.10 (0.10.22.2-1) experimental; urgency=low * New upstream pre-release: + debian/build-deps.in, debian/rules: - Build-depend on GStreamer core/base 0.10.35.2. - Build-depend on GLib 2.24. + debian/build-deps.in, debian/gstreamer-plugins-bad.install, debian/gstreamer-amrwbenc.install, debian/README.Debian: - Add audiovisualizers, cdaudio, faceoverlay, freeverb, inter, openal, removesilence, smooth, spandsp, teletextdec, voaacenc, voamrwbenc plugins. - Remove invtelecine, mpeg4videoparse plugins. - Remove amrwbenc extra plugin. + debian/patches/01_path-max.patch: - Dropped, merged upstream. + debian/patches/99_ltmain_as-needed.patch: - Refreshed to apply cleanly again. + debian/patches/01_dtsdec-libs.patch: - Add libgstbase to the libraries of dtsdec. + debian/patches/02_teletextdec-subdirs.patch: - Add the teletextdec directory to SUBDIRS. * debian/control.in: + Suggest frei0r-plugins (Closes: #633097). * debian/build-deps.in, debian/compat, debian/control.in, debian/gstreamer-amrwbenc.install, debian/gstreamer-faac.install, debian/gstreamer-mpeg2enc.install, debian/gstreamer-plugins-bad.install, debian/gstreamer-sdl.install, debian/rules: + Transition package to multi-arch (Closes: #647487). Patch taken from the Ubuntu package. -- Sebastian Dröge Mon, 12 Dec 2011 10:41:20 +0100 gst-plugins-bad0.10 (0.10.22-3) unstable; urgency=low * Add xvid to the bad plugin set as it's available in debian now. * Remove any reference to LAME or MP3 from README.Debian. -- Fabian Greffrath Fri, 29 Jul 2011 13:24:53 +0200 gst-plugins-bad0.10 (0.10.22-2) unstable; urgency=low * debian/patches/01_path-max.patch: + Don't use PATH_MAX, it's not defined on GNU Hurd and others. Thanks to Pino Toscano for the patch (Closes: #626795). -- Sebastian Dröge Mon, 16 May 2011 09:13:54 +0200 gst-plugins-bad0.10 (0.10.22-1) unstable; urgency=low * New upstream release, "Toy Piano": + debian/patches/99_decklink.patch, debian/patches/99_decklink-linking.patch: - Dropped, merged upstream. + debian/rules, debian/build-deps.in: - Build-depend on GStreamer core/base 0.10.33. -- Sebastian Dröge Tue, 10 May 2011 15:55:38 +0200 gst-plugins-bad0.10 (0.10.21.3-1) experimental; urgency=low * New upstream pre-release. * debian/rules, debian/gstreamer-plugins-bad.install: + Enable the decklink and linsys plugins. * debian/patches/99_decklink.patch, debian/patches/99_decklink-linking.patch: + Add decklink to sys/Makefile.am SUBDIRS and check for pthread.h and link to pthread. -- Sebastian Dröge Thu, 28 Apr 2011 09:20:34 +0200 gst-plugins-bad0.10 (0.10.21.2-1) experimental; urgency=low [ Alessandro Decina ] * debian/rules: + Include dh-autoreconf cdbs rule * debian/build-deps.in: + Add dependency on dh-autoreconf [ Loïc Minier ] * Use linux-any in build-deps instead of type-handling. * Rework sed calls to avoid cat | sed and sed | sed. * s/amrwb/amrwbenc/ in a leftover case statement in debian/extra; thanks Mohamed Amine IL Idrissi; closes: #592757. [ Sebastian Dröge ] * New upstream pre-release: + debian/patches/01_soundtouch-pc.patch, debian/patches/02_shm_fixes.patch: - Dropped, merged upstream. + debian/build-deps.in: - Update ORC build dependency to >= 0.4.11. + debian/rules, debian/build-deps.in: - Build-depend on GStreamer core/base >= 0.10.32.2. + debian/build-deps.in, debian/rules, debian/gstreamer-plugins-bad.install: - Remove audioparsersbad and qtmux plugins, they moved to -good. - Add curl, fieldanalysis, fragmented, mpegtsdemux, patchdetect, rtpvp8, sdi, videofiltersbad and videoparsersbad plugins. -- Sebastian Dröge Sun, 17 Apr 2011 11:10:36 +0200 gst-plugins-bad0.10 (0.10.21-4) unstable; urgency=low * Upload to unstable. -- Sebastian Dröge Tue, 22 Mar 2011 15:33:52 +0100 gst-plugins-bad0.10 (0.10.21-3) experimental; urgency=low [ Sebastian Dröge ] * debian/build-deps.in: + Build depend on libsoundtouch-dev (>= 1.5.0). * debian/control.in: + Remove conflicts for the Fluendo MPEG demuxer/muxer packages. They're not in the archive anymore and if they were they wouldn't conflict anymore because of changes in gst-plugins-bad. [ Sjoerd Simons ] * debian/patches/02_shm_fixes.patch * Added, various fixes for the SHM plugin (crasher, potential race conditions). From upstream git -- Sjoerd Simons Wed, 16 Mar 2011 21:59:38 +0000 gst-plugins-bad0.10 (0.10.21-2) experimental; urgency=low * debian/build-deps.in, debian/patches/01_soundtouch-pc.patch: + The soundtouch pkg-config file is nowadays called soundtouch.pc and the name of the -dev package changed too (Closes: #612050). -- Sebastian Dröge Mon, 07 Mar 2011 10:40:46 +0100 gst-plugins-bad0.10 (0.10.21-1) experimental; urgency=low * New upstream stable release, "Pink Noise": + debian/control.in, debian/build-deps.in: - Require GStreamer, gst-plugins-base >= 0.10.32. -- Sebastian Dröge Sat, 22 Jan 2011 14:12:31 +0100 gst-plugins-bad0.10 (0.10.20.4-1) experimental; urgency=low * New upstream pre-release: + debian/control.in, debian/build-deps.in: - Require GStreamer, gst-plugins-base >= 0.10.31.4. -- Sebastian Dröge Wed, 19 Jan 2011 21:20:29 +0100 gst-plugins-bad0.10 (0.10.20.3-1) experimental; urgency=low * New upstream pre-release: + debian/control.in, debian/build-deps.in: - Require GStreamer, gst-plugins-base >= 0.10.31.3 -- Sebastian Dröge Thu, 13 Jan 2011 13:59:14 +0100 gst-plugins-bad0.10 (0.10.20.2-1) experimental; urgency=low [ Emilio Pozuelo Monfort ] * debian/build-deps.in, debian/rules: + Use dpkg-vendor instead of lsb_release. [ Sebastian Dröge ] * New upstream pre-release: + debian/control.in, debian/build-deps.in: - Require GStreamer, gst-plugins-base >= 0.10.31.2 - Require ORC >= 0.4.7. + debian/rules, debian/gstreamer-plugins-bad.install: - Drop the alsaspdif plugin, the functionality is in the alsa plugin now. - Drop the selector and valve plugins, they're in GStreamer core now. - Drop the jack plugin, it's in gst-plugins-good now. - Add the new camerabin2, colorspace, dvbsuboverlay, interlace, jp2kdecimator and y4mdec plugins. -- Sebastian Dröge Mon, 10 Jan 2011 15:17:04 +0100 gst-plugins-bad0.10 (0.10.20-2) experimental; urgency=low * debian/build-deps.in: + Add the epoch to the orc build dependency to get dependencies on the correct version. -- Sebastian Dröge Fri, 17 Sep 2010 13:26:42 +0200 gst-plugins-bad0.10 (0.10.20-1) experimental; urgency=low * New upstream release, "For it is a Human Number". -- Sebastian Dröge Fri, 03 Sep 2010 12:37:05 +0200 gst-plugins-bad0.10 (0.10.19.5-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Mon, 30 Aug 2010 16:13:21 +0200 gst-plugins-bad0.10 (0.10.19.4-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Sat, 21 Aug 2010 22:00:02 +0200 gst-plugins-bad0.10 (0.10.19.3-1) experimental; urgency=low * debian/build-deps.in: + Fix build dependency on libdvdnav-dev to be ignored on GNU Hurd for real now (Closes: #585095). * New upstream pre-release: + debian/patches/01_wildmidi-0.2.3.patch, debian/patches/99_autoreconf.patch: - Dropped, merged upstream. + debian/build-deps.in, debian/rules: - Build depend on GStreamer and gst-plugins-base 0.10.30. - Build depend on orc instead of liboil. - Build depend on GLib >= 2.20 and GTK >= 2.14. - Build depend on celt >= 0.5.0. + debian/build-deps.in, debian/gstreamer-plugins-bad.install: - Add the new coloreffects, gaudieffects, geometrictransform, gsettingselements, ivfparse, rtmpsrc, shm and videomaxrate plugins. * debian/rules, debian/compat, debian/control.in, debian/source/format, debian/patches/*: + Update to debhelper compat level 7. + Update to source format 3.0 (quilt). -- Sebastian Dröge Wed, 11 Aug 2010 11:44:23 +0200 gst-plugins-bad0.10 (0.10.19-2) unstable; urgency=low [Loïc Minier] * Fail before generating control if type-handling isn't installed; avoids silently generating a bogus control file. [Sebastian Dröge] * debian/rules, debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Don't build the resindvd plugin on GNU Hurd (Closes: #585095). * debian/patches/99_autoreconf.patch, debian/patches/01_wildmidi-0.2.3.patch, debian/build-deps.in: + Build against wildmidi 0.2.3 because of API changes and many bugfixes. -- Sebastian Dröge Wed, 07 Jul 2010 08:46:02 +0200 gst-plugins-bad0.10 (0.10.19-1) unstable; urgency=low * New upstream release, "The World Kicked Back". -- Sebastian Dröge Mon, 31 May 2010 05:43:20 +0200 gst-plugins-bad0.10 (0.10.18.3-2) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Enable and ship the VP8 encoder/decoder plugin. -- Sebastian Dröge Sat, 29 May 2010 07:10:49 +0200 gst-plugins-bad0.10 (0.10.18.3-1) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add the zbar plugin, now that zbar >= 0.9 is available. * New upstream pre-release: + debian/patches/*: - Drop all VP8/WebM patches and other patches that are upstream now. VP8 plugin is still not enabled and waiting for libvpx. -- Sebastian Dröge Wed, 26 May 2010 15:35:21 +0200 gst-plugins-bad0.10 (0.10.18.2-2) unstable; urgency=low * debian/patches/00*, debian/patches/98_autoreconf.patch, debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add VP8 plugin. * debian/control.in: + Let the -doc package depend on the GStreamer core/base documentation for cross references. * Upload to unstable, the VP8 plugin is disabled until libvpx is accepted. -- Sebastian Dröge Sat, 22 May 2010 08:09:15 +0200 gst-plugins-bad0.10 (0.10.18.2-1) experimental; urgency=low * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Remove the oss4audio plugin, it was moved to gstreamer0.10-plugins-good. - Add the segmentclip and invtelecine plugins. + debian/control.in, debian/build-deps.in: - Require GStreamer core/base >= 0.10.29. * debian/build-deps.in: + Build depend on GStreamer core/base documentation to get correct cross references. * debian/patches/01_resindvdbin-linking.patch: + Fix linking of the resindvdbin plugin. -- Sebastian Dröge Sat, 15 May 2010 10:03:19 +0200 gst-plugins-bad0.10 (0.10.18-2) unstable; urgency=low * debian/gstreamer-plugins-bad.install: + Add camerabin plugin. -- Sebastian Dröge Wed, 17 Mar 2010 14:54:11 +0100 gst-plugins-bad0.10 (0.10.18-1) unstable; urgency=low * New upstream stable release, "Dimishing Returns": + debian/rules, debian/build-deps.in: - Build depend on gstreamer and gst-plugins-base >= 0.10.27. -- Sebastian Dröge Mon, 08 Mar 2010 10:06:36 +0000 gst-plugins-bad0.10 (0.10.17.3-1) experimental; urgency=low * New upstream pre-release: + debian/rules, debian/build-deps.in: - Build depend on gstreamer and gst-plugins-base >= 0.10.26.3. + debian/patches/01_faad-linking.patch: - Dropped, merged upstream. -- Sebastian Dröge Thu, 25 Feb 2010 08:29:47 +0100 gst-plugins-bad0.10 (0.10.17.2-1) experimental; urgency=low * New upstream pre-release: + Fixes midi plugin that claims that it sometimes doesn't support files (Closes: #502952, #468083). + debian/build-deps.in, debian/rules: - Build depend on gstreamer and gst-plugins-base >= 0.10.26.2. + debian/build-deps.in: - Update orc and gtk build dependencies. + debian/gstreamer-plugins-bad.install, debian/build-deps.in: - Add adpcmdec, adpcmenc, dataurisrc, flite, jpegformat plugins. - Remove shapewipe plugin, it was moved to gst-plugins-good. + debian/patches/01_cog-orc-memcpy.patch, debian/patches/02_cog-link-lm.patch, debian/patches/03_frei0r.patch: - Dropped, merged upstream. + debian/control.in: - Add Conflict with gst-plugins-ugly << 0.10.13.2 because of the id3mux plugin. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add LV2 plugin again, now that broken plugins can't crash the main process anymore. * debian/patches/01_faad-linking.patch: + Fix linking of the faad plugin. -- Sebastian Dröge Fri, 19 Feb 2010 14:06:38 +0100 gst-plugins-bad0.10 (0.10.17-4) unstable; urgency=low * debian/build-deps.in: + And remove the unnecessary build dependencies for SDL again as bug #565579 is fixed now (Closes: #567775). -- Sebastian Dröge Mon, 01 Feb 2010 05:35:12 +0100 gst-plugins-bad0.10 (0.10.17-3) unstable; urgency=low * debian/patches/03_frei0r.patch: + Patch from upstream GIT to ensure correct GObject property names (Closes: #565505). * debian/build-deps.in: + Add some unnecessary build dependencies to be able to build the SDL plugin, see libsdl1.2 bug #565579. -- Sebastian Dröge Sat, 16 Jan 2010 17:04:34 +0100 gst-plugins-bad0.10 (0.10.17-2) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Enable cog plugin. * debian/patches/01_cog-orc-memcpy.patch, debian/patches/02_cog-link-lm.patch: + Fix build of the cog plugin. -- Sebastian Dröge Mon, 14 Dec 2009 13:20:24 +0100 gst-plugins-bad0.10 (0.10.17-1) unstable; urgency=low * New upstream release, "Anny bobany". -- Sebastian Dröge Tue, 17 Nov 2009 09:18:15 +0100 gst-plugins-bad0.10 (0.10.16.3-1) experimental; urgency=low * New upstream pre-release: + Fixes build with celt >= 0.7.0. * debian/rules: + Add gstreamer0.10-plugins-bad's library directory to LD_LIBRARY_PATH before calling dh_gstscancodecs. Otherwise some plugins can't be loaded because of missing libraries. -- Sebastian Dröge Fri, 13 Nov 2009 07:58:42 +0100 gst-plugins-bad0.10 (0.10.16.2-1) experimental; urgency=low * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Rename aiffparse plugin to aiff. -- Sebastian Dröge Tue, 10 Nov 2009 10:28:32 +0100 gst-plugins-bad0.10 (0.10.16-1) unstable; urgency=low [ Fabian Greffrath ] * debian/extra, debian/gstreamer-amrwbenc.install, debian/README.Debian: + Renamed the gstreamer-amrwb extra package to gstreamer-amrwbenc. There's still the amrwb encoder in gst-plugins-bad because the opencore-amr codecs in gst-plugins-ugly have no amrwb encoder. [ Sebastian Dröge ] * New upstream bugfix release, "Sensible Precaution": + Fixes build of the faac plugin (Closes: #552080). -- Sebastian Dröge Sat, 24 Oct 2009 06:17:23 +0200 gst-plugins-bad0.10 (0.10.15-1) unstable; urgency=low * New upstream release, "Ending the war". -- Sebastian Dröge Wed, 21 Oct 2009 19:48:35 +0200 gst-plugins-bad0.10 (0.10.14.4-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Fri, 16 Oct 2009 14:36:20 +0200 gst-plugins-bad0.10 (0.10.14.3-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Fri, 16 Oct 2009 09:02:55 +0200 gst-plugins-bad0.10 (0.10.14.2-1) experimental; urgency=low * New upstream pre-release: + debian/build-deps.in, debian/gstreamer-plugins-bad.install: - Remove xdgmime plugin, it's in gst-plugins-base now. - Add videomeasure, pnm, rsvg and mpegpsmux plugins. + debian/rules, debian/build-deps.in: - Update GStreamer and gst-plugins-base build dependencies. + debian/patches/02_libass-0.9.7.patch: - Dropped, merged upstream. -- Sebastian Dröge Mon, 12 Oct 2009 17:14:50 +0200 gst-plugins-bad0.10 (0.10.14-4) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Disable the LV2 plugin until it works reliable and doesn't crash GStreamer on startup every time (Closes: #549189). Unfortunately I can't reproduce that crash... -- Sebastian Dröge Sat, 03 Oct 2009 14:09:46 +0200 gst-plugins-bad0.10 (0.10.14-3) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add the LV2 plugin. * debian/gstreamer-plugins-bad.install, debian/patches/01_static-unstable-libraries.patch: + Install the experimental helper libraries into /usr/lib but don't ship any headers or anything else. Static linking causes problems if multiple plugins use the same library. * debian/patches/99_automake.patch: + Dropped, not needed anymore. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Drop the neonhttpsrc plugin, the souphttpsrc plugin from gst-plugins-good is better in all cases. -- Sebastian Dröge Wed, 30 Sep 2009 12:43:23 +0200 gst-plugins-bad0.10 (0.10.14-2) unstable; urgency=low * debian/control.in: + Add a Replaces for gstreamer0.10-plugins-really-bad from the Debian Multimedia repository, which also contains the Dirac plugin (Closes: #544667). -- Sebastian Dröge Wed, 02 Sep 2009 11:43:32 +0200 gst-plugins-bad0.10 (0.10.14-1) unstable; urgency=low * New upstream release, 'Your New Best Friends'. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add game-music-emu plugin. -- Sebastian Dröge Sun, 30 Aug 2009 11:02:59 +0200 gst-plugins-bad0.10 (0.10.13.5-2) experimental; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add mimic plugin. -- Sebastian Dröge Wed, 26 Aug 2009 19:02:30 +0200 gst-plugins-bad0.10 (0.10.13.5-1) experimental; urgency=low * New upstream pre-release. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add Dirac plugin that uses the Dirac reference implementation. * debian/control.in: + Update Standards-Version to 3.8.3, no additional changes needed. * debian/build-deps.in, debian/patches/02_libass-0.9.7.patch: + Add support for building against libass >= 0.9.7. -- Sebastian Dröge Wed, 26 Aug 2009 17:40:24 +0200 gst-plugins-bad0.10 (0.10.13.3-1) experimental; urgency=low * New upstream pre-release: + debian/build-deps.in: - Build depend on libass-dev (<< 0.9.7) because of API changes in that version that we don't support yet. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Remove gmyth plugin because libgmyth will be removed (Closes: #542128). -- Sebastian Dröge Wed, 19 Aug 2009 08:55:24 +0200 gst-plugins-bad0.10 (0.10.13.2-1) experimental; urgency=low [ Fabian Greffrath ] * debian/extra: + Use @GST_PKGNAME@ instead of hard-coded "gstreamer0.10". * debian/extra, debian/gstreamer-x264.install, debian/README.Debian: + Removed all references to the x264 plugin which has been moved to gst-plugins-ugly0.10. [ Sebastian Dröge ] * New upstream pre-release: + Fixes integer overflow in MPEG demuxer that prevents playback of files larger than 4GB (Closes: #537392). + debian/patches/01_static-unstable-libraries.patch, debian/patches/99_automake.patch: - Only build static libraries, they're not API/ABI stable yet but are used by some plugins already. + debian/rules, debian/build-deps.in: - Update build dependencies. + debian/gstreamer-plugins-bad.install: - Add new asfmux, frei0r, kate and schroedinger plugins. - Remove rtpmanager plugin, which was moved to gst-plugins-good. + debian/control.in: - Add Conflicts/Replaces/Provides for gstreamer0.10-schroedinger. * debian/control.in: + Update Standards-Version to 3.8.2, no additional changes needed. -- Sebastian Dröge Wed, 12 Aug 2009 07:20:46 +0200 gst-plugins-bad0.10 (0.10.13-1) unstable; urgency=low * New upstream release, 'Supersonic Rocket': + debian/patches/01_hdvparse-link-libm.patch: - Dropped, merged upstream. -- Sebastian Dröge Thu, 18 Jun 2009 13:47:30 +0200 gst-plugins-bad0.10 (0.10.12.2-1) experimental; urgency=low [ Fabian Greffrath ] * debian/extra: + gstreamer0.10-faac recommends gstreamer0.10-ffmpeg for the ffmux_mp4 element. [ Sebastian Dröge ] * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Add new plugins: hdvparse, id3tag and shapewipe. + debian/control.in: - Conflict with gst-plugins-ugly << 0.10.11.2 because of the id3tag plugin. + debian/patches/01_hdvparse-link-libm.patch: - Link hdvparse with -lm to fix unresolved symbols. -- Sebastian Dröge Sat, 06 Jun 2009 19:35:24 +0200 gst-plugins-bad0.10 (0.10.12-1) unstable; urgency=low * debian/build-deps.in: + Remove liblrdf build dependency as it only causes crashes in dependend packages like pidgin. There seems to be some kind of conflict if libraptor/liblrdf and libxml2 are used in the same process (Closes: #523345). * New upstream release, 'More than I can handle'. -- Sebastian Dröge Wed, 20 May 2009 23:19:08 +0200 gst-plugins-bad0.10 (0.10.11.3-1) experimental; urgency=low [ Sebastian Dröge ] * debian/control.in: + Update Standards-Version to 3.8.1, no additional changes needed. * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Remove flv, deinterlace and y4menc plugins that were moved to gst-plugins-good. [ Fabian Greffrath ] * debian/control, debian/control.in, debian/extra: + Removed duplicate Section fields from gstreamer0.10-plugins-bad and the extra plugins. + Changed Section to debug for gstreamer0.10-plugins-bad-dbg. + Added Depends on ${misc:Depends} to gstreamer0.10-plugins-bad-dbg and the extra plugins. + Improved duplicate short description for gstreamer0.10-plugins-bad-dbg. -- Sebastian Dröge Sat, 16 May 2009 14:04:37 +0200 gst-plugins-bad0.10 (0.10.11.2-1) experimental; urgency=low [ Fabian Greffrath ] * debian/TODO.Debian: + Removed, I don't think any of these things are still relevant. [ Sebastian Dröge ] * New upstream pre-release: + debian/build-deps.in, debian/rules: - Update build dependencies. + debian/gstreamer-plugins-bad.install: - Add new debugutilsbad plugin. * debian/build-deps.in: + Use unversioned libjack-dev b-d (Closes: #526109). -- Sebastian Dröge Tue, 12 May 2009 09:51:24 +0200 gst-plugins-bad0.10 (0.10.11-2) unstable; urgency=low * Upload to unstable, now that the DirectFB transition is done. * debian/build-deps.in: + Build depend on liblrdf0-dev for the LADSPA plugin to enable support for reading RDF files for informations about LADSPA plugins. -- Sebastian Dröge Mon, 30 Mar 2009 14:41:32 +0200 gst-plugins-bad0.10 (0.10.11-1) experimental; urgency=low [ Sebastian Dröge ] * New upstream release, 'A precious stone'. [ Fabian Greffrath ] * debian/extra: + Added XB-GStreamer-* fields for the extra packages. * debian/rules: + Run debian/extra with sh (it has no execute permissions). * debian/build-deps, debian/control, debian/rules: + Order, wrap and indent Build-Depends; this will improve interdiffs for packages that provide the extra plugins. [ Sebastian Dröge ] * Upload to experimental to prevent blocking the ffmpeg/etc transition. -- Sebastian Dröge Thu, 26 Mar 2009 07:36:33 +0100 gst-plugins-bad0.10 (0.10.10.3-1) unstable; urgency=low * New upstream pre-release. -- Sebastian Dröge Sat, 14 Mar 2009 19:49:34 +0100 gst-plugins-bad0.10 (0.10.10.2-1) unstable; urgency=low * New upstream pre-release: + debian/patches/01_bpmdetect-stack-overflow.patch: - Dropped, merged upstream. + debian/build-deps.in: - Update gst-plugins-base build dependency to >= 0.10.22. - Update library build dependencies according to configure.ac. + debian/control.in, debian/gstreamer-plugins-bad.install: - This release now contains all plugins from gst-plugins-farsight and thus replaces files of it. - Add new plugins: assrender, autoconvert, dtmf, liveadder, rtpmux, siren, valve, xdgmime. - Remove filter plugin, it's obsoleted by audioiirfilter from gst-plugins-good. - Remove twolame plugin, it was moved to gst-plugins-ugly. -- Sebastian Dröge Tue, 10 Mar 2009 08:23:48 +0100 gst-plugins-bad0.10 (0.10.10-3) unstable; urgency=low * debian/patches/01_bpmdetect-stack-overflow.patch: + Patch from upstream GIT to fix stack overflow in the bpmdetect plugin. * debian/patches/02_no-Werror.patch, debian/rules: + Pass -Wno-error via C(XX)FLAGS instead of patching configure. * debian/build-deps.in: + Build depend on libdca-dev instead of libdts-dev, which is the successor. libdts-dev is still necessary for the dts.h header. -- Sebastian Dröge Mon, 23 Feb 2009 12:14:32 +0100 gst-plugins-bad0.10 (0.10.10-2) unstable; urgency=low * Upload to unstable. -- Sebastian Dröge Sun, 15 Feb 2009 20:12:00 +0100 gst-plugins-bad0.10 (0.10.10-1) experimental; urgency=low * New upstream release, 'Keep the dogies rollin'': + debian/rules: - Update GStreamer build dependencies. -- Sebastian Dröge Tue, 20 Jan 2009 09:12:34 +0100 gst-plugins-bad0.10 (0.10.9.3-1) experimental; urgency=low * New upstream pre-release: + debian/patches/01_ladspa-modules.patch: - Dropped, merged upstream. -- Sebastian Dröge Sun, 11 Jan 2009 21:31:03 +0100 gst-plugins-bad0.10 (0.10.9.2-1) experimental; urgency=low * New upstream pre-release: + A lot DVD nagivation fixes (Closes: #506573). + debian/patches/01_ladspa-modules.patch: - Add plugin dependency for the LADSPA modules to make sure that the plugin is updated when new LADSPA modules are installed. + debian/build-deps.in, debian/rules: - Update build dependencies. + debian/gstreamer-plugins-bad.install: - Add new plugins. - Remove speexresample (it's in gst-plugins-base as audioresample now). -- Sebastian Dröge Thu, 08 Jan 2009 07:59:36 +0100 gst-plugins-bad0.10 (0.10.9-1) experimental; urgency=low * New upstream release, 'Matters Of Fact'. -- Sebastian Dröge Sat, 25 Oct 2008 09:39:49 +0200 gst-plugins-bad0.10 (0.10.8.4-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Wed, 22 Oct 2008 11:20:04 +0200 gst-plugins-bad0.10 (0.10.8.3-1) experimental; urgency=low * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Add apexsink plugin. -- Sebastian Dröge Sat, 18 Oct 2008 10:23:50 +0200 gst-plugins-bad0.10 (0.10.8.2-1) experimental; urgency=low * New upstream pre-release: + Some Midi playback fixes (Closes: #489170). + debian/patches/03_resindvd-update.patch: - Dropped, merged upstream. + debian/rules: - Build depend on gstreamer >= 0.10.21. + debian/build-deps.in: - Build depend on openssl. - Build depend on CELT. - Build depend on Jasper2k. - Build depend on TwoLAME. + debian/gstreamer-plugins-bad.install: - Add aiffparse, celt, dccp, jp2k, mpegdemux, mpegtsmux, pcapparse, scaletempo and twolame plugins (Closes: #482970). + debian/control.in: - Conflict with gstreamer0.10-fluendo-mpegdemux and gstreamer0.10-fluendo-mpegmux as the mpegdemux and mpegtsmux plugins from gst-plugins-bad are their successors. -- Sebastian Dröge Sat, 11 Oct 2008 15:48:19 +0200 gst-plugins-bad0.10 (0.10.8-3) experimental; urgency=low * debian/patches/03_resindvd-update.patch: + Update the resindvd plugin from latest CVS to get some important bugfixes. -- Sebastian Dröge Sat, 11 Oct 2008 12:59:59 +0200 gst-plugins-bad0.10 (0.10.8-2) experimental; urgency=low * debian/rules, debian/control.in: + Use the new automatic plugin installation infrastructure. * debian/control.in: + Wrap control fields. + Depend on gstreamer0.10-plugins-base as some plugins need it. -- Sebastian Dröge Fri, 15 Aug 2008 18:43:04 +0200 gst-plugins-bad0.10 (0.10.8-1) experimental; urgency=low * New upstream release, 'Vapour Trails'. -- Sebastian Dröge Fri, 01 Aug 2008 11:33:33 +0200 gst-plugins-bad0.10 (0.10.7.3-1) experimental; urgency=low * New upstream pre-release: + debian/patches/03_resindvd-configure.patch, debian/patches/04_ladspa-linking.patch, debian/patches/05_resindvd-missing-header.patch: - Dropped, merged upstream. -- Sebastian Dröge Sat, 26 Jul 2008 12:35:24 +0200 gst-plugins-bad0.10 (0.10.7.2-1) experimental; urgency=low * New upstream pre-release: + debian/gstreamer-plugins-bad.install: - Remove replaygain and interleave plugins. - Add deinterlace2 plugin. + debian/gstreamer-plugins-bad.install, debian/build-deps.in: - Add resindvd plugin. + debian/rules, debian/build-deps.in: - Update gstreamer and gst-plugins-base build dependency. + debian/patches/02_wildmidi-config.patch, debian/patches/03_rtspsession_rtcp_bye.patch, debian/patches/04_mpeg4videoparse.patch: - Dropped, merged upstream. + Ported to the new libmpcdec API (Closes: #476380). + Fixes playback of certain mms streams (Closes: #467268). * debian/patches/03_resindvd-configure.patch: + Fix configure check for the resindvd plugin. * debian/patches/04_ladspa-linking.patch: + Link ladspa with -ldl to prevent unresolved symbols. * debian/patches/05_resindvd-missing-header.patch: + Add missing header file. * debian/control.in: + Update Standards-Version to 3.8.0, no additional changes needed. -- Sebastian Dröge Sun, 20 Jul 2008 12:07:37 +0200 gst-plugins-bad0.10 (0.10.7-2) unstable; urgency=low * debian/patches/03_rtspsession_rtcp_bye.patch + Added. Send RTCP BYE on EOS (From upstream CVS) * debian/control: Add myself to uploaders * debian/patches/04_mpeg4videoparse.patch + Added. mpeg4videoparse update from CVS * debian/rules: Append extra_plugins entries to debian/control instead of truncating it (Patch from Mike Massonnet) (Closes: #481034) -- Sjoerd Simons Sun, 01 Jun 2008 16:08:37 +0200 gst-plugins-bad0.10 (0.10.7-1) unstable; urgency=low * New upstream release, 'House of Cards'. -- Sebastian Dröge Thu, 24 Apr 2008 07:42:15 +0200 gst-plugins-bad0.10 (0.10.6.4-1) experimental; urgency=low * New upstream pre-release. -- Sebastian Dröge Tue, 22 Apr 2008 10:29:25 +0200 gst-plugins-bad0.10 (0.10.6.3-1) experimental; urgency=low * New upstream pre-release: + debian/patches/01_timidity-missing-header.patch: - Dropped, merged upstream. -- Sebastian Dröge Fri, 18 Apr 2008 10:36:44 +0200 gst-plugins-bad0.10 (0.10.6.2-2) experimental; urgency=low * debian/patches/02_no-Werror.patch: + Don't build with -Werror to fix FTBFS on some architectures. -- Sebastian Dröge Tue, 15 Apr 2008 05:29:54 +0200 gst-plugins-bad0.10 (0.10.6.2-1) experimental; urgency=low * New upstream pre-release: + debian/build-deps.in, debian/rules: - Update build dependencies. + debian/rules, debian/gstreamer-plugins-bad.install: - Ship new dc1394, ofa, oss4audio, subenc plugins. - Drop souphttpsrc plugin which moved to gst-plugins-good. + debian/patches/01_wildmidi-build.patch, debian/patches/03_soup-icecast.patch, debian/patches/04_soup-primary-rank.patch, debian/patches/05_soup-no-dav.patch, debian/patches/06_neon-28.patch, debian/patches/10_fix-faad-header-check.patch debian/patches/75_build_docs_without_python_xml.patch, debian/patches/80_unit-tests.patch: - Dropped, merged upstream. + debian/patches/02_wildmidi-config.patch: - Updated for the new version. + debian/patches/01_timidity-missing-header.patch: - Add missing timidity header file. -- Sebastian Dröge Mon, 14 Apr 2008 12:10:32 +0200 gst-plugins-bad0.10 (0.10.6-7) unstable; urgency=low * debian/patches/06_neon-28.patch: + Fix build with neon 0.28. * debian/build-deps.in: + Use neon-gnutls instead of plain neon. -- Sebastian Dröge Tue, 01 Apr 2008 13:19:03 +0200 gst-plugins-bad0.10 (0.10.6-6) unstable; urgency=low * debian/patches/03_soup-icecast.patch: + Set correct caps on the srcpad if we have an icecast server. Fixes glitches/crackling (Closes: #472135). * debian/patches/04_soup-primary-rank.patch: + Give souphttpsrc RANK_PRIMARY so it's used always as HTTP source if available. * debian/patches/05_soup-no-dav.patch: + Don't use soup for dav/davs. This is better handled by GIO and GnomeVFS as they provide authentication. -- Sebastian Dröge Sat, 22 Mar 2008 19:30:07 +0100 gst-plugins-bad0.10 (0.10.6-5) unstable; urgency=low * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Include the soup HTTP plugin. * debian/build-deps.in: + Drop python-xml build dependency for real now. -- Sebastian Dröge Tue, 11 Mar 2008 05:31:11 +0100 gst-plugins-bad0.10 (0.10.6-4) unstable; urgency=low * debian/patches/75_build_docs_without_python_xml.patch: + Added. Build documentation using xml.dom.minidom instead of pyxml. Patch by Sebastian Dröge. * debian/control: Drop build-depend on python-xml * debian/patches/10_fix-faad-header-check.patch: + Added. Fix faad header check to match the check faad2 does. Fixes playback of various streams. -- Sjoerd Simons Sat, 08 Mar 2008 19:59:00 +0100 gst-plugins-bad0.10 (0.10.6-3) unstable; urgency=low * debian/extra, debian/gstreamer-amrwb.install, debian/gstreamer-mpeg2enc.install, debian/README.Debian: + Patch by Fabian Greffrath to add support for an amrwb and mpeg2enc package and making the use of MPEG more conform (Closes: #467439). * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Add the gmyth plugin. -- Sebastian Dröge Tue, 26 Feb 2008 08:35:54 +0100 gst-plugins-bad0.10 (0.10.6-2) unstable; urgency=low * debian/extra: + Update for new xvid package names in Debian Multimedia and Debian Unofficial Thanks to Fabian Greffrath (Closes: #466861). Also add support for x264 and do some small cleanup. * debian/rules: + SPC is only available on Linux-i386, enable it as such. Fixes FTBFS on kfreebsd-i386. * debian/build-deps.in, debian/patches/01_wildmidi-build.patch, debian/patches/02_wildmidi-config.patch, debian/gstreamer-plugins-bad.install: + Enable the wildmidi plugin and change the config file path to our default (Closes: #346455). -- Sebastian Dröge Mon, 25 Feb 2008 07:03:11 +0100 gst-plugins-bad0.10 (0.10.6-1) unstable; urgency=low * New upstream release, "A Big Deep Breath": + debian/patches/01_linking-fixes.patch: - Dropped, merged upstream. * debian/rules, debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Enable the alsaspdif, libcdaudio, dvb, fbdev and vcd plugins only on Linux architectures to try to fix FTBFS on kfreebsd. -- Sebastian Dröge Thu, 21 Feb 2008 13:34:46 +0100 gst-plugins-bad0.10 (0.10.5.4-1) experimental; urgency=low * New upstream pre-release. * debian/control.in: + Add Replaces for gstreamer0.10-plugins-bad-multiverse (<< 0.10.5-2) to keep the Ubuntu delta lower and don't break Debian installation with some Ubuntu packages. * debian/patches/99_ltmain_as-needed.patch, debian/rules: + Add -Wl,-z,defs -Wl,-O1 -Wl,--as-needed to LDFLAGS to remove some unnecessary dependencies on various packages. * debian/patches/01_linking-fixes.patch: + Link the tta plugin with libm. -- Sebastian Dröge Tue, 19 Feb 2008 06:55:50 +0100 gst-plugins-bad0.10 (0.10.5.3-1) experimental; urgency=low * New upstream pre-release. * debian/build-deps.in: + Build depend on gstreamer0.10-plugins-base for the unit tests. * debian/patches/80_unit-tests.patch: + Disable some elements for the generic/states unit test. -- Sebastian Dröge Thu, 14 Feb 2008 13:18:33 +0100 gst-plugins-bad0.10 (0.10.5.2-1) experimental; urgency=low [ Emilio Pozuelo Monfort ] * debian/rules: - Decide the package name and url depending on the distribution. * debian/build-deps.in: - Build-Depend on lsb-release. [ Sebastian Dröge ] * New upstream pre-release: + Fixes FTBFS if built twice in a row (Closes: #424399). + Adds support for VCD playback (Closes: #454599). + Fixes conflict between Fluendo mpeg demuxer and DTS decoder (Closes: #448411). + debian/build-deps.in, debian/control.in: - Update liboil and gstreamer build dependencies. - Add and update a few build dependencies. + debian/gstreamer-plugins-bad.install: - Add dvdspu, festival, flv, mpegtsparse, mpeg4videoparse, rawparse, sdp, selector, speexresample, stereo, fbdev, metadata, vcd plugins. - Remove equalizer, multifile, spectrum, switch, videoparse, xingheader plugins. These have moved to other places now. - Sort everything alphabetically. + debian/control.in, debian/build-deps.in, debian/rules: - Drop the OpenGL plugin. This will go to a new source package named gst-plugins-gl once we have mesa >= 7.1 somewhere. * debian/rules: + Run the unit test suite but don't fail the build on failures. * debian/control.in: + Update Standards-Version to 3.7.3, no additional changes needed. -- Sebastian Dröge Sat, 09 Feb 2008 14:04:01 +0100 gst-plugins-bad0.10 (0.10.5-5) unstable; urgency=low * debian/rules: + Fix GST_REGISTRY envirnment variable setting (Closes: #452568). -- Sebastian Dröge Sat, 24 Nov 2007 20:02:13 +0100 gst-plugins-bad0.10 (0.10.5-4) unstable; urgency=low * debian/rules: + Set GST_REGISTRY before the dh_gstscancodecs call to save the registry somewhere on buildds without writable home and speed things up a bit. * debian/build-deps.in: + Remove check from build dependencies. This is only an indirect build dependency that is already satisfied by libgstreamer0.10-dev. configure only checks for libgstcheck, not check. * debian/build-deps.in, debian/gstreamer-plugins-bad.install: + Enable the DirectFB video sink plugin. -- Sebastian Dröge Wed, 19 Sep 2007 15:44:46 +0200 gst-plugins-bad0.10 (0.10.5-3) unstable; urgency=low * debian/control.in, debian/rules, debian/gstreamer-plugins-bad.install: + Move docs, SDL and GL to a separate package. + Create a package with debug symbols. * debian/rules: + Call dh_gstscancodecs. * debian/control: + Replace Source-Version with binary:Version to make lintian happy. -- Sebastian Dröge Thu, 30 Aug 2007 20:22:35 +0200 gst-plugins-bad0.10 (0.10.5-2) unstable; urgency=low * debian/build-deps.in: + Drop swfdec build dependency. The plugin doesn't work with 0.5. -- Sebastian Dröge Thu, 30 Aug 2007 10:10:49 +0200 gst-plugins-bad0.10 (0.10.5-1) unstable; urgency=medium * Change Maintainer to pkg-gstreamer, add myself to Uploaders and use "standard" GStreamer packaging, used for all the other plugin packages too. * New upstream version (Closes: #429727): + Fixes remaining use of deprecated function (Closes: #436353). + Somewhat fixes FTBFS caused by deprecation warnings by not compiling with -Werror (Closes: #424559). * debian/build-deps.in: + Build depend on new enough GStreamer (Closes: #433495). * debian/gstreamer-plugins-bad.install, debian/build-deps.in: + Ship the GSM plugin (Closes: #429594). + Ship the dtsdec plugins (Closes: #428742). + Ship the ladspa plugin (Closes: #429527). * debian/rules, debian/gstreamer-plugins-bad.install, debian/build-deps.in: + Ship the SPC plugin on i386 (Closes: #430045). * debian/control.in: + Fix typo in package description (Closes: #436664). * debian/gstreamer-plugins-bad.install: + Don't ship the libgstapp library as it still randomly changes API and ABI until it is moved to gst-plugins-good at some point. + Don't ship completely unneeded .a files for the plugins. * debian/changelog: + Urgency medium because of RC bugfixes. -- Sebastian Dröge Sun, 19 Aug 2007 14:41:31 +0200 gst-plugins-bad0.10 (0.10.4+cvs2007.04.30) unstable; urgency=low * Get a CVS version which contains the relevant FAAD patches. * Enable FAAD support. (Closes: #399438, #399042, #327163, #403093) -- Joe Wreschnig Mon, 30 Apr 2007 21:42:39 -0700 gst-plugins-bad0.10 (0.10.4-2) unstable; urgency=low * Disable spcdec for now, as it's i386-only. (Closes: #420444) -- Joe Wreschnig Sun, 22 Apr 2007 11:58:24 -0700 gst-plugins-bad0.10 (0.10.4-1) unstable; urgency=low * New upstream version. (Closes: #419904) * Remove patch added in 0.10.3-3.1, as it was merged upstream. Thanks to Loic Minier for the fast response and NMU. (Closes: #408213) * debian/control: Explain why the modules are "bad". (Closes: #387970) * Enable sdlvideosink/sdlaudiosink. (Closes: #404493) * Enable jacksink. (Closes: #407679) * Enable dvbsrc. (Closes: #418381) * Enable spcdec. -- Joe Wreschnig Sat, 21 Apr 2007 17:11:17 -0700 gst-plugins-bad0.10 (0.10.3-3.1) unstable; urgency=high * Non-maintainer upload. * SECURITY: buffer overflow. * Fix potential buffer overflow in gst/modplug/libmodplug/sndfile.cpp; CVE-2006-4192; GNOME #385788; from upstream CVS / next upstream release; closes: #407956. -- Loic Minier Mon, 22 Jan 2007 16:05:35 +0100 gst-plugins-bad0.10 (0.10.3-3) unstable; urgency=low * debian/rules: * Enable v4l2src. (Closes: #379867) * Force disabling of MusicBrainz. * Allow FAAD=enable environment variable to override build options. * README.Debian: Explain how to get FAAD support. -- Joe Wreschnig Mon, 31 Jul 2006 16:38:12 -0500 gst-plugins-bad0.10 (0.10.3-2) unstable; urgency=low * Build-Depend on zlib1g-dev. (Closes: #379752) -- Joe Wreschnig Tue, 25 Jul 2006 11:46:05 -0500 gst-plugins-bad0.10 (0.10.3-1) unstable; urgency=low * New upstream release. * debian/rules: Disable experimental and libneon modules. * debian/control: Build-Dep on liboil3-dev. * debian/copyright: Add copyrights for new modules. -- Joe Wreschnig Thu, 22 Jun 2006 18:46:04 -0500 gst-plugins-bad0.10 (0.10.1-1) unstable; urgency=low * New upstream release. * Build-Depend on python for building docs. -- Joe Wreschnig Tue, 21 Feb 2006 16:04:33 -0600 gst-plugins-bad0.10 (0.10.0+cvs20060214-2) unstable; urgency=low * Update debian/copyright. * Explicitly disable more modules. * Build and include documentation. -- Joe Wreschnig Wed, 15 Feb 2006 12:24:20 -0600 gst-plugins-bad0.10 (0.10.0+cvs20060214-1) unstable; urgency=low * Initial release. -- Joe Wreschnig Tue, 14 Feb 2006 13:22:33 -0600 debian/gstreamer-plugins-bad-videoparsers.install0000664000000000000000000000010212276646227017467 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstvideoparsersbad.so debian/gstreamer-plugins-bad-doc.install0000664000000000000000000000003512324573056015524 0ustar debian/tmp/usr/share/gtk-doc debian/source/0000775000000000000000000000000012324573064010476 5ustar debian/source/format0000664000000000000000000000001412324573056011705 0ustar 3.0 (quilt) debian/compat0000664000000000000000000000000212324573056010375 0ustar 9 debian/libgstreamer-plugins-bad.install0000664000000000000000000000041512324573056015452 0ustar debian/tmp/usr/lib/*/libgstegl-@GST_ABI@.so.* debian/tmp/usr/lib/*/libgstinsertbin-@GST_ABI@.so.* debian/tmp/usr/lib/*/libgstcodecparsers-@GST_ABI@.so.* debian/tmp/usr/lib/*/libgstmpegts-@GST_ABI@.so.* debian/tmp/usr/lib/*/libgsturidownloader-@GST_ABI@.so.* @miralloc@ debian/libgstreamer-plugins-bad-dev.install0000664000000000000000000000110012324573056016216 0ustar debian/tmp/usr/lib/*/pkgconfig debian/tmp/usr/include/gstreamer-@GST_ABI@/gst/codecparsers debian/tmp/usr/include/gstreamer-@GST_ABI@/gst/egl debian/tmp/usr/include/gstreamer-@GST_ABI@/gst/insertbin debian/tmp/usr/include/gstreamer-@GST_ABI@/gst/mpegts debian/tmp/usr/include/gstreamer-@GST_ABI@/gst/uridownloader debian/tmp/usr/lib/*/libgstcodecparsers-@GST_ABI@.so debian/tmp/usr/lib/*/libgstegl-@GST_ABI@.so debian/tmp/usr/lib/*/libgstinsertbin-@GST_ABI@.so debian/tmp/usr/lib/*/libgstmpegts-@GST_ABI@.so debian/tmp/usr/lib/*/libgsturidownloader-@GST_ABI@.so @mirallocdev@ debian/patches/0000775000000000000000000000000013013177036010620 5ustar debian/patches/vmncdec_overflow.patch0000664000000000000000000000363613013177036015213 0ustar Backport of: From 4cb1bcf1422bbcd79c0f683edb7ee85e3f7a31fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 16 Nov 2016 20:41:39 +0200 Subject: vmncdec: Sanity-check width/height before using it We will allocate a screen area of width*height*bpp bytes, however this calculation can easily overflow if too high width or height are given inside the stream. Nonetheless we would just assume that enough memory was allocated, try to fill it and overwrite as much memory as wanted. Also allocate the screen area filled with zeroes to ensure that we start with full-black and not any random (or not so random) data. https://scarybeastsecurity.blogspot.gr/2016/11/0day-poc-risky-design-decisions-in.html Ideally we should just remove this plugin in favour of the one in gst-libav, which generally seems to be of better code quality. https://bugzilla.gnome.org/show_bug.cgi?id=774533 Index: gst-plugins-bad1.0-1.2.4/gst/vmnc/vmncdec.c =================================================================== --- gst-plugins-bad1.0-1.2.4.orig/gst/vmnc/vmncdec.c 2016-11-16 19:46:04.819578535 -0500 +++ gst-plugins-bad1.0-1.2.4/gst/vmnc/vmncdec.c 2016-11-16 19:47:02.240187274 -0500 @@ -370,7 +370,7 @@ if (dec->imagedata) g_free (dec->imagedata); - dec->imagedata = g_malloc (dec->format.width * dec->format.height * + dec->imagedata = g_malloc0 (dec->format.width * dec->format.height * dec->format.bytes_per_pixel); GST_DEBUG_OBJECT (dec, "Allocated image data at %p", dec->imagedata); @@ -901,6 +901,10 @@ GST_WARNING_OBJECT (dec, "Rectangle out of range, type %d", r.type); return ERROR_INVALID; } + } else if (r.width > 16384 || r.height > 16384) { + GST_WARNING_OBJECT (dec, "Width or height too high: %ux%u", r.width, + r.height); + return ERROR_INVALID; } switch (r.type) { debian/patches/pcfile-requires-plugins-good0000664000000000000000000000372312302224175016251 0ustar Description: Have libgstreamer-plugins-bad-1.0.pc Require the moved copy in -good Author: Iain Lane Forwarded: not-needed Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gst-plugins-bad1.0/+bug/1170923 Index: b/pkgconfig/gstreamer-plugins-bad.pc.in =================================================================== --- a/pkgconfig/gstreamer-plugins-bad.pc.in +++ b/pkgconfig/gstreamer-plugins-bad.pc.in @@ -7,7 +7,5 @@ Name: GStreamer Bad Plugin libraries Description: Streaming media framework, bad plugins libraries -Requires: gstreamer-@GST_API_VERSION@ +Requires: gstreamer-@GST_API_VERSION@ gstreamer-plugins-good-@GST_API_VERSION@ Version: @VERSION@ -Libs: -L${libdir} -Cflags: -I${includedir} Index: b/pkgconfig/gstreamer-plugins-bad-uninstalled.pc.in =================================================================== --- a/pkgconfig/gstreamer-plugins-bad-uninstalled.pc.in +++ b/pkgconfig/gstreamer-plugins-bad-uninstalled.pc.in @@ -9,6 +9,6 @@ Name: GStreamer Bad Plugin libraries, Uninstalled Description: Streaming media framework, bad plugins libraries, uninstalled Version: @VERSION@ -Requires: gstreamer-@GST_API_VERSION@ -Libs: -L@abs_top_builddir@/gst-libs/gst/basecamerabinsrc -L@abs_top_builddir@/gst-libs/gst/codecparsers -L@abs_top_builddir@/gst-libs/gst/egl -L@abs_top_builddir@/gst-libs/gst/insertbin -L@abs_top_builddir@/gst-libs/gst/interfaces -L@abs_top_builddir@/gst-libs/gst/mpegts -L@abs_top_builddir@/gst-libs/gst/signalprocessor -L@abs_top_builddir@/gst-libs/gst/video +Requires: gstreamer-@GST_API_VERSION@ gstreamer-plugins-good-@GST_API_VERSION@ +Libs: -L@abs_top_builddir@/gst-libs/gst/codecparsers -L@abs_top_builddir@/gst-libs/gst/egl -L@abs_top_builddir@/gst-libs/gst/insertbin -L@abs_top_builddir@/gst-libs/gst/interfaces -L@abs_top_builddir@/gst-libs/gst/mpegts -L@abs_top_builddir@/gst-libs/gst/signalprocessor -L@abs_top_builddir@/gst-libs/gst/video Cflags: -I@abs_top_srcdir@/gst-libs -I@abs_top_builddir@/gst-libs debian/patches/adding-mirsink-and-android-media-over-hybris-support.patch0000664000000000000000000100364512302224175023763 0ustar Description: Adding mirsink and Android media over hybris support, for hardware accelerated decode using libstagefright and the hybris compat layer. Author: Jim Hodapp Origin: vendor Forwarded: no diff --git a/configure.ac b/configure.ac index 95edd76..b22e0e3 100644 --- a/configure.ac +++ b/configure.ac @@ -847,6 +847,14 @@ AG_GST_CHECK_FEATURE(ANDROID_MEDIA, [Android Media], androidmedia, [ esac ]) +dnl *** A Hybris-based Platform *** +translit(dnm, m, l) AM_CONDITIONAL(USE_ANDROID_MEDIA_HYBRIS, true) +HAVE_ANDROID_MEDIA_HYBRIS="no" +dnl Check for the presence of Hybris (Ubuntu Touch) +AG_GST_CHECK_FEATURE(ANDROID_MEDIA_HYBRIS, [Android Media Hybris], androidmediahybris, [ + AC_CHECK_HEADER(hybris/media/media_codec_layer.h, HAVE_ANDROID_MEDIA_HYBRIS="yes", HAVE_ANDROID_MEDIA_HYBRIS="no") +]) + dnl *** AppleMedia (OS X and iOS) *** translit(dnm, m, l) AM_CONDITIONAL(USE_APPLE_MEDIA, true) HAVE_APPLE_MEDIA="no" @@ -2195,6 +2203,7 @@ AM_CONDITIONAL(DECKLINK_OSX, false) AM_CONDITIONAL(USE_DIRECTFB, false) AM_CONDITIONAL(USE_WAYLAND, false) AM_CONDITIONAL(USE_DAALA, false) +AM_CONDITIONAL(USE_ANDROID_MEDIA_HYBRIS, false) AM_CONDITIONAL(USE_DTS, false) AM_CONDITIONAL(USE_EXIF, false) AM_CONDITIONAL(USE_RESINDVD, false) @@ -2405,6 +2414,7 @@ gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/basecamerabinsrc/Makefile gst-libs/gst/egl/Makefile +gst-libs/gst/mir/Makefile gst-libs/gst/insertbin/Makefile gst-libs/gst/interfaces/Makefile gst-libs/gst/codecparsers/Makefile @@ -2465,6 +2475,7 @@ ext/dc1394/Makefile ext/directfb/Makefile ext/wayland/Makefile ext/daala/Makefile +ext/mir/Makefile ext/dts/Makefile ext/eglgles/Makefile ext/faac/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index 8be0ea7..b199c83 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -76,6 +76,12 @@ else DAALA_DIR= endif +if USE_ANDROID_MEDIA_HYBRIS +MIR_DIR=mir +else +MIR_DIR= +endif + if USE_DTS DTS_DIR=dts else @@ -412,6 +418,7 @@ SUBDIRS=\ $(LV2_DIR) \ $(LIBFAME_DIR) \ $(LIBMMS_DIR) \ + $(MIR_DIR) \ $(MODPLUG_DIR) \ $(MPEG2ENC_DIR) \ $(MPG123_DIR) \ @@ -458,6 +465,7 @@ DIST_SUBDIRS = \ dc1394 \ directfb \ wayland \ + mir \ faac \ faad \ flite \ diff --git a/ext/mir/Makefile.am b/ext/mir/Makefile.am new file mode 100644 index 0000000..2121504 --- /dev/null +++ b/ext/mir/Makefile.am @@ -0,0 +1,16 @@ +plugin_LTLIBRARIES = libgstmirsink.la + +libgstmirsink_la_SOURCES = gstmirsink.c mirpool.c +libgstmirsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ + $(MIR_CFLAGS) \ + -I../../gst-libs/ +libgstmirsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \ + -lgstvideo-$(GST_API_VERSION) \ + $(top_builddir)/gst-libs/gst/mir/libgstmiralloc-$(GST_API_VERSION).la \ + -lmedia \ + $(EGL_LIBS) $(EGLGLES_LIBS) \ + $(MIR_LIBS) +libgstmirsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) +libgstmirsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) +include_HEADERS = mirpool.h gstmirsink.h +noinst_HEADERS = diff --git a/ext/mir/gstmirsink.c b/ext/mir/gstmirsink.c new file mode 100644 index 0000000..794cbd5 --- /dev/null +++ b/ext/mir/gstmirsink.c @@ -0,0 +1,824 @@ +/* + * GStreamer Mir video sink + * Copyright (C) 2013 Canonical Ltd + * + * 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 3 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +/** + * SECTION:element-mirsink + * + * The mirsink creates its own window and renders the decoded video frames there. + * Setup the Mir environment as described in + * Mir home page. + * + * + * Example pipeline + * |[ + * gst-launch -v filesrc ! qtdemux ! h264parse ! queue ! amcviddec-omxtiducati1videodecoder ! mirsink + * ]| test the video rendering with mirsink + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gstmirsink.h" +#include "mirpool.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +/* signals */ +enum +{ + SIGNAL_0, + LAST_SIGNAL +}; + +/* Properties */ +enum +{ + PROP_0, + PROP_MIR_TEXTURE_ID +}; + +GST_DEBUG_CATEGORY (gstmir_debug); +#define GST_CAT_DEFAULT gstmir_debug + +#if 0 +static const char gst_mirsink_sink_caps_str[] = +GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_MIR_IMAGE, + GST_VIDEO_FORMATS_ALL) ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, + GST_VIDEO_FORMATS_ALL); + + static GstStaticPadTemplate gst_mirsink_sink_caps_template = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (gst_mirsink_sink_caps_str)); +#else +static GstStaticPadTemplate gst_mirsink_sink_caps_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw, " + "format=(string) {RGBA, BGRA, ARGB, ABGR, RGBx, BGRx, xRGB, xBGR, " + "AYUV, Y444, I420, YV12, NV12, NV21, Y42B, Y41B, RGB, BGR, RGB16}, " + "width=(int)[ 1, MAX ], " "height=(int)[ 1, MAX ], " + "framerate=(fraction)[ 0, MAX ] ") + ); +#endif + +static guint frame_ready_signal = 0; +static guint surface_texture_client_set_signal = 0; + +/* Fixme: Add more interfaces */ +#define gst_mir_sink_parent_class parent_class +G_DEFINE_TYPE (GstMirSink, gst_mir_sink, GST_TYPE_VIDEO_SINK); + +static void gst_mir_sink_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_mir_sink_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec); +static void gst_mir_sink_finalize (GObject * object); +static void gst_mir_sink_set_context (GstElement * element, + GstContext * context); +static GstCaps *gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter); +static gboolean gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps); +static gboolean gst_mir_sink_start (GstBaseSink * bsink); +static gboolean gst_mir_sink_stop (GstBaseSink * bsink); +static gboolean gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer); +static gboolean +gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query); +static gboolean gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer); +static gboolean gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query); + +static void +gst_mir_sink_class_init (GstMirSinkClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasesink_class = (GstBaseSinkClass *) klass; + + gobject_class->set_property = gst_mir_sink_set_property; + gobject_class->get_property = gst_mir_sink_get_property; + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_mir_sink_finalize); + gstelement_class->set_context = gst_mir_sink_set_context; + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_mirsink_sink_caps_template)); + + gst_element_class_set_static_metadata (gstelement_class, + "Mir video sink", "Sink/Video", + "Output to Mir surface", "Jim Hodapp "); + + gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_get_caps); + gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_mir_sink_set_caps); + gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_mir_sink_start); + gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_mir_sink_stop); + gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_mir_sink_preroll); + gstbasesink_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_mir_sink_propose_allocation); + gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_mir_sink_render); + gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_mir_sink_query); + + /* This signal is for being notified when a frame is ready to be rendered. This + * is useful for anything outside of the sink that needs to know when each frame + * is ready. */ + frame_ready_signal = + g_signal_new ("frame-ready", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstMirSinkClass, frame_ready_changed), NULL, NULL, + g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 0); + + surface_texture_client_set_signal = + g_signal_new ("surface-texture-client", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstMirSinkClass, surface_texture_client_changed), NULL, + NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); + + g_object_class_install_property (gobject_class, PROP_MIR_TEXTURE_ID, + g_param_spec_uint ("texture-id", "Texture ID", + "Texture ID to render video to, created by the application", 0, + UINT_MAX, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_mir_sink_init (GstMirSink * sink) +{ + GST_DEBUG_OBJECT (sink, "Initializing mirsink"); + sink->pool = NULL; + + g_mutex_init (&sink->mir_lock); + + sink->context = NULL; + +} + +static void +gst_mir_sink_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec) +{ + GstMirSink *sink = GST_MIR_SINK (object); + + switch (prop_id) { + case PROP_MIR_TEXTURE_ID: + g_value_set_uint (value, sink->texture_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_mir_sink_create_surface_texture (GObject * object) +{ + GstMirSink *sink = GST_MIR_SINK (object); + + /* Create a new SurfaceTextureClientHybris instance from a texture ID */ + sink->surface_texture_client = + surface_texture_client_create_by_id (sink->texture_id); + GST_DEBUG_OBJECT (sink, "Created new SurfaceTextureClientHybris instance: %p", + sink->surface_texture_client); + /* Because mirsink is being loaded, we are definitely doing + * hardware rendering. + */ + surface_texture_client_set_hardware_rendering (sink->surface_texture_client, + TRUE); + + /* Signal the client API that a surface_texture_client instance has been set */ + g_signal_emit (G_OBJECT (sink), surface_texture_client_set_signal, 0, + (gpointer) sink->surface_texture_client); +} + +static void +gst_mir_sink_set_property (GObject * object, + guint prop_id, const GValue * value, GParamSpec * pspec) +{ + GstMirSink *sink = GST_MIR_SINK (object); + + switch (prop_id) { + case PROP_MIR_TEXTURE_ID: + sink->texture_id = g_value_get_uint (value); + GST_WARNING_OBJECT (object, "texture_id: %d", sink->texture_id); + gst_mir_sink_create_surface_texture (object); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +#if 0 +static void +destroy_display (struct display *display) +{ + free (display); +} + +static void +destroy_session (struct session *session) +{ + if (session->app_options) + u_application_options_destroy (session->app_options); + + if (session->app_description) + u_application_description_destroy (session->app_description); + + free (session); +} + +static void +destroy_window (struct window *window) +{ + if (window->properties) + ua_ui_window_properties_destroy (window->properties); + + if (window->window) + ua_ui_window_destroy (window->window); + + free (window); +} +#endif + +static void +gst_mir_sink_finalize (GObject * object) +{ + GstMirSink *sink = GST_MIR_SINK (object); + + GST_DEBUG_OBJECT (sink, "Finalizing the sink.."); + +#if 0 + if (sink->window) + destroy_window (sink->window); + if (sink->display) + destroy_display (sink->display); + if (sink->session) + destroy_session (sink->session); +#endif + + /* Make sure that the SurfaceTextureClientHybris instance gets cleaned + * up when the pipeline is being torn down. + */ + if (sink->surface_texture_client) + surface_texture_client_unref (sink->surface_texture_client); + + g_mutex_clear (&sink->mir_lock); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_mir_sink_set_context (GstElement * element, GstContext * context) +{ + GST_DEBUG_OBJECT (element, "%s", __PRETTY_FUNCTION__); +} + +static gboolean +gst_mir_sink_query (GstBaseSink * bsink, GstQuery * query) +{ + GstMirSink *sink = GST_MIR_SINK (bsink); + + GST_INFO_OBJECT (sink, "query type %s", GST_QUERY_TYPE_NAME (query)); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_CONTEXT:{ + const gchar *context_type; + GstMirContext *gst_mir_context; + + if (gst_query_parse_context_type (query, &context_type) && + strcmp (context_type, GST_MIR_CONTEXT_TYPE) == 0 && + sink->surface_texture_client) { + GST_DEBUG_OBJECT (sink, "GST_MIR_CONTEXT_TYPE"); + + gst_mir_context = gst_mir_context_new (GST_ELEMENT_CAST (sink), + sink->surface_texture_client); + sink->context = gst_mir_context_new_with_stc (gst_mir_context); + GST_INFO_OBJECT (sink, "Setting context on the sink"); + gst_query_set_context (query, sink->context); + gst_context_unref (sink->context); + + return TRUE; + } else { + goto base_class; + } + break; + } + default: + goto base_class; + break; + } + +base_class: + return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); +} + +#if 0 +static struct display * +create_display (void) +{ + struct display *display; + display = malloc (sizeof *display); + + display->display = ua_ui_display_new_with_index (0); + if (display->display == NULL) { + free (display); + return NULL; + } + + display->height = ua_ui_display_query_vertical_res (display->display); + display->width = ua_ui_display_query_horizontal_res (display->display); + + GST_DEBUG ("Display resolution: (%d,%d)\n", display->height, display->width); + + return display; +} + +static struct session * +create_session (void) +{ + struct session *session; + char argv[1][1]; + session = malloc (sizeof *session); + + session->properties = ua_ui_session_properties_new (); + ua_ui_session_properties_set_type (session->properties, U_SYSTEM_SESSION); + session->session = ua_ui_session_new_with_properties (session->properties); + if (!session->session) + GST_WARNING ("Failed to start new Ubuntu Application API session"); + + session->app_description = u_application_description_new (); + session->app_lifecycle_delegate = u_application_lifecycle_delegate_new (); + /* No context data to pass to the lifecycle delegate for now */ + u_application_lifecycle_delegate_set_context + (session->app_lifecycle_delegate, NULL); + u_application_description_set_application_lifecycle_delegate + (session->app_description, session->app_lifecycle_delegate); + + /* The UA requires a command line option set, so give it a fake argv array */ + argv[0][0] = '\n'; + session->app_options = + u_application_options_new_from_cmd_line (1, (char **) argv); + session->app_instance = + u_application_instance_new_from_description_with_options + (session->app_description, session->app_options); + if (!session->app_instance) + GST_WARNING ("Failed to start a new Ubuntu Application API instance"); + + return session; +} + +static void +create_window (GstMirSink * sink, struct display *display, int width, + int height) +{ + struct window *window; + + /* No need to create a window a second time */ + if (sink->window) + return; + + g_mutex_lock (&sink->mir_lock); + + window = malloc (sizeof *window); + window->display = display; + window->width = width; + window->height = height; + + window->properties = ua_ui_window_properties_new_for_normal_window (); + ua_ui_window_properties_set_titlen (window->properties, "MirSinkWindow", 13); + + ua_ui_window_properties_set_role (window->properties, 1); + ua_ui_window_properties_set_input_cb_and_ctx (window->properties, NULL, NULL); + GST_DEBUG ("Creating new UA window"); + window->window = + ua_ui_window_new_for_application_with_properties (sink->session-> + app_instance, window->properties); + GST_DEBUG ("Setting window geometry"); + window->width = window->display->width; + window->height = window->display->height; + GST_DEBUG_OBJECT (sink, "width: %d, height: %d", window->width, + window->height); + + if (height != 0 || width != 0) + ua_ui_window_resize (window->window, window->width, window->height); + + + window->egl_native_window = ua_ui_window_get_native_type (window->window); + sink->window = window; + + g_mutex_unlock (&sink->mir_lock); +} +#endif + +static GstCaps * +gst_mir_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) +{ + GstMirSink *sink; + GstCaps *caps; + + sink = GST_MIR_SINK (bsink); + + GST_DEBUG_OBJECT (sink, "%s", __PRETTY_FUNCTION__); + + caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); + if (filter) { + GstCaps *intersection; + + intersection = + gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + caps = intersection; + } + return caps; +} + +static gboolean +gst_mir_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) +{ + GstMirSink *sink = GST_MIR_SINK (bsink); + GstBufferPool *newpool, *oldpool; + GstMirBufferPool *m_pool; + GstVideoInfo info; + GstStructure *config; + static GstAllocationParams params = { + 0, 0, 0, 15, + }; + guint size; + + sink = GST_MIR_SINK (bsink); + + GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); + + if (!gst_video_info_from_caps (&info, caps)) + goto invalid_format; + + sink->video_width = info.width; + sink->video_height = info.height; + size = info.size; + + GST_DEBUG_OBJECT (sink, "Creating new GstMirBufferPool"); + /* Create a new pool for the new configuration */ + newpool = gst_mir_buffer_pool_new (sink); + + if (!newpool) { + GST_ERROR_OBJECT (sink, "Failed to create new pool"); + return FALSE; + } + + GST_DEBUG_OBJECT (sink, + "Setting SurfaceTextureClientHybris instance in m_pool"); + /* Add the SurfaceTextureClientHybris instance to the pool for later use */ + gst_mir_buffer_pool_set_surface_texture_client (newpool, + sink->surface_texture_client); + GST_WARNING_OBJECT (sink, "SurfaceTextureClientHybris: %p", + sink->surface_texture_client); + + m_pool = GST_MIR_BUFFER_POOL_CAST (newpool); + GST_WARNING_OBJECT (sink, "m_pool SurfaceTextureClientHybris: %p", + m_pool->surface_texture_client); + m_pool->width = sink->video_width; + m_pool->height = sink->video_height; + + config = gst_buffer_pool_get_config (newpool); + gst_buffer_pool_config_set_params (config, caps, size, 2, 0); + gst_buffer_pool_config_set_allocator (config, NULL, ¶ms); + if (!gst_buffer_pool_set_config (newpool, config)) + goto config_failed; + + GST_OBJECT_LOCK (sink); + oldpool = sink->pool; + sink->pool = newpool; + GST_OBJECT_UNLOCK (sink); + + GST_DEBUG_OBJECT (sink, "Finishing up set_caps"); + + if (oldpool) + gst_object_unref (oldpool); + + return TRUE; + +invalid_format: + { + GST_DEBUG_OBJECT (sink, + "Could not locate image format from caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +config_failed: + { + GST_DEBUG_OBJECT (bsink, "failed setting config"); + return FALSE; + } +} + +static gboolean +gst_mir_sink_start (GstBaseSink * bsink) +{ + GstMirSink *sink = (GstMirSink *) bsink; + + GST_DEBUG_OBJECT (sink, "start"); + + /* If we start playback again after an EOS, make sure we have a new valid + * SurfaceTextureClientHybris instance to use and pass to the decoder. + */ + if (!sink->surface_texture_client && sink->texture_id > 0) { + GST_DEBUG_OBJECT (sink, "Creating new SurfaceTextureClientHybris instance"); + gst_mir_sink_create_surface_texture (G_OBJECT (bsink)); + } +#if 0 + /* If we are using a texture_id, there's no need to use the Ubuntu + * Platform API to create an EGLNativeWindowType */ + if (sink->texture_id) + return TRUE; + + /* Create a new Ubuntu Application API session */ + if (sink->session == NULL) + sink->session = create_session (); + + if (sink->session == NULL) { + GST_ELEMENT_ERROR (bsink, RESOURCE, OPEN_READ_WRITE, + ("Could not initialize Mir output"), + ("Could not start a Mir app session")); + return FALSE; + } + + if (sink->display == NULL) + sink->display = create_display (); + + if (sink->display == NULL) { + GST_ELEMENT_ERROR (bsink, RESOURCE, OPEN_READ_WRITE, + ("Could not initialize Mir output"), + ("Could not create a Mir display")); + return FALSE; + } + + /* Create an EGLNativeWindowType instance so that a pure playbin + * scenario will render video */ + if (sink->window == NULL) { + sink->video_width = sink->display->width; + sink->video_height = sink->display->height; + GST_DEBUG_OBJECT (sink, "video_width: %d, video_height: %d", + sink->video_width, sink->video_height); + create_window (sink, sink->display, sink->video_width, sink->video_height); + sink->surface_texture_client = + surface_texture_client_create (sink->window->egl_native_window); + } +#endif + + return TRUE; +} + +static gboolean +gst_mir_sink_stop (GstBaseSink * bsink) +{ + GstMirSink *sink = (GstMirSink *) bsink; + + GST_DEBUG_OBJECT (sink, "stop"); + + /* MediaCodec (hybris layer) will destroy the underlying + * SurfaceTextureClientHybris instance, * so set it to NULL here so that + * we don't point to an invalid instance. + */ + sink->surface_texture_client = NULL; + + return TRUE; +} + +static gboolean +gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) +{ + GstMirSink *sink = GST_MIR_SINK (bsink); + GstBufferPool *pool; + GstStructure *config; + GstCaps *caps; + guint size = 0; + gboolean need_pool; + GstAllocator *allocator; + GstAllocationParams params; + + GST_DEBUG_OBJECT (sink, "Proposing ALLOCATION params"); + + gst_allocation_params_init (¶ms); + + gst_query_parse_allocation (query, &caps, &need_pool); + if (!caps) + goto no_caps; + + GST_OBJECT_LOCK (sink); + pool = sink->pool ? gst_object_ref (sink->pool) : NULL; + GST_OBJECT_UNLOCK (sink); + + GST_DEBUG_OBJECT (sink, "pool: %p, need_pool: %d", pool, need_pool); + + if (pool) { + GstCaps *pcaps; + GST_WARNING_OBJECT (sink, "already have a pool"); + + /* We had a pool, check caps */ + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL); + + if (!gst_caps_is_equal (caps, pcaps)) { + /* Different caps, we can't use this pool */ + gst_object_unref (pool); + pool = NULL; + } + gst_structure_free (config); + } + + if (pool == NULL && need_pool) { + GstVideoInfo info; + info.size = 0; + + if (!gst_video_info_from_caps (&info, caps)) + goto invalid_caps; + + GST_DEBUG_OBJECT (sink, "size: %d", size); + GST_DEBUG_OBJECT (sink, "caps %" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (sink, "create new pool"); + pool = gst_mir_buffer_pool_new (sink); + + /* The normal size of a frame */ + size = (info.size == 0) ? info.height * info.width : info.size; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, size, 2, 0); + if (!gst_buffer_pool_set_config (pool, config)) + goto config_failed; + } + + if (pool) { + /* We are doing hardware rendering */ + gst_mir_buffer_pool_set_hardware_rendering (pool, TRUE); + + // FIXME: How many buffers min do we need? It's 2 right now. + GST_DEBUG_OBJECT (sink, "size: %d", size); + GST_DEBUG_OBJECT (sink, "adding allocation pool"); + gst_query_add_allocation_pool (query, pool, size, 2, 0); + gst_object_unref (pool); + } + + /* First the default allocator */ + if (!gst_mir_image_memory_is_mappable ()) { + allocator = gst_allocator_find (NULL); + gst_query_add_allocation_param (query, allocator, ¶ms); + gst_object_unref (allocator); + } + + allocator = gst_mir_image_allocator_obtain (); + if (!gst_mir_image_memory_is_mappable ()) + params.flags |= GST_MEMORY_FLAG_NOT_MAPPABLE; + gst_query_add_allocation_param (query, allocator, ¶ms); + gst_object_unref (allocator); + + //gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + + return TRUE; + + /* ERRORS */ +no_caps: + { + GST_DEBUG_OBJECT (bsink, "no caps specified"); + return FALSE; + } +invalid_caps: + { + GST_DEBUG_OBJECT (bsink, "invalid caps specified"); + return FALSE; + } +config_failed: + { + GST_DEBUG_OBJECT (bsink, "failed setting config"); + gst_object_unref (pool); + return FALSE; + } +} + +static GstFlowReturn +gst_mir_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer) +{ + GST_DEBUG_OBJECT (bsink, "preroll buffer %p", buffer); + return gst_mir_sink_render (bsink, buffer); +} + +static GstFlowReturn +gst_mir_sink_render (GstBaseSink * bsink, GstBuffer * buffer) +{ + GstMirSink *sink = GST_MIR_SINK (bsink); + //GstVideoRectangle src, dst, res; + GstBuffer *to_render; + GstMirMeta *meta; + //GstFlowReturn ret; + + GST_DEBUG_OBJECT (sink, "render buffer %p", buffer); + + meta = gst_buffer_get_mir_meta (buffer); + + if (meta && meta->sink == sink) { + GST_LOG_OBJECT (sink, "buffer %p from our pool, writing directly", buffer); + to_render = buffer; + } else { + //GstMapInfo src; + GST_LOG_OBJECT (sink, "buffer %p not from our pool, copying", buffer); + to_render = buffer; + +#if 0 + if (!sink->pool) + goto no_pool; + + if (!gst_buffer_pool_set_active (sink->pool, TRUE)) + goto activate_failed; + + ret = gst_buffer_pool_acquire_buffer (sink->pool, &to_render, NULL); + if (ret != GST_FLOW_OK) + goto no_buffer; + + gst_buffer_map (buffer, &src, GST_MAP_READ); + gst_buffer_fill (to_render, 0, src.data, src.size); + gst_buffer_unmap (buffer, &src); + + meta = gst_buffer_get_mir_meta (to_render); +#endif + } + + g_signal_emit (G_OBJECT (bsink), frame_ready_signal, 0); + +#if 0 + src.w = sink->video_width; + src.h = sink->video_height; + dst.w = sink->window->width; + dst.h = sink->window->height; + + gst_video_sink_center_rect (src, dst, &res, FALSE); +#endif + + if (buffer != to_render) + gst_buffer_unref (to_render); + return GST_FLOW_OK; + +#if 0 +no_buffer: + { + GST_WARNING_OBJECT (sink, "could not create image"); + return ret; + } +no_pool: + { + GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, + ("Internal error: can't allocate images"), + ("We don't have a bufferpool negotiated")); + return GST_FLOW_ERROR; + } +activate_failed: + { + GST_ERROR_OBJECT (sink, "failed to activate bufferpool."); + ret = GST_FLOW_ERROR; + return ret; + } +#endif +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gstmir_debug, "mirsink", 0, " mir video sink"); + + return gst_element_register (plugin, "mirsink", GST_RANK_MARGINAL, + GST_TYPE_MIR_SINK); +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + mirsink, + "Mir Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, + GST_PACKAGE_ORIGIN) diff --git a/ext/mir/gstmirsink.h b/ext/mir/gstmirsink.h new file mode 100644 index 0000000..3dbf4c8 --- /dev/null +++ b/ext/mir/gstmirsink.h @@ -0,0 +1,130 @@ +/* + * GStreamer Mir video sink + * Copyright (C) 2013 Canonical Ltd + * + * 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 3 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __GST_MIR_VIDEO_SINK_H__ +#define __GST_MIR_VIDEO_SINK_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +//#include + +#define GST_TYPE_MIR_SINK \ + (gst_mir_sink_get_type()) +#define GST_MIR_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MIR_SINK,GstMirSink)) +#define GST_MIR_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MIR_SINK,GstMirSinkClass)) +#define GST_IS_MIR_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MIR_SINK)) +#define GST_IS_MIR_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MIR_SINK)) +#define GST_MIR_SINK_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_MIR_SINK, GstMirSinkClass)) + +typedef struct _GstMirSink GstMirSink; +typedef struct _GstMirSinkClass GstMirSinkClass; + +#include "mirpool.h" + +struct session +{ + UAUiSession *session; + UAUiSessionProperties *properties; + + UApplicationDescription *app_description; + UApplicationOptions *app_options; + UApplicationInstance *app_instance; + UApplicationLifecycleDelegate *app_lifecycle_delegate; +}; + +struct display +{ + UAUiDisplay *display; + int width; + int height; + uint32_t formats; +}; + +struct window +{ + struct display *display; + int width; + int height; + UAUiWindow *window; + UAUiWindowProperties *properties; + EGLNativeWindowType egl_native_window; +}; + +struct _GstMirSink +{ + GstVideoSink parent; + + GstContext * context; + SurfaceTextureClientHybris surface_texture_client; + + struct session *session; + struct display *display; + struct window *window; + + guint texture_id; + + GstBufferPool *pool; + + GMutex mir_lock; + + gint video_width; + gint video_height; +}; + +struct _GstMirSinkClass +{ + GstVideoSinkClass parent; + + void (*frame_ready_changed) (GstMirSink *sink, gpointer renderer); + void (*surface_texture_client_changed) (GstMirSink *sink, gpointer surface_texture_client, gpointer renderer); +}; + +GType gst_mir_sink_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GST_MIR_VIDEO_SINK_H__ */ diff --git a/ext/mir/mirpool.c b/ext/mir/mirpool.c new file mode 100644 index 0000000..d802dc0 --- /dev/null +++ b/ext/mir/mirpool.c @@ -0,0 +1,434 @@ +/* + * GStreamer Mir buffer pool + * Copyright (C) 2013 Canonical Ltd + + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Object header */ +#include "gstmirsink.h" +#include "mirpool.h" + +#include + +/* Debugging category */ +#include + +/* Helper functions */ +#include +#include +#include + +GST_DEBUG_CATEGORY (gstmirbufferpool_debug); +#define GST_CAT_DEFAULT gstmirbufferpool_debug + +/* mir metadata */ +GType +gst_mir_meta_api_get_type (void) +{ + static volatile GType type; + static const gchar *tags[] = + { "memory", "size", "colorspace", "orientation", NULL }; + + if (g_once_init_enter (&type)) { + GType _type = gst_meta_api_type_register ("GstMirMetaAPI", tags); + g_once_init_leave (&type, _type); + } + return type; +} + +static void +gst_mir_meta_free (GstMirMeta * meta, GstBuffer * buffer) +{ + gst_object_unref (meta->sink); +} + +const GstMetaInfo * +gst_mir_meta_get_info (void) +{ + static const GstMetaInfo *mir_meta_info = NULL; + + if (g_once_init_enter (&mir_meta_info)) { + const GstMetaInfo *meta = + gst_meta_register (GST_MIR_META_API_TYPE, "GstMirMeta", + sizeof (GstMirMeta), (GstMetaInitFunction) NULL, + (GstMetaFreeFunction) gst_mir_meta_free, + (GstMetaTransformFunction) NULL); + g_once_init_leave (&mir_meta_info, meta); + } + return mir_meta_info; +} + +/* bufferpool */ +static void gst_mir_buffer_pool_finalize (GObject * object); + +#define gst_mir_buffer_pool_parent_class parent_class +G_DEFINE_TYPE (GstMirBufferPool, gst_mir_buffer_pool, GST_TYPE_BUFFER_POOL); + +static gboolean +mir_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) +{ + GstMirBufferPool *mpool = GST_MIR_BUFFER_POOL_CAST (pool); + GstVideoInfo info; + GstCaps *caps; + + GST_DEBUG_OBJECT (mpool, "%s", __PRETTY_FUNCTION__); + + if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) + goto wrong_config; + + if (caps == NULL) + goto no_caps; + + if (mpool->allocator) + gst_object_unref (mpool->allocator); + mpool->allocator = NULL; + + /* now parse the caps from the config */ + if (!gst_video_info_from_caps (&info, caps)) + goto wrong_caps; + + if (!gst_buffer_pool_config_get_allocator (config, &mpool->allocator, + &mpool->params)) + return FALSE; + if (mpool->allocator) + gst_object_ref (mpool->allocator); + + GST_LOG_OBJECT (mpool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, + info.height, caps); + + /*Fixme: Enable metadata checking handling based on the config of pool */ + + mpool->caps = gst_caps_ref (caps); + mpool->info = info; + mpool->width = info.width; + mpool->height = info.height; + + GST_DEBUG_OBJECT (mpool, "Calling set_config() on the parent class"); + return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); + /* ERRORS */ +wrong_config: + { + GST_WARNING_OBJECT (pool, "invalid config"); + return FALSE; + } +no_caps: + { + GST_WARNING_OBJECT (pool, "no caps in config"); + return FALSE; + } +wrong_caps: + { + GST_WARNING_OBJECT (pool, + "failed getting geometry from caps %" GST_PTR_FORMAT, caps); + return FALSE; + } +} + +static GstMirMeta * +gst_buffer_add_mir_meta (GstBuffer * buffer, GstMirBufferPool * mpool) +{ + GstMirMeta *mmeta; + GstMirSink *sink; + guint stride = 0; + guint size = 0; + + sink = mpool->sink; + stride = mpool->width * 4; + size = stride * mpool->height; + + GST_DEBUG_OBJECT (mpool, "%s", __PRETTY_FUNCTION__); + + /* Add metadata so that the render function can tell the difference between a zero-copy + * rendering buffer vs one that it must manually copy through the main CPU */ + mmeta = (GstMirMeta *) gst_buffer_add_meta (buffer, GST_MIR_META_INFO, NULL); + mmeta->sink = gst_object_ref (sink); + + mmeta->size = size; + mmeta->hardware_rendering = + gst_mir_buffer_pool_get_hardware_rendering (mpool); + + return mmeta; +} + +// FIXME: rename this function since it no longer makes sense +static GstBuffer * +gst_mir_allocate_native_window_buffer (GstBufferPool * pool, + GstAllocator * allocator, GstBufferPoolAcquireParams * params, + GstVideoFormat format, gint width, gint height) +{ + GstMirBufferPool *m_pool = GST_MIR_BUFFER_POOL_CAST (pool); + GstBuffer *buffer; + GstMemory *mem = { NULL }; + gsize size = 0; + gint stride = 0; + GstMemoryFlags flags = 0; + + GST_DEBUG_OBJECT (pool, "%s", __PRETTY_FUNCTION__); + + if (!gst_mir_image_memory_is_mappable ()) + flags |= GST_MEMORY_FLAG_NOT_MAPPABLE; + + flags |= GST_MEMORY_FLAG_NO_SHARE; + + switch (format) { + gsize buffer_id = 0; + + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + case GST_VIDEO_FORMAT_RGB16: + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_AYUV: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_Y41B:{ + + GST_WARNING_OBJECT (m_pool, + "Allocating new Mir image, height: %d, width: %d, size: %d", height, + width, size); + + /* A fallback to make sure we have a size (taken from OMXCodec.cpp + * in the JB 4.2 sources) + */ + if (size == 0) + size = (height * width * 3) / 2; + + stride = size / height; + size = stride * height; + + GST_WARNING_OBJECT (m_pool, "stride: %d, size: %d", stride, size); + + buffer_id = 0; + + GST_WARNING_OBJECT (m_pool, "Allocating new buffer memory of size: %d", + size); + mem = + gst_mir_image_allocator_wrap (allocator, m_pool->codec_delegate, + buffer_id, flags, size, m_pool->hardware_rendering, NULL, NULL); + if (mem == NULL) + GST_WARNING_OBJECT (m_pool, "mem is NULL!"); + + break; + } + default: + GST_WARNING_OBJECT (m_pool, + "Using the default buffer allocator, hit the default case"); + if (GST_BUFFER_POOL_CLASS (gst_mir_buffer_pool_parent_class)->alloc_buffer + (pool, &buffer, params) != GST_FLOW_OK) + return NULL; + break; + } + + buffer = gst_buffer_new (); + if (!buffer) { + GST_WARNING_OBJECT (m_pool, "Fallback memory allocation"); + if (GST_BUFFER_POOL_CLASS (gst_mir_buffer_pool_parent_class)->alloc_buffer + (pool, &buffer, params) != GST_FLOW_OK) + return NULL; + } + + GST_DEBUG ("Appending memory to GstBuffer"); + gst_buffer_append_memory (buffer, mem); + + return buffer; +} + +static GstFlowReturn +mir_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, + GstBufferPoolAcquireParams * params) +{ + GstMirBufferPool *m_pool = GST_MIR_BUFFER_POOL_CAST (pool); + GstMirMeta *meta; + + GST_DEBUG_OBJECT (m_pool, "%s", __PRETTY_FUNCTION__); + + if (m_pool->allocator == NULL) { + GST_ERROR_OBJECT (m_pool, "Can't create buffer, couldn't get allocator"); + return GST_FLOW_ERROR; + } + + GST_WARNING_OBJECT (m_pool, "Height: %d, width: %d", m_pool->height, + m_pool->width); + + *buffer = + gst_mir_allocate_native_window_buffer (pool, m_pool->allocator, params, + m_pool->info.finfo->format, m_pool->width, m_pool->height); + + meta = gst_buffer_add_mir_meta (*buffer, m_pool); + if (meta == NULL) { + gst_buffer_unref (*buffer); + goto no_buffer; + } + + return GST_FLOW_OK; + + /* ERROR */ +no_buffer: + { + GST_WARNING_OBJECT (pool, "can't create buffer"); + return GST_FLOW_ERROR; + } +} + +static void +gst_mir_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer) +{ + GstMemory *mem = { NULL }; + int err = 0; + MediaCodecDelegate delegate; + + /* Get access to the GstMemory stored in the GstBuffer */ + if (gst_buffer_n_memory (buffer) >= 1 && + (mem = gst_buffer_peek_memory (buffer, 0)) + && gst_is_mir_image_memory (mem)) { + GST_DEBUG_OBJECT (pool, "It is Mir image memory"); + } else + GST_DEBUG_OBJECT (pool, "It is NOT Mir image memory"); + + delegate = gst_mir_image_memory_get_codec (mem); + if (!delegate) { + GST_WARNING_OBJECT (pool, "delegate is NULL, rendering will not function"); + goto done; + } + + GST_DEBUG_OBJECT (pool, "mem: %p", mem); + GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_codec (mem): %p", delegate); + GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_buffer_index (mem): %d", + gst_mir_image_memory_get_buffer_index (mem)); + GST_DEBUG_OBJECT (pool, "Rendering buffer: %d", + gst_mir_image_memory_get_buffer_index (mem)); + GST_DEBUG_OBJECT (pool, "Releasing output buffer index: %d", + gst_mir_image_memory_get_buffer_index (mem)); + + /* Render and release the output buffer back to the decoder */ + err = + media_codec_release_output_buffer (delegate, + gst_mir_image_memory_get_buffer_index (mem), TRUE); + if (err < 0) + GST_WARNING_OBJECT (pool, + "Failed to release output buffer. Rendering will probably be affected (err: %d).", + err); + +done: + GST_BUFFER_POOL_CLASS (parent_class)->release_buffer (pool, buffer); +} + +GstBufferPool * +gst_mir_buffer_pool_new (GstMirSink * mirsink) +{ + GstMirBufferPool *m_pool; + + GST_WARNING ("%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (GST_IS_MIR_SINK (mirsink), NULL); + m_pool = g_object_new (GST_TYPE_MIR_BUFFER_POOL, NULL); + m_pool->sink = gst_object_ref (mirsink); + + return GST_BUFFER_POOL_CAST (m_pool); +} + +void +gst_mir_buffer_pool_set_surface_texture_client (GstBufferPool * pool, + SurfaceTextureClientHybris sfc) +{ + GstMirBufferPool *m_pool = GST_MIR_BUFFER_POOL_CAST (pool); + + GST_DEBUG_OBJECT (m_pool, "%s", __PRETTY_FUNCTION__); + m_pool->surface_texture_client = sfc; +} + +void +gst_mir_buffer_pool_set_hardware_rendering (GstBufferPool * pool, + gboolean do_hardware_rendering) +{ + GstMirBufferPool *m_pool = NULL; + g_return_if_fail (GST_IS_MIR_BUFFER_POOL (pool)); + + m_pool = GST_MIR_BUFFER_POOL_CAST (pool); + + GST_DEBUG_OBJECT (m_pool, "%s", __PRETTY_FUNCTION__); + m_pool->hardware_rendering = do_hardware_rendering; +} + +gboolean +gst_mir_buffer_pool_get_hardware_rendering (GstMirBufferPool * mpool) +{ + g_return_val_if_fail (mpool != NULL, FALSE); + return mpool->hardware_rendering; +} + +void +gst_mir_buffer_pool_set_codec_delegate (GstBufferPool * pool, + MediaCodecDelegate * delegate) +{ + GstMirBufferPool *m_pool = NULL; + g_return_if_fail (GST_IS_MIR_BUFFER_POOL (pool)); + + m_pool = GST_MIR_BUFFER_POOL_CAST (pool); + + GST_DEBUG_OBJECT (m_pool, "%s", __PRETTY_FUNCTION__); + m_pool->codec_delegate = delegate; +} + +static void +gst_mir_buffer_pool_class_init (GstMirBufferPoolClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass; + + gobject_class->finalize = gst_mir_buffer_pool_finalize; + + gstbufferpool_class->set_config = mir_buffer_pool_set_config; + gstbufferpool_class->alloc_buffer = mir_buffer_pool_alloc; + gstbufferpool_class->release_buffer = gst_mir_buffer_pool_release_buffer; +} + +static void +gst_mir_buffer_pool_init (GstMirBufferPool * pool) +{ + GST_DEBUG_CATEGORY_INIT (gstmirbufferpool_debug, "mirbufferpool", 0, + " mir buffer pool"); + + pool->surface_texture_client = NULL; + pool->codec_delegate = NULL; + pool->hardware_rendering = FALSE; +} + +static void +gst_mir_buffer_pool_finalize (GObject * object) +{ + GstMirBufferPool *pool = GST_MIR_BUFFER_POOL_CAST (object); + + GST_DEBUG_OBJECT (pool, "%s", __PRETTY_FUNCTION__); + gst_object_unref (pool->sink); + + G_OBJECT_CLASS (gst_mir_buffer_pool_parent_class)->finalize (object); +} diff --git a/ext/mir/mirpool.h b/ext/mir/mirpool.h new file mode 100644 index 0000000..3853aa8 --- /dev/null +++ b/ext/mir/mirpool.h @@ -0,0 +1,91 @@ +/* + * GStreamer Mir buffer pool + * Copyright (C) 2013 Canonical Ltd + * + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_MIR_BUFFER_POOL_H__ +#define __GST_MIR_BUFFER_POOL_H__ + +G_BEGIN_DECLS + +#include "gstmirsink.h" +#include +#include +typedef struct _GstMirMeta GstMirMeta; + +typedef struct _GstMirBufferPool GstMirBufferPool; +typedef struct _GstMirBufferPoolClass GstMirBufferPoolClass; + +GType gst_mir_meta_api_get_type (void); +#define GST_MIR_META_API_TYPE (gst_mir_meta_api_get_type()) +const GstMetaInfo * gst_mir_meta_get_info (void); +#define GST_MIR_META_INFO (gst_mir_meta_get_info()) + +#define gst_buffer_get_mir_meta(b) ((GstMirMeta*)gst_buffer_get_meta((b),GST_MIR_META_API_TYPE)) + +struct _GstMirMeta { + GstMeta meta; + + GstMirSink *sink; + + size_t size; + /* Are we doing hardware rendering? */ + gboolean hardware_rendering; +}; + +/* buffer pool functions */ +#define GST_TYPE_MIR_BUFFER_POOL (gst_mir_buffer_pool_get_type()) +#define GST_IS_MIR_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIR_BUFFER_POOL)) +#define GST_MIR_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIR_BUFFER_POOL, GstMirBufferPool)) +#define GST_MIR_BUFFER_POOL_CAST(obj) ((GstMirBufferPool*)(obj)) + +struct _GstMirBufferPool +{ + GstBufferPool bufferpool; + + GstMirSink *sink; + + /*Fixme: keep all these in GstMirBufferPoolPrivate*/ + GstCaps *caps; + GstVideoInfo info; + guint width; + guint height; + GstAllocator *allocator; + GstAllocationParams params; + SurfaceTextureClientHybris surface_texture_client; + MediaCodecDelegate *codec_delegate; + /* Are we doing hardware rendering? */ + gboolean hardware_rendering; +}; + +struct _GstMirBufferPoolClass +{ + GstBufferPoolClass parent_class; +}; + +GType gst_mir_buffer_pool_get_type (void); + +GstBufferPool *gst_mir_buffer_pool_new (GstMirSink * mirsink); +void gst_mir_buffer_pool_set_surface_texture_client (GstBufferPool * pool, SurfaceTextureClientHybris sfc); +void gst_mir_buffer_pool_set_hardware_rendering (GstBufferPool * pool, gboolean do_hardware_rendering); +gboolean gst_mir_buffer_pool_get_hardware_rendering (GstMirBufferPool * mpool); +void gst_mir_buffer_pool_set_codec_delegate (GstBufferPool * pool, MediaCodecDelegate *delegate); + +G_END_DECLS + +#endif /*__GST_MIR_BUFFER_POOL_H__*/ diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 1d6cc35..748105e 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -2,8 +2,12 @@ if HAVE_EGL EGL_DIR = egl endif +if USE_ANDROID_MEDIA_HYBRIS +MIR_DIR = mir +endif + SUBDIRS = interfaces basecamerabinsrc codecparsers \ - insertbin uridownloader mpegts $(EGL_DIR) + insertbin uridownloader mpegts $(EGL_DIR) $(MIR_DIR) noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h DIST_SUBDIRS = interfaces egl basecamerabinsrc codecparsers \ diff --git a/gst-libs/gst/mir/Makefile.am b/gst-libs/gst/mir/Makefile.am new file mode 100644 index 0000000..a2bfe9b --- /dev/null +++ b/gst-libs/gst/mir/Makefile.am @@ -0,0 +1,26 @@ +lib_LTLIBRARIES = libgstmiralloc-@GST_API_VERSION@.la + +libgstmiralloc_@GST_API_VERSION@_la_SOURCES = mirallocator.c gstmircontext.c + +libgstmiralloc_@GST_API_VERSION@includedir = \ + $(includedir)/gstreamer-@GST_API_VERSION@/gst/mir + +libgstmiralloc_@GST_API_VERSION@include_HEADERS = mirallocator.h gstmircontext.h + +libgstmiralloc_@GST_API_VERSION@_la_CFLAGS = \ + $(GST_PLUGINS_BAD_CFLAGS) \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_CFLAGS) \ + $(MIR_CFLAGS) + +libgstmiralloc_@GST_API_VERSION@_la_LIBADD = \ + $(GST_PLUGINS_BASE_LIBS) \ + -lgstvideo-@GST_API_VERSION@ \ + $(GST_LIBS) \ + $(MIR_LIBS) + -lmedia + +libgstmiralloc_@GST_API_VERSION@_la_LDFLAGS = \ + $(GST_LIB_LDFLAGS) \ + $(GST_ALL_LDFLAGS) \ + $(GST_LT_LDFLAGS) diff --git a/gst-libs/gst/mir/gstmircontext.c b/gst-libs/gst/mir/gstmircontext.c new file mode 100644 index 0000000..dbabcd7 --- /dev/null +++ b/gst-libs/gst/mir/gstmircontext.c @@ -0,0 +1,216 @@ +/* + * Provides a struct for transfering context between elements + * Copyright (C) 2013 Collabora Ltd. + * @author: Jim Hodapp + * * + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "gstmircontext.h" + +#include +#include + +#define GST_MIR_TYPE_CONTEXT \ + gst_mir_context_get_type() + +GType +gst_mir_stc_get_type (void) + G_GNUC_CONST; + +G_DEFINE_BOXED_TYPE (GstMirContext, gst_mir_context, + (GBoxedCopyFunc) gst_mir_context_ref, + (GBoxedFreeFunc) gst_mir_context_unref) + + GstMirContext *gst_mir_context_new (GstElement * element, + SurfaceTextureClientHybris surface_texture_client) +{ + GstMirContext *ctx = g_new0 (GstMirContext, 1); + + ctx->element = gst_object_ref (element); + ctx->surface_texture_client = surface_texture_client; + + GST_DEBUG_OBJECT (element, "ctx->surface_texture_client: %p", + ctx->surface_texture_client); + + return ctx; +} + +GstContext * +gst_mir_context_new_with_stc (GstMirContext * gst_mir_context) +{ + GstContext *context; + GstStructure *structure; + + GST_DEBUG_OBJECT (gst_mir_context, + "gst_mir_context->surface_texture_client: %p", + gst_mir_context->surface_texture_client); + + /* Create a new GstContext, not persistent */ + context = gst_context_new (GST_MIR_CONTEXT_TYPE, TRUE); + structure = gst_context_writable_structure (context); + gst_structure_set (structure, "gst_mir_context", GST_MIR_TYPE_CONTEXT, + gst_mir_context, NULL); + return context; +} + +void +gst_mir_context_free (GstMirContext * ctx) +{ + gst_object_unref (ctx->element); + g_free (ctx); +} + +gboolean +gst_is_mir_context (GstContext * ctx) +{ + g_return_val_if_fail (ctx != NULL, FALSE); + return g_strcmp0 (gst_context_get_context_type (ctx), + GST_MIR_CONTEXT_TYPE) == 0; +} + +GstMirContext * +gst_mir_context_ref (GstMirContext * context) +{ + g_return_val_if_fail (context != NULL, NULL); + + g_atomic_int_inc (&context->ref_count); + return context; +} + +void +gst_mir_context_unref (GstMirContext * context) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (context->ref_count > 0); + + if (g_atomic_int_dec_and_test (&context->ref_count)) + gst_mir_context_free (context); +} + +static gboolean +context_pad_query (const GValue * item, GValue * value, gpointer data) +{ + GstPad *const pad = g_value_get_object (item); + GstQuery *const query = data; + + if (gst_pad_peer_query (pad, query)) { + g_value_set_boolean (value, TRUE); + return FALSE; + } + + return TRUE; +} + +static gboolean +do_context_query (GstElement * element, GstQuery * query) +{ + GstIteratorFoldFunction const func = context_pad_query; + GstIterator *it; + GValue res = { 0 }; + + g_value_init (&res, G_TYPE_BOOLEAN); + g_value_set_boolean (&res, FALSE); + + GST_DEBUG_OBJECT (element, "Querying downstream elements for CONTEXT query"); + /* First check downstream elements for a CONTEXT query reply */ + it = gst_element_iterate_src_pads (element); + while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync (it); + + gst_iterator_free (it); + + /* If we got a reply from a downstream element, return success now */ + if (g_value_get_boolean (&res)) + return TRUE; + + GST_DEBUG_OBJECT (element, "Querying upstream elements for CONTEXT query"); + /* Now try upstream elements */ + it = gst_element_iterate_sink_pads (element); + while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC) + gst_iterator_resync (it); + + gst_iterator_free (it); + + return g_value_get_boolean (&res); +} + +void +gst_mir_do_context_query (gpointer element) +{ + GstQuery *query; + GstMessage *msg; + + g_return_if_fail (GST_IS_ELEMENT (element)); + + GST_WARNING_OBJECT (element, "Sending new CONTEXT query"); + /* Get a pointer to a SurfaceTextureClientHybris instance to configure MediaCodec with */ + query = gst_query_new_context (GST_MIR_CONTEXT_TYPE); + if (do_context_query (element, query)) { + GstContext *context = NULL; + + GST_WARNING_OBJECT (element, "Got a successful reply to the CONTEXT query"); + gst_query_parse_context (query, &context); + gst_element_set_context (element, context); + } else { + /* Second, try to get a context from mirsink via a NEED_CONTEXT bus message */ + GST_WARNING_OBJECT (element, "Sending new NEED_CONTEXT bus message"); + msg = gst_message_new_need_context (GST_OBJECT_CAST (element), + GST_MIR_CONTEXT_TYPE); + gst_element_post_message (GST_ELEMENT_CAST (element), msg); + } + gst_query_unref (query); +} + +gboolean +gst_mir_ensure_surface_texture_client (gpointer element) +{ + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + + GST_DEBUG_OBJECT (element, "Calling gst_mir_do_context_query()"); + /* Otherwise check the neighboring elements and app for a GstContext */ + gst_mir_do_context_query (element); + + return TRUE; +} + +SurfaceTextureClientHybris +gst_context_get_surface_texture_client (GstContext * context) //, +// SurfaceTextureClientHybris * surface_texture_client) +{ + const GstStructure *s; + const GstMirContext *gst_mir_context; + SurfaceTextureClientHybris surface_texture_client; + + GST_WARNING_OBJECT (context, "%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); + g_return_val_if_fail (strcmp (gst_context_get_context_type (context), + GST_MIR_CONTEXT_TYPE) == 0, FALSE); + + s = gst_context_get_structure (context); + if (gst_structure_get (s, "gst_mir_context", GST_MIR_TYPE_CONTEXT, + &gst_mir_context, NULL)) { + surface_texture_client = gst_mir_context->surface_texture_client; + GST_DEBUG_OBJECT (context, "gst_mir_context->surface_texture_client: %p", + gst_mir_context->surface_texture_client); + GST_DEBUG_OBJECT (context, "surface_texture_client: %p", + surface_texture_client); + return surface_texture_client; + } + + return NULL; +} diff --git a/gst-libs/gst/mir/gstmircontext.h b/gst-libs/gst/mir/gstmircontext.h new file mode 100644 index 0000000..11655fb --- /dev/null +++ b/gst-libs/gst/mir/gstmircontext.h @@ -0,0 +1,64 @@ +/* + * Provides a struct for transfering context between elements + * Copyright (C) 2013 Collabora Ltd. + * @author: Jim Hodapp + * * + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_MIR_COMMON_H__ +#define __GST_MIR_COMMON_H__ + +#include + +#include + +G_BEGIN_DECLS + +#define GST_MIR_CONTEXT_TYPE "gst.mir.MirContext" + + +typedef struct _GstMirContext GstMirContext; + +struct _GstMirContext +{ + GstElement *element; + volatile gint ref_count; + + SurfaceTextureClientHybris *surface_texture_client; +}; + +#define GST_MIR_CONTEXT(ctx) ((GstMirContext*)(ctx)) + +GType +gst_mir_context_get_type(void) G_GNUC_CONST; + +GstMirContext * gst_mir_context_new (GstElement * element, + SurfaceTextureClientHybris surface_texture_client); +GstContext * gst_mir_context_new_with_stc (GstMirContext * gst_mir_context); +void gst_mir_context_free (GstMirContext * ctx); +gboolean gst_is_mir_context (GstContext * ctx); +GstMirContext * gst_mir_context_ref(GstMirContext *context); +void gst_mir_context_unref(GstMirContext *context); + +/** Gets a context from upstream/downstream peers or from the app **/ +void gst_mir_do_context_query (gpointer element); +gboolean gst_mir_ensure_surface_texture_client (gpointer element); +SurfaceTextureClientHybris gst_context_get_surface_texture_client (GstContext * context); + +G_END_DECLS + +#endif /* __GST_MIR_COMMON_H__ */ diff --git a/gst-libs/gst/mir/mirallocator.c b/gst-libs/gst/mir/mirallocator.c new file mode 100644 index 0000000..bf5d04e --- /dev/null +++ b/gst-libs/gst/mir/mirallocator.c @@ -0,0 +1,274 @@ +/* + * Mir GstMemory allocator + * Copyright (C) 2013 Collabora Ltd. + * @author: Jim Hodapp + * * + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "mirallocator.h" + +#include + +#define GST_MIR_IMAGE_MEMORY(mem) ((GstMirImageMemory*)(mem)) + +gboolean +gst_mir_image_memory_is_mappable (void) +{ + return FALSE; +} + +gboolean +gst_is_mir_image_memory (GstMemory * mem) +{ + g_return_val_if_fail (mem != NULL, FALSE); + g_return_val_if_fail (mem->allocator != NULL, FALSE); + + return g_strcmp0 (mem->allocator->mem_type, GST_MIR_IMAGE_MEMORY_TYPE) == 0; +} + +gsize +gst_mir_image_memory_get_buffer_index (GstMemory * mem) +{ + g_return_val_if_fail (gst_is_mir_image_memory (mem), 0); + + if (mem->parent) + mem = mem->parent; + + return GST_MIR_IMAGE_MEMORY (mem)->buffer_index; +} + +MediaCodecDelegate +gst_mir_image_memory_get_codec (GstMemory * mem) +{ + g_return_val_if_fail (gst_is_mir_image_memory (mem), 0); + + if (mem->parent) + mem = mem->parent; + + return GST_MIR_IMAGE_MEMORY (mem)->codec_delegate; +} + +gboolean +gst_mir_do_hardware_render (GstMemory * mem) +{ + /* Default to doing software render if NULL */ + g_return_val_if_fail (gst_is_mir_image_memory (mem), FALSE); + + if (mem->parent) + mem = mem->parent; + + return GST_MIR_IMAGE_MEMORY (mem)->hardware_rendering; +} + +void +gst_mir_image_memory_set_codec (GstMemory * mem, MediaCodecDelegate delegate) +{ + g_return_if_fail (gst_is_mir_image_memory (mem)); + g_return_if_fail (delegate != NULL); + + if (mem->parent) + mem = mem->parent; + + GST_MIR_IMAGE_MEMORY (mem)->codec_delegate = delegate; +} + +void +gst_mir_image_memory_set_buffer_index (GstMemory * mem, gsize index) +{ + g_return_if_fail (gst_is_mir_image_memory (mem)); + + if (mem->parent) + mem = mem->parent; + + GST_MIR_IMAGE_MEMORY (mem)->buffer_index = index; +} + +static GstMemory * +gst_mir_image_allocator_alloc_vfunc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) +{ + g_warning + ("Use gst_mir_image_allocator_alloc() to allocate from this allocator"); + + return NULL; +} + +static void +gst_mir_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem) +{ + GstMirImageMemory *emem = (GstMirImageMemory *) mem; + GST_WARNING ("%s", __PRETTY_FUNCTION__); + + g_return_if_fail (gst_is_mir_image_memory (mem)); + + /* Shared memory should not destroy all the data */ + if (!mem->parent) { + + if (emem->user_data_destroy) + emem->user_data_destroy (emem->user_data); + } + + g_slice_free (GstMirImageMemory, emem); +} + +static gpointer +gst_mir_image_mem_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) +{ + return NULL; +} + +static void +gst_mir_image_mem_unmap (GstMemory * mem) +{ +} + +static GstMemory * +gst_mir_image_mem_share (GstMemory * mem, gssize offset, gssize size) +{ + GstMemory *sub; + GstMemory *parent; + + GST_WARNING ("%s", __PRETTY_FUNCTION__); + + if (offset != 0) + return NULL; + + if (size != -1 && size != mem->size) + return NULL; + + /* find the real parent */ + if ((parent = mem->parent) == NULL) + parent = (GstMemory *) mem; + + if (size == -1) + size = mem->size - offset; + + sub = (GstMemory *) g_slice_new (GstMirImageMemory); + + /* the shared memory is always readonly */ + gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) | + GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->allocator, parent, + mem->maxsize, mem->align, mem->offset + offset, size); + + return sub; +} + +static GstMemory * +gst_mir_image_mem_copy (GstMemory * mem, gssize offset, gssize size) +{ + return NULL; +} + +static gboolean +gst_mir_image_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) +{ + return FALSE; +} + +typedef GstAllocator GstMirImageAllocator; +typedef GstAllocatorClass GstMirImageAllocatorClass; + +GType gst_mir_image_allocator_get_type (void); +G_DEFINE_TYPE (GstMirImageAllocator, gst_mir_image_allocator, + GST_TYPE_ALLOCATOR); + +#define GST_TYPE_MIR_IMAGE_ALLOCATOR (gst_mir_image_mem_allocator_get_type()) +#define GST_IS_MIR_IMAGE_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIR_IMAGE_ALLOCATOR)) + +static void +gst_mir_image_allocator_class_init (GstMirImageAllocatorClass * klass) +{ + GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass; + + allocator_class->alloc = gst_mir_image_allocator_alloc_vfunc; + allocator_class->free = gst_mir_image_allocator_free_vfunc; +} + +static void +gst_mir_image_allocator_init (GstMirImageAllocator * allocator) +{ + GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); + + alloc->mem_type = GST_MIR_IMAGE_MEMORY_TYPE; + alloc->mem_map = gst_mir_image_mem_map; + alloc->mem_unmap = gst_mir_image_mem_unmap; + alloc->mem_share = gst_mir_image_mem_share; + alloc->mem_copy = gst_mir_image_mem_copy; + alloc->mem_is_span = gst_mir_image_mem_is_span; + + GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); +} + +static gpointer +gst_mir_image_allocator_init_instance (gpointer data) +{ + return g_object_new (gst_mir_image_allocator_get_type (), NULL); +} + +GstAllocator * +gst_mir_image_allocator_obtain (void) +{ + static GOnce once = G_ONCE_INIT; + + g_once (&once, gst_mir_image_allocator_init_instance, NULL); + + g_return_val_if_fail (once.retval != NULL, NULL); + + return GST_ALLOCATOR (g_object_ref (once.retval)); +} + +GstMemory * +gst_mir_image_allocator_alloc (GstAllocator * allocator, + gint width, gint height, gsize * size) +{ + GST_WARNING ("%s", __PRETTY_FUNCTION__); + return NULL; +} + +GstMemory * +gst_mir_image_allocator_wrap (GstAllocator * allocator, + MediaCodecDelegate delegate, gsize buffer_id, GstMemoryFlags flags, + gsize size, gboolean do_hardware_render, gpointer user_data, + GDestroyNotify user_data_destroy) +{ + GstMirImageMemory *mem; + + GST_WARNING ("%s", __PRETTY_FUNCTION__); + GST_WARNING ("size: %d", size); + GST_WARNING ("delegate: %p", delegate); + + if (!allocator) { + allocator = gst_mir_image_allocator_obtain (); + } + mem = g_slice_new (GstMirImageMemory); + // FIXME: calling gst_mir_image_allocator_obtain() is a hack to select my allocator, this really + // should be selected automatically by the decoder. This selection is not working correctly yet. + gst_memory_init (GST_MEMORY_CAST (mem), flags, + gst_mir_image_allocator_obtain (), NULL, size, 0, 0, size); + + mem->codec_delegate = delegate; + mem->buffer_index = buffer_id; + mem->hardware_rendering = do_hardware_render; + mem->user_data = user_data; + mem->user_data_destroy = user_data_destroy; + + return GST_MEMORY_CAST (mem); +} diff --git a/gst-libs/gst/mir/mirallocator.h b/gst-libs/gst/mir/mirallocator.h new file mode 100644 index 0000000..efe3fe0 --- /dev/null +++ b/gst-libs/gst/mir/mirallocator.h @@ -0,0 +1,69 @@ +/* + * Mir GstMemory allocator + * Copyright (C) 2013 Collabora Ltd. + * @author: Jim Hodapp + * * + * 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 3 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_MIR_ALLOCATOR_H__ +#define __GST_MIR_ALLOCATOR_H__ + +#include +#include +#include +#include + +#include +#include + +#define GST_MIR_IMAGE_MEMORY_TYPE "MirImage" + +#define GST_CAPS_FEATURE_MEMORY_MIR_IMAGE "memory:MirImage" + +typedef struct _GstMirDisplay GstMirDisplay; + +typedef struct +{ + GstMemory parent; + + MediaCodecDelegate codec_delegate; + gsize buffer_index; + + gboolean hardware_rendering; + + gpointer user_data; + GDestroyNotify user_data_destroy; +} GstMirImageMemory; + +/* MirImage GstMemory handling */ +gboolean gst_mir_image_memory_is_mappable (void); +gboolean gst_is_mir_image_memory (GstMemory * mem); +gsize gst_mir_image_memory_get_buffer_index (GstMemory * mem); +MediaCodecDelegate gst_mir_image_memory_get_codec (GstMemory * mem); +gboolean gst_mir_do_hardware_render(GstMemory * mem); +void gst_mir_image_memory_set_codec (GstMemory * mem, MediaCodecDelegate delegate); +void gst_mir_image_memory_set_buffer_index (GstMemory * mem, gsize index); + +/* Generic MirImage allocator that doesn't support mapping, copying or anything */ +GstAllocator *gst_mir_image_allocator_obtain (void); +GstMemory *gst_mir_image_allocator_alloc (GstAllocator * allocator, + gint width, gint height, gsize * size); +GstMemory *gst_mir_image_allocator_wrap (GstAllocator * allocator, MediaCodecDelegate delegate, + gsize buffer_id, GstMemoryFlags flags, gsize size, gboolean do_hardware_render, + gpointer user_data, GDestroyNotify user_data_destroy); + +#endif /* __GST_MIR_ALLOCATOR_H__ */ diff --git a/sys/Makefile.am b/sys/Makefile.am index b1abda6..e5bf070 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -10,6 +10,12 @@ else ANDROID_MEDIA_DIR= endif +if USE_ANDROID_MEDIA_HYBRIS +ANDROID_MEDIA_DIR=androidmedia +else +ANDROID_MEDIA_DIR= +endif + if USE_APPLE_MEDIA APPLE_MEDIA_DIR=applemedia applemedia-nonpublic else diff --git a/sys/androidmedia/Makefile.am b/sys/androidmedia/Makefile.am index fba8777..6c49647 100644 --- a/sys/androidmedia/Makefile.am +++ b/sys/androidmedia/Makefile.am @@ -1,9 +1,16 @@ plugin_LTLIBRARIES = libgstandroidmedia.la +if USE_ANDROID_MEDIA_HYBRIS +libgstandroidmedia_la_SOURCES = \ + gstamchybris.c \ + gstamcaudiodechybris.c \ + gstamcvideodechybris.c +else libgstandroidmedia_la_SOURCES = \ gstamc.c \ gstamcaudiodec.c \ gstamcvideodec.c +endif noinst_HEADERS = \ gstamc.h \ @@ -12,18 +19,22 @@ noinst_HEADERS = \ gstamcvideodec.h libgstandroidmedia_la_CFLAGS = \ + $(GST_PLUGINS_BAD_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \ $(GST_CFLAGS) \ $(ORC_CFLAGS) libgstandroidmedia_la_LIBADD = \ + $(GST_PLUGINS_BAD_LIBS) \ $(GST_PLUGINS_BASE_LIBS) \ -lgstaudio-@GST_API_VERSION@ \ -lgstpbutils-@GST_API_VERSION@ \ -lgstvideo-@GST_API_VERSION@ \ + -lmedia \ $(GST_BASE_LIBS) \ $(GST_LIBS) \ - $(ORC_LIBS) + $(ORC_LIBS) \ + $(top_builddir)/gst-libs/gst/mir/libgstmiralloc-@GST_API_VERSION@.la libgstandroidmedia_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstandroidmedia_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) @@ -34,7 +45,7 @@ Android.mk: Makefile.am $(BUILT_SOURCES) -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ -:SOURCES $(libgstandroidmedia_la_SOURCES) \ $(nodist_libgstandroidmedia_la_SOURCES) \ - -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstandroidmedia_la_CFLAGS) \ + -:CPPFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstandroidmedia_la_CFLAGS) \ -:LDFLAGS $(libgstandroidmedia_la_LDFLAGS) \ $(libgstandroidmedia_la_LIBADD) \ -ldl \ diff --git a/sys/androidmedia/gstamc-constants.h b/sys/androidmedia/gstamc-constants.h index f263cdd..7eecc7d 100644 --- a/sys/androidmedia/gstamc-constants.h +++ b/sys/androidmedia/gstamc-constants.h @@ -93,11 +93,15 @@ enum COLOR_Format24BitARGB6666 = 42, COLOR_Format24BitABGR6666 = 43, COLOR_FormatAndroidOpaque = 0x7F000789, + /* From hardware/ti/omap4xxx/domx/omx_core/inc/OMX_TI_IVCommon.h */ + COLOR_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x100, COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100, COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00, COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7fa30c03, /* From hardware/ti/omap4xxx/domx/omx_core/inc/OMX_TI_IVCommon.h */ - COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001 + COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001, + COLOR_EXYNOS_FormatNV12Tiled = 0x7fc00002, + COLOR_EXYNOS_FormatNV21Linear = 0x7f000011 }; enum diff --git a/sys/androidmedia/gstamc.h b/sys/androidmedia/gstamc.h index b48a3ee..da0d7d3 100644 --- a/sys/androidmedia/gstamc.h +++ b/sys/androidmedia/gstamc.h @@ -24,10 +24,54 @@ #include #include #include +#ifdef HAVE_ANDROID_MEDIA #include +#endif + +#ifdef HAVE_ANDROID_MEDIA_HYBRIS +#include +#include + +#include +#include +#include +#include +#endif G_BEGIN_DECLS +#ifdef HAVE_ANDROID_MEDIA_HYBRIS +struct ua_session +{ + UAUiSession *session; + UAUiSessionProperties *properties; + + UApplicationDescription *app_description; + UApplicationOptions *app_options; + UApplicationId *app_id; + UApplicationInstance *app_instance; + UApplicationLifecycleDelegate *app_lifecycle_delegate; +}; + +struct ua_display +{ + UAUiDisplay *display; + int width; + int height; + uint32_t formats; +}; + +struct ua_window +{ + struct ua_display *display; + int width; + int height; + UAUiWindow *window; + UAUiWindowProperties *properties; + EGLNativeWindowType egl_native_window; +}; +#endif + typedef struct _GstAmcCodecInfo GstAmcCodecInfo; typedef struct _GstAmcCodecType GstAmcCodecType; typedef struct _GstAmcCodec GstAmcCodec; @@ -56,19 +100,34 @@ struct _GstAmcCodecInfo { }; struct _GstAmcBuffer { +#ifdef HAVE_ANDROID_MEDIA jobject object; /* global reference */ +#endif guint8 *data; gsize size; }; struct _GstAmcFormat { +#ifdef HAVE_ANDROID_MEDIA /* < private > */ jobject object; /* global reference */ +#endif + MediaFormat format; }; struct _GstAmcCodec { +#ifdef HAVE_ANDROID_MEDIA /* < private > */ jobject object; /* global reference */ +#endif +#ifdef HAVE_ANDROID_MEDIA_HYBRIS + MediaCodecDelegate *codec_delegate; + SurfaceTextureClientHybris surface_texture_client; + struct ua_session *session; + struct ua_display *display; + struct ua_window *window; + guint texture_id; +#endif }; struct _GstAmcBufferInfo { @@ -83,7 +142,14 @@ extern GQuark gst_amc_codec_info_quark; GstAmcCodec * gst_amc_codec_new (const gchar *name); void gst_amc_codec_free (GstAmcCodec * codec); +#ifdef HAVE_ANDROID_MEDIA_HYBRIS +gboolean gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format, SurfaceTextureClientHybris stc, gint flags); +gboolean gst_amc_codec_set_surface_texture_client (GstAmcCodec * codec, SurfaceTextureClientHybris stc); +SurfaceTextureClientHybris gst_amc_codec_get_surface_texture_client (GstAmcCodec * codec); +#else gboolean gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format, gint flags); +#endif +gboolean gst_amc_codec_queue_csd (GstAmcCodec * codec, GstAmcFormat * format); GstAmcFormat * gst_amc_codec_get_output_format (GstAmcCodec * codec); gboolean gst_amc_codec_start (GstAmcCodec * codec); @@ -99,8 +165,11 @@ gint gst_amc_codec_dequeue_input_buffer (GstAmcCodec * codec, gint64 timeoutUs); gint gst_amc_codec_dequeue_output_buffer (GstAmcCodec * codec, GstAmcBufferInfo *info, gint64 timeoutUs); gboolean gst_amc_codec_queue_input_buffer (GstAmcCodec * codec, gint index, const GstAmcBufferInfo *info); +#ifdef HAVE_ANDROID_MEDIA_HYBRIS +gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, gboolean render); +#else gboolean gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index); - +#endif GstAmcFormat * gst_amc_format_new_audio (const gchar *mime, gint sample_rate, gint channels); GstAmcFormat * gst_amc_format_new_video (const gchar *mime, gint width, gint height); @@ -119,6 +188,10 @@ void gst_amc_format_set_string (GstAmcFormat *format, const gchar *key, const gc gboolean gst_amc_format_get_buffer (GstAmcFormat *format, const gchar *key, guint8 **data, gsize *size); void gst_amc_format_set_buffer (GstAmcFormat *format, const gchar *key, guint8 *data, gsize size); +#ifdef HAVE_ANDROID_MEDIA_HYBRIS +void gst_amc_surface_texture_client_set_hardware_rendering (SurfaceTextureClientHybris stc, gboolean hardware_rendering); +#endif + GstVideoFormat gst_amc_color_format_to_video_format (gint color_format); gint gst_amc_video_format_to_color_format (GstVideoFormat video_format); diff --git a/sys/androidmedia/gstamcaudiodechybris.c b/sys/androidmedia/gstamcaudiodechybris.c new file mode 100644 index 0000000..8cd08a8 --- /dev/null +++ b/sys/androidmedia/gstamcaudiodechybris.c @@ -0,0 +1,1292 @@ +/* + * Initially based on gst-omx/omx/gstomxvideodec.c + * + * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. + * Author: Sebastian Dröge , Collabora Ltd. + * + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge + * + * 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 + * version 2.1 of the License. + * + * 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 + +#ifdef HAVE_ORC +#include +#else +#define orc_memcpy memcpy +#endif + +#include "gstamcaudiodec.h" +#include "gstamc-constants.h" + +GST_DEBUG_CATEGORY_STATIC (gst_amc_audio_dec_debug_category); +#define GST_CAT_DEFAULT gst_amc_audio_dec_debug_category + +/* prototypes */ +static void gst_amc_audio_dec_finalize (GObject * object); + +static GstStateChangeReturn +gst_amc_audio_dec_change_state (GstElement * element, + GstStateChange transition); + +static gboolean gst_amc_audio_dec_open (GstAudioDecoder * decoder); +static gboolean gst_amc_audio_dec_close (GstAudioDecoder * decoder); +static gboolean gst_amc_audio_dec_start (GstAudioDecoder * decoder); +static gboolean gst_amc_audio_dec_stop (GstAudioDecoder * decoder); +static gboolean gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, + GstCaps * caps); +static void gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard); +static GstFlowReturn gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, + GstBuffer * buffer); + +static GstFlowReturn gst_amc_audio_dec_drain (GstAmcAudioDec * self); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +static void gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass); +static void gst_amc_audio_dec_init (GstAmcAudioDec * self); +static void gst_amc_audio_dec_base_init (gpointer g_class); + +static GstAudioDecoderClass *parent_class = NULL; + +GType +gst_amc_audio_dec_get_type (void) +{ + static volatile gsize type = 0; + + if (g_once_init_enter (&type)) { + GType _type; + static const GTypeInfo info = { + sizeof (GstAmcAudioDecClass), + gst_amc_audio_dec_base_init, + NULL, + (GClassInitFunc) gst_amc_audio_dec_class_init, + NULL, + NULL, + sizeof (GstAmcAudioDec), + 0, + (GInstanceInitFunc) gst_amc_audio_dec_init, + NULL + }; + + _type = g_type_register_static (GST_TYPE_AUDIO_DECODER, "GstAmcAudioDec", + &info, 0); + + GST_DEBUG_CATEGORY_INIT (gst_amc_audio_dec_debug_category, "amcaudiodec", 0, + "Android MediaCodec audio decoder"); + + g_once_init_leave (&type, _type); + } + return type; +} + +static GstCaps * +create_sink_caps (const GstAmcCodecInfo * codec_info) +{ + GstCaps *ret; + gint i; + + ret = gst_caps_new_empty (); + + for (i = 0; i < codec_info->n_supported_types; i++) { + const GstAmcCodecType *type = &codec_info->supported_types[i]; + + if (strcmp (type->mime, "audio/mpeg") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/mpeg", + "mpegversion", G_TYPE_INT, 1, + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/3gpp") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/AMR", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/amr-wb") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/AMR-WB", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/mp4a-latm") == 0) { + gint j; + GstStructure *tmp, *tmp2; + gboolean have_profile = FALSE; + GValue va = { 0, }; + GValue v = { 0, }; + + g_value_init (&va, GST_TYPE_LIST); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, "raw"); + gst_value_list_append_value (&va, &v); + g_value_set_string (&v, "adts"); + gst_value_list_append_value (&va, &v); + g_value_unset (&v); + + tmp = gst_structure_new ("audio/mpeg", + "mpegversion", G_TYPE_INT, 4, + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "framed", G_TYPE_BOOLEAN, TRUE, NULL); + gst_structure_set_value (tmp, "stream-format", &va); + g_value_unset (&va); + + for (j = 0; j < type->n_profile_levels; j++) { + const gchar *profile; + + profile = + gst_amc_aac_profile_to_string (type->profile_levels[j].profile); + + if (!profile) { + GST_ERROR ("Unable to map AAC profile 0x%08x", + type->profile_levels[j].profile); + continue; + } + + tmp2 = gst_structure_copy (tmp); + gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL); + ret = gst_caps_merge_structure (ret, tmp2); + + have_profile = TRUE; + } + + if (!have_profile) { + ret = gst_caps_merge_structure (ret, tmp); + } else { + gst_structure_free (tmp); + } + } else if (strcmp (type->mime, "audio/g711-alaw") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/x-alaw", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/g711-mlaw") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/x-mulaw", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/vorbis") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/x-vorbis", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/flac") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/x-flac", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "framed", G_TYPE_BOOLEAN, TRUE, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "audio/mpeg-L2") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("audio/mpeg", + "mpegversion", G_TYPE_INT, 1, + "layer", G_TYPE_INT, 2, + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else { + GST_WARNING ("Unsupported mimetype '%s'", type->mime); + } + } + + return ret; +} + +static const gchar * +caps_to_mime (GstCaps * caps) +{ + GstStructure *s; + const gchar *name; + + s = gst_caps_get_structure (caps, 0); + if (!s) + return NULL; + + name = gst_structure_get_name (s); + + if (strcmp (name, "audio/mpeg") == 0) { + gint mpegversion; + + if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) + return NULL; + + if (mpegversion == 1) { + gint layer; + + if (!gst_structure_get_int (s, "layer", &layer) || layer == 3) + return "audio/mpeg"; + else if (layer == 2) + return "audio/mpeg-L2"; + } else if (mpegversion == 2 || mpegversion == 4) { + return "audio/mp4a-latm"; + } + } else if (strcmp (name, "audio/AMR") == 0) { + return "audio/3gpp"; + } else if (strcmp (name, "audio/AMR-WB") == 0) { + return "audio/amr-wb"; + } else if (strcmp (name, "audio/x-alaw") == 0) { + return "audio/g711-alaw"; + } else if (strcmp (name, "audio/x-mulaw") == 0) { + return "audio/g711-mlaw"; + } else if (strcmp (name, "audio/x-vorbis") == 0) { + return "audio/vorbis"; + } + + return NULL; +} + +static GstCaps * +create_src_caps (const GstAmcCodecInfo * codec_info) +{ + GstCaps *ret; + + ret = gst_caps_new_simple ("audio/x-raw", + "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "format", G_TYPE_STRING, GST_AUDIO_NE (S16), NULL); + + return ret; +} + +static void +gst_amc_audio_dec_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstAmcAudioDecClass *amcaudiodec_class = GST_AMC_AUDIO_DEC_CLASS (g_class); + const GstAmcCodecInfo *codec_info; + GstPadTemplate *templ; + GstCaps *caps; + gchar *longname; + + codec_info = + g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), gst_amc_codec_info_quark); + /* This happens for the base class and abstract subclasses */ + if (!codec_info) + return; + + amcaudiodec_class->codec_info = codec_info; + + /* Add pad templates */ + caps = create_sink_caps (codec_info); + templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (caps); + + caps = create_src_caps (codec_info); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (caps); + + longname = g_strdup_printf ("Android MediaCodec %s", codec_info->name); + gst_element_class_set_metadata (element_class, + codec_info->name, + "Codec/Decoder/Audio", + longname, "Sebastian Dröge "); + g_free (longname); +} + +static void +gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = gst_amc_audio_dec_finalize; + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_amc_audio_dec_change_state); + + audiodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_start); + audiodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_stop); + audiodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_open); + audiodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_close); + audiodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_flush); + audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_set_format); + audiodec_class->handle_frame = + GST_DEBUG_FUNCPTR (gst_amc_audio_dec_handle_frame); +} + +static void +gst_amc_audio_dec_init (GstAmcAudioDec * self) +{ + gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (self), TRUE); + gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (self), TRUE); + + g_mutex_init (&self->drain_lock); + g_cond_init (&self->drain_cond); +} + +static gboolean +gst_amc_audio_dec_open (GstAudioDecoder * decoder) +{ + GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder); + GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self); + + GST_DEBUG_OBJECT (self, "Opening decoder"); + + self->codec = gst_amc_codec_new (klass->codec_info->name); + if (!self->codec) + return FALSE; + self->started = FALSE; + self->flushing = TRUE; + + GST_DEBUG_OBJECT (self, "Opened decoder"); + + return TRUE; +} + +static gboolean +gst_amc_audio_dec_close (GstAudioDecoder * decoder) +{ + GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Closing decoder"); + + if (self->codec) + gst_amc_codec_free (self->codec); + self->codec = NULL; + + self->started = FALSE; + self->flushing = TRUE; + + GST_DEBUG_OBJECT (self, "Closed decoder"); + + return TRUE; +} + +static void +gst_amc_audio_dec_finalize (GObject * object) +{ + GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (object); + + g_mutex_clear (&self->drain_lock); + g_cond_clear (&self->drain_cond); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static GstStateChangeReturn +gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition) +{ + GstAmcAudioDec *self; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + g_return_val_if_fail (GST_IS_AMC_AUDIO_DEC (element), + GST_STATE_CHANGE_FAILURE); + self = GST_AMC_AUDIO_DEC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + self->downstream_flow_ret = GST_FLOW_OK; + self->draining = FALSE; + self->started = FALSE; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + self->flushing = TRUE; + gst_amc_codec_flush (self->codec); + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + break; + default: + break; + } + + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + 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: + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->started = FALSE; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +static gboolean +gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format) +{ + gint rate, channels; + guint32 channel_mask = 0; + GstAudioChannelPosition to[64]; + + if (!gst_amc_format_get_int (format, "sample-rate", &rate) || + !gst_amc_format_get_int (format, "channel-count", &channels)) { + GST_ERROR_OBJECT (self, "Failed to get output format metadata"); + return FALSE; + } + + if (rate == 0 || channels == 0) { + GST_ERROR_OBJECT (self, "Rate or channels not set"); + return FALSE; + } + + /* Not always present */ + if (gst_amc_format_contains_key (format, "channel-mask")) + gst_amc_format_get_int (format, "channel-mask", (gint *) & channel_mask); + + gst_amc_audio_channel_mask_to_positions (channel_mask, channels, + self->positions); + memcpy (to, self->positions, sizeof (to)); + gst_audio_channel_positions_to_valid_order (to, channels); + self->needs_reorder = + (memcmp (self->positions, to, + sizeof (GstAudioChannelPosition) * channels) != 0); + if (self->needs_reorder) + gst_audio_get_channel_reorder_map (channels, self->positions, to, + self->reorder_map); + + gst_audio_info_init (&self->info); + gst_audio_info_set_format (&self->info, GST_AUDIO_FORMAT_S16, rate, channels, + to); + + if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (self), + &self->info)) + return FALSE; + + self->input_caps_changed = FALSE; + + return TRUE; +} + +static void +gst_amc_audio_dec_loop (GstAmcAudioDec * self) +{ + GstFlowReturn flow_ret = GST_FLOW_OK; + gboolean is_eos; + GstAmcBufferInfo buffer_info; + gint idx; + + GST_AUDIO_DECODER_STREAM_LOCK (self); + +retry: + /*if (self->input_caps_changed) { + idx = INFO_OUTPUT_FORMAT_CHANGED; + } else { */ + GST_DEBUG_OBJECT (self, "Waiting for available output buffer"); + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + /* Wait at most 100ms here, some codecs don't fail dequeueing if + * the codec is flushing, causing deadlocks during shutdown */ + idx = gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000); + GST_AUDIO_DECODER_STREAM_LOCK (self); + /*} */ + + if (idx < 0) { + if (self->flushing) + goto flushing; + + switch (idx) { + case INFO_OUTPUT_BUFFERS_CHANGED:{ + GST_DEBUG_OBJECT (self, "Output buffers have changed"); + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, + self->n_output_buffers); + self->output_buffers = + gst_amc_codec_get_output_buffers (self->codec, + &self->n_output_buffers); + if (!self->output_buffers) + goto get_output_buffers_error; + break; + } + case INFO_OUTPUT_FORMAT_CHANGED:{ + GstAmcFormat *format; + gchar *format_string; + + GST_DEBUG_OBJECT (self, "Output format has changed"); + + format = gst_amc_codec_get_output_format (self->codec); + if (!format) + goto format_error; + + format_string = gst_amc_format_to_string (format); + GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string); + g_free (format_string); + + if (!gst_amc_audio_dec_set_src_caps (self, format)) { + gst_amc_format_free (format); + goto format_error; + } + gst_amc_format_free (format); + + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, + self->n_output_buffers); + self->output_buffers = + gst_amc_codec_get_output_buffers (self->codec, + &self->n_output_buffers); + if (!self->output_buffers) + goto get_output_buffers_error; + + goto retry; + break; + } + case INFO_TRY_AGAIN_LATER: + GST_DEBUG_OBJECT (self, "Dequeueing output buffer timed out"); + goto retry; + break; + case G_MININT: + GST_ERROR_OBJECT (self, "Failure dequeueing output buffer"); + goto dequeue_error; + break; + default: + g_assert_not_reached (); + break; + } + + goto retry; + } + + GST_DEBUG_OBJECT (self, + "Got output buffer at index %d: size %d time %" G_GINT64_FORMAT + " flags 0x%08x", idx, buffer_info.size, buffer_info.presentation_time_us, + buffer_info.flags); + + is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM); + self->n_buffers++; + + if (buffer_info.size > 0) { + GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self); + GstBuffer *outbuf; + GstAmcBuffer *buf; + GstMapInfo minfo; + + /* This sometimes happens at EOS or if the input is not properly framed, + * let's handle it gracefully by allocating a new buffer for the current + * caps and filling it + */ + if (idx >= self->n_output_buffers) + goto invalid_buffer_index; + + if (strcmp (klass->codec_info->name, "OMX.google.mp3.decoder") == 0) { + /* Google's MP3 decoder outputs garbage in the first output buffer + * so we just drop it here */ + if (self->n_buffers == 1) { + GST_DEBUG_OBJECT (self, + "Skipping first buffer of Google MP3 decoder output"); + goto done; + } + } + + outbuf = + gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self), + buffer_info.size); + if (!outbuf) + goto failed_allocate; + + gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE); + buf = &self->output_buffers[idx]; + if (self->needs_reorder) { + gint i, n_samples, c, n_channels; + gint *reorder_map = self->reorder_map; + gint16 *dest, *source; + + dest = (gint16 *) minfo.data; + source = (gint16 *) (buf->data + buffer_info.offset); + n_samples = buffer_info.size / self->info.bpf; + n_channels = self->info.channels; + + for (i = 0; i < n_samples; i++) { + for (c = 0; c < n_channels; c++) { + dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c]; + } + } + } else { + orc_memcpy (minfo.data, buf->data + buffer_info.offset, buffer_info.size); + } + gst_buffer_unmap (outbuf, &minfo); + + /* FIXME: We should get one decoded input frame here for + * every buffer. If this is not the case somewhere, we will + * error out at some point and will need to add workarounds + */ + flow_ret = + gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1); + } + +done: + if (!gst_amc_codec_release_output_buffer (self->codec, idx, TRUE)) + goto failed_release; + + if (is_eos || flow_ret == GST_FLOW_EOS) { + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + g_mutex_lock (&self->drain_lock); + if (self->draining) { + GST_DEBUG_OBJECT (self, "Drained"); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + } else if (flow_ret == GST_FLOW_OK) { + GST_DEBUG_OBJECT (self, "Component signalled EOS"); + flow_ret = GST_FLOW_EOS; + } + g_mutex_unlock (&self->drain_lock); + GST_AUDIO_DECODER_STREAM_LOCK (self); + } else { + GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret)); + } + + self->downstream_flow_ret = flow_ret; + + if (flow_ret != GST_FLOW_OK) + goto flow_error; + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + + return; + +dequeue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to dequeue output buffer")); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +get_output_buffers_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to get output buffers")); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +format_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to handle format")); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } +failed_release: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to release output buffer index %d", idx)); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- stopping task"); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_FLUSHING; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +flow_error: + { + if (flow_ret == GST_FLOW_EOS) { + GST_DEBUG_OBJECT (self, "EOS"); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + } else if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_EOS) { + GST_ELEMENT_ERROR (self, STREAM, FAILED, + ("Internal data stream error."), ("stream stopped, reason %s", + gst_flow_get_name (flow_ret))); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + } + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +invalid_buffer_index: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } + +failed_allocate: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Failed to allocate output buffer")); + gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + return; + } +} + +static gboolean +gst_amc_audio_dec_start (GstAudioDecoder * decoder) +{ + GstAmcAudioDec *self; + + self = GST_AMC_AUDIO_DEC (decoder); + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + self->started = FALSE; + self->flushing = TRUE; + + return TRUE; +} + +static gboolean +gst_amc_audio_dec_stop (GstAudioDecoder * decoder) +{ + GstAmcAudioDec *self; + + self = GST_AMC_AUDIO_DEC (decoder); + GST_DEBUG_OBJECT (self, "Stopping decoder"); + self->flushing = TRUE; + if (self->started) { + gst_amc_codec_flush (self->codec); + gst_amc_codec_stop (self->codec); + self->started = FALSE; + if (self->input_buffers) + gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); + self->input_buffers = NULL; + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); + self->output_buffers = NULL; + } + gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); + + memset (self->positions, 0, sizeof (self->positions)); + + g_list_foreach (self->codec_datas, (GFunc) g_free, NULL); + g_list_free (self->codec_datas); + self->codec_datas = NULL; + + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->eos = FALSE; + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + + GST_DEBUG_OBJECT (self, "Stopped decoder"); + return TRUE; +} + +static gboolean +gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) +{ + GstAmcAudioDec *self; + GstStructure *s; + GstAmcFormat *format; + const gchar *mime; + gboolean is_format_change = FALSE; + gboolean needs_disable = FALSE; + gchar *format_string; + gint rate, channels; + + self = GST_AMC_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps); + + /* Check if the caps change is a real format change or if only irrelevant + * parts of the caps have changed or nothing at all. + */ + is_format_change |= (!self->input_caps + || !gst_caps_is_equal (self->input_caps, caps)); + + needs_disable = self->started; + + /* If the component is not started and a real format change happens + * we have to restart the component. If no real format change + * happened we can just exit here. + */ + if (needs_disable && !is_format_change) { + /* Framerate or something minor changed */ + self->input_caps_changed = TRUE; + GST_DEBUG_OBJECT (self, + "Already running and caps did not change the format"); + return TRUE; + } + + if (needs_disable && is_format_change) { + gst_amc_audio_dec_drain (self); + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + gst_amc_audio_dec_stop (GST_AUDIO_DECODER (self)); + GST_AUDIO_DECODER_STREAM_LOCK (self); + gst_amc_audio_dec_close (GST_AUDIO_DECODER (self)); + if (!gst_amc_audio_dec_open (GST_AUDIO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Failed to open codec again"); + return FALSE; + } + + if (!gst_amc_audio_dec_start (GST_AUDIO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Failed to start codec again"); + } + } + /* srcpad task is not running at this point */ + + mime = caps_to_mime (caps); + if (!mime) { + GST_ERROR_OBJECT (self, "Failed to convert caps to mime"); + return FALSE; + } + + s = gst_caps_get_structure (caps, 0); + if (!gst_structure_get_int (s, "rate", &rate) || + !gst_structure_get_int (s, "channels", &channels)) { + GST_ERROR_OBJECT (self, "Failed to get rate/channels"); + return FALSE; + } + + format = gst_amc_format_new_audio (mime, rate, channels); + if (!format) { + GST_ERROR_OBJECT (self, "Failed to create audio format"); + return FALSE; + } + + /* FIXME: These buffers needs to be valid until the codec is stopped again */ + g_list_foreach (self->codec_datas, (GFunc) gst_buffer_unref, NULL); + g_list_free (self->codec_datas); + self->codec_datas = NULL; + if (gst_structure_has_field (s, "codec_data")) { + const GValue *h = gst_structure_get_value (s, "codec_data"); + GstBuffer *codec_data = gst_value_get_buffer (h); + GstMapInfo minfo; + guint8 *data; + + gst_buffer_map (codec_data, &minfo, GST_MAP_READ); + data = g_memdup (minfo.data, minfo.size); + self->codec_datas = g_list_prepend (self->codec_datas, data); + gst_amc_format_set_buffer (format, "csd-0", data, minfo.size); + gst_buffer_unmap (codec_data, &minfo); + } else if (gst_structure_has_field (s, "streamheader")) { + const GValue *sh = gst_structure_get_value (s, "streamheader"); + gint nsheaders = gst_value_array_get_size (sh); + GstBuffer *buf; + const GValue *h; + gint i, j; + gchar *fname; + GstMapInfo minfo; + guint8 *data; + + for (i = 0, j = 0; i < nsheaders; i++) { + h = gst_value_array_get_value (sh, i); + buf = gst_value_get_buffer (h); + + if (strcmp (mime, "audio/vorbis") == 0) { + guint8 header_type; + + gst_buffer_extract (buf, 0, &header_type, 1); + + /* Only use the identification and setup packets */ + if (header_type != 0x01 && header_type != 0x05) + continue; + } + + fname = g_strdup_printf ("csd-%d", j); + gst_buffer_map (buf, &minfo, GST_MAP_READ); + data = g_memdup (minfo.data, minfo.size); + self->codec_datas = g_list_prepend (self->codec_datas, data); + gst_amc_format_set_buffer (format, fname, data, minfo.size); + gst_buffer_unmap (buf, &minfo); + g_free (fname); + j++; + } + } + + format_string = gst_amc_format_to_string (format); + GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", format_string); + g_free (format_string); + + self->n_buffers = 0; + if (!gst_amc_codec_configure (self->codec, format, NULL, 0)) { + GST_ERROR_OBJECT (self, "Failed to configure codec"); + return FALSE; + } + + gst_amc_format_free (format); + + if (!gst_amc_codec_start (self->codec)) { + GST_ERROR_OBJECT (self, "Failed to start codec"); + return FALSE; + } + + if (self->input_buffers) + gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); + self->input_buffers = + gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers); + if (!self->input_buffers) { + GST_ERROR_OBJECT (self, "Failed to get input buffers"); + return FALSE; + } + + self->started = TRUE; + self->input_caps_changed = TRUE; + + /* Start the srcpad loop again */ + self->flushing = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); + + return TRUE; +} + +static void +gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) +{ + GstAmcAudioDec *self; + + self = GST_AMC_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Resetting decoder"); + + if (!self->started) { + GST_DEBUG_OBJECT (self, "Codec not started yet"); + return; + } + + self->flushing = TRUE; + gst_amc_codec_flush (self->codec); + + /* Wait until the srcpad loop is finished, + * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks + * caused by using this lock from inside the loop function */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + GST_PAD_STREAM_LOCK (GST_AUDIO_DECODER_SRC_PAD (self)); + GST_PAD_STREAM_UNLOCK (GST_AUDIO_DECODER_SRC_PAD (self)); + GST_AUDIO_DECODER_STREAM_LOCK (self); + self->flushing = FALSE; + + /* Start the srcpad loop again */ + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); + + GST_DEBUG_OBJECT (self, "Reset decoder"); +} + +static GstFlowReturn +gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) +{ + GstAmcAudioDec *self; + gint idx; + GstAmcBuffer *buf; + GstAmcBufferInfo buffer_info; + guint offset = 0; + GstClockTime timestamp, duration, timestamp_offset = 0; + GstMapInfo minfo; + + memset (&minfo, 0, sizeof (minfo)); + + self = GST_AMC_AUDIO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Handling frame"); + + /* Make sure to keep a reference to the input here, + * it can be unreffed from the other thread if + * finish_frame() is called */ + if (inbuf) + inbuf = gst_buffer_ref (inbuf); + + if (!self->started) { + GST_ERROR_OBJECT (self, "Codec not started yet"); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_NOT_NEGOTIATED; + } + + if (self->eos) { + GST_WARNING_OBJECT (self, "Got frame after EOS"); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_EOS; + } + + if (self->flushing) + goto flushing; + + if (self->downstream_flow_ret != GST_FLOW_OK) + goto downstream_error; + + if (!inbuf) + return gst_amc_audio_dec_drain (self); + + timestamp = GST_BUFFER_PTS (inbuf); + duration = GST_BUFFER_DURATION (inbuf); + + gst_buffer_map (inbuf, &minfo, GST_MAP_READ); + + while (offset < minfo.size) { + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + /* Wait at most 100ms here, some codecs don't fail dequeueing if + * the codec is flushing, causing deadlocks during shutdown */ + idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000); + GST_AUDIO_DECODER_STREAM_LOCK (self); + + if (idx < 0) { + if (self->flushing) + goto flushing; + switch (idx) { + case INFO_TRY_AGAIN_LATER: + GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out"); + continue; /* next try */ + break; + case G_MININT: + GST_ERROR_OBJECT (self, "Failed to dequeue input buffer"); + goto dequeue_error; + default: + g_assert_not_reached (); + break; + } + + continue; + } + + if (idx >= self->n_input_buffers) + goto invalid_buffer_index; + + if (self->flushing) + goto flushing; + + if (self->downstream_flow_ret != GST_FLOW_OK) { + memset (&buffer_info, 0, sizeof (buffer_info)); + gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info); + goto downstream_error; + } + + /* Now handle the frame */ + + /* Copy the buffer content in chunks of size as requested + * by the port */ + buf = &self->input_buffers[idx]; + + memset (&buffer_info, 0, sizeof (buffer_info)); + buffer_info.offset = 0; + buffer_info.size = MIN (minfo.size - offset, buf->size); + + orc_memcpy (buf->data, minfo.data + offset, buffer_info.size); + + /* Interpolate timestamps if we're passing the buffer + * in multiple chunks */ + if (offset != 0 && duration != GST_CLOCK_TIME_NONE) { + timestamp_offset = gst_util_uint64_scale (offset, duration, minfo.size); + } + + if (timestamp != GST_CLOCK_TIME_NONE) { + buffer_info.presentation_time_us = + gst_util_uint64_scale (timestamp + timestamp_offset, 1, GST_USECOND); + self->last_upstream_ts = timestamp + timestamp_offset; + } + if (duration != GST_CLOCK_TIME_NONE) + self->last_upstream_ts += duration; + + if (offset == 0) { + if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT)) + buffer_info.flags |= BUFFER_FLAG_SYNC_FRAME; + } + + offset += buffer_info.size; + GST_DEBUG_OBJECT (self, + "Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x", + idx, buffer_info.size, buffer_info.presentation_time_us, + buffer_info.flags); + if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) + goto queue_error; + } + gst_buffer_unmap (inbuf, &minfo); + gst_buffer_unref (inbuf); + + return self->downstream_flow_ret; + +downstream_error: + { + GST_ERROR_OBJECT (self, "Downstream returned %s", + gst_flow_get_name (self->downstream_flow_ret)); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); + if (inbuf) + gst_buffer_unref (inbuf); + return self->downstream_flow_ret; + } +invalid_buffer_index: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_ERROR; + } +dequeue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to dequeue input buffer")); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_ERROR; + } +queue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to queue input buffer")); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_ERROR; + } +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING"); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); + if (inbuf) + gst_buffer_unref (inbuf); + return GST_FLOW_FLUSHING; + } +} + +static GstFlowReturn +gst_amc_audio_dec_drain (GstAmcAudioDec * self) +{ + GstFlowReturn ret; + gint idx; + + GST_DEBUG_OBJECT (self, "Draining codec"); + if (!self->started) { + GST_DEBUG_OBJECT (self, "Codec not started yet"); + return GST_FLOW_OK; + } + + /* Don't send EOS buffer twice, this doesn't work */ + if (self->eos) { + GST_DEBUG_OBJECT (self, "Codec is EOS already"); + return GST_FLOW_OK; + } + + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + /* Send an EOS buffer to the component and let the base + * class drop the EOS event. We will send it later when + * the EOS buffer arrives on the output port. + * Wait at most 0.5s here. */ + idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000); + GST_AUDIO_DECODER_STREAM_LOCK (self); + + if (idx >= 0 && idx < self->n_input_buffers) { + GstAmcBufferInfo buffer_info; + + GST_AUDIO_DECODER_STREAM_UNLOCK (self); + g_mutex_lock (&self->drain_lock); + self->draining = TRUE; + + memset (&buffer_info, 0, sizeof (buffer_info)); + buffer_info.size = 0; + buffer_info.presentation_time_us = + gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND); + buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM; + + if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) { + GST_DEBUG_OBJECT (self, "Waiting until codec is drained"); + g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained codec"); + ret = GST_FLOW_OK; + } else { + GST_ERROR_OBJECT (self, "Failed to queue input buffer"); + ret = GST_FLOW_ERROR; + } + + g_mutex_unlock (&self->drain_lock); + GST_AUDIO_DECODER_STREAM_LOCK (self); + } else if (idx >= self->n_input_buffers) { + GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d", + idx, self->n_input_buffers); + ret = GST_FLOW_ERROR; + } else { + GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx); + ret = GST_FLOW_ERROR; + } + + return ret; +} diff --git a/sys/androidmedia/gstamchybris.c b/sys/androidmedia/gstamchybris.c new file mode 100644 index 0000000..c8321b6 --- /dev/null +++ b/sys/androidmedia/gstamchybris.c @@ -0,0 +1,2077 @@ +/* + * Initially based on gstamc.c + * + * Copyright (C) 2013, Canonical Ltd. + * Author: Jim Hodapp + * + * 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 + * version 2.1 of the License. + * + * 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 "gstamc.h" +#include "gstamc-constants.h" + +#include "gstamcvideodec.h" +#include "gstamcaudiodec.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +GST_DEBUG_CATEGORY (gst_amc_debug); +#define GST_CAT_DEFAULT gst_amc_debug + +GQuark gst_amc_codec_info_quark = 0; + +static GList *codec_infos = NULL; +#ifdef GST_AMC_IGNORE_UNKNOWN_COLOR_FORMATS +static gboolean ignore_unknown_color_formats = TRUE; +#else +static gboolean ignore_unknown_color_formats = FALSE; +#endif + +static gboolean accepted_color_formats (GstAmcCodecType * type, + gboolean is_encoder); + +/* FIXME: enable support for platform-api again once it's stable enough + * when using it with MIR (currently it creates all sorts of crashes */ +#if 0 +static struct ua_display * +create_display (void) +{ + struct ua_display *display; + display = malloc (sizeof (struct ua_display)); + + display->display = ua_ui_display_new_with_index (0); + if (display->display == NULL) { + free (display); + return NULL; + } + + display->height = ua_ui_display_query_vertical_res (display->display); + display->width = ua_ui_display_query_horizontal_res (display->display); + + GST_DEBUG ("Display resolution: (%d,%d)\n", display->height, display->width); + + return display; +} + +static struct ua_session * +create_session (void) +{ + struct ua_session *session; + char argv[1][1]; + session = malloc (sizeof (struct ua_session)); + + session->properties = ua_ui_session_properties_new (); + ua_ui_session_properties_set_type (session->properties, U_USER_SESSION); + session->session = ua_ui_session_new_with_properties (session->properties); + if (!session->session) + GST_WARNING ("Failed to start new Ubuntu Application API session"); + + /* The UA requires a command line option set, so give it a fake argv array */ + argv[0][0] = '\0'; + session->app_options = + u_application_options_new_from_cmd_line (1, (char **) argv); + + session->app_description = u_application_description_new (); + + /* Required by Mir */ + session->app_id = u_application_id_new_from_stringn ("gstamc", 6); + u_application_description_set_application_id (session->app_description, + session->app_id); + + session->app_lifecycle_delegate = u_application_lifecycle_delegate_new (); + /* No context data to pass to the lifecycle delegate for now */ + u_application_lifecycle_delegate_set_context + (session->app_lifecycle_delegate, NULL); + u_application_description_set_application_lifecycle_delegate + (session->app_description, session->app_lifecycle_delegate); + + session->app_instance = + u_application_instance_new_from_description_with_options + (session->app_description, session->app_options); + if (!session->app_instance) + GST_WARNING ("Failed to start a new Ubuntu Application API instance"); + + return session; +} + +static struct ua_window * +create_window (struct ua_display *display, struct ua_session *session, + int width, int height) +{ + struct ua_window *window; + + g_return_val_if_fail (display != NULL, NULL); + g_return_val_if_fail (session != NULL, NULL); + + window = malloc (sizeof (struct ua_window)); + window->display = display; + window->width = width; + window->height = height; + + window->properties = ua_ui_window_properties_new_for_normal_window (); + ua_ui_window_properties_set_titlen (window->properties, "VideoRenderWindow", + 13); + + ua_ui_window_properties_set_role (window->properties, 1); + ua_ui_window_properties_set_input_cb_and_ctx (window->properties, NULL, NULL); + GST_DEBUG ("Creating new UA window"); + window->window = + ua_ui_window_new_for_application_with_properties (session->app_instance, + window->properties); + GST_DEBUG ("Setting window geometry"); + window->width = window->display->width; + window->height = window->display->height; + GST_DEBUG ("width: %d, height: %d", window->width, window->height); + + if (height != 0 || width != 0) + ua_ui_window_resize (window->window, window->width, window->height); + + window->egl_native_window = ua_ui_window_get_native_type (window->window); + return window; +} + +static void +destroy_display (struct ua_display *display) +{ + g_return_if_fail (display != NULL); + free (display); +} + +static void +destroy_session (struct ua_session *session) +{ + g_return_if_fail (session != NULL); + +/* FIXME: Segfaults on SurfaceFlinger. Can uncomment once the transition to Mir is complete. + if (session->app_options) + u_application_options_destroy (session->app_options); + */ + + if (session->app_id) + u_application_id_destroy (session->app_id); + + if (session->app_description) + u_application_description_destroy (session->app_description); + + free (session); +} + +static void +destroy_window (struct ua_window *window) +{ + g_return_if_fail (window != NULL); + if (window->properties) + ua_ui_window_properties_destroy (window->properties); + + if (window->window) + ua_ui_window_destroy (window->window); + + free (window); +} +#endif + +static gchar * +locale_to_utf8 (gchar * str, gssize len) +{ + GError *error = NULL; + gsize bytes_read = 0, bytes_written = 0; + gchar *out = NULL; + + out = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, &error); + if (bytes_read == 0) + GST_WARNING ("Zero bytes read for UTF8 string conversion"); + if (bytes_written == 0) + GST_WARNING ("Zero bytes written for UTF8 string conversion"); + + return out; +} + +GstAmcCodec * +gst_amc_codec_new (const gchar * name) +{ + GstAmcCodec *codec = NULL; + gchar *name_str = NULL; + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (name != NULL, NULL); + + codec = g_slice_new0 (GstAmcCodec); + + name_str = g_strdup (name); + name_str = locale_to_utf8 (name_str, strlen (name)); + if (name_str == NULL) + goto error; + GST_DEBUG ("codec name '%s'", name_str); + + codec->surface_texture_client = NULL; + codec->codec_delegate = media_codec_create_by_codec_name (name_str); + if (codec->codec_delegate == NULL) { + GST_ERROR ("Failed to create codec '%s'", name_str); + goto error; + } + +done: + if (name_str) + g_free (name_str); + name_str = NULL; + + return codec; + +error: + if (codec) + g_slice_free (GstAmcCodec, codec); + codec = NULL; + goto done; +} + +void +gst_amc_codec_free (GstAmcCodec * codec) +{ + g_return_if_fail (codec != NULL); + g_return_if_fail (codec->codec_delegate != NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + // Cleanup the hardware decoder's resources + media_codec_delegate_unref (codec->codec_delegate); + + g_slice_free (GstAmcCodec, codec); +} + +gboolean +gst_amc_codec_configure (GstAmcCodec * codec, GstAmcFormat * format, + SurfaceTextureClientHybris stc, gint flags) +{ + gboolean ret = TRUE; + int err = 0; + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (codec != NULL, FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + if (surface_texture_client_hardware_rendering (stc)) { + guint8 i = 0; + const guint8 MAX_TRIES = 25; + /* Make sure that we have a valid texture_id before we proceed with configuring */ + while (!surface_texture_client_is_ready_for_rendering (stc) + && i < MAX_TRIES) { + GST_WARNING + ("Surface texture client is not yet ready, waiting a bit for the texture id"); + g_usleep (G_USEC_PER_SEC / 5); + ++i; + } + + if (i >= MAX_TRIES) { + GST_ERROR + ("Failed to get a valid texture id, cannot configure the codec."); + ret = FALSE; + goto done; + } + } else { + GST_WARNING ("surface_texture_client_is_ready_for_rendering: %d", + surface_texture_client_is_ready_for_rendering (stc)); + + if (!surface_texture_client_is_ready_for_rendering (stc)) { + GST_WARNING + ("SurfaceTextureClientHybris is not ready for rendering, creating EGLNativeWindowType"); + +#if 0 + /* Create a new Ubuntu Application API session */ + codec->session = create_session (); + + if (codec->session == NULL) { + GST_ERROR + ("Could not initialize Mir output, could not start a Mir app session"); + return FALSE; + } + + codec->display = create_display (); + + if (codec->display == NULL) { + GST_ERROR + ("Could not initialize Mir output could not create a Mir display"); + return FALSE; + } + + /* Create an EGLNativeWindowType instance so that a pure playbin + * scenario will render video */ + codec->window = + create_window (codec->display, codec->session, codec->display->width, + codec->display->height); + surface_texture_client_create (codec->window->egl_native_window); +#endif + } + } + + err = media_codec_configure (codec->codec_delegate, format->format, stc, 0); + if (err > 0) { + GST_ERROR ("Failed to configure media codec"); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +gboolean +gst_amc_codec_set_surface_texture_client (GstAmcCodec * codec, + SurfaceTextureClientHybris stc) +{ + g_return_val_if_fail (codec != NULL, FALSE); + g_return_val_if_fail (stc != NULL, FALSE); + + codec->surface_texture_client = stc; + + GST_DEBUG_OBJECT (codec, "stc: %p", stc); + GST_DEBUG_OBJECT (codec, "codec->surface_texture_client: %p", + codec->surface_texture_client); + + return TRUE; +} + +SurfaceTextureClientHybris +gst_amc_codec_get_surface_texture_client (GstAmcCodec * codec) +{ + g_return_val_if_fail (codec != NULL, NULL); + + return codec->surface_texture_client; +} + +gboolean +gst_amc_codec_queue_csd (GstAmcCodec * codec, GstAmcFormat * format) +{ + gboolean ret = TRUE; + int err = 0; + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (codec != NULL, FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + err = media_codec_queue_csd (codec->codec_delegate, format->format); + if (err > 0) { + GST_ERROR ("Failed to queue codec specific data"); + ret = FALSE; + goto done; + } + +done: + + return ret; +} + +GstAmcFormat * +gst_amc_codec_get_output_format (GstAmcCodec * codec) +{ + GstAmcFormat *ret = NULL; + + g_return_val_if_fail (codec != NULL, NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + ret = g_slice_new0 (GstAmcFormat); + + ret->format = media_codec_get_output_format (codec->codec_delegate); + if (ret->format == NULL) { + GST_ERROR ("Failed to get output format"); + g_slice_free (GstAmcFormat, ret); + ret = NULL; + goto done; + } + +done: + + return ret; +} + +gboolean +gst_amc_codec_start (GstAmcCodec * codec) +{ + gboolean ret = TRUE; + int err = 0; + + g_return_val_if_fail (codec != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + err = media_codec_start (codec->codec_delegate); + if (err > 0) { + GST_ERROR ("Failed to start media codec"); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +gboolean +gst_amc_codec_stop (GstAmcCodec * codec) +{ + gboolean ret = TRUE; + int err = 0; + + g_return_val_if_fail (codec != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + err = media_codec_stop (codec->codec_delegate); + if (err > 0) { + GST_ERROR ("Failed to start media codec"); + ret = FALSE; + goto done; + } +#if 0 + if (codec->window) + destroy_window (codec->window); + if (codec->display) + destroy_display (codec->display); + if (codec->session) + destroy_session (codec->session); +#endif + +done: + + return ret; +} + +gboolean +gst_amc_codec_flush (GstAmcCodec * codec) +{ + gboolean ret = TRUE; + gint err = 0; + + g_return_val_if_fail (codec != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + err = media_codec_flush (codec->codec_delegate); + if (err < 0) { + GST_ERROR ("Failed to flush the media codec (err: %d)", err); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +gboolean +gst_amc_codec_release (GstAmcCodec * codec) +{ + gboolean ret = TRUE; + gint err = 0; + + g_return_val_if_fail (codec != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + err = media_codec_release (codec->codec_delegate); + if (err < 0) { + GST_ERROR ("Failed to release media codec (err: %d)", err); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +void +gst_amc_codec_free_buffers (GstAmcBuffer * buffers, gsize n_buffers) +{ + g_return_if_fail (buffers != NULL); + + g_free (buffers); +} + +GstAmcBuffer * +gst_amc_codec_get_output_buffers (GstAmcCodec * codec, gsize * n_buffers) +{ + size_t n_output_buffers; + GstAmcBuffer *ret = NULL; + size_t i; + + g_return_val_if_fail (codec != NULL, NULL); + g_return_val_if_fail (n_buffers != NULL, NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + *n_buffers = 0; + n_output_buffers = + media_codec_get_output_buffers_size (codec->codec_delegate); + if (n_output_buffers == 0) { + GST_ERROR ("Failed to get output buffers array length"); + goto done; + } + GST_DEBUG ("n_output_buffers: %u", n_output_buffers); + + *n_buffers = n_output_buffers; + ret = g_new0 (GstAmcBuffer, n_output_buffers); + + for (i = 0; i < n_output_buffers; i++) { + ret[i].data = media_codec_get_nth_output_buffer (codec->codec_delegate, i); + // It's no longer an error if the buffer address is zero, it just means + // MediaCodec with v4.4+ doesn't return the buffer address when doing hardware + // rendering + if (!ret[i].data) + GST_DEBUG ("Output buffer address is NULL for buffer #%d", i); + + ret[i].size = + media_codec_get_nth_output_buffer_capacity (codec->codec_delegate, i); + GST_DEBUG ("output buffer[%d] size: %d", i, ret[i].size); + } + +done: + return ret; +} + +GstAmcBuffer * +gst_amc_codec_get_input_buffers (GstAmcCodec * codec, gsize * n_buffers) +{ + size_t n_input_buffers; + GstAmcBuffer *ret = NULL; + size_t i; + + g_return_val_if_fail (codec != NULL, NULL); + g_return_val_if_fail (n_buffers != NULL, NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + *n_buffers = 0; + n_input_buffers = media_codec_get_input_buffers_size (codec->codec_delegate); + if (n_input_buffers == 0) { + GST_ERROR ("Failed to get input buffers array length"); + goto done; + } + GST_DEBUG ("n_input_buffers: %u", n_input_buffers); + + *n_buffers = n_input_buffers; + ret = g_new0 (GstAmcBuffer, n_input_buffers); + + for (i = 0; i < n_input_buffers; i++) { + ret[i].data = media_codec_get_nth_input_buffer (codec->codec_delegate, i); + if (!ret[i].data) { + GST_ERROR ("Failed to get input buffer address %d", i); + goto error; + } + ret[i].size = + media_codec_get_nth_input_buffer_capacity (codec->codec_delegate, i); + GST_DEBUG ("input buffer[%d] size: %d", i, ret[i].size); + } + +done: + return ret; + +error: + if (ret) + gst_amc_codec_free_buffers (ret, n_input_buffers); + ret = NULL; + *n_buffers = 0; + goto done; +} + +gint +gst_amc_codec_dequeue_input_buffer (GstAmcCodec * codec, gint64 timeoutUs) +{ + gint ret = G_MININT; + size_t index = 0; + + g_return_val_if_fail (codec != NULL, G_MININT); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + ret = + media_codec_dequeue_input_buffer (codec->codec_delegate, &index, + timeoutUs); + if (ret < 0) { + GST_DEBUG ("Failed to dequeue input buffer (ret: %d)", ret); + if (ret == -11) + ret = INFO_TRY_AGAIN_LATER; + goto done; + } + ret = index; + + GST_DEBUG ("Dequeued input buffer #%d", index); + +done: + return ret; +} + +gint +gst_amc_codec_dequeue_output_buffer (GstAmcCodec * codec, + GstAmcBufferInfo * info, gint64 timeoutUs) +{ + gint ret = G_MININT; + MediaCodecBufferInfo priv_info; + + g_return_val_if_fail (codec != NULL, G_MININT); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + ret = + media_codec_dequeue_output_buffer (codec->codec_delegate, &priv_info, + timeoutUs); + GST_DEBUG ("dequeue output buffer ret: %d", ret); + if (ret == INFO_TRY_AGAIN_LATER) { + GST_DEBUG ("media_codec_dequeue_output_buffer timed out, trying again"); + info->flags = 0; + info->offset = 0; + info->size = 0; + info->presentation_time_us = 0; + goto done; + } else if (ret == INFO_OUTPUT_FORMAT_CHANGED) { + GST_INFO ("Output format has changed"); + goto done; + } else if (ret == INFO_OUTPUT_BUFFERS_CHANGED) { + GST_INFO ("Output buffers have changed"); + goto done; + } + + info->flags = priv_info.flags; + info->offset = priv_info.offset; + info->size = priv_info.size; + info->presentation_time_us = priv_info.presentation_time_us; + + GST_DEBUG ("info->flags: %d", info->flags); + GST_DEBUG ("info->offset: %d", info->offset); + GST_DEBUG ("info->size: %d", info->size); + GST_DEBUG ("info->presentation_time_us: %lld", info->presentation_time_us); + +done: + return ret; +} + +gboolean +gst_amc_codec_queue_input_buffer (GstAmcCodec * codec, gint index, + const GstAmcBufferInfo * info) +{ + gboolean ret = TRUE; + gint err = 0; + MediaCodecBufferInfo buf_info; + + g_return_val_if_fail (codec != NULL, FALSE); + g_return_val_if_fail (info != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + buf_info.index = index; + buf_info.offset = info->offset; + buf_info.size = info->size; + buf_info.presentation_time_us = info->presentation_time_us; + buf_info.flags = info->flags; + GST_DEBUG ("buf_info.index: %d", buf_info.index); + GST_DEBUG ("buf_info.offset %d", buf_info.offset); + GST_DEBUG ("buf_info.size %d", buf_info.size); + GST_DEBUG ("buf_info.presentation_time_us %lld", + buf_info.presentation_time_us); + GST_DEBUG ("buf_info.flags %d", buf_info.flags); + + err = media_codec_queue_input_buffer (codec->codec_delegate, &buf_info); + if (err < 0) { + GST_ERROR ("Failed to queue input buffer (err: %d, index: %d)", err, index); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +gboolean +gst_amc_codec_release_output_buffer (GstAmcCodec * codec, gint index, + gboolean render) +{ + gboolean ret = TRUE; + gint err = 0; + + g_return_val_if_fail (codec != NULL, FALSE); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + err = + media_codec_release_output_buffer (codec->codec_delegate, index, render); + if (err < 0) { + GST_ERROR ("Failed to release output buffer (err: %d, index: %d)", err, + index); + ret = FALSE; + goto done; + } + +done: + return ret; +} + +GstAmcFormat * +gst_amc_format_new_audio (const gchar * mime, gint sample_rate, gint channels) +{ +#if 0 + JNIEnv *env; + GstAmcFormat *format = NULL; + jstring mime_str; + jobject object = NULL; +#endif + + g_return_val_if_fail (mime != NULL, NULL); + +#if 0 + env = gst_amc_get_jni_env (); + + mime_str = (*env)->NewStringUTF (env, mime); + if (mime_str == NULL) + goto error; + + format = g_slice_new0 (GstAmcFormat); + + object = + (*env)->CallStaticObjectMethod (env, media_format.klass, + media_format.create_audio_format, mime_str, sample_rate, channels); + if ((*env)->ExceptionCheck (env) || !object) { + (*env)->ExceptionClear (env); + GST_ERROR ("Failed to create format '%s'", mime); + goto error; + } + + format->object = (*env)->NewGlobalRef (env, object); + if (!format->object) { + GST_ERROR ("Failed to create global reference"); + (*env)->ExceptionClear (env); + goto error; + } + +done: + if (object) + (*env)->DeleteLocalRef (env, object); + if (mime_str) + (*env)->DeleteLocalRef (env, mime_str); + mime_str = NULL; + + + return format; + +error: + if (format) + g_slice_free (GstAmcFormat, format); + format = NULL; + goto done; +#endif + + return NULL; +} + +GstAmcFormat * +gst_amc_format_new_video (const gchar * mime, gint width, gint height) +{ + GstAmcFormat *format = NULL; + gchar *mime_str = NULL; + + g_return_val_if_fail (mime != NULL, NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + mime_str = g_strdup (mime); + mime_str = locale_to_utf8 (mime_str, strlen (mime_str)); + if (mime_str == NULL) + goto error; + + format = g_slice_new0 (GstAmcFormat); + + format->format = + media_format_create_video_format (mime_str, width, height, 0, 0); + if (format->format == NULL) { + GST_ERROR ("Failed to create format '%s'", mime); + goto error; + } + +done: + if (mime_str) + g_free (mime_str); + mime_str = NULL; + + return format; + +error: + if (format) + g_slice_free (GstAmcFormat, format); + format = NULL; + goto done; +} + +void +gst_amc_format_free (GstAmcFormat * format) +{ + g_return_if_fail (format != NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + media_format_destroy (format->format); + g_slice_free (GstAmcFormat, format); +} + +gchar * +gst_amc_format_to_string (GstAmcFormat * format) +{ + return NULL; +} + +gboolean +gst_amc_format_contains_key (GstAmcFormat * format, const gchar * key) +{ + return FALSE; +} + +gboolean +gst_amc_format_get_float (GstAmcFormat * format, const gchar * key, + gfloat * value) +{ + return FALSE; +} + +void +gst_amc_format_set_float (GstAmcFormat * format, const gchar * key, + gfloat value) +{ +} + +gboolean +gst_amc_format_get_int (GstAmcFormat * format, const gchar * key, gint * value) +{ + return FALSE; +} + +void +gst_amc_format_set_int (GstAmcFormat * format, const gchar * key, gint value) +{ +} + +gboolean +gst_amc_format_get_string (GstAmcFormat * format, const gchar * key, + gchar ** value) +{ + return FALSE; +} + +void +gst_amc_format_set_string (GstAmcFormat * format, const gchar * key, + const gchar * value) +{ +} + +gboolean +gst_amc_format_get_buffer (GstAmcFormat * format, const gchar * key, + guint8 ** data, gsize * size) +{ + return FALSE; +} + +void +gst_amc_format_set_buffer (GstAmcFormat * format, const gchar * key, + guint8 * data, gsize size) +{ + gchar *key_str = NULL; + + g_return_if_fail (format != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (data != NULL); + + GST_DEBUG ("%s", __PRETTY_FUNCTION__); + + key_str = g_strdup (key); + key_str = locale_to_utf8 (key_str, strlen (key)); + if (!key_str) + goto done; + + media_format_set_byte_buffer (format->format, key, data, size); + +done: + if (key_str) + g_free (key_str); + key_str = NULL; +} + +void gst_amc_surface_texture_client_set_hardware_rendering + (SurfaceTextureClientHybris stc, gboolean hardware_rendering) +{ + surface_texture_client_set_hardware_rendering (stc, hardware_rendering); +} + +static gboolean +scan_codecs (GstPlugin * plugin) +{ + gboolean ret = TRUE; + guint32 codec_count, i; + const GstStructure *cache_data; + + GST_DEBUG ("Scanning available codecs"); + + if ((cache_data = gst_plugin_get_cache_data (plugin))) { + const GValue *arr = gst_structure_get_value (cache_data, "codecs"); + guint i, n; + + GST_DEBUG ("Getting codecs from cache"); + n = gst_value_array_get_size (arr); + for (i = 0; i < n; i++) { + const GValue *cv = gst_value_array_get_value (arr, i); + const GstStructure *cs = gst_value_get_structure (cv); + const gchar *name; + gboolean is_encoder; + const GValue *starr; + guint j, n2; + GstAmcCodecInfo *gst_codec_info; + + gst_codec_info = g_new0 (GstAmcCodecInfo, 1); + + name = gst_structure_get_string (cs, "name"); + gst_structure_get_boolean (cs, "is-encoder", &is_encoder); + gst_codec_info->name = g_strdup (name); + gst_codec_info->is_encoder = is_encoder; + + starr = gst_structure_get_value (cs, "supported-types"); + n2 = gst_value_array_get_size (starr); + + gst_codec_info->n_supported_types = n2; + gst_codec_info->supported_types = g_new0 (GstAmcCodecType, n2); + + for (j = 0; j < n2; j++) { + const GValue *stv = gst_value_array_get_value (starr, j); + const GstStructure *sts = gst_value_get_structure (stv); + const gchar *mime; + const GValue *cfarr; + const GValue *plarr; + guint k, n3; + GstAmcCodecType *gst_codec_type = &gst_codec_info->supported_types[j]; + + mime = gst_structure_get_string (sts, "mime"); + gst_codec_type->mime = g_strdup (mime); + + cfarr = gst_structure_get_value (sts, "color-formats"); + n3 = gst_value_array_get_size (cfarr); + + gst_codec_type->n_color_formats = n3; + gst_codec_type->color_formats = g_new0 (gint, n3); + + for (k = 0; k < n3; k++) { + const GValue *cfv = gst_value_array_get_value (cfarr, k); + gint cf = g_value_get_int (cfv); + + gst_codec_type->color_formats[k] = cf; + } + + plarr = gst_structure_get_value (sts, "profile-levels"); + n3 = gst_value_array_get_size (plarr); + + gst_codec_type->n_profile_levels = n3; + gst_codec_type->profile_levels = + g_malloc0 (sizeof (gst_codec_type->profile_levels[0]) * n3); + + for (k = 0; k < n3; k++) { + const GValue *plv = gst_value_array_get_value (plarr, k); + const GValue *p, *l; + + p = gst_value_array_get_value (plv, 0); + l = gst_value_array_get_value (plv, 1); + gst_codec_type->profile_levels[k].profile = g_value_get_int (p); + gst_codec_type->profile_levels[k].level = g_value_get_int (l); + } + } + + codec_infos = g_list_append (codec_infos, gst_codec_info); + } + + return TRUE; + } + + codec_count = media_codec_list_count_codecs (); + if (codec_count == 0) { + GST_ERROR ("Failed to get number of available codecs"); + goto done; + } + + GST_DEBUG ("Found %d available codecs", codec_count); + + for (i = 0; i < codec_count; i++) { + GstAmcCodecInfo *gst_codec_info; + const gchar *name_str = NULL; + gboolean is_encoder; + size_t n_supported_types = 0; + size_t j; + gboolean valid_codec = TRUE; + + gst_codec_info = g_new0 (GstAmcCodecInfo, 1); + + media_codec_list_get_codec_info_at_id (i); + + name_str = media_codec_list_get_codec_name (i); + if (!name_str) { + GST_ERROR ("Failed to get codec name"); + valid_codec = FALSE; + goto next_codec; + } + + GST_INFO ("Checking codec '%s'", name_str); + + /* FIXME: enable software decoders once we have software rendering + * working in mir */ + if (g_str_has_prefix (name_str, "OMX.google")) { + GST_INFO ("Skipping Google Software codec '%s'", name_str); + valid_codec = FALSE; + goto next_codec; + } + + /* Compatibility codec names */ + if (strcmp (name_str, "AACEncoder") == 0 || + strcmp (name_str, "OMX.google.raw.decoder") == 0) { + GST_INFO ("Skipping compatibility codec '%s'", name_str); + valid_codec = FALSE; + goto next_codec; + } + + if (g_str_has_suffix (name_str, ".secure")) { + GST_INFO ("Skipping DRM codec '%s'", name_str); + valid_codec = FALSE; + goto next_codec; + } + + /* FIXME: Non-Google codecs usually just don't work and hang forever + * or crash when not used from a process that started the Java + * VM via the non-public AndroidRuntime class. Can we somehow + * initialize all this? + */ +#if 0 + if (!g_str_has_prefix (name_str, "OMX.google.")) { + GST_INFO ("Skipping non-Google codec '%s' in standalone mode", name_str); + valid_codec = FALSE; + goto next_codec; + } +#endif + + if (g_str_has_prefix (name_str, "OMX.ARICENT.")) { + GST_INFO ("Skipping possible broken codec '%s'", name_str); + valid_codec = FALSE; + goto next_codec; + } + + /* FIXME: + * - Vorbis: Generates clicks for multi-channel streams + * - *Law: Generates output with too low frequencies + */ + if (strcmp (name_str, "OMX.google.vorbis.decoder") == 0 || + strcmp (name_str, "OMX.google.g711.alaw.decoder") == 0 || + strcmp (name_str, "OMX.google.g711.mlaw.decoder") == 0) { + GST_INFO ("Skipping known broken codec '%s'", name_str); + valid_codec = FALSE; + goto next_codec; + } + gst_codec_info->name = g_strdup (name_str); + + is_encoder = media_codec_list_is_encoder (i); + gst_codec_info->is_encoder = is_encoder; + + n_supported_types = media_codec_list_get_num_supported_types (i); + + GST_INFO ("Codec '%s' has %d supported types", name_str, n_supported_types); + + gst_codec_info->supported_types = + g_new0 (GstAmcCodecType, n_supported_types); + gst_codec_info->n_supported_types = n_supported_types; + + if (n_supported_types == 0) { + valid_codec = FALSE; + GST_ERROR ("Codec has no supported types"); + goto next_codec; + } + + for (j = 0; j < n_supported_types; j++) { + GstAmcCodecType *gst_codec_type; + gchar *supported_type_str; + guint32 *color_formats_elems = NULL; + size_t n_elems = 0, k; + int err = 0; + size_t len = 0; + gchar *mime = NULL; + + gst_codec_type = &gst_codec_info->supported_types[j]; + + len = media_codec_list_get_nth_supported_type_len (i, j); + supported_type_str = g_malloc (len); + err = media_codec_list_get_nth_supported_type (i, supported_type_str, j); + if (err > 0 || !supported_type_str) { + GST_ERROR ("Failed to get %d-th supported type", j); + valid_codec = FALSE; + goto next_supported_type; + } + + mime = g_malloc (len); + mime = locale_to_utf8 (supported_type_str, len); + if (!mime) { + GST_ERROR ("Failed to convert supported type to UTF8"); + valid_codec = FALSE; + goto next_supported_type; + } + + GST_INFO ("Supported type '%s'", mime); + gst_codec_type->mime = g_strdup (mime); + + n_elems = media_codec_list_get_num_color_formats (i, mime); + GST_INFO ("Type '%s' has %d supported color formats", mime, n_elems); + if (n_elems == 0) { + GST_INFO ("Zero supported color formats for type '%s'", mime); + valid_codec = FALSE; + goto next_supported_type; + } + gst_codec_type->n_color_formats = n_elems; + gst_codec_type->color_formats = g_new0 (gint, n_elems); + + color_formats_elems = g_new0 (guint32, n_elems); + err = + media_codec_list_get_codec_color_formats (i, mime, + color_formats_elems); + if (!color_formats_elems) { + GST_ERROR ("Failed to get color format elements"); + valid_codec = FALSE; + goto next_supported_type; + } + + for (k = 0; k < n_elems; k++) { + GST_INFO ("Color format %d: %d", k, color_formats_elems[k]); + gst_codec_type->color_formats[k] = color_formats_elems[k]; + } + + if (g_str_has_prefix (gst_codec_type->mime, "video/")) { + if (!n_elems) { + GST_ERROR ("No supported color formats for video codec"); + valid_codec = FALSE; + goto next_supported_type; + } + + if (!ignore_unknown_color_formats + && !accepted_color_formats (gst_codec_type, is_encoder)) { + GST_ERROR ("Codec has unknown color formats, ignoring"); + valid_codec = FALSE; + g_assert_not_reached (); + goto next_supported_type; + } + } + + n_elems = media_codec_list_get_num_profile_levels (i, mime); + GST_INFO ("Type '%s' has %d supported profile levels", mime, n_elems); + if (n_elems == 0) { + GST_INFO ("Zero supported profile levels for type '%s'", mime); + valid_codec = FALSE; + goto next_supported_type; + } + gst_codec_type->n_profile_levels = n_elems; + gst_codec_type->profile_levels = + g_malloc0 (sizeof (gst_codec_type->profile_levels[0]) * n_elems); + + for (k = 0; k < n_elems; k++) { + guint32 level = 0, profile = 0; + profile_level pro_level; + + err = + media_codec_list_get_nth_codec_profile_level (i, mime, &pro_level, + k); + if (err > 0) { + GST_ERROR ("Failed to get %d-th profile/level", k); + valid_codec = FALSE; + goto next_profile_level; + } + + level = pro_level.level; + profile = pro_level.profile; + + GST_INFO ("Level %d: 0x%08x", k, level); + gst_codec_type->profile_levels[k].level = level; + + GST_INFO ("Profile %d: 0x%08x", k, profile); + gst_codec_type->profile_levels[k].profile = profile; + + next_profile_level: + if (!valid_codec) + break; + } + + next_supported_type: + if (color_formats_elems) + g_free (color_formats_elems); + color_formats_elems = NULL; + if (supported_type_str) + g_free (supported_type_str); + supported_type_str = NULL; + if (mime) + g_free (mime); + mime = NULL; + if (!valid_codec) + break; + } + + /* We need at least a valid supported type */ + if (valid_codec) { + GST_LOG ("Successfully scanned codec '%s'", name_str); + codec_infos = g_list_append (codec_infos, gst_codec_info); + gst_codec_info = NULL; + } + + /* Clean up of all local references we got */ + next_codec: + if (gst_codec_info) { + gint j; + + for (j = 0; j < gst_codec_info->n_supported_types; j++) { + GstAmcCodecType *gst_codec_type = &gst_codec_info->supported_types[j]; + + g_free (gst_codec_type->mime); + g_free (gst_codec_type->color_formats); + g_free (gst_codec_type->profile_levels); + } + g_free (gst_codec_info->supported_types); + g_free (gst_codec_info->name); + g_free (gst_codec_info); + } + gst_codec_info = NULL; + valid_codec = TRUE; + } + + ret = codec_infos != NULL; + + /* If successful we store a cache of the codec information in + * the registry. Otherwise we would always load all codecs during + * plugin initialization which can take quite some time (because + * of hardware) and also loads lots of shared libraries (which + * number is limited by 64 in Android). + */ + if (ret) { + GstStructure *new_cache_data = gst_structure_new_empty ("gst-amc-cache"); + GList *l; + GValue arr = { 0, }; + + g_value_init (&arr, GST_TYPE_ARRAY); + + for (l = codec_infos; l; l = l->next) { + GstAmcCodecInfo *gst_codec_info = l->data; + GValue cv = { 0, }; + GstStructure *cs = gst_structure_new_empty ("gst-amc-codec"); + GValue starr = { 0, }; + gint i; + + gst_structure_set (cs, "name", G_TYPE_STRING, gst_codec_info->name, + "is-encoder", G_TYPE_BOOLEAN, gst_codec_info->is_encoder, NULL); + + g_value_init (&starr, GST_TYPE_ARRAY); + + for (i = 0; i < gst_codec_info->n_supported_types; i++) { + GstAmcCodecType *gst_codec_type = &gst_codec_info->supported_types[i]; + GstStructure *sts = gst_structure_new_empty ("gst-amc-supported-type"); + GValue stv = { 0, }; + GValue tmparr = { 0, }; + gint j; + + gst_structure_set (sts, "mime", G_TYPE_STRING, gst_codec_type->mime, + NULL); + + g_value_init (&tmparr, GST_TYPE_ARRAY); + for (j = 0; j < gst_codec_type->n_color_formats; j++) { + GValue tmp = { 0, }; + + g_value_init (&tmp, G_TYPE_INT); + g_value_set_int (&tmp, gst_codec_type->color_formats[j]); + gst_value_array_append_value (&tmparr, &tmp); + g_value_unset (&tmp); + } + gst_structure_set_value (sts, "color-formats", &tmparr); + g_value_unset (&tmparr); + + g_value_init (&tmparr, GST_TYPE_ARRAY); + for (j = 0; j < gst_codec_type->n_profile_levels; j++) { + GValue tmparr2 = { 0, }; + GValue tmp = { 0, }; + + g_value_init (&tmparr2, GST_TYPE_ARRAY); + g_value_init (&tmp, G_TYPE_INT); + g_value_set_int (&tmp, gst_codec_type->profile_levels[j].profile); + gst_value_array_append_value (&tmparr2, &tmp); + g_value_set_int (&tmp, gst_codec_type->profile_levels[j].level); + gst_value_array_append_value (&tmparr2, &tmp); + gst_value_array_append_value (&tmparr, &tmparr2); + g_value_unset (&tmp); + g_value_unset (&tmparr2); + } + gst_structure_set_value (sts, "profile-levels", &tmparr); + + g_value_init (&stv, GST_TYPE_STRUCTURE); + gst_value_set_structure (&stv, sts); + gst_value_array_append_value (&starr, &stv); + g_value_unset (&tmparr); + gst_structure_free (sts); + } + + gst_structure_set_value (cs, "supported-types", &starr); + g_value_unset (&starr); + + g_value_init (&cv, GST_TYPE_STRUCTURE); + gst_value_set_structure (&cv, cs); + gst_value_array_append_value (&arr, &cv); + g_value_unset (&cv); + gst_structure_free (cs); + } + + gst_structure_set_value (new_cache_data, "codecs", &arr); + g_value_unset (&arr); + + gst_plugin_set_cache_data (plugin, new_cache_data); + } + +done: + return ret; +} + +static const struct +{ + gint color_format; + GstVideoFormat video_format; +} color_format_mapping_table[] = { + { + COLOR_FormatYUV420Planar, GST_VIDEO_FORMAT_I420}, { + COLOR_FormatYUV420SemiPlanar, GST_VIDEO_FORMAT_NV12}, { + COLOR_TI_FormatYUV420PackedSemiPlanar, GST_VIDEO_FORMAT_NV12}, { + COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, GST_VIDEO_FORMAT_NV12}, { + COLOR_QCOM_FormatYUV420SemiPlanar, GST_VIDEO_FORMAT_NV12}, { + COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, GST_VIDEO_FORMAT_NV12}, { + COLOR_EXYNOS_FormatNV12Tiled, GST_VIDEO_FORMAT_NV12}, { + COLOR_EXYNOS_FormatNV21Linear, GST_VIDEO_FORMAT_NV21}, { + 256, GST_VIDEO_FORMAT_NV12}, { + 263, GST_VIDEO_FORMAT_NV12} +}; + +static gboolean +accepted_color_formats (GstAmcCodecType * type, gboolean is_encoder) +{ + gint i, j; + gint accepted = 0, all = type->n_color_formats; + + for (i = 0; i < type->n_color_formats; i++) { + gboolean found = FALSE; + /* We ignore this one */ + if (type->color_formats[i] == COLOR_FormatAndroidOpaque) + all--; + + for (j = 0; j < G_N_ELEMENTS (color_format_mapping_table); j++) { + //g_print("color_format_mapping_table[%d].color_format: %d, type->color_formats[%d]: %d", j, color_format_mapping_table[j].color_format, i, type->color_formats[i]); + if (color_format_mapping_table[j].color_format == type->color_formats[i]) { + found = TRUE; + break; + } + } + + if (found) + accepted++; + } + + if (is_encoder) + return accepted > 0; + else + return accepted == all && all > 0; +} + +GstVideoFormat +gst_amc_color_format_to_video_format (gint color_format) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (color_format_mapping_table); i++) { + if (color_format_mapping_table[i].color_format == color_format) + return color_format_mapping_table[i].video_format; + } + + return GST_VIDEO_FORMAT_UNKNOWN; +} + +gint +gst_amc_video_format_to_color_format (GstVideoFormat video_format) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (color_format_mapping_table); i++) { + if (color_format_mapping_table[i].video_format == video_format) + return color_format_mapping_table[i].color_format; + } + + return -1; +} + +static const struct +{ + gint id; + const gchar *str; + const gchar *alt_str; +} avc_profile_mapping_table[] = { + { + AVCProfileBaseline, "baseline", "constrained-baseline"}, { + AVCProfileMain, "main", NULL}, { + AVCProfileExtended, "extended", NULL}, { + AVCProfileHigh, "high"}, { + AVCProfileHigh10, "high-10", "high-10-intra"}, { + AVCProfileHigh422, "high-4:2:2", "high-4:2:2-intra"}, { + AVCProfileHigh444, "high-4:4:4", "high-4:4:4-intra"} +}; + +const gchar * +gst_amc_avc_profile_to_string (gint profile, const gchar ** alternative) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (avc_profile_mapping_table); i++) { + if (avc_profile_mapping_table[i].id == profile) { + *alternative = avc_profile_mapping_table[i].alt_str; + return avc_profile_mapping_table[i].str; + } + } + + return NULL; +} + +gint +gst_amc_avc_profile_from_string (const gchar * profile) +{ + gint i; + + g_return_val_if_fail (profile != NULL, -1); + + for (i = 0; i < G_N_ELEMENTS (avc_profile_mapping_table); i++) { + if (strcmp (avc_profile_mapping_table[i].str, profile) == 0) + return avc_profile_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + const gchar *str; +} avc_level_mapping_table[] = { + { + AVCLevel1, "1"}, { + AVCLevel1b, "1b"}, { + AVCLevel11, "1.1"}, { + AVCLevel12, "1.2"}, { + AVCLevel13, "1.3"}, { + AVCLevel2, "2"}, { + AVCLevel21, "2.1"}, { + AVCLevel22, "2.2"}, { + AVCLevel3, "3"}, { + AVCLevel31, "3.1"}, { + AVCLevel32, "3.2"}, { + AVCLevel4, "4"}, { + AVCLevel41, "4.1"}, { + AVCLevel42, "4.2"}, { + AVCLevel5, "5"}, { + AVCLevel51, "5.1"} +}; + +const gchar * +gst_amc_avc_level_to_string (gint level) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (avc_level_mapping_table); i++) { + if (avc_level_mapping_table[i].id == level) + return avc_level_mapping_table[i].str; + } + + return NULL; +} + +gint +gst_amc_avc_level_from_string (const gchar * level) +{ + gint i; + + g_return_val_if_fail (level != NULL, -1); + + for (i = 0; i < G_N_ELEMENTS (avc_level_mapping_table); i++) { + if (strcmp (avc_level_mapping_table[i].str, level) == 0) + return avc_level_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + gint gst_id; +} h263_profile_mapping_table[] = { + { + H263ProfileBaseline, 0}, { + H263ProfileH320Coding, 1}, { + H263ProfileBackwardCompatible, 2}, { + H263ProfileISWV2, 3}, { + H263ProfileISWV3, 4}, { + H263ProfileHighCompression, 5}, { + H263ProfileInternet, 6}, { + H263ProfileInterlace, 7}, { + H263ProfileHighLatency, 8} +}; + +gint +gst_amc_h263_profile_to_gst_id (gint profile) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (h263_profile_mapping_table); i++) { + if (h263_profile_mapping_table[i].id == profile) + return h263_profile_mapping_table[i].gst_id; + } + + return -1; +} + +gint +gst_amc_h263_profile_from_gst_id (gint profile) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (h263_profile_mapping_table); i++) { + if (h263_profile_mapping_table[i].gst_id == profile) + return h263_profile_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + gint gst_id; +} h263_level_mapping_table[] = { + { + H263Level10, 10}, { + H263Level20, 20}, { + H263Level30, 30}, { + H263Level40, 40}, { + H263Level50, 50}, { + H263Level60, 60}, { + H263Level70, 70} +}; + +gint +gst_amc_h263_level_to_gst_id (gint level) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (h263_level_mapping_table); i++) { + if (h263_level_mapping_table[i].id == level) + return h263_level_mapping_table[i].gst_id; + } + + return -1; +} + +gint +gst_amc_h263_level_from_gst_id (gint level) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (h263_level_mapping_table); i++) { + if (h263_level_mapping_table[i].gst_id == level) + return h263_level_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + const gchar *str; +} mpeg4_profile_mapping_table[] = { + { + MPEG4ProfileSimple, "simple"}, { + MPEG4ProfileSimpleScalable, "simple-scalable"}, { + MPEG4ProfileCore, "core"}, { + MPEG4ProfileMain, "main"}, { + MPEG4ProfileNbit, "n-bit"}, { + MPEG4ProfileScalableTexture, "scalable"}, { + MPEG4ProfileSimpleFace, "simple-face"}, { + MPEG4ProfileSimpleFBA, "simple-fba"}, { + MPEG4ProfileBasicAnimated, "basic-animated-texture"}, { + MPEG4ProfileHybrid, "hybrid"}, { + MPEG4ProfileAdvancedRealTime, "advanced-real-time"}, { + MPEG4ProfileCoreScalable, "core-scalable"}, { + MPEG4ProfileAdvancedCoding, "advanced-coding-efficiency"}, { + MPEG4ProfileAdvancedCore, "advanced-core"}, { + MPEG4ProfileAdvancedScalable, "advanced-scalable-texture"}, { + MPEG4ProfileAdvancedSimple, "advanced-simple"} +}; + +const gchar * +gst_amc_mpeg4_profile_to_string (gint profile) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (mpeg4_profile_mapping_table); i++) { + if (mpeg4_profile_mapping_table[i].id == profile) + return mpeg4_profile_mapping_table[i].str; + } + + return NULL; +} + +gint +gst_amc_avc_mpeg4_profile_from_string (const gchar * profile) +{ + gint i; + + g_return_val_if_fail (profile != NULL, -1); + + for (i = 0; i < G_N_ELEMENTS (mpeg4_profile_mapping_table); i++) { + if (strcmp (mpeg4_profile_mapping_table[i].str, profile) == 0) + return mpeg4_profile_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + const gchar *str; +} mpeg4_level_mapping_table[] = { + { + MPEG4Level0, "0"}, { + MPEG4Level0b, "0b"}, { + MPEG4Level1, "1"}, { + MPEG4Level2, "2"}, { + MPEG4Level3, "3"}, { + MPEG4Level4, "4"}, { + MPEG4Level4a, "4a"}, { +MPEG4Level5, "5"},}; + +const gchar * +gst_amc_mpeg4_level_to_string (gint level) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (mpeg4_level_mapping_table); i++) { + if (mpeg4_level_mapping_table[i].id == level) + return mpeg4_level_mapping_table[i].str; + } + + return NULL; +} + +gint +gst_amc_mpeg4_level_from_string (const gchar * level) +{ + gint i; + + g_return_val_if_fail (level != NULL, -1); + + for (i = 0; i < G_N_ELEMENTS (mpeg4_level_mapping_table); i++) { + if (strcmp (mpeg4_level_mapping_table[i].str, level) == 0) + return mpeg4_level_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + gint id; + const gchar *str; +} aac_profile_mapping_table[] = { + { + AACObjectMain, "main"}, { + AACObjectLC, "lc"}, { + AACObjectSSR, "ssr"}, { + AACObjectLTP, "ltp"} +}; + +const gchar * +gst_amc_aac_profile_to_string (gint profile) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (aac_profile_mapping_table); i++) { + if (aac_profile_mapping_table[i].id == profile) + return aac_profile_mapping_table[i].str; + } + + return NULL; +} + +gint +gst_amc_aac_profile_from_string (const gchar * profile) +{ + gint i; + + g_return_val_if_fail (profile != NULL, -1); + + for (i = 0; i < G_N_ELEMENTS (aac_profile_mapping_table); i++) { + if (strcmp (aac_profile_mapping_table[i].str, profile) == 0) + return aac_profile_mapping_table[i].id; + } + + return -1; +} + +static const struct +{ + guint32 mask; + GstAudioChannelPosition pos; +} channel_mapping_table[] = { + { + CHANNEL_OUT_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, { + CHANNEL_OUT_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, { + CHANNEL_OUT_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, { + CHANNEL_OUT_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, { + CHANNEL_OUT_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, { + CHANNEL_OUT_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, { + CHANNEL_OUT_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, { + CHANNEL_OUT_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, { + CHANNEL_OUT_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, { + CHANNEL_OUT_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, { + CHANNEL_OUT_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, { + CHANNEL_OUT_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_INVALID}, { + CHANNEL_OUT_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_INVALID} +}; + +gboolean +gst_amc_audio_channel_mask_to_positions (guint32 channel_mask, gint channels, + GstAudioChannelPosition * pos) +{ + gint i, j; + + if (channel_mask == 0) { + if (channels == 1) { + pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO; + return TRUE; + } + if (channels == 2) { + pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; + pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; + return TRUE; + } + + /* Now let the guesswork begin, these are the + * AAC default channel assignments for these numbers + * of channels */ + if (channels == 3) { + channel_mask = + CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER; + } else if (channels == 4) { + channel_mask = + CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER; + } else if (channels == 5) { + channel_mask = + CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_LEFT | + CHANNEL_OUT_BACK_RIGHT; + } else if (channels == 6) { + channel_mask = + CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_LEFT | + CHANNEL_OUT_BACK_RIGHT | CHANNEL_OUT_LOW_FREQUENCY; + } else if (channels == 8) { + channel_mask = + CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_LEFT | + CHANNEL_OUT_BACK_RIGHT | CHANNEL_OUT_LOW_FREQUENCY | + CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER; + } + } + + for (i = 0, j = 0; i < G_N_ELEMENTS (channel_mapping_table); i++) { + if ((channel_mask & channel_mapping_table[i].mask)) { + pos[j++] = channel_mapping_table[i].pos; + if (channel_mapping_table[i].pos == GST_AUDIO_CHANNEL_POSITION_INVALID) { + memset (pos, 0, sizeof (GstAudioChannelPosition) * channels); + GST_ERROR ("Unable to map channel mask 0x%08x", + channel_mapping_table[i].mask); + return FALSE; + } + if (j == channels) + break; + } + } + + if (j != channels) { + memset (pos, 0, sizeof (GstAudioChannelPosition) * channels); + GST_ERROR ("Unable to map all channel positions in mask 0x%08x", + channel_mask); + return FALSE; + } + + return TRUE; +} + +guint32 +gst_amc_audio_channel_mask_from_positions (GstAudioChannelPosition * positions, + gint channels) +{ + gint i, j; + guint32 channel_mask = 0; + + if (channels == 1 && !positions) + return CHANNEL_OUT_FRONT_CENTER; + if (channels == 2 && !positions) + return CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT; + + for (i = 0; i < channels; i++) { + if (positions[i] == GST_AUDIO_CHANNEL_POSITION_INVALID) + return 0; + + for (j = 0; j < G_N_ELEMENTS (channel_mapping_table); j++) { + if (channel_mapping_table[j].pos == positions[i]) { + channel_mask |= channel_mapping_table[j].mask; + break; + } + } + + if (j == G_N_ELEMENTS (channel_mapping_table)) { + GST_ERROR ("Unable to map channel position %d", positions[i]); + return 0; + } + } + + return channel_mask; +} + +static gchar * +create_type_name (const gchar * parent_name, const gchar * codec_name) +{ + gchar *typified_name; + gint i, k; + gint parent_name_len = strlen (parent_name); + gint codec_name_len = strlen (codec_name); + gboolean upper = TRUE; + + typified_name = g_new0 (gchar, parent_name_len + 1 + strlen (codec_name) + 1); + memcpy (typified_name, parent_name, parent_name_len); + typified_name[parent_name_len] = '-'; + + for (i = 0, k = 0; i < codec_name_len; i++) { + if (g_ascii_isalnum (codec_name[i])) { + if (upper) + typified_name[parent_name_len + 1 + k++] = + g_ascii_toupper (codec_name[i]); + else + typified_name[parent_name_len + 1 + k++] = + g_ascii_tolower (codec_name[i]); + + upper = FALSE; + } else { + /* Skip all non-alnum chars and start a new upper case word */ + upper = TRUE; + } + } + + return typified_name; +} + +static gchar * +create_element_name (gboolean video, gboolean encoder, const gchar * codec_name) +{ +#define PREFIX_LEN 10 + static const gchar *prefixes[] = { + "amcviddec-", + "amcauddec-", + "amcvidenc-", + "amcaudenc-" + }; + gchar *element_name; + gint i, k; + gint codec_name_len = strlen (codec_name); + const gchar *prefix; + + if (video && !encoder) + prefix = prefixes[0]; + else if (!video && !encoder) + prefix = prefixes[1]; + else if (video && encoder) + prefix = prefixes[2]; + else + prefix = prefixes[3]; + + element_name = g_new0 (gchar, PREFIX_LEN + strlen (codec_name) + 1); + memcpy (element_name, prefix, PREFIX_LEN); + + for (i = 0, k = 0; i < codec_name_len; i++) { + if (g_ascii_isalnum (codec_name[i])) { + element_name[PREFIX_LEN + k++] = g_ascii_tolower (codec_name[i]); + } + /* Skip all non-alnum chars */ + } + + return element_name; +} + +#undef PREFIX_LEN + +static gboolean +register_codecs (GstPlugin * plugin) +{ + gboolean ret = TRUE; + GList *l; + + GST_DEBUG ("Registering plugins"); + + for (l = codec_infos; l; l = l->next) { + GstAmcCodecInfo *codec_info = l->data; + gboolean is_audio = FALSE; + gboolean is_video = FALSE; + gint i; + gint n_types; + + GST_DEBUG ("Registering codec '%s'", codec_info->name); + for (i = 0; i < codec_info->n_supported_types; i++) { + GstAmcCodecType *codec_type = &codec_info->supported_types[i]; + + if (g_str_has_prefix (codec_type->mime, "audio/")) + is_audio = TRUE; + else if (g_str_has_prefix (codec_type->mime, "video/")) + is_video = TRUE; + } + + n_types = 0; + if (is_audio) + n_types++; + if (is_video) + n_types++; + + for (i = 0; i < n_types; i++) { + GTypeQuery type_query; + GTypeInfo type_info = { 0, }; + GType type, subtype; + gchar *type_name, *element_name; + guint rank; + + if (is_video && !codec_info->is_encoder) { + type = gst_amc_video_dec_get_type (); + } else if (is_audio && !codec_info->is_encoder) { + type = gst_amc_audio_dec_get_type (); + } else { + GST_DEBUG ("Skipping unsupported codec type"); + continue; + } + + g_type_query (type, &type_query); + memset (&type_info, 0, sizeof (type_info)); + type_info.class_size = type_query.class_size; + type_info.instance_size = type_query.instance_size; + type_name = create_type_name (type_query.type_name, codec_info->name); + + if (g_type_from_name (type_name) != G_TYPE_INVALID) { + GST_ERROR ("Type '%s' already exists for codec '%s'", type_name, + codec_info->name); + g_free (type_name); + continue; + } + + subtype = g_type_register_static (type, type_name, &type_info, 0); + g_free (type_name); + + g_type_set_qdata (subtype, gst_amc_codec_info_quark, codec_info); + + element_name = + create_element_name (is_video, codec_info->is_encoder, + codec_info->name); + + /* Give the Google software codec a secondary rank, + * everything else is likely a hardware codec */ + if (g_str_has_prefix (codec_info->name, "OMX.google")) + rank = GST_RANK_SECONDARY; + else + rank = GST_RANK_PRIMARY; + + ret |= gst_element_register (plugin, element_name, rank, subtype); + g_free (element_name); + + is_video = FALSE; + } + } + + return ret; +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + const gchar *ignore; + + GST_DEBUG_CATEGORY_INIT (gst_amc_debug, "amc", 0, "android-media-codec"); + + gst_plugin_add_dependency_simple (plugin, NULL, "/system/etc", + "media_codecs.xml", GST_PLUGIN_DEPENDENCY_FLAG_NONE); + + /* Set this to TRUE to allow registering decoders that have + * any unknown color formats, or encoders that only have + * unknown color formats + */ + ignore = g_getenv ("GST_AMC_IGNORE_UNKNOWN_COLOR_FORMATS"); + if (ignore && strcmp (ignore, "yes") == 0) + ignore_unknown_color_formats = TRUE; + + /* Check if the media compat layer is available */ + if (!media_compat_check_availability ()) + return FALSE; + + if (!scan_codecs (plugin)) + return FALSE; + + gst_amc_codec_info_quark = g_quark_from_static_string ("gst-amc-codec-info"); + + if (!register_codecs (plugin)) + return FALSE; + + GST_DEBUG ("Finished %s", __PRETTY_FUNCTION__); + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + androidmedia, + "Android Media Hybris plugin", + plugin_init, + PACKAGE_VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/sys/androidmedia/gstamcvideodec.h b/sys/androidmedia/gstamcvideodec.h index 3353dc6..2ff0ad1 100644 --- a/sys/androidmedia/gstamcvideodec.h +++ b/sys/androidmedia/gstamcvideodec.h @@ -25,6 +25,10 @@ #include +#ifdef HAVE_ANDROID_MEDIA_HYBRIS + #include +#endif + #include "gstamc.h" G_BEGIN_DECLS @@ -57,6 +61,11 @@ struct _GstAmcVideoDec GstVideoCodecState *input_state; gboolean input_state_changed; + /* Current timeout value to pass for doing + * queueing/dequeueing of input/output buffers + */ + gint64 current_timeout; + /* Output format of the codec */ GstVideoFormat format; gint color_format; @@ -71,6 +80,10 @@ struct _GstAmcVideoDec gboolean started; gboolean flushing; +#ifdef HAVE_ANDROID_MEDIA_HYBRIS + guint8 num_outbuf_dequeue_tries; +#endif + GstClockTime last_upstream_ts; /* Draining state */ diff --git a/sys/androidmedia/gstamcvideodechybris.c b/sys/androidmedia/gstamcvideodechybris.c new file mode 100644 index 0000000..36aa4b8 --- /dev/null +++ b/sys/androidmedia/gstamcvideodechybris.c @@ -0,0 +1,2100 @@ +/* + * Initially based on gstamcvideodec.c + * + * Copyright (C) 2011, Hewlett-Packard Development Company, L.P. + * Author: Sebastian Dröge , Collabora Ltd. + * + * Copyright (C) 2012, Collabora Ltd. + * Author: Sebastian Dröge + * + * Copyright (C) 2012, Rafaël Carré + * + * Copyright (C) 2013, Canonical Ltd.. + * Author: Jim Hodapp + * + * 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 + * version 2.1 of the License. + * + * 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 + +#include +#include + +#ifdef HAVE_ORC +#include +#else +#define orc_memcpy memcpy +#endif + +#include "gstamcvideodec.h" +#include "gstamc-constants.h" + +GST_DEBUG_CATEGORY_STATIC (gst_amc_video_dec_debug_category); +#define GST_CAT_DEFAULT gst_amc_video_dec_debug_category + +typedef struct _BufferIdentification BufferIdentification; +struct _BufferIdentification +{ + guint64 timestamp; +}; + +static BufferIdentification * +buffer_identification_new (GstClockTime timestamp) +{ + BufferIdentification *id = g_slice_new (BufferIdentification); + + id->timestamp = timestamp; + + return id; +} + +static void +buffer_identification_free (BufferIdentification * id) +{ + g_slice_free (BufferIdentification, id); +} + +/* prototypes */ +static void gst_amc_video_dec_finalize (GObject * object); + +static GstStateChangeReturn +gst_amc_video_dec_change_state (GstElement * element, + GstStateChange transition); + +static gboolean gst_amc_video_dec_open (GstVideoDecoder * decoder); +static gboolean gst_amc_video_dec_close (GstVideoDecoder * decoder); +static gboolean gst_amc_video_dec_start (GstVideoDecoder * decoder); +static gboolean gst_amc_video_dec_stop (GstVideoDecoder * decoder); +static gboolean gst_amc_video_dec_set_format (GstVideoDecoder * decoder, + GstVideoCodecState * state); +static gboolean gst_amc_video_dec_flush (GstVideoDecoder * decoder); +static GstFlowReturn gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder, + GstVideoCodecFrame * frame); +static GstFlowReturn gst_amc_video_dec_finish (GstVideoDecoder * decoder); +static void gst_amc_video_dec_set_context (GstElement * element, + GstContext * context); +static gboolean gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec, + GstQuery * query); + +static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self, + gboolean at_eos); + +enum +{ + PROP_0 +}; + +/* class initialization */ + +static void gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass); +static void gst_amc_video_dec_init (GstAmcVideoDec * self); +static void gst_amc_video_dec_base_init (gpointer g_class); + +static GstVideoDecoderClass *parent_class = NULL; + +GType +gst_amc_video_dec_get_type (void) +{ + static volatile gsize type = 0; + + if (g_once_init_enter (&type)) { + GType _type; + static const GTypeInfo info = { + sizeof (GstAmcVideoDecClass), + gst_amc_video_dec_base_init, + NULL, + (GClassInitFunc) gst_amc_video_dec_class_init, + NULL, + NULL, + sizeof (GstAmcVideoDec), + 0, + (GInstanceInitFunc) gst_amc_video_dec_init, + NULL + }; + + _type = g_type_register_static (GST_TYPE_VIDEO_DECODER, "GstAmcVideoDec", + &info, 0); + + GST_DEBUG_CATEGORY_INIT (gst_amc_video_dec_debug_category, "amcvideodec", 0, + "Android MediaCodec video decoder"); + + g_once_init_leave (&type, _type); + } + return type; +} + +static GstCaps * +create_sink_caps (const GstAmcCodecInfo * codec_info) +{ + GstCaps *ret; + gint i; + + ret = gst_caps_new_empty (); + + for (i = 0; i < codec_info->n_supported_types; i++) { + const GstAmcCodecType *type = &codec_info->supported_types[i]; + + if (strcmp (type->mime, "video/mp4v-es") == 0) { + gint j; + GstStructure *tmp, *tmp2; + gboolean have_profile_level = FALSE; + + tmp = gst_structure_new ("video/mpeg", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + "mpegversion", G_TYPE_INT, 4, + "systemstream", G_TYPE_BOOLEAN, FALSE, + "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + + if (type->n_profile_levels) { + for (j = type->n_profile_levels - 1; j >= 0; j--) { + const gchar *profile, *level; + gint k; + GValue va = { 0, }; + GValue v = { 0, }; + + g_value_init (&va, GST_TYPE_LIST); + g_value_init (&v, G_TYPE_STRING); + + profile = + gst_amc_mpeg4_profile_to_string (type->profile_levels[j].profile); + if (!profile) { + GST_ERROR ("Unable to map MPEG4 profile 0x%08x", + type->profile_levels[j].profile); + continue; + } + + for (k = 1; k <= type->profile_levels[j].level && k != 0; k <<= 1) { + level = gst_amc_mpeg4_level_to_string (k); + if (!level) + continue; + + g_value_set_string (&v, level); + gst_value_list_append_value (&va, &v); + g_value_reset (&v); + } + + tmp2 = gst_structure_copy (tmp); + gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL); + gst_structure_set_value (tmp2, "level", &va); + g_value_unset (&va); + g_value_unset (&v); + ret = gst_caps_merge_structure (ret, tmp2); + have_profile_level = TRUE; + } + } + + if (!have_profile_level) { + ret = gst_caps_merge_structure (ret, tmp); + } else { + gst_structure_free (tmp); + } + + tmp = gst_structure_new ("video/x-divx", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + "divxversion", GST_TYPE_INT_RANGE, 3, 5, + "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "video/3gpp") == 0) { + gint j; + GstStructure *tmp, *tmp2; + gboolean have_profile_level = FALSE; + + tmp = gst_structure_new ("video/x-h263", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + "parsed", G_TYPE_BOOLEAN, TRUE, + "variant", G_TYPE_STRING, "itu", NULL); + + if (type->n_profile_levels) { + for (j = type->n_profile_levels - 1; j >= 0; j--) { + gint profile, level; + gint k; + GValue va = { 0, }; + GValue v = { 0, }; + + g_value_init (&va, GST_TYPE_LIST); + g_value_init (&v, G_TYPE_UINT); + + profile = + gst_amc_h263_profile_to_gst_id (type->profile_levels[j].profile); + + if (profile == -1) { + GST_ERROR ("Unable to map h263 profile 0x%08x", + type->profile_levels[j].profile); + continue; + } + + for (k = 1; k <= type->profile_levels[j].level && k != 0; k <<= 1) { + level = gst_amc_h263_level_to_gst_id (k); + if (level == -1) + continue; + + g_value_set_uint (&v, level); + gst_value_list_append_value (&va, &v); + g_value_reset (&v); + } + tmp2 = gst_structure_copy (tmp); + gst_structure_set (tmp2, "profile", G_TYPE_UINT, profile, NULL); + gst_structure_set_value (tmp2, "level", &va); + g_value_unset (&va); + g_value_unset (&v); + ret = gst_caps_merge_structure (ret, tmp2); + have_profile_level = TRUE; + } + } + + if (!have_profile_level) { + ret = gst_caps_merge_structure (ret, tmp); + } else { + gst_structure_free (tmp); + } + } else if (strcmp (type->mime, "video/avc") == 0) { + gint j; + GstStructure *tmp, *tmp2; + gboolean have_profile_level = FALSE; + + tmp = gst_structure_new ("video/x-h264", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + "parsed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, "byte-stream", + "alignment", G_TYPE_STRING, "au", NULL); + + if (type->n_profile_levels) { + for (j = type->n_profile_levels - 1; j >= 0; j--) { + const gchar *profile, *alternative = NULL, *level; + gint k; + GValue va = { 0, }; + GValue v = { 0, }; + + g_value_init (&va, GST_TYPE_LIST); + g_value_init (&v, G_TYPE_STRING); + + profile = + gst_amc_avc_profile_to_string (type->profile_levels[j].profile, + &alternative); + + if (!profile) { + GST_ERROR ("Unable to map H264 profile 0x%08x", + type->profile_levels[j].profile); + continue; + } + + for (k = 1; k <= type->profile_levels[j].level && k != 0; k <<= 1) { + level = gst_amc_avc_level_to_string (k); + if (!level) + continue; + + g_value_set_string (&v, level); + gst_value_list_append_value (&va, &v); + g_value_reset (&v); + } + tmp2 = gst_structure_copy (tmp); + gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL); + gst_structure_set_value (tmp2, "level", &va); + if (!alternative) + g_value_unset (&va); + g_value_unset (&v); + ret = gst_caps_merge_structure (ret, tmp2); + + if (alternative) { + tmp2 = gst_structure_copy (tmp); + gst_structure_set (tmp2, "profile", G_TYPE_STRING, alternative, + NULL); + gst_structure_set_value (tmp2, "level", &va); + g_value_unset (&va); + ret = gst_caps_merge_structure (ret, tmp2); + } + have_profile_level = TRUE; + } + } + + if (!have_profile_level) { + ret = gst_caps_merge_structure (ret, tmp); + } else { + gst_structure_free (tmp); + } + } else if (strcmp (type->mime, "video/x-vnd.on2.vp8") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("video/x-vp8", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + + ret = gst_caps_merge_structure (ret, tmp); + } else if (strcmp (type->mime, "video/mpeg2") == 0) { + GstStructure *tmp; + + tmp = gst_structure_new ("video/mpeg", + "width", GST_TYPE_INT_RANGE, 16, 4096, + "height", GST_TYPE_INT_RANGE, 16, 4096, + "framerate", GST_TYPE_FRACTION_RANGE, + 0, 1, G_MAXINT, 1, + "mpegversion", GST_TYPE_INT_RANGE, 1, 2, + "systemstream", G_TYPE_BOOLEAN, FALSE, + "parsed", G_TYPE_BOOLEAN, TRUE, NULL); + + ret = gst_caps_merge_structure (ret, tmp); + } else { + GST_WARNING ("Unsupported mimetype '%s'", type->mime); + } + } + + return ret; +} + +static const gchar * +caps_to_mime (GstCaps * caps) +{ + GstStructure *s; + const gchar *name; + + s = gst_caps_get_structure (caps, 0); + if (!s) + return NULL; + + name = gst_structure_get_name (s); + + if (strcmp (name, "video/mpeg") == 0) { + gint mpegversion; + + if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) + return NULL; + + if (mpegversion == 4) + return "video/mp4v-es"; + else if (mpegversion == 1 || mpegversion == 2) + return "video/mpeg2"; + } else if (strcmp (name, "video/x-h263") == 0) { + return "video/3gpp"; + } else if (strcmp (name, "video/x-h264") == 0) { + return "video/avc"; + } else if (strcmp (name, "video/x-vp8") == 0) { + return "video/x-vnd.on2.vp8"; + } else if (strcmp (name, "video/x-divx") == 0) { + return "video/mp4v-es"; + } + + return NULL; +} + +static GstCaps * +create_src_caps (const GstAmcCodecInfo * codec_info) +{ + GstCaps *ret; + gint i; + + ret = gst_caps_new_empty (); + + for (i = 0; i < codec_info->n_supported_types; i++) { + const GstAmcCodecType *type = &codec_info->supported_types[i]; + gint j; + + for (j = 0; j < type->n_color_formats; j++) { + GstVideoFormat format; + GstCaps *tmp; + + format = gst_amc_color_format_to_video_format (type->color_formats[j]); + if (format == GST_VIDEO_FORMAT_UNKNOWN) { + GST_WARNING ("Unknown color format 0x%08x", type->color_formats[j]); + continue; + } + + tmp = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, gst_video_format_to_string (format), + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + ret = gst_caps_merge (ret, tmp); + } + } + + return ret; +} + +static void +gst_amc_video_dec_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + GstAmcVideoDecClass *amcvideodec_class = GST_AMC_VIDEO_DEC_CLASS (g_class); + const GstAmcCodecInfo *codec_info; + GstPadTemplate *templ; + GstCaps *caps; + gchar *longname; + + codec_info = + g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), gst_amc_codec_info_quark); + /* This happens for the base class and abstract subclasses */ + if (!codec_info) + return; + + amcvideodec_class->codec_info = codec_info; + + /* Add pad templates */ + caps = create_sink_caps (codec_info); + templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (caps); + + caps = create_src_caps (codec_info); + templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps); + gst_element_class_add_pad_template (element_class, templ); + gst_caps_unref (caps); + + longname = g_strdup_printf ("Android MediaCodec Hybris %s", codec_info->name); + gst_element_class_set_metadata (element_class, + codec_info->name, + "Codec/Decoder/Video", longname, "Jim Hodapp "); + g_free (longname); +} + +static void +gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstVideoDecoderClass *videodec_class = GST_VIDEO_DECODER_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = gst_amc_video_dec_finalize; + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_amc_video_dec_change_state); + element_class->set_context = + GST_DEBUG_FUNCPTR (gst_amc_video_dec_set_context); + + videodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_video_dec_start); + videodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_video_dec_stop); + videodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_video_dec_open); + videodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_video_dec_close); + videodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_video_dec_flush); + videodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_video_dec_set_format); + videodec_class->handle_frame = + GST_DEBUG_FUNCPTR (gst_amc_video_dec_handle_frame); + videodec_class->finish = GST_DEBUG_FUNCPTR (gst_amc_video_dec_finish); + videodec_class->decide_allocation = + GST_DEBUG_FUNCPTR (gst_amc_video_dec_decide_allocation); +} + +static void +gst_amc_video_dec_init (GstAmcVideoDec * self) +{ + gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE); + + g_mutex_init (&self->drain_lock); + g_cond_init (&self->drain_cond); + + /* Start queueing/dequeueing operations with a timeout of 0 */ + self->current_timeout = 0; +} + +static gboolean +gst_amc_video_dec_open (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder); + GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self); + + GST_DEBUG_OBJECT (self, "Opening hardware decoder"); + + self->codec = gst_amc_codec_new (klass->codec_info->name); + if (!self->codec) { + GST_WARNING_OBJECT (self, "Failed to get valid hardware decoder"); + return FALSE; + } + self->started = FALSE; + self->flushing = TRUE; + + self->num_outbuf_dequeue_tries = 0; + + return TRUE; +} + +static gboolean +gst_amc_video_dec_close (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Closing decoder"); + + if (self->codec) + gst_amc_codec_free (self->codec); + self->codec = NULL; + + self->started = FALSE; + self->flushing = TRUE; + + GST_DEBUG_OBJECT (self, "Closed decoder"); + + return TRUE; +} + +static void +gst_amc_video_dec_finalize (GObject * object) +{ + GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (object); + + g_mutex_clear (&self->drain_lock); + g_cond_clear (&self->drain_cond); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static GstStateChangeReturn +gst_amc_video_dec_change_state (GstElement * element, GstStateChange transition) +{ + GstAmcVideoDec *self; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + g_return_val_if_fail (GST_IS_AMC_VIDEO_DEC (element), + GST_STATE_CHANGE_FAILURE); + self = GST_AMC_VIDEO_DEC (element); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + self->downstream_flow_ret = GST_FLOW_OK; + self->draining = FALSE; + self->started = FALSE; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + self->flushing = TRUE; + gst_amc_codec_flush (self->codec); + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + break; + default: + break; + } + + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + 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: + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->started = FALSE; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + break; + default: + break; + } + + return ret; +} + +#define MAX_FRAME_DIST_TIME (5 * GST_SECOND) +#define MAX_FRAME_DIST_FRAMES (100) + +static GstVideoCodecFrame * +_find_nearest_frame (GstAmcVideoDec * self, GstClockTime reference_timestamp) +{ + GList *l, *best_l = NULL; + GList *finish_frames = NULL; + GstVideoCodecFrame *best = NULL; + guint64 best_timestamp = 0; + guint64 best_diff = G_MAXUINT64; + BufferIdentification *best_id = NULL; + GList *frames; + + frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)); + + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; + BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); + guint64 timestamp, diff; + + /* This happens for frames that were just added but + * which were not passed to the component yet. Ignore + * them here! + */ + if (!id) + continue; + + timestamp = id->timestamp; + + if (timestamp > reference_timestamp) + diff = timestamp - reference_timestamp; + else + diff = reference_timestamp - timestamp; + + if (best == NULL || diff < best_diff) { + best = tmp; + best_timestamp = timestamp; + best_diff = diff; + best_l = l; + best_id = id; + + /* For frames without timestamp we simply take the first frame */ + if ((reference_timestamp == 0 && timestamp == 0) || diff == 0) + break; + } + } + + if (best_id) { + for (l = frames; l && l != best_l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; + BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); + guint64 diff_time, diff_frames; + + if (id->timestamp > best_timestamp) + break; + + if (id->timestamp == 0 || best_timestamp == 0) + diff_time = 0; + else + diff_time = best_timestamp - id->timestamp; + diff_frames = best->system_frame_number - tmp->system_frame_number; + + if (diff_time > MAX_FRAME_DIST_TIME + || diff_frames > MAX_FRAME_DIST_FRAMES) { + finish_frames = + g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); + } + } + } + + if (finish_frames) { + g_warning ("%s: Frames are too old, bug in decoder -- please file a bug", + GST_ELEMENT_NAME (self)); + for (l = finish_frames; l; l = l->next) { + gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), l->data); + } + } + + if (best) + gst_video_codec_frame_ref (best); + + g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL); + g_list_free (frames); + + return best; +} + +static gboolean +gst_amc_video_dec_set_src_caps (GstAmcVideoDec * self, GstAmcFormat * format) +{ + GstVideoCodecState *output_state; + gint color_format, width, height; + gint stride, slice_height; + gint crop_left, crop_right; + gint crop_top, crop_bottom; + GstVideoFormat gst_format; + GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self); + + GST_DEBUG_OBJECT (self, "Setting src caps"); + + color_format = media_format_get_color_format (format->format); + width = media_format_get_width (format->format); + height = media_format_get_height (format->format); + if (!color_format || !height || !width) { + GST_ERROR_OBJECT (self, "Failed to get output format metadata"); + return FALSE; + } + + if (strcmp (klass->codec_info->name, "OMX.k3.video.decoder.avc") == 0 && + color_format == COLOR_FormatYCbYCr) + color_format = COLOR_TI_FormatYUV420PackedSemiPlanar; + + stride = media_format_get_stride (format->format); + slice_height = media_format_get_slice_height (format->format); + if (!stride || !slice_height) { + GST_ERROR_OBJECT (self, "Failed to get stride and slice-height"); + return FALSE; + } + + crop_left = media_format_get_crop_left (format->format); + crop_right = media_format_get_crop_right (format->format); + crop_top = media_format_get_crop_top (format->format); + crop_bottom = media_format_get_crop_bottom (format->format); + + if (width == 0 || height == 0) { + GST_ERROR_OBJECT (self, "Height or width not set"); + return FALSE; + } + + if (crop_bottom) + height = height - (height - crop_bottom - 1); + if (crop_top) + height = height - crop_top; + + if (crop_right) + width = width - (width - crop_right - 1); + if (crop_left) + width = width - crop_left; + + gst_format = gst_amc_color_format_to_video_format (color_format); + if (gst_format == GST_VIDEO_FORMAT_UNKNOWN) { + GST_ERROR_OBJECT (self, "Unknown color format 0x%08x", color_format); + return FALSE; + } + + output_state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self), + gst_format, width, height, self->input_state); + + self->format = gst_format; + self->color_format = color_format; + self->height = height; + self->width = width; + self->stride = stride; + self->slice_height = slice_height; + self->crop_left = crop_left; + self->crop_right = crop_right; + self->crop_top = crop_top; + self->crop_bottom = crop_bottom; + + gst_video_decoder_negotiate (GST_VIDEO_DECODER (self)); + gst_video_codec_state_unref (output_state); + self->input_state_changed = FALSE; + + return TRUE; +} + +/* + * The format is called QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka. + * Which is actually NV12 (interleaved U&V). + */ +#define TILE_WIDTH 64 +#define TILE_HEIGHT 32 +#define TILE_SIZE (TILE_WIDTH * TILE_HEIGHT) +#define TILE_GROUP_SIZE (4 * TILE_SIZE) + +/* get frame tile coordinate. XXX: nothing to be understood here, don't try. */ +static size_t +tile_pos (size_t x, size_t y, size_t w, size_t h) +{ + size_t flim = x + (y & ~1) * w; + + if (y & 1) { + flim += (x & ~3) + 2; + } else if ((h & 1) == 0 || y != (h - 1)) { + flim += (x + 2) & ~3; + } + + return flim; +} + +/* The weird handling of cropping, alignment and everything is taken from + * platform/frameworks/media/libstagefright/colorconversion/ColorConversion.cpp + */ +static gboolean +gst_amc_video_dec_fill_buffer (GstAmcVideoDec * self, gint idx, + const GstAmcBufferInfo * buffer_info, GstBuffer * outbuf) +{ + GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self); + GstAmcBuffer *buf = &self->output_buffers[idx]; + GstVideoCodecState *state = + gst_video_decoder_get_output_state (GST_VIDEO_DECODER (self)); + GstVideoInfo *info = &state->info; + gboolean ret = FALSE; + GstMemory *mem = { NULL }; + gboolean do_hardware_rendering = FALSE; + gint err = 0; + + GST_DEBUG_OBJECT (self, "%s", __PRETTY_FUNCTION__); + + if (idx >= self->n_output_buffers) { + GST_ERROR_OBJECT (self, "Invalid output buffer index %d of %d", + idx, self->n_output_buffers); + goto done; + } + + if (!self->codec->codec_delegate) { + GST_ERROR_OBJECT (self, + "codec_delegate is NULL, can't decode/render properly"); + goto done; + } + + GST_DEBUG_OBJECT (self, + "buffer_info->size: %d, gst_buffer_get_size (outbuf): %d", + buffer_info->size, gst_buffer_get_size (outbuf)); + + if (gst_buffer_n_memory (outbuf) >= 1 && + (mem = gst_buffer_peek_memory (outbuf, 0)) + && gst_is_mir_image_memory (mem)) { + + GST_DEBUG_OBJECT (self, "It is Mir image memory"); + do_hardware_rendering = gst_mir_do_hardware_render (mem); + } + + GST_DEBUG_OBJECT (self, "hardware_rendering: %d", do_hardware_rendering); + + /* Same video format */ + if (do_hardware_rendering > 0) { + + if (gst_buffer_n_memory (outbuf) >= 1 && gst_is_mir_image_memory (mem)) { + GST_DEBUG_OBJECT (self, "Doing hardware rendering"); + GST_DEBUG_OBJECT (self, "gst_mir_image_memory_get_codec: %p", + self->codec->codec_delegate); + + ret = TRUE; + goto done; + } + } else if (!do_hardware_rendering + && buffer_info->size == gst_buffer_get_size (outbuf)) { + GstMapInfo minfo; + GST_DEBUG_OBJECT (self, "Doing fast software rendering"); + + gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE); + orc_memcpy (minfo.data, buf->data + buffer_info->offset, buffer_info->size); + gst_buffer_unmap (outbuf, &minfo); + + ret = TRUE; + } else { + /* Disabled for now since this plugin does not support non-hardware accelerated + * video rendering at the moment. + */ + GST_DEBUG_OBJECT (self, + "Doing slow software line-by-line copying with format conversion"); + + /* Different video format, try to convert */ + switch (self->color_format) { + case COLOR_FormatYUV420Planar:{ + GstVideoFrame vframe; + gint i, j, height; + guint8 *src, *dest; + gint stride, slice_height; + gint src_stride, dest_stride; + gint row_length; + + stride = self->stride; + if (stride == 0) { + GST_ERROR_OBJECT (self, "Stride not set"); + goto done; + } + + slice_height = self->slice_height; + if (slice_height == 0) { + /* NVidia Tegra 3 on Nexus 7 does not set this */ + if (g_str_has_prefix (klass->codec_info->name, "OMX.Nvidia.")) { + slice_height = GST_ROUND_UP_32 (self->height); + } else { + GST_ERROR_OBJECT (self, "Slice height not set"); + goto done; + } + } + + gst_video_frame_map (&vframe, info, outbuf, GST_MAP_WRITE); + for (i = 0; i < 3; i++) { + if (i == 0) { + src_stride = stride; + dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i); + } else { + src_stride = (stride + 1) / 2; + dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i); + } + + src = buf->data + buffer_info->offset; + + if (i == 0) { + src += self->crop_top * stride; + src += self->crop_left; + row_length = self->width; + } else if (i > 0) { + /* skip the Y plane */ + src += slice_height * stride; + + /* crop_top/crop_left divided by two + * because one byte of the U/V planes + * corresponds to two pixels horizontally/vertically */ + src += self->crop_top / 2 * src_stride; + src += self->crop_left / 2; + row_length = (self->width + 1) / 2; + } + if (i == 2) { + /* skip the U plane */ + src += ((slice_height + 1) / 2) * ((stride + 1) / 2); + } + + dest = GST_VIDEO_FRAME_COMP_DATA (&vframe, i); + height = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, i); + + for (j = 0; j < height; j++) { + orc_memcpy (dest, src, row_length); + src += src_stride; + dest += dest_stride; + } + } + gst_video_frame_unmap (&vframe); + ret = TRUE; + break; + } + case COLOR_TI_COLOR_FormatYUV420PackedSemiPlanar: + case COLOR_TI_FormatYUV420PackedSemiPlanar: + case COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced:{ + gint i, j, height; + guint8 *src, *dest; + gint src_stride, dest_stride; + gint row_length; + GstVideoFrame vframe; + + GST_DEBUG_OBJECT (self, + "COLOR_TI_COLOR_FormatYUV420PackedSemiPlanar conversion"); + + /* This should always be set */ + if (self->stride == 0 || self->slice_height == 0) { + GST_ERROR_OBJECT (self, "Stride or slice height not set"); + goto done; + } + + /* FIXME: This does not work for odd widths or heights + * but might as well be a bug in the codec */ + gst_video_frame_map (&vframe, info, outbuf, GST_MAP_WRITE); + for (i = 0; i < 2; i++) { + if (i == 0) { + src_stride = self->stride; + dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i); + } else { + src_stride = GST_ROUND_UP_2 (self->stride); + dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i); + } + + src = buf->data + buffer_info->offset; +#if 0 + GST_DEBUG_OBJECT (self, "buf->data: %p, buffer_info->offset: %d", + buf->data, buffer_info->offset); + GST_DEBUG_OBJECT (self, "buf->size: %d", buf->size); +#endif + if (i == 0) { + row_length = self->width; + } else if (i == 1) { + src += (self->slice_height - self->crop_top / 2) * self->stride; + row_length = GST_ROUND_UP_2 (self->width); + } + + dest = GST_VIDEO_FRAME_COMP_DATA (&vframe, i); + height = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, i); + + for (j = 0; j < height; j++) { +#if 0 + GST_DEBUG_OBJECT (self, + "Copying data row (dest: %p, src: %p, row_length: %d", dest, + src, row_length); +#endif + orc_memcpy (dest, src, row_length); + src += src_stride; + dest += dest_stride; +#if 0 + GST_DEBUG_OBJECT (self, + "Finished copying data row (src_stride: %d, dst_stride: %d", + src_stride, dest_stride); +#endif + } + } + gst_video_frame_unmap (&vframe); + ret = TRUE; + break; + } + case COLOR_QCOM_FormatYUV420SemiPlanar: + case COLOR_FormatYUV420SemiPlanar:{ + gint i, j, height; + guint8 *src, *dest; + gint src_stride, dest_stride, fixed_stride; + gint row_length; + GstVideoFrame vframe; + + /* This should always be set */ + if (self->stride == 0 || self->slice_height == 0) { + GST_ERROR_OBJECT (self, "Stride or slice height not set"); + goto done; + } + + /* Samsung Galaxy S3 seems to report wrong strides. + I.e. BigBuckBunny 854x480 H264 reports a stride of 864 when it is + actually 854, so we use width instead of stride here. + This is obviously bound to break in the future. */ + if (g_str_has_prefix (klass->codec_info->name, "OMX.SEC.")) { + fixed_stride = self->width; + } else { + fixed_stride = self->stride; + } + + gst_video_frame_map (&vframe, info, outbuf, GST_MAP_WRITE); + + for (i = 0; i < 2; i++) { + src_stride = fixed_stride; + dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, i); + + src = buf->data + buffer_info->offset; + if (i == 0) { + src += self->crop_top * fixed_stride; + src += self->crop_left; + row_length = self->width; + } else if (i == 1) { + src += self->slice_height * fixed_stride; + src += self->crop_top * fixed_stride; + src += self->crop_left; + row_length = self->width; + } + + dest = GST_VIDEO_FRAME_COMP_DATA (&vframe, i); + height = GST_VIDEO_FRAME_COMP_HEIGHT (&vframe, i); + + for (j = 0; j < height; j++) { + orc_memcpy (dest, src, row_length); + src += src_stride; + dest += dest_stride; + } + } + gst_video_frame_unmap (&vframe); + ret = TRUE; + break; + } + /* FIXME: This should be in libgstvideo as MT12 or similar, see v4l2 */ + case COLOR_EXYNOS_FormatNV12Tiled: + case COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka:{ + GstVideoFrame vframe; + gint width = self->width; + gint height = self->height; + gint dest_luma_stride, dest_chroma_stride; + guint8 *src = buf->data + buffer_info->offset; + guint8 *dest_luma, *dest_chroma; + gint y; + const size_t tile_w = (width - 1) / TILE_WIDTH + 1; + const size_t tile_w_align = (tile_w + 1) & ~1; + const size_t tile_h_luma = (height - 1) / TILE_HEIGHT + 1; + const size_t tile_h_chroma = (height / 2 - 1) / TILE_HEIGHT + 1; + size_t luma_size = tile_w_align * tile_h_luma * TILE_SIZE; + + gst_video_frame_map (&vframe, info, outbuf, GST_MAP_WRITE); + dest_luma = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0); + dest_chroma = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1); + dest_luma_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0); + dest_chroma_stride = GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 1); + + if ((luma_size % TILE_GROUP_SIZE) != 0) + luma_size = + (((luma_size - 1) / TILE_GROUP_SIZE) + 1) * TILE_GROUP_SIZE; + + for (y = 0; y < tile_h_luma; y++) { + size_t row_width = width; + gint x; + + for (x = 0; x < tile_w; x++) { + size_t tile_width = row_width; + size_t tile_height = height; + gint luma_idx; + gint chroma_idx; + /* luma source pointer for this tile */ + const uint8_t *src_luma = src + + tile_pos (x, y, tile_w_align, tile_h_luma) * TILE_SIZE; + + /* chroma source pointer for this tile */ + const uint8_t *src_chroma = src + luma_size + + tile_pos (x, y / 2, tile_w_align, tile_h_chroma) * TILE_SIZE; + if (y & 1) + src_chroma += TILE_SIZE / 2; + + /* account for right columns */ + if (tile_width > TILE_WIDTH) + tile_width = TILE_WIDTH; + + /* account for bottom rows */ + if (tile_height > TILE_HEIGHT) + tile_height = TILE_HEIGHT; + + /* dest luma memory index for this tile */ + luma_idx = y * TILE_HEIGHT * dest_luma_stride + x * TILE_WIDTH; + + /* dest chroma memory index for this tile */ + /* XXX: remove divisions */ + chroma_idx = + y * TILE_HEIGHT / 2 * dest_chroma_stride + x * TILE_WIDTH; + + tile_height /= 2; // we copy 2 luma lines at once + while (tile_height--) { + memcpy (dest_luma + luma_idx, src_luma, tile_width); + src_luma += TILE_WIDTH; + luma_idx += dest_luma_stride; + + memcpy (dest_luma + luma_idx, src_luma, tile_width); + src_luma += TILE_WIDTH; + luma_idx += dest_luma_stride; + + memcpy (dest_chroma + chroma_idx, src_chroma, tile_width); + src_chroma += TILE_WIDTH; + chroma_idx += dest_chroma_stride; + } + row_width -= TILE_WIDTH; + } + height -= TILE_HEIGHT; + } + gst_video_frame_unmap (&vframe); + ret = TRUE; + break; + + } + default: + GST_ERROR_OBJECT (self, "Unsupported color format %d", + self->color_format); + goto done; + break; + } + } + + /* Just release the output buffer back to the decoder */ + err = + media_codec_release_output_buffer (self->codec->codec_delegate, 0, FALSE); + if (err < 0) + GST_WARNING_OBJECT (self, + "Failed to release output buffer. Rendering will probably be affected (err: %d).", + err); + +done: + gst_video_codec_state_unref (state); + return ret; +} + +static gboolean +gst_amc_video_dec_configure_self (GstVideoDecoder * decoder, + GstAmcFormat * format) +{ + GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder); + SurfaceTextureClientHybris surface_texture_client = NULL; + guint8 i = 0; + const guint8 MAX_TRIES = 3; + + GST_DEBUG_OBJECT (self, "%s", __PRETTY_FUNCTION__); + + g_return_val_if_fail (decoder != NULL, FALSE); + g_return_val_if_fail (format != NULL, FALSE); + + /* This is a hack that should be able to go away when media-hub is used + * to instantiate the playbin pipeline instead of QtMultimedia. This is + * only required for the faster devices so that an eglContext exists and is + * valid for rendering, and a valid texture id can be passed to the hybris + * layer. + */ + while (i < MAX_TRIES) { + GST_WARNING_OBJECT (self, "Waiting a bit for the texture id"); + g_usleep (G_USEC_PER_SEC / 5); + ++i; + } + + /* Try to get a SurfaceTextureClientHybris instance from mirsink */ + if (!gst_mir_ensure_surface_texture_client (self)) { + GST_ERROR_OBJECT (decoder, + "Failed to ensure a SurfaceTextureClientHybris instance"); + return FALSE; + } + + surface_texture_client = + gst_amc_codec_get_surface_texture_client (self->codec); + GST_INFO_OBJECT (self, "surface_texture_client: %p", surface_texture_client); + + /* Configure the hardware decoder */ + if (!gst_amc_codec_configure (self->codec, format, surface_texture_client, 0)) { + GST_ERROR_OBJECT (self, "Failed to configure codec"); + return FALSE; + } + + if (!gst_amc_codec_start (self->codec)) { + GST_ERROR_OBJECT (self, "Failed to start codec"); + return FALSE; + } + + if (self->input_buffers) + gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); + self->input_buffers = + gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers); + if (!self->input_buffers) { + GST_ERROR_OBJECT (self, "Failed to get input buffers"); + return FALSE; + } + // JH added + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); + self->output_buffers = + gst_amc_codec_get_output_buffers (self->codec, &self->n_output_buffers); + if (!self->output_buffers) { + GST_ERROR_OBJECT (self, "Failed to get output buffers"); + return FALSE; + } + + return TRUE; +} + +static void +gst_amc_video_dec_loop (GstAmcVideoDec * self) +{ + GstVideoCodecFrame *frame; + GstFlowReturn flow_ret = GST_FLOW_OK; + GstClockTimeDiff deadline; + gboolean is_eos; + GstAmcBufferInfo buffer_info; + gint idx; + + GST_VIDEO_DECODER_STREAM_LOCK (self); + +retry: + /*if (self->input_state_changed) { + idx = INFO_OUTPUT_FORMAT_CHANGED; + } else { */ + GST_DEBUG_OBJECT (self, "Waiting for available output buffer"); + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + /* Wait at most 100ms here, some codecs don't fail dequeueing if + * the codec is flushing, causing deadlocks during shutdown */ + idx = + gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, + self->current_timeout); + GST_VIDEO_DECODER_STREAM_LOCK (self); + /*} */ + + GST_DEBUG_OBJECT (self, "Tried to dequeue output buffer (idx: %d)", idx); + if (idx < 0) { + if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING) + goto flushing; + + switch (idx) { + case INFO_OUTPUT_BUFFERS_CHANGED:{ + GST_INFO_OBJECT (self, "Output buffers have changed"); + + /* Once the output buffers have changed, we don't need such an + * aggressive timeout value anymore for queueing/dequeueing + */ + self->current_timeout = 10000; + + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, + self->n_output_buffers); + self->output_buffers = + gst_amc_codec_get_output_buffers (self->codec, + &self->n_output_buffers); + if (!self->output_buffers) + goto get_output_buffers_error; + break; + } + case INFO_OUTPUT_FORMAT_CHANGED:{ + GstAmcFormat *format; + /* gchar *format_string; */ + + GST_INFO_OBJECT (self, "Output format has changed"); + + format = gst_amc_codec_get_output_format (self->codec); + if (!format) + goto format_error; + + /* + format_string = gst_amc_format_to_string (format); + GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string); + g_free (format_string); + */ + + if (!gst_amc_video_dec_set_src_caps (self, format)) { + gst_amc_format_free (format); + goto format_error; + } + gst_amc_format_free (format); + + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, + self->n_output_buffers); + self->output_buffers = + gst_amc_codec_get_output_buffers (self->codec, + &self->n_output_buffers); + if (!self->output_buffers) + goto get_output_buffers_error; + + goto retry; + break; + } + case INFO_TRY_AGAIN_LATER: + GST_DEBUG_OBJECT (self, + "Dequeueing output buffer timed out, trying again"); + goto retry; + break; + case G_MININT: + GST_ERROR_OBJECT (self, "Failure dequeueing output buffer"); + goto dequeue_error; + break; + default: + g_assert_not_reached (); + break; + } + + goto retry; + } + + GST_DEBUG_OBJECT (self, + "Got output buffer at index %d: size %d time %" G_GINT64_FORMAT + " flags 0x%08x", idx, buffer_info.size, buffer_info.presentation_time_us, + buffer_info.flags); + + frame = + _find_nearest_frame (self, + gst_util_uint64_scale (buffer_info.presentation_time_us, GST_USECOND, 1)); + + is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM); + + if (is_eos) { + GST_DEBUG_OBJECT (self, "EOS detected"); + flow_ret = GST_FLOW_EOS; + } + + GST_DEBUG_OBJECT (self, "Checking the max decode time deadline"); + if (frame + && (deadline = + gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (self), + frame)) < 0) { + GST_WARNING_OBJECT (self, + "Frame is too late, dropping (deadline %" GST_TIME_FORMAT ")", + GST_TIME_ARGS (-deadline)); + flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); + } else if (!frame && buffer_info.size > 0) { + GstBuffer *outbuf; + + /* This sometimes happens at EOS or if the input is not properly framed, + * let's handle it gracefully by allocating a new buffer for the current + * caps and filling it + */ + GST_ERROR_OBJECT (self, "No corresponding frame found"); + + outbuf = + gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self)); + + if (!gst_amc_video_dec_fill_buffer (self, idx, &buffer_info, outbuf)) { + gst_buffer_unref (outbuf); + if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE)) + GST_ERROR_OBJECT (self, "Failed to release output buffer index %d", + idx); + goto invalid_buffer; + } + + GST_BUFFER_PTS (outbuf) = + gst_util_uint64_scale (buffer_info.presentation_time_us, GST_USECOND, + 1); + flow_ret = gst_pad_push (GST_VIDEO_DECODER_SRC_PAD (self), outbuf); + } else if (buffer_info.size >= 0 && is_eos == FALSE) { + GST_DEBUG_OBJECT (self, "Allocating buffer from pool"); + /* Allocate buffer from the GstBufferPool */ + if ((flow_ret = gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER + (self), frame)) != GST_FLOW_OK) { + GST_ERROR_OBJECT (self, "Failed to allocate buffer"); + goto flow_error; + } + + GST_DEBUG_OBJECT (self, "Filling the output buffer"); + /* Stuff the raw decoded video data into the buffer */ + if (!gst_amc_video_dec_fill_buffer (self, idx, &buffer_info, + frame->output_buffer)) { + gst_buffer_replace (&frame->output_buffer, NULL); + gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); + if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE)) + GST_ERROR_OBJECT (self, "Failed to release output buffer index %d", + idx); + goto invalid_buffer; + } + + /* Push the frame downstream through the pipeline */ + flow_ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame); + } else if (frame != NULL) { + GST_DEBUG_OBJECT (self, "Dropping frame"); + flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame); + } + + if (is_eos || flow_ret == GST_FLOW_EOS) { + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + g_mutex_lock (&self->drain_lock); + if (self->draining) { + GST_DEBUG_OBJECT (self, "Drained"); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + } else if (flow_ret == GST_FLOW_OK) { + GST_DEBUG_OBJECT (self, "Component signalled EOS"); + flow_ret = GST_FLOW_EOS; + } + g_mutex_unlock (&self->drain_lock); + GST_VIDEO_DECODER_STREAM_LOCK (self); + } else { + GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret)); + } + + self->downstream_flow_ret = flow_ret; + + if (flow_ret != GST_FLOW_OK) + goto flow_error; + + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + + return; + +dequeue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to dequeue output buffer")); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +get_output_buffers_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to get output buffers")); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +format_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to handle format")); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_ERROR; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- stopping task"); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_FLUSHING; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +flow_error: + { + if (flow_ret == GST_FLOW_EOS) { + GST_DEBUG_OBJECT (self, "EOS"); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + } else if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_EOS) { + GST_ELEMENT_ERROR (self, STREAM, FAILED, + ("Internal data stream error."), ("stream stopped, reason %s", + gst_flow_get_name (flow_ret))); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), + gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + } + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +invalid_buffer: + { + GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), + ("Invalid sized input buffer")); + gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ()); + gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); + self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED; + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + return; + } +} + +static gboolean +gst_amc_video_dec_start (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self; + + self = GST_AMC_VIDEO_DEC (decoder); + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + self->started = FALSE; + self->flushing = TRUE; + + return TRUE; +} + +static gboolean +gst_amc_video_dec_stop (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self; + + self = GST_AMC_VIDEO_DEC (decoder); + GST_DEBUG_OBJECT (self, "Stopping decoder"); + self->flushing = TRUE; + if (self->started) { + gst_amc_codec_flush (self->codec); + gst_amc_codec_stop (self->codec); + self->started = FALSE; + if (self->input_buffers) + gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); + self->input_buffers = NULL; + if (self->output_buffers) + gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); + self->output_buffers = NULL; + } + gst_pad_stop_task (GST_VIDEO_DECODER_SRC_PAD (decoder)); + + self->downstream_flow_ret = GST_FLOW_FLUSHING; + self->eos = FALSE; + g_mutex_lock (&self->drain_lock); + self->draining = FALSE; + g_cond_broadcast (&self->drain_cond); + g_mutex_unlock (&self->drain_lock); + g_free (self->codec_data); + self->codec_data_size = 0; + if (self->input_state) + gst_video_codec_state_unref (self->input_state); + self->input_state = NULL; + self->current_timeout = 0; + GST_DEBUG_OBJECT (self, "Stopped decoder"); + return TRUE; +} + +static gboolean +gst_amc_video_dec_set_format (GstVideoDecoder * decoder, + GstVideoCodecState * state) +{ + GstAmcVideoDec *self; + GstAmcFormat *format; + gboolean ret = TRUE; + const gchar *mime; + gboolean is_format_change = FALSE; + gboolean needs_disable = FALSE; + /* gchar *format_string; */ + guint8 *codec_data = NULL; + gsize codec_data_size = 0; + + self = GST_AMC_VIDEO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, state->caps); + + /* Check if the caps change is a real format change or if only irrelevant + * parts of the caps have changed or nothing at all. + */ + is_format_change |= self->width != state->info.width; + is_format_change |= self->height != state->info.height; + if (state->codec_data) { + GstMapInfo cminfo; + + GST_DEBUG_OBJECT (self, "state->codec_data present!"); + + gst_buffer_map (state->codec_data, &cminfo, GST_MAP_READ); + codec_data = g_memdup (cminfo.data, cminfo.size); + codec_data_size = cminfo.size; + + is_format_change |= (!self->codec_data + || self->codec_data_size != codec_data_size + || memcmp (self->codec_data, codec_data, codec_data_size) != 0); + gst_buffer_unmap (state->codec_data, &cminfo); + } else if (self->codec_data) { + GST_DEBUG_OBJECT (self, "format change"); + is_format_change |= TRUE; + } + + needs_disable = self->started; + + /* If the component is not started and a real format change happens + * we have to restart the component. If no real format change + * happened we can just exit here. + */ + if (needs_disable && !is_format_change) { + g_free (codec_data); + codec_data = NULL; + codec_data_size = 0; + + /* Framerate or something minor changed */ + self->input_state_changed = TRUE; + if (self->input_state) + gst_video_codec_state_unref (self->input_state); + self->input_state = gst_video_codec_state_ref (state); + GST_DEBUG_OBJECT (self, + "Already running and caps did not change the format"); + return TRUE; + } + + if (needs_disable && is_format_change) { + gst_amc_video_dec_drain (self, FALSE); + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + gst_amc_video_dec_stop (GST_VIDEO_DECODER (self)); + GST_VIDEO_DECODER_STREAM_LOCK (self); + gst_amc_video_dec_close (GST_VIDEO_DECODER (self)); + if (!gst_amc_video_dec_open (GST_VIDEO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Failed to open codec again"); + return FALSE; + } + + if (!gst_amc_video_dec_start (GST_VIDEO_DECODER (self))) { + GST_ERROR_OBJECT (self, "Failed to start codec again"); + } + } + /* srcpad task is not running at this point */ + if (self->input_state) + gst_video_codec_state_unref (self->input_state); + self->input_state = NULL; + + g_free (self->codec_data); + self->codec_data = codec_data; + self->codec_data_size = codec_data_size; + + GST_DEBUG_OBJECT (self, "codec_data_size: %d", codec_data_size); + + mime = caps_to_mime (state->caps); + if (!mime) { + GST_ERROR_OBJECT (self, "Failed to convert caps to mime"); + return FALSE; + } + + GST_DEBUG_OBJECT (self, "mime: '%s', width: %d, height %d", mime, + state->info.width, state->info.height); + format = + gst_amc_format_new_video (mime, state->info.width, state->info.height); + if (!format) { + GST_ERROR_OBJECT (self, "Failed to create video format"); + return FALSE; + } + + /* FIXME: This buffer needs to be valid until the codec is stopped again */ + if (self->codec_data) + gst_amc_format_set_buffer (format, "csd-0", self->codec_data, + self->codec_data_size); + +/* + format_string = gst_amc_format_to_string (format); + GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", format_string); + g_free (format_string); +*/ + + /* Configure the hardware codec with format */ + ret = gst_amc_video_dec_configure_self (decoder, format); + if (!ret) { + goto failed_configure; + } + + gst_amc_format_free (format); + format = NULL; + + self->started = TRUE; + self->input_state = gst_video_codec_state_ref (state); + self->input_state_changed = TRUE; + + /* Start the srcpad loop again */ + self->flushing = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL); + + return ret; + +failed_configure: + GST_ERROR_OBJECT (self, "Failed to configure hardware codec"); + gst_amc_format_free (format); + format = NULL; + return FALSE; +} + +static gboolean +gst_amc_video_dec_flush (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self; + + self = GST_AMC_VIDEO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Flushing decoder"); + + if (!self->started) { + GST_DEBUG_OBJECT (self, "Codec not started yet"); + return TRUE; + } + + self->flushing = TRUE; + gst_amc_codec_flush (self->codec); + + /* Wait until the srcpad loop is finished, + * unlock GST_VIDEO_DECODER_STREAM_LOCK to prevent deadlocks + * caused by using this lock from inside the loop function */ + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + GST_PAD_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self)); + GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self)); + GST_VIDEO_DECODER_STREAM_LOCK (self); + self->flushing = FALSE; + + /* Start the srcpad loop again */ + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_amc_video_dec_loop, decoder, NULL); + + GST_DEBUG_OBJECT (self, "Flushed decoder"); + + return TRUE; +} + +static GstFlowReturn +gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder, + GstVideoCodecFrame * frame) +{ + GstAmcVideoDec *self; + gint idx; + GstAmcBuffer *buf; + GstAmcBufferInfo buffer_info; + guint offset = 0; + GstClockTime timestamp, duration, timestamp_offset = 0; + GstMapInfo minfo; + + memset (&minfo, 0, sizeof (minfo)); + + self = GST_AMC_VIDEO_DEC (decoder); + + GST_DEBUG_OBJECT (self, "Handling frame"); + + if (!self->started) { + GST_ERROR_OBJECT (self, "Codec not started yet"); + gst_video_codec_frame_unref (frame); + return GST_FLOW_NOT_NEGOTIATED; + } + + if (self->eos) { + GST_WARNING_OBJECT (self, "Got frame after EOS"); + gst_video_codec_frame_unref (frame); + return GST_FLOW_EOS; + } + + if (self->flushing) + goto flushing; + + if (self->downstream_flow_ret != GST_FLOW_OK) + goto downstream_error; + + timestamp = frame->pts; + duration = frame->duration; + + gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ); + + while (offset < minfo.size) { + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + /* Wait at most 100ms here, some codecs don't fail dequeueing if + * the codec is flushing, causing deadlocks during shutdown */ + idx = + gst_amc_codec_dequeue_input_buffer (self->codec, self->current_timeout); + GST_VIDEO_DECODER_STREAM_LOCK (self); + + GST_DEBUG_OBJECT (self, "Tried to dequeue input buffer idx: %d", idx); + if (idx < 0) { + if (self->flushing) + goto flushing; + switch (idx) { + case INFO_TRY_AGAIN_LATER: + GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out"); + continue; /* next try */ + break; + case G_MININT: + GST_ERROR_OBJECT (self, "Failed to dequeue input buffer"); + goto dequeue_error; + default: + g_assert_not_reached (); + break; + } + + continue; + } + + if (idx >= self->n_input_buffers) + goto invalid_buffer_index; + + if (self->flushing) + goto flushing; + + if (self->downstream_flow_ret != GST_FLOW_OK) { + memset (&buffer_info, 0, sizeof (buffer_info)); + gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info); + goto downstream_error; + } + + /* Now handle the frame */ + + /* Copy the buffer content in chunks of size as requested + * by the port */ + buf = &self->input_buffers[idx]; + + memset (&buffer_info, 0, sizeof (buffer_info)); + buffer_info.offset = 0; + buffer_info.size = MIN (minfo.size - offset, buf->size); + + orc_memcpy (buf->data, minfo.data + offset, buffer_info.size); + + /* Interpolate timestamps if we're passing the buffer + * in multiple chunks */ + if (offset != 0 && duration != GST_CLOCK_TIME_NONE) { + timestamp_offset = gst_util_uint64_scale (offset, duration, minfo.size); + } + + if (timestamp != GST_CLOCK_TIME_NONE) { + buffer_info.presentation_time_us = + gst_util_uint64_scale (timestamp + timestamp_offset, 1, GST_USECOND); + self->last_upstream_ts = timestamp + timestamp_offset; + } + if (duration != GST_CLOCK_TIME_NONE) + self->last_upstream_ts += duration; + + if (offset == 0) { + BufferIdentification *id = + buffer_identification_new (timestamp + timestamp_offset); + if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) + buffer_info.flags |= BUFFER_FLAG_SYNC_FRAME; + gst_video_codec_frame_set_user_data (frame, id, + (GDestroyNotify) buffer_identification_free); + } + + offset += buffer_info.size; + GST_DEBUG_OBJECT (self, + "Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x", + idx, buffer_info.size, buffer_info.presentation_time_us, + buffer_info.flags); + if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) + goto queue_error; + } + + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + + return self->downstream_flow_ret; + +downstream_error: + { + GST_ERROR_OBJECT (self, "Downstream returned %s", + gst_flow_get_name (self->downstream_flow_ret)); + if (minfo.data) + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + return self->downstream_flow_ret; + } +invalid_buffer_index: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); + if (minfo.data) + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } +dequeue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to dequeue input buffer")); + if (minfo.data) + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } +queue_error: + { + GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), + ("Failed to queue input buffer")); + if (minfo.data) + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + return GST_FLOW_ERROR; + } +flushing: + { + GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING"); + if (minfo.data) + gst_buffer_unmap (frame->input_buffer, &minfo); + gst_video_codec_frame_unref (frame); + return GST_FLOW_FLUSHING; + } +} + +static GstFlowReturn +gst_amc_video_dec_finish (GstVideoDecoder * decoder) +{ + GstAmcVideoDec *self; + + self = GST_AMC_VIDEO_DEC (decoder); + + return gst_amc_video_dec_drain (self, TRUE); +} + +static GstFlowReturn +gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos) +{ + GstFlowReturn ret; + gint idx; + + GST_DEBUG_OBJECT (self, "Draining codec"); + if (!self->started) { + GST_DEBUG_OBJECT (self, "Codec not started yet"); + return GST_FLOW_OK; + } + + /* Don't send EOS buffer twice, this doesn't work */ + if (self->eos) { + GST_DEBUG_OBJECT (self, "Codec is EOS already"); + return GST_FLOW_OK; + } + if (at_eos) + self->eos = TRUE; + + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + /* Send an EOS buffer to the component and let the base + * class drop the EOS event. We will send it later when + * the EOS buffer arrives on the output port. + * Wait at most 0.5s here. */ + idx = gst_amc_codec_dequeue_input_buffer (self->codec, self->current_timeout); + GST_DEBUG_OBJECT (self, "dequeued input buffer with idx: %d", idx); + GST_VIDEO_DECODER_STREAM_LOCK (self); + + if (idx >= 0 && idx < self->n_input_buffers) { + GstAmcBufferInfo buffer_info; + + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + g_mutex_lock (&self->drain_lock); + self->draining = TRUE; + + memset (&buffer_info, 0, sizeof (buffer_info)); + buffer_info.size = 0; + buffer_info.presentation_time_us = + gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND); + buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM; + + if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) { + GST_DEBUG_OBJECT (self, "Waiting until codec is drained"); + g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained codec"); + ret = GST_FLOW_OK; + } else { + GST_ERROR_OBJECT (self, "Failed to queue input buffer"); + ret = GST_FLOW_ERROR; + } + + g_mutex_unlock (&self->drain_lock); + GST_VIDEO_DECODER_STREAM_LOCK (self); + } else if (idx >= self->n_input_buffers) { + GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d", + idx, self->n_input_buffers); + ret = GST_FLOW_ERROR; + } else { + GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx); + ret = GST_FLOW_ERROR; + } + + return ret; +} + +static void +gst_amc_video_dec_set_context (GstElement * element, GstContext * context) +{ + GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (element); + SurfaceTextureClientHybris stc; + + GST_DEBUG_OBJECT (element, "%s", __PRETTY_FUNCTION__); + + stc = gst_context_get_surface_texture_client (context); + if (!stc) + GST_ERROR_OBJECT (self, + "Failed to get SurfaceTextureClient instance. Hardware video rendering will not function"); + + GST_DEBUG_OBJECT (self, "stc: %p", stc); + if (!gst_amc_codec_set_surface_texture_client (self->codec, stc)) + GST_ERROR_OBJECT (self, + "Failed to set SurfaceTextureClientHybris instance for decoder. Hardware video rendering will not function"); +} + +static gboolean +gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query) +{ + GstBufferPool *pool; + GstMirBufferPool *m_pool; + GstStructure *config; + GstCaps *caps; + guint i, n; + + GST_DEBUG_OBJECT (bdec, "%s", __PRETTY_FUNCTION__); + GST_DEBUG_OBJECT (bdec, "Deciding ALLOCATION params"); + + /* Prefer a MirImage allocator if available */ + gst_query_parse_allocation (query, &caps, NULL); + /* if (caps && gst_video_info_from_caps (&info, caps) && info.finfo->format == GST_VIDEO_FORMAT_RGBA) { */ + { + GST_DEBUG_OBJECT (bdec, "Considering using the MirImage allocator"); + n = gst_query_get_n_allocation_params (query); + for (i = 0; i < n; i++) { + GstAllocator *allocator = NULL; + GstAllocationParams params; + + gst_query_parse_nth_allocation_param (query, i, &allocator, ¶ms); + /* Select the MirImage allocator from the ALLOCATION query */ + if (allocator + && g_strcmp0 (allocator->mem_type, GST_MIR_IMAGE_MEMORY_TYPE) == 0) { + GST_DEBUG_OBJECT (bdec, "Found the MirImage allocator!"); + g_assert (allocator != NULL); + gst_query_set_nth_allocation_param (query, 0, allocator, ¶ms); + while (gst_query_get_n_allocation_params (query) > 1) + gst_query_remove_nth_allocation_param (query, 1); + break; + } + } + } + + if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query)) + return FALSE; + + g_assert (gst_query_get_n_allocation_pools (query) > 0); + gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL); + g_assert (pool != NULL); + + /* Add the codec_delegate instance to the current pool */ + m_pool = (GstMirBufferPool *) pool; + m_pool->codec_delegate = (GST_AMC_VIDEO_DEC (bdec))->codec->codec_delegate; + + config = gst_buffer_pool_get_config (pool); + if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { + GST_DEBUG_OBJECT (bdec, + "ALLOCATION query has GST_VIDEO_META_API_TYPE embedded"); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); + } + gst_buffer_pool_set_config (pool, config); + gst_object_unref (pool); + + return TRUE; +} diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index ae06100..2ee73a0 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -169,6 +169,12 @@ else check_shm= endif +if USE_ANDROID_MEDIA_HYBRIS +check_gstamc=elements/gstamcvideodec +else +check_gstamc= +endif + VALGRIND_TO_FIX = \ elements/mpeg2enc \ elements/mplex \ @@ -223,6 +229,7 @@ check_PROGRAMS = \ elements/mxfmux \ elements/id3mux \ pipelines/mxf \ + pipelines/gstamcvideodec \ $(check_mimic) \ libs/mpegvideoparser \ libs/h264parser \ diff --git a/tests/check/pipelines/gstamcvideodec.c b/tests/check/pipelines/gstamcvideodec.c new file mode 100644 index 0000000..eb6d9e9 --- /dev/null +++ b/tests/check/pipelines/gstamcvideodec.c @@ -0,0 +1,538 @@ +/* + * Unit and functional tests for gstamcvideodec + * + * Copyright (C) 2013, Canonical Ltd. + * Author: Jim Hodapp + * + * 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 + * version 2.1 of the License. + * + * 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 + +static GstElement *pipeline; +static GstBus *bus; +static GMainLoop *loop; +static guint messages = 0; +static guint num_tags = 0; + +extern void setup_egl (void); + +static void +element_message_cb (GstBus * bus, GstMessage * message, gpointer user_data) +{ + gchar *s = gst_structure_to_string (gst_message_get_structure (message)); + GST_DEBUG ("Received message: %s", s); + g_free (s); + + ++messages; +} + +static void +eos_message_cb (GstBus * bus, GstMessage * message, gpointer user_data) +{ + GST_DEBUG ("Received EOS"); + g_main_loop_quit (loop); +} + +static GstPadProbeReturn +pad_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) +{ + GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + GST_INFO ("GST_EVENT_FLUSH_START"); + break; + case GST_EVENT_FLUSH_STOP: + GST_INFO ("GST_EVENT_FLUSH_STOP"); + break; + case GST_EVENT_STREAM_START: + GST_INFO ("GST_EVENT_STREAM_START"); + break; + case GST_EVENT_CAPS: + GST_INFO ("GST_EVENT_CAPS"); + break; + case GST_EVENT_SEGMENT: + GST_INFO ("GST_EVENT_SEGMENT"); + break; + case GST_EVENT_TAG: + GST_INFO ("GST_EVENT_TAG"); + ++num_tags; + break; + case GST_EVENT_BUFFERSIZE: + GST_INFO ("GST_EVENT_BUFFERSIZE"); + break; + case GST_EVENT_SINK_MESSAGE: + GST_INFO ("GST_EVENT_SINK_MESSAGE"); + break; + case GST_EVENT_EOS: + GST_INFO ("GST_EVENT_EOS"); + break; + case GST_EVENT_TOC: + GST_INFO ("GST_EVENT_TOC"); + break; + case GST_EVENT_SEGMENT_DONE: + GST_INFO ("GST_EVENT_SEGMENT_DONE"); + break; + case GST_EVENT_GAP: + GST_INFO ("GST_EVENT_GAP"); + break; + case GST_EVENT_QOS: + GST_INFO ("GST_EVENT_QOS"); + break; + case GST_EVENT_SEEK: + GST_INFO ("GST_EVENT_SEEK"); + break; + case GST_EVENT_NAVIGATION: + GST_INFO ("GST_EVENT_NAVIGATION"); + break; + case GST_EVENT_LATENCY: + GST_INFO ("GST_EVENT_LATENCY"); + break; + case GST_EVENT_STEP: + GST_INFO ("GST_EVENT_STEP"); + break; + case GST_EVENT_RECONFIGURE: + GST_INFO ("GST_EVENT_RECONFIGURE"); + break; + case GST_EVENT_TOC_SELECT: + GST_INFO ("GST_EVENT_TOC_SELECT"); + break; + case GST_EVENT_CUSTOM_UPSTREAM: + GST_INFO ("GST_EVENT_CUSTOM_UPSTREAM"); + break; + case GST_EVENT_CUSTOM_DOWNSTREAM: + GST_INFO ("GST_EVENT_CUSTOM_DOWNSTREAM"); + break; + case GST_EVENT_CUSTOM_DOWNSTREAM_OOB: + GST_INFO ("GST_EVENT_CUSTOM_DOWNSTREAM_OOB"); + break; + case GST_EVENT_CUSTOM_DOWNSTREAM_STICKY: + GST_INFO ("GST_EVENT_CUSTOM_DOWNSTREAM_STICKY"); + break; + case GST_EVENT_CUSTOM_BOTH: + GST_INFO ("GST_EVENT_CUSTOM_BOTH"); + break; + case GST_EVENT_CUSTOM_BOTH_OOB: + GST_INFO ("GST_EVENT_CUSTOM_BOTH_OOB"); + break; + default: + GST_INFO ("Unknown GstEventType: %d", event->type); + break; + } + + return GST_PAD_PROBE_OK; +} + +static GstElement * +setup_filesink (void) +{ + GstElement *sink; + + GST_DEBUG ("Setting up filesink"); + + sink = gst_element_factory_make ("filesink", "video-sink"); + + return sink; +} + +static GstElement * +setup_fakesink (void) +{ + GstElement *sink; + + GST_DEBUG ("Setting up fakesink"); + + sink = gst_element_factory_make ("fakesink", "video-sink"); + + return sink; +} + +static gboolean +remove_tmp_file (const char *filename) +{ + gint ret = 0; + g_return_val_if_fail (filename != NULL, FALSE); + + GST_INFO ("g_access: %d", g_access (filename, R_OK | W_OK)); + /* Check to make sure we can remove the temp file */ + ret = g_access (filename, R_OK | W_OK); + if (ret != 0) + return FALSE; + + ret = g_remove (filename); + if (ret != 0) + return FALSE; + + return TRUE; +} + +static void +setup_pipeline (const char *pipe_str, GstElement * video_sink, + GstElement * audio_sink) +{ + GError *error = NULL; + GstPad *pad = NULL; + + fail_if (pipe_str == NULL); + + pipeline = gst_parse_launch (pipe_str, &error); + fail_unless (pipeline != NULL, "Error parsing pipeline: %s", + error ? error->message : "(invalid error)"); + + if (video_sink) + g_object_set (G_OBJECT (pipeline), "video-sink", video_sink, NULL); + if (audio_sink) + g_object_set (G_OBJECT (pipeline), "audio-sink", audio_sink, NULL); + + bus = gst_element_get_bus (pipeline); + fail_if (bus == NULL); + gst_bus_add_signal_watch (bus); + g_signal_connect (bus, "message::element", (GCallback) element_message_cb, + NULL); + g_signal_connect (bus, "message::eos", (GCallback) eos_message_cb, NULL); + + messages = 0; + num_tags = 0; + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + /* Run the test pipeline until we hit the EOS */ + loop = g_main_loop_new (NULL, FALSE); + + if (video_sink) { + GST_INFO ("Getting video sink pad on video-sink"); + /* Get the video src pad which should contain raw decoded frames */ + pad = gst_element_get_static_pad (video_sink, "sink"); + fail_if (pad == NULL); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_DATA_BOTH, + pad_event_probe_cb, NULL, NULL); + } +} + +static void +teardown_pipeline (GstElement * video_sink, GstElement * audio_sink) +{ + g_main_loop_unref (loop); + fail_unless (gst_element_set_state (pipeline, + GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS); + + gst_bus_remove_signal_watch (bus); + gst_object_unref (bus); + + if (video_sink) + video_sink = NULL; + + fail_if (messages > 0, "Received too many decoding errors"); + pipeline = NULL; +} + +GST_START_TEST (test_hardware_decode) +{ + gchar *pipe_str = + g_strdup_printf ("playbin video-sink=fakesink audio-sink=fakesink" + " uri=file:///home/phablet/Videos/sintel_trailer-480p.mp4"); + + setup_pipeline (pipe_str, NULL, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); +} + +GST_END_TEST +GST_START_TEST (test_hardware_decode_verify_height_width) +{ + //GstElement *decodebin = NULL; + GstElement *video_sink; + //GstPad *pad = NULL; + gchar *location; + gchar *pipe_str; + + g_random_int_range (0, INT_MAX); + location = g_strdup_printf ("/tmp/gstamc_%d.raw", g_random_int ()); + pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/sintel_trailer-480p.mp4"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_filesink (); + fail_if (video_sink == NULL); + g_object_set (G_OBJECT (video_sink), "location", location, NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); +#if 0 + decodebin = gst_bin_get_by_name (GST_BIN (pipeline), "decodebin0"); + fail_if (decodebin == NULL); +#endif + + g_main_loop_run (loop); + + /* Discussion from #gstreamer of how to get the height/width from + * the pipeline video stream: + * "you can either get it from the pad or - if you use appsink - + * you can get it from appsink (the caps will be in the GstSample structure along with the buffer) + * __tim, so from the pad, I could call gst_pad_get_current_caps(), yes? + * <__tim> yes, once the pipeline is prerolled (async-done message) + */ + + teardown_pipeline (video_sink, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); + + GST_INFO ("Removing tmp file: %s", location); + fail_if (remove_tmp_file (location) != TRUE); + g_free (location); +} + +GST_END_TEST +#if 0 +GST_START_TEST (test_hardware_decode_and_render) +{ + gchar *pipe_str = + g_strdup_printf ("playbin video-sink=mirsink audio-sink=fakesink" + " uri=file:///home/phablet/Videos/sintel_trailer-480p.mp4"); + + setup_pipeline (pipe_str, NULL, NULL); + g_free (pipe_str); + setup_egl (); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); +} + +GST_END_TEST +#endif +GST_START_TEST (test_h264_decode_avi_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/h264.avi"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_h264_decode_flv_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/h264.flv"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_h264_decode_mov_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/h264.mov"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_h264_decode_mp4_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/h264.mp4"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_mpeg4_decode_avi_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/mpeg4.avi"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (video_sink, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_mpeg4_decode_mov_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/mpeg4.mov"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_mpeg4_decode_mp4_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/mpeg4.mp4"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_xvid_decode_mp4_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/xvid.mp4"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_vorbis_decode_ogg_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/vorbis.ogg"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST +GST_START_TEST (test_vpx_decode_webm_container) +{ + GstElement *video_sink; + gchar *pipe_str = g_strdup_printf ("playbin audio-sink=fakesink" + " uri=file:///home/phablet/Videos/vpx.webm"); + + /* Send the raw video frames to a temp file */ + video_sink = setup_fakesink (); + fail_if (video_sink == NULL); + + setup_pipeline (pipe_str, video_sink, NULL); + g_free (pipe_str); + g_main_loop_run (loop); + teardown_pipeline (NULL, NULL); + GST_INFO ("num_tags: %d", num_tags); + fail_if (num_tags < 25); +} + +GST_END_TEST static Suite * +gstamcvideodec_suite (void) +{ + Suite *s = suite_create ("gstamcvideodec"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + //tcase_add_checked_fixture (tc_chain, setup_pipeline, teardown_pipeline); + tcase_set_timeout (tc_chain, 60); + //tcase_add_test (tc_chain, test_hardware_decode_verify_height_width); + tcase_add_test (tc_chain, test_hardware_decode); + //tcase_add_test (tc_chain, test_hardware_decode_and_render); + tcase_add_test (tc_chain, test_h264_decode_avi_container); + tcase_add_test (tc_chain, test_h264_decode_flv_container); + tcase_add_test (tc_chain, test_h264_decode_mov_container); + tcase_add_test (tc_chain, test_h264_decode_mp4_container); + tcase_add_test (tc_chain, test_mpeg4_decode_avi_container); + /* Doesn't work correctly yet: */ + //tcase_add_test (tc_chain, test_mpeg4_decode_mov_container); + //tcase_add_test (tc_chain, test_mpeg4_decode_mp4_container); + //tcase_add_test (tc_chain, test_xvid_decode_mp4_container); + //tcase_add_test (tc_chain, test_vorbis_decode_ogg_container); + //tcase_add_test (tc_chain, test_vpx_decode_webm_container); + + return s; +} + +GST_CHECK_MAIN (gstamcvideodec); diff --git a/tests/check/pipelines/gstamcvideodec_egl.c b/tests/check/pipelines/gstamcvideodec_egl.c new file mode 100644 index 0000000..56b70ed --- /dev/null +++ b/tests/check/pipelines/gstamcvideodec_egl.c @@ -0,0 +1,56 @@ +/* + * EGL functionality for gstamcvideodec + * + * Copyright (C) 2013, Canonical Ltd. + * Author: Jim Hodapp + * + * 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 + * version 2.1 of the License. + * + * 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 + +void +setup_egl (void) +{ + EGLDisplay egl_display; + EGLConfig egl_config; + EGLContext egl_context; + EGLint major = 0, minor = 0; + EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + EGLint n = 0; + EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE + }; + + GST_INFO ("Initializing EGL"); + + egl_display = eglGetDisplay (EGL_DEFAULT_DISPLAY); + fail_if (egl_display == EGL_NO_DISPLAY); + + fail_if (eglInitialize (egl_display, &major, &minor) == EGL_FALSE); + + fail_if (eglChooseConfig (egl_display, attribs, &egl_config, 1, + &n) == EGL_FALSE); + + egl_context = + eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, + context_attribs); + fail_if (egl_context == EGL_NO_CONTEXT); +} debian/patches/series0000664000000000000000000000024413013176710012033 0ustar 01_fix-modplug-linking.patch 02_opencv-linking.patch pcfile-requires-plugins-good adding-mirsink-and-android-media-over-hybris-support.patch vmncdec_overflow.patch debian/patches/02_opencv-linking.patch0000664000000000000000000000121612324573056015073 0ustar diff --git a/ext/opencv/Makefile.am b/ext/opencv/Makefile.am index 3ba1c34..2bda4e3 100644 --- a/ext/opencv/Makefile.am +++ b/ext/opencv/Makefile.am @@ -40,7 +40,9 @@ libgstopencv_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) \ -DCV_INLINE="static inline" \ -DCV_NO_BACKWARD_COMPATIBILITY -libgstopencv_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(OPENCV_LIBS) \ +# workaround for broken pkg-config file +OPENCV_LIBS_FIXED = $(subst ocl,ml,$(OPENCV_LIBS)) +libgstopencv_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(OPENCV_LIBS_FIXED) \ $(GSTPB_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) libgstopencv_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) debian/patches/01_fix-modplug-linking.patch0000664000000000000000000000160512324573056016035 0ustar Description: Tell libtool not to deduplicate linked libraries which causes problems in the case of circular deps. Force -lc to be added at the end. Author: Iain Lane Index: b/ext/modplug/Makefile.am =================================================================== --- a/ext/modplug/Makefile.am +++ b/ext/modplug/Makefile.am @@ -2,8 +2,8 @@ libgstmodplug_la_SOURCES = gstmodplug.cc libgstmodplug_la_CXXFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CXXFLAGS) $(MODPLUG_CFLAGS) -libgstmodplug_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lstdc++ $(LIBM) $(MODPLUG_LIBS) +libgstmodplug_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lstdc++ $(LIBM) $(MODPLUG_LIBS) -lc libgstmodplug_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstmodplug_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) +libgstmodplug_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) --preserve-dup-deps noinst_HEADERS = gstmodplug.h debian/extra0000664000000000000000000000522012324573056010244 0ustar #!/bin/sh if [ $# -lt 2 ]; then echo "usage: $1 deps|control plugin" exit 1 fi case $1 in deps) case $2 in amrwbenc) echo "libamrwb-dev | amrwb-dev" ;; faac) echo "libfaac-dev" ;; mpeg2enc) echo "libmjpegtools-dev | mjpegtools-dev" ;; *) echo "ERROR invalid plugin: add your plugin to debian/extra" exit 1 ;; esac ;; control) case $2 in amrwbenc) cat << EOF Package: @GST_PKGNAME@-amrwbenc Architecture: any Depends: \${shlibs:Depends}, \${misc:Depends}, @GST_LIB@ XB-GStreamer-Version: \${gstreamer:Version} XB-GStreamer-Elements: \${gstreamer:Elements} XB-GStreamer-URI-Sources: \${gstreamer:URISources} XB-GStreamer-URI-Sinks: \${gstreamer:URISinks} XB-GStreamer-Encoders: \${gstreamer:Encoders} XB-GStreamer-Decoders: \${gstreamer:Decoders} Provides: \${gstreamer:Provides} Description: amrwb encoder plugin for GStreamer This GStreamer plugin uses amrwb to encode audio stream into an Adaptive Multi-Rate - Wideband (AMR-WB) speech codec compressed audio stream. . amrwb Homepage: http://www.penguin.cz/~utx/amr EOF ;; faac) cat << EOF Package: @GST_PKGNAME@-faac Architecture: any Depends: \${shlibs:Depends}, \${misc:Depends}, @GST_LIB@ Recommends: @GST_PKGNAME@-ffmpeg XB-GStreamer-Version: \${gstreamer:Version} XB-GStreamer-Elements: \${gstreamer:Elements} XB-GStreamer-URI-Sources: \${gstreamer:URISources} XB-GStreamer-URI-Sinks: \${gstreamer:URISinks} XB-GStreamer-Encoders: \${gstreamer:Encoders} XB-GStreamer-Decoders: \${gstreamer:Decoders} Provides: \${gstreamer:Provides} Description: FAAC plugin for GStreamer This GStreamer plugin uses FAAC to encode audio stream into a AAC compressed audio stream. This is commonly known as the "mp4" format. . FAAC Homepage: http://www.audiocoding.com/ EOF ;; mpeg2enc) cat << EOF Package: @GST_PKGNAME@-mpeg2enc Architecture: any Depends: \${shlibs:Depends}, \${misc:Depends}, \${misc:Depends}, @GST_LIB@ XB-GStreamer-Version: \${gstreamer:Version} XB-GStreamer-Elements: \${gstreamer:Elements} XB-GStreamer-URI-Sources: \${gstreamer:URISources} XB-GStreamer-URI-Sinks: \${gstreamer:URISinks} XB-GStreamer-Encoders: \${gstreamer:Encoders} XB-GStreamer-Decoders: \${gstreamer:Decoders} Provides: \${gstreamer:Provides} Description: MJPEG Tools plugin for GStreamer This GStreamer plugin uses MJPEG Tools to encode video stream into a MPEG-2 compressed video stream. . MJPEG Tools Homepage: http://mjpeg.sourceforge.net/ EOF ;; *) echo "ERROR invalid plugin: add your plugin to debian/extra" exit 1 ;; esac ;; *) echo "ERROR use deps or control" ;; esac debian/maint0000664000000000000000000000047612324573056010241 0ustar #!/usr/bin/make -f missing: make -f debian/rules list-missing missing-so: make -f debian/rules list-missing | grep so$$ | cut -c 2- missing-libs: for i in `make -f debian/rules list-missing | grep so$$ | cut -c 2-`; do echo "=== $$i ==="; ldd debian/tmp/$$i; echo; done .PHONY: missing missing-so missing-libs debian/build-deps0000664000000000000000000000316012326430771011150 0ustar autoconf (>= 2.62) automake (>= 1.11) autopoint (>= 0.17) autotools-dev cdbs (>= 0.4.93) debhelper (>= 9) dh-autoreconf dpkg-dev (>= 1.15.1) flite-dev @GST_EXTRA_BUILD_DEPENDS@ @GST_LIB_DEV_DEP@ gstreamer@GST_ABI@-doc gstreamer@GST_ABI@-plugins-base (>= 1.0.0) gstreamer@GST_ABI@-plugins-base-doc gtk-doc-tools (>= 1.12) ladspa-sdk libass-dev (>= 0.9.4) libbz2-dev libcairo2-dev libchromaprint-dev libcurl4-gnutls-dev (>= 7.21.0) libdca-dev libdirac-dev (>= 0.10) libdirectfb-dev (>= 0.9.25) libdvdnav-dev (>= 4.1.2) [!hurd-any] libegl1-mesa-dev libexempi-dev libexif-dev (>= 0.6.16) libfaad-dev libfluidsynth-dev (>= 1.0) libgles2-mesa-dev libglib2.0-dev (>= 2.32) libgme-dev libgnutls-dev (>= 2.11.3) libgsm1-dev libgstreamer-plugins-base@GST_ABI@-dev (>= 1.2.0) libgstreamer-plugins-good@GST_ABI@-dev (>= 1.2.0) libgtk2.0-dev (>= 2.14.0) libiptcdata0-dev (>= 1.0.2) libjasper-dev libkate-dev (>= 0.1.7) libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf] libmimic-dev (>= 1.0) libmms-dev (>= 0.4) libmodplug-dev libmpcdec-dev libmpg123-dev (>= 1.13) libofa0-dev (>= 0.9.3) libopenal-dev (>= 1:1.14) libopencv-dev (>= 2.0.0) libopenjpeg-dev libopus-dev (>= 0.9.4) liborc-0.4-dev (>= 1:0.4.17) libplatform-api1-dev [i386 armhf] libpng-dev librsvg2-dev (>= 2.36) librtmp-dev libschroedinger-dev (>= 1.0.7) libslv2-dev (>= 0.6.6) libsndfile1-dev (>= 1.0.16) libsoundtouch-dev (>= 1.5.0) libspandsp-dev libsrtp0-dev libssl-dev libtool (>= 2.2.6) libvo-aacenc-dev libvo-amrwbenc-dev libwebp-dev (>= 0.2.1) libwildmidi-dev (>= 0.2.3) libx11-dev libxml2-dev (>= 2.4) libxvidcore-dev libzbar-dev (>= 0.9) libzvbi-dev pkg-config (>= 0.11.0) debian/copyright0000664000000000000000000021417412324573056011143 0ustar This package was debianized by David I. Lehn on Mon, 15 Jan 2001 18:21:37 -0500. It was downloaded from http://gstreamer.freedesktop.org/ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: GStreamer Bad Plugins 1.0 Upstream-Contact: gstreamer-devel@lists.freedesktop.org Source: http://gstreamer.freedesktop.org Files: ext/gsettings/gstgsettings.h ext/gsettings/gstgsettingsaudiosink.c ext/gsettings/gstgsettingsaudiosink.h ext/gsettings/gstgsettingsaudiosrc.c ext/gsettings/gstgsettingsaudiosrc.h ext/gsettings/gstgsettingsvideosink.c ext/gsettings/gstgsettingsvideosink.h ext/gsettings/gstgsettingsvideosrc.c ext/gsettings/gstgsettingsvideosrc.h ext/gsettings/plugin.c ext/opus/gstopuscommon.c ext/opus/gstopuscommon.h gst/frei0r/gstfrei0r.c gst/frei0r/gstfrei0r.h gst/frei0r/gstfrei0rfilter.c gst/frei0r/gstfrei0rfilter.h gst/frei0r/gstfrei0rmixer.c gst/frei0r/gstfrei0rmixer.h gst/frei0r/gstfrei0rsrc.c gst/frei0r/gstfrei0rsrc.h gst/mxf/mxfaes-bwf.c gst/mxf/mxfaes-bwf.h gst/mxf/mxfalaw.c gst/mxf/mxfalaw.h gst/mxf/mxfd10.c gst/mxf/mxfd10.h gst/mxf/mxfdemux.c gst/mxf/mxfdemux.h gst/mxf/mxfdms1.c gst/mxf/mxfdms1.h gst/mxf/mxfdv-dif.c gst/mxf/mxfdv-dif.h gst/mxf/mxfessence.c gst/mxf/mxfessence.h gst/mxf/mxfjpeg2000.c gst/mxf/mxfjpeg2000.h gst/mxf/mxfmetadata.c gst/mxf/mxfmetadata.h gst/mxf/mxfmpeg.c gst/mxf/mxfmpeg.h gst/mxf/mxfmux.c gst/mxf/mxfmux.h gst/mxf/mxftypes.c gst/mxf/mxftypes.h gst/mxf/mxfup.c gst/mxf/mxfup.h gst/mxf/mxfvc3.c gst/mxf/mxfvc3.h gst/segmentclip/gstaudiosegmentclip.c gst/segmentclip/gstaudiosegmentclip.h gst/segmentclip/gstsegmentclip.c gst/segmentclip/gstsegmentclip.h gst/segmentclip/gstvideosegmentclip.c gst/segmentclip/gstvideosegmentclip.h gst/segmentclip/plugin.c tests/check/elements/assrender.c tests/check/elements/vp8dec.c tests/check/elements/vp8enc.c Copyright: 2008-2009, Sebastian Dröge 2009, Sebastian Dröge 2009-2010, Sebastian Dröge 2010, Sebastian Dröge License: LGPL-2+ Files: gst-libs/gst/codecparsers/gstmpeg4parser.h sys/vdpau/basevideodecoder/gstvideoframe.c sys/vdpau/basevideodecoder/gstvideoframe.h sys/vdpau/gstvdp/gstvdp.c sys/vdpau/gstvdp/gstvdp.h sys/vdpau/gstvdp/gstvdpbuffer.c sys/vdpau/gstvdp/gstvdpbuffer.h sys/vdpau/gstvdp/gstvdpbufferpool.c sys/vdpau/gstvdp/gstvdpbufferpool.h sys/vdpau/gstvdp/gstvdpdecoder.c sys/vdpau/gstvdp/gstvdpdecoder.h sys/vdpau/gstvdp/gstvdpdevice.c sys/vdpau/gstvdp/gstvdpdevice.h sys/vdpau/gstvdp/gstvdpoutputbuffer.c sys/vdpau/gstvdp/gstvdpoutputbuffer.h sys/vdpau/gstvdp/gstvdpoutputsrcpad.c sys/vdpau/gstvdp/gstvdpoutputsrcpad.h sys/vdpau/gstvdp/gstvdputils.c sys/vdpau/gstvdp/gstvdputils.h sys/vdpau/gstvdp/gstvdpvideobuffer.c sys/vdpau/gstvdp/gstvdpvideobuffer.h sys/vdpau/gstvdp/gstvdpvideosrcpad.c sys/vdpau/gstvdp/gstvdpvideosrcpad.h sys/vdpau/gstvdpvideopostprocess.c sys/vdpau/gstvdpvideopostprocess.h sys/vdpau/h264/gsth264dpb.c sys/vdpau/h264/gsth264dpb.h sys/vdpau/h264/gsth264frame.c sys/vdpau/h264/gsth264frame.h sys/vdpau/h264/gsth264parser.c sys/vdpau/h264/gsth264parser.h sys/vdpau/h264/gstnalreader.c sys/vdpau/h264/gstnalreader.h sys/vdpau/h264/gstvdph264dec.c sys/vdpau/h264/gstvdph264dec.h sys/vdpau/mpeg/gstvdpmpegdec.c sys/vdpau/mpeg/gstvdpmpegdec.h sys/vdpau/mpeg/gstvdpmpegframe.c sys/vdpau/mpeg/gstvdpmpegframe.h sys/vdpau/mpeg4/gstmpeg4frame.c sys/vdpau/mpeg4/gstmpeg4frame.h sys/vdpau/mpeg4/gstvdpmpeg4dec.c sys/vdpau/mpeg4/gstvdpmpeg4dec.h sys/vdpau/mpeg4/mpeg4util.c sys/vdpau/mpeg4/mpeg4util.h Copyright: 2009, Carl-Anton Ingmarsson 2010, Carl-Anton Ingmarsson License: LGPL-2+ Files: ext/cog/gstcog.c ext/cog/gstcogmse.c ext/cog/gstcogutils.c ext/cog/gstcogutils.h ext/dirac/gstdiracenc.cc ext/flite/gstflite.c ext/schroedinger/gstschro.c ext/schroedinger/gstschrodec.c ext/schroedinger/gstschroenc.c ext/schroedinger/gstschroutils.c ext/schroedinger/gstschroutils.h gst-libs/gst/glib-compat-private.h gst-libs/gst/video/gstbasevideocodec.c gst-libs/gst/video/gstbasevideocodec.h gst-libs/gst/video/gstbasevideoutils.c gst-libs/gst/video/gstbasevideoutils.h gst/bayer/gstbayer.c gst/bayer/gstbayer2rgb.c gst/debugutils/gstchecksumsink.c gst/debugutils/gstchecksumsink.h gst/debugutils/gstchopmydata.c gst/sdi/gstsdi.c gst/sdi/gstsdidemux.c gst/sdi/gstsdimux.c gst/videofilters/gstvideofilter2.c gst/videofilters/gstvideofilter2.h gst/videofilters/gstzebrastripe.h gst/videoparsers/gstdiracparse.c gst/y4m/gsty4mdec.c gst/y4m/gsty4mdec.h sys/decklink/gstdecklink.cpp sys/decklink/gstdecklink.h sys/decklink/gstdecklinksink.h sys/decklink/gstdecklinksrc.cpp sys/decklink/gstdecklinksrc.h sys/vdpau/basevideodecoder/gstbasevideodecoder.c sys/vdpau/basevideodecoder/gstbasevideodecoder.h sys/vdpau/basevideodecoder/gstbasevideoutils.h tests/check/elements/logoinsert.c Copyright: 2005, David Schleef 2006, David Schleef 2007, David Schleef 2007,2009, David Schleef 2008, David Schleef 2010, David Schleef 2011, David Schleef License: LGPL-2+ Files: ext/opencv/gstcvdilate.c ext/opencv/gstcvdilate.h ext/opencv/gstcvdilateerode.c ext/opencv/gstcvdilateerode.h ext/opencv/gstcvequalizehist.c ext/opencv/gstcvequalizehist.h ext/opencv/gstcverode.c ext/opencv/gstcverode.h ext/opencv/gstcvlaplace.c ext/opencv/gstcvlaplace.h ext/opencv/gstcvsmooth.c ext/opencv/gstcvsmooth.h ext/opencv/gstcvsobel.c ext/opencv/gstcvsobel.h ext/opencv/gstopencvvideofilter.c ext/opencv/gstopencvvideofilter.h gst/geometrictransform/geometricmath.c gst/geometrictransform/geometricmath.h gst/geometrictransform/gstcircle.c gst/geometrictransform/gstcircle.h gst/geometrictransform/gstcirclegeometrictransform.c gst/geometrictransform/gstcirclegeometrictransform.h gst/geometrictransform/gstdiffuse.c gst/geometrictransform/gstdiffuse.h gst/geometrictransform/gstkaleidoscope.c gst/geometrictransform/gstkaleidoscope.h gst/geometrictransform/gstmarble.c gst/geometrictransform/gstmarble.h gst/geometrictransform/gstpinch.c gst/geometrictransform/gstpinch.h gst/geometrictransform/gstrotate.c gst/geometrictransform/gstrotate.h gst/geometrictransform/gstsphere.c gst/geometrictransform/gstsphere.h gst/geometrictransform/gsttwirl.c gst/geometrictransform/gsttwirl.h gst/geometrictransform/gstwaterripple.c gst/geometrictransform/gstwaterripple.h Copyright: 2010, Thiago Santos License: MIT/X11 (BSD like) LGPL-2+ Files: sys/applemedia/avfvideosrc.h sys/applemedia/bufferfactory.h sys/applemedia/celapi.c sys/applemedia/celapi.h sys/applemedia/celvideosrc.c sys/applemedia/celvideosrc.h sys/applemedia/cmapi.c sys/applemedia/cmapi.h sys/applemedia/coremediabuffer.c sys/applemedia/coremediabuffer.h sys/applemedia/coremediactx.c sys/applemedia/coremediactx.h sys/applemedia/corevideobuffer.c sys/applemedia/corevideobuffer.h sys/applemedia/cvapi.c sys/applemedia/cvapi.h sys/applemedia/dynapi-internal.h sys/applemedia/dynapi.c sys/applemedia/dynapi.h sys/applemedia/mioapi.c sys/applemedia/mioapi.h sys/applemedia/miovideodevice.h sys/applemedia/miovideosrc.h sys/applemedia/mtapi.c sys/applemedia/mtapi.h sys/applemedia/qtkitvideosrc.h sys/applemedia/vtapi.c sys/applemedia/vtapi.h sys/applemedia/vtdec.c sys/applemedia/vtdec.h sys/applemedia/vtenc.h sys/applemedia/vth264decbin.h sys/applemedia/vth264encbin.h sys/applemedia/vtutil.c sys/applemedia/vtutil.h Copyright: 2009, Ole Andr? Vadla Ravnås 2010, Ole Andr? Vadla Ravnås License: LGPL-2+ Files: gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.c gst-libs/gst/basecamerabinsrc/gstcamerabin-enum.h gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.c gst-libs/gst/interfaces/photography.c gst-libs/gst/interfaces/photography.h gst/camerabin/camerabindebug.h gst/camerabin/camerabingeneral.c gst/camerabin/camerabingeneral.h gst/camerabin/camerabinimage.c gst/camerabin/camerabinimage.h gst/camerabin/camerabinpreview.c gst/camerabin/camerabinpreview.h gst/camerabin/camerabinvideo.c gst/camerabin/camerabinvideo.h gst/camerabin/gstcamerabin-enum.c gst/camerabin/gstcamerabin-enum.h gst/camerabin/gstcamerabin.c gst/camerabin/gstcamerabin.h gst/camerabin/gstcamerabincolorbalance.c gst/camerabin/gstcamerabincolorbalance.h gst/camerabin2/camerabingeneral.c gst/camerabin2/camerabingeneral.h gst/debugutils/fpsdisplaysink.c gst/debugutils/fpsdisplaysink.h tests/check/elements/camerabin.c tests/examples/camerabin/gst-camera-perf.c tests/examples/camerabin/gst-camera.c tests/examples/camerabin/gst-camera.h tests/examples/camerabin/gst-camerabin-test.c tests/examples/camerabin2/gst-camera2.h Copyright: 2008, Nokia Corporation 2009, Nokia Corporation 2010, Nokia Corporation License: LGPL-2+ Files: gst/mpegdemux/mpegtspacketizer.h gst/mpegdemux/mpegtsparse.h gst/mpegtsdemux/mpegtspacketizer.h gst/mpegtsdemux/mpegtsparse.c gst/mpegtsdemux/mpegtsparse.h sys/dvb/cam.c sys/dvb/cam.h sys/dvb/camapplication.c sys/dvb/camapplication.h sys/dvb/camapplicationinfo.c sys/dvb/camapplicationinfo.h sys/dvb/camdevice.c sys/dvb/camdevice.h sys/dvb/camresourcemanager.c sys/dvb/camresourcemanager.h sys/dvb/camsession.c sys/dvb/camsession.h sys/dvb/camswclient.c sys/dvb/camswclient.h sys/dvb/camtransport.c sys/dvb/camtransport.h sys/dvb/camutils.c sys/dvb/camutils.h sys/dvb/dvbbasebin.c sys/dvb/dvbbasebin.h sys/dvb/gstdvb.c sys/dvb/parsechannels.h Copyright: 2007, Alessandro Decina License: LGPL-2+ Files: ext/opus/gstrtpopusdepay.c ext/opus/gstrtpopusdepay.h ext/opus/gstrtpopuspay.c ext/opus/gstrtpopuspay.h gst/mpegtsdemux/gsttsdemux.c gst/siren/common.c gst/siren/common.h gst/siren/dct4.c gst/siren/dct4.h gst/siren/decoder.c gst/siren/decoder.h gst/siren/encoder.c gst/siren/encoder.h gst/siren/gstsiren.c gst/siren/gstsirendec.c gst/siren/gstsirendec.h gst/siren/gstsirenenc.c gst/siren/gstsirenenc.h gst/siren/huffman.c gst/siren/huffman.h gst/siren/huffman_consts.h gst/siren/rmlt.c gst/siren/rmlt.h gst/siren/siren7.h Copyright: *No copyright* License: LGPL-2+ Files: ext/divx/gstdivxdec.c ext/divx/gstdivxdec.h ext/divx/gstdivxenc.c ext/divx/gstdivxenc.h ext/dts/gstdtsdec.h ext/faac/gstfaac.h ext/faad/gstfaad.h ext/mpeg2enc/gstmpeg2encoptions.cc ext/mpeg2enc/gstmpeg2encoptions.hh ext/mpeg2enc/gstmpeg2encpicturereader.cc ext/mpeg2enc/gstmpeg2encpicturereader.hh ext/mplex/gstmplex.hh ext/mplex/gstmplexjob.cc ext/mplex/gstmplexjob.hh ext/musepack/gstmusepackdec.h ext/musepack/gstmusepackreader.c ext/musepack/gstmusepackreader.h ext/sdl/sdlvideosink.c ext/sdl/sdlvideosink.h ext/xvid/gstxvid.c ext/xvid/gstxvid.h ext/xvid/gstxviddec.h ext/xvid/gstxvidenc.h Copyright: 2001-2002, Ronald Bultje 2003, Ronald Bultje 2004, Ronald Bultje License: LGPL-2+ Files: ext/cdaudio/gstcdaudio.c ext/gsm/gstgsmdec.h ext/gsm/gstgsmenc.h ext/ladspa/gstladspa.h ext/lv2/gstlv2.h ext/modplug/gstmodplug.cc ext/modplug/gstmodplug.h ext/nas/nassink.h ext/swfdec/gstswfdec.h gst/aiff/aiffparse.c gst/cdxaparse/gstcdxaparse.c gst/cdxaparse/gstcdxaparse.h gst/legacyresample/gstlegacyresample.h gst/smooth/gstsmooth.c gst/smooth/gstsmooth.h gst/speed/gstspeed.h gst/stereo/gststereo.c gst/stereo/gststereo.h sys/vcd/vcdsrc.c sys/vcd/vcdsrc.h Copyright: <1999> Erik Walthinsen License: LGPL-2+ Files: ext/cog/gstcms.c ext/cog/gstcms.h ext/cog/gstcolorconvert.c ext/cog/gstlogoinsert.c gst/bayer/gstrgb2bayer.c gst/inter/gstinter.c gst/inter/gstintersubsink.c gst/inter/gstintersubsink.h gst/inter/gstintersubsrc.c gst/inter/gstintersubsrc.h gst/patchdetect/gstpatchdetect.c gst/patchdetect/gstpatchdetect.h gst/videofilters/gstvideofiltersbad.c gst/videofilters/gstzebrastripe.c sys/avc/gstavcplugin.cpp sys/avc/gstavcsrc.cpp sys/decklink/gstdecklinksink.cpp sys/linsys/gstlinsyssdisink.c sys/linsys/gstlinsyssdisrc.c Copyright: 2008, David Schleef 2010, David Schleef 2011, David Schleef License: LGPL-2+ Files: gst/nsf/dis6502.h gst/nsf/fds_snd.c gst/nsf/fds_snd.h gst/nsf/log.c gst/nsf/log.h gst/nsf/mmc5_snd.c gst/nsf/mmc5_snd.h gst/nsf/nes6502.c gst/nsf/nes6502.h gst/nsf/nes_apu.c gst/nsf/nes_apu.h gst/nsf/nsf.c gst/nsf/nsf.h gst/nsf/osd.h gst/nsf/types.h gst/nsf/vrc7_snd.c gst/nsf/vrc7_snd.h gst/nsf/vrcvisnd.c gst/nsf/vrcvisnd.h Copyright: 1998-2000, Matthew Conte (matt@conte.com) License: LGPL-2+ Files: sys/d3dvideosink/d3dvideosink.h sys/d3dvideosink/directx/d3d.c sys/d3dvideosink/directx/d3d.h sys/d3dvideosink/directx/directx.h sys/d3dvideosink/directx/directx10/dx10.c sys/d3dvideosink/directx/directx10/dx10.h sys/d3dvideosink/directx/directx10/dx10_d3d.c sys/d3dvideosink/directx/directx10/dx10_d3d.h sys/d3dvideosink/directx/directx11/dx11.c sys/d3dvideosink/directx/directx11/dx11.h sys/d3dvideosink/directx/directx11/dx11_d3d.c sys/d3dvideosink/directx/directx11/dx11_d3d.h sys/d3dvideosink/directx/directx9/dx9.c sys/d3dvideosink/directx/directx9/dx9.h sys/d3dvideosink/directx/directx9/dx9_d3d.c sys/d3dvideosink/directx/directx9/dx9_d3d.h sys/d3dvideosink/directx/dx.c sys/d3dvideosink/directx/dx.h Copyright: 2010, David Hoyt 2011, David Hoyt License: LGPL-2+ Files: gst/pcapparse/gstpcapparse.c gst/pcapparse/gstpcapparse.h gst/pcapparse/plugin.c sys/wasapi/gstwasapi.c sys/wasapi/gstwasapisink.c sys/wasapi/gstwasapisink.h sys/wasapi/gstwasapisrc.c sys/wasapi/gstwasapisrc.h sys/wasapi/gstwasapiutil.c sys/wasapi/gstwasapiutil.h sys/wininet/gstwininetsrc.c sys/wininet/gstwininetsrc.h sys/winks/gstksclock.c sys/winks/gstksclock.h sys/winks/gstksvideodevice.c sys/winks/gstksvideodevice.h sys/winks/gstksvideosrc.c sys/winks/gstksvideosrc.h Copyright: 2007, Ole Andr? Vadla Ravnås 2008, Ole Andr? Vadla Ravnås License: LGPL-2+ Files: ext/resindvd/plugin.c ext/resindvd/resindvdbin.c ext/resindvd/resindvdbin.h ext/resindvd/resindvdsrc.c ext/resindvd/resindvdsrc.h ext/resindvd/rsnaudiomunge.c ext/resindvd/rsnaudiomunge.h ext/resindvd/rsnwrappedbuffer.c ext/resindvd/rsnwrappedbuffer.h ext/rtmp/gstrtmpsink.c ext/rtmp/gstrtmpsink.h gst/dvdspu/gstspu-pgs.c gst/dvdspu/gstspu-pgs.h gst/dvdspu/gstspu-vobsub.c gst/dvdspu/gstspu-vobsub.h tests/check/elements/autoconvert.c Copyright: 2008, Jan Schmidt 2008-2009, Jan Schmidt 2009, Jan Schmidt 2010, Jan Schmidt License: LGPL-2+ Files: sys/decklink/capture.cpp sys/decklink/linux/DeckLinkAPI.h sys/decklink/linux/DeckLinkAPIDispatch.cpp sys/decklink/linux/LinuxCOM.h sys/decklink/osx/DeckLinkAPI.h sys/decklink/osx/DeckLinkAPIConfiguration.h sys/decklink/osx/DeckLinkAPIDeckControl.h sys/decklink/osx/DeckLinkAPIDiscovery.h sys/decklink/osx/DeckLinkAPIDispatch-osx.cpp sys/decklink/osx/DeckLinkAPIModes.h sys/decklink/osx/DeckLinkAPIStreaming.h sys/decklink/osx/DeckLinkAPITypes.h sys/decklink/osx/DeckLinkAPIVersion.h sys/decklink/win/DeckLinkAPIDispatch.cpp Copyright: 2009, Blackmagic Design 2011, Blackmagic Design License: UNKNOWN Files: gst/dccp/gstdccp.c gst/dccp/gstdccp.h gst/dccp/gstdccp_common.h gst/dccp/gstdccpclientsink.c gst/dccp/gstdccpclientsink.h gst/dccp/gstdccpclientsrc.c gst/dccp/gstdccpclientsrc.h gst/dccp/gstdccpplugin.c gst/dccp/gstdccpserversink.c gst/dccp/gstdccpserversink.h gst/dccp/gstdccpserversrc.c gst/dccp/gstdccpserversrc.h Copyright: <2007> Leandro Melo de Sales License: LGPL-2+ Files: gst/geometrictransform/gstbulge.c gst/geometrictransform/gstbulge.h gst/geometrictransform/gstfisheye.c gst/geometrictransform/gstfisheye.h gst/geometrictransform/gstmirror.c gst/geometrictransform/gstmirror.h gst/geometrictransform/gstsquare.c gst/geometrictransform/gstsquare.h gst/geometrictransform/gststretch.c gst/geometrictransform/gststretch.h gst/geometrictransform/gsttunnel.c gst/geometrictransform/gsttunnel.h Copyright: 2010, Filippo Argiolas License: MIT/X11 (BSD like) LGPL-2+ Files: gst/audiovisualizers/gstbaseaudiovisualizer.c gst/audiovisualizers/gstbaseaudiovisualizer.h gst/audiovisualizers/gstspacescope.c gst/audiovisualizers/gstspacescope.h gst/audiovisualizers/gstspectrascope.c gst/audiovisualizers/gstspectrascope.h gst/audiovisualizers/gstsynaescope.c gst/audiovisualizers/gstsynaescope.h gst/audiovisualizers/gstwavescope.c gst/audiovisualizers/gstwavescope.h gst/audiovisualizers/plugin.c Copyright: <2011> Stefan Kost License: GPL-2+ Files: ext/dirac/gstdirac.cc gst/inter/gstinteraudiosink.c gst/inter/gstinteraudiosink.h gst/inter/gstinteraudiosrc.c gst/inter/gstinteraudiosrc.h gst/inter/gstintersurface.c gst/inter/gstintersurface.h gst/inter/gstintervideosink.c gst/inter/gstintervideosink.h gst/inter/gstintervideosrc.c gst/inter/gstintervideosrc.h Copyright: 2004, David A. Schleef 2011, David A. Schleef License: LGPL-2+ Files: sys/dshowdecwrapper/gstdshowfakesrc.cpp sys/dshowdecwrapper/gstdshowfakesrc.h sys/dshowdecwrapper/gstdshowutil.cpp sys/dshowsrcwrapper/gstdshow.cpp sys/dshowsrcwrapper/gstdshow.h sys/dshowsrcwrapper/gstdshowaudiosrc.cpp sys/dshowsrcwrapper/gstdshowaudiosrc.h sys/dshowsrcwrapper/gstdshowfakesink.cpp sys/dshowsrcwrapper/gstdshowfakesink.h sys/dshowsrcwrapper/gstdshowsrcwrapper.cpp sys/dshowsrcwrapper/gstdshowvideosrc.h Copyright: 2007, Sebastien Moutte License: LGPL-2+ Files: gst/mpegdemux/flumpegdemux.c gst/mpegdemux/flutspatinfo.h gst/mpegdemux/flutspmtinfo.h gst/mpegdemux/flutspmtstreaminfo.h gst/mpegdemux/gstmpegdefs.h gst/mpegdemux/gstmpegdemux.c gst/mpegdemux/gstmpegdemux.h gst/mpegdemux/gstmpegtsdemux.h gst/mpegdemux/gstpesfilter.c gst/mpegdemux/gstpesfilter.h gst/mpegdemux/gstsectionfilter.h Copyright: 2005 2005-2009 License: MPL-1.1 LGPL-2+ Files: ext/ladspa/gstladspa.c ext/libmms/gstmms.c ext/lv2/gstlv2.c ext/rtmp/gstrtmp.c ext/rtmp/gstrtmpsrc.c ext/rtmp/gstrtmpsrc.h ext/sndfile/gstsfsrc.c gst-libs/gst/signalprocessor/gstsignalprocessor.c gst-libs/gst/signalprocessor/gstsignalprocessor.h gst/speed/gstspeed.c Copyright: 1999, Erik Walthinsen 1999-2000, Erik Walthinsen 1999-2001, Erik Walthinsen License: LGPL-2+ Files: ext/celt/gstcelt.c ext/celt/gstceltdec.h ext/celt/gstceltenc.c ext/celt/gstceltenc.h ext/opus/gstopus.c ext/opus/gstopusdec.h ext/opus/gstopusenc.h ext/opus/gstopusheader.h ext/opus/gstopusparse.h Copyright: <1999> Erik Walthinsen <2008> Sebastian Dröge License: LGPL-2+ Files: sys/qtwrapper/codecmapping.c sys/qtwrapper/codecmapping.h sys/qtwrapper/imagedescription.c sys/qtwrapper/imagedescription.h sys/qtwrapper/qtutils.c sys/qtwrapper/qtutils.h sys/qtwrapper/qtwrapper.c sys/qtwrapper/qtwrapper.h sys/qtwrapper/videodecoders.c Copyright: <2006-2007> Fluendo <2006-2007> Pioneers of the Inevitable License: MIT/X11 (BSD like) LGPL-2+ Files: gst/gaudieffects/gstburn.c gst/gaudieffects/gstburn.h gst/gaudieffects/gstchromium.c gst/gaudieffects/gstdilate.c gst/gaudieffects/gstdilate.h gst/gaudieffects/gstdodge.c gst/gaudieffects/gstexclusion.c gst/gaudieffects/gstsolarize.c gst/gaudieffects/gstsolarize.h Copyright: 2010, Luis de Bethencourt License: MIT/X11 (BSD like) LGPL-2+ Files: ext/rsvg/gstrsvgdec.c ext/rsvg/gstrsvgdec.h gst/mxf/mxfquark.c gst/mxf/mxfquark.h gst/mxf/mxful.c gst/mxf/mxful.h tests/check/elements/mxfmux.c tests/check/pipelines/mxf.c Copyright: <2009> Sebastian Dröge License: LGPL-2+ Files: gst/mve/gstmve.c gst/mve/gstmvedemux.c gst/mve/gstmvedemux.h gst/mve/gstmvemux.c gst/mve/gstmvemux.h gst/mve/mve.h gst/mve/mvevideoenc16.c gst/mve/mvevideoenc8.c Copyright: 2006, Jens Granseuer 2006-2008, Jens Granseuer License: LGPL-2+ Files: ext/mpeg2enc/gstmpeg2enc.cc ext/mpeg2enc/gstmpeg2enc.hh ext/mpeg2enc/gstmpeg2encoder.cc ext/mpeg2enc/gstmpeg2encoder.hh ext/mpeg2enc/gstmpeg2encstreamwriter.cc ext/mpeg2enc/gstmpeg2encstreamwriter.hh ext/xvid/gstxviddec.c ext/xvid/gstxvidenc.c Copyright: 2003, Ronald Bultje 2006, Mark Nauwelaerts License: LGPL-2+ Files: gst/asfmux/gstasfmux.c gst/asfmux/gstasfmux.h gst/asfmux/gstasfobjects.c gst/asfmux/gstasfobjects.h gst/asfmux/gstasfparse.c gst/asfmux/gstasfparse.h gst/asfmux/gstrtpasfpay.c gst/asfmux/gstrtpasfpay.h Copyright: 2009, Thiago Santos License: LGPL-2+ Files: gst/mpegpsmux/crc.h gst/mpegpsmux/mpegpsmux.c gst/mpegpsmux/mpegpsmux.h gst/mpegpsmux/psmux.c gst/mpegpsmux/psmux.h gst/mpegpsmux/psmuxcommon.h gst/mpegpsmux/psmuxstream.c gst/mpegpsmux/psmuxstream.h Copyright: 2008, Lin YANG License: MIT/X11 (BSD like) LGPL-2+ Files: ext/opencv/gstopencvutils.c ext/opencv/gstopencvutils.h gst/camerabin2/gstplugin.c gst/geometrictransform/gstgeometrictransform.c gst/geometrictransform/gstgeometrictransform.h gst/geometrictransform/plugin.c tests/check/elements/jifmux.c Copyright: <2010> Thiago Santos License: LGPL-2+ Files: gst/pnm/gstpnm.c gst/pnm/gstpnmdec.c gst/pnm/gstpnmdec.h gst/pnm/gstpnmenc.c gst/pnm/gstpnmenc.h gst/pnm/gstpnmutils.c gst/pnm/gstpnmutils.h Copyright: 2009, Lutz Mueller License: LGPL-2+ Files: ext/opencv/gstedgedetect.c ext/opencv/gstedgedetect.h ext/opencv/gstfaceblur.c ext/opencv/gstfaceblur.h ext/opencv/gstpyramidsegment.c ext/opencv/gstpyramidsegment.h ext/opencv/gsttemplatematch.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2008, Michael Sheldon License: MIT/X11 (BSD like) LGPL-2+ Files: ext/resindvd/gstmpegdefs.h ext/resindvd/gstmpegdemux.c ext/resindvd/gstmpegdemux.h ext/resindvd/gstmpegdesc.c ext/resindvd/gstmpegdesc.h ext/resindvd/gstpesfilter.c ext/resindvd/gstpesfilter.h Copyright: Copyright (C) 2005 Fluendo, S.L. License: MPL-1.1 Files: gst-libs/gst/video/gstsurfaceconverter.c gst-libs/gst/video/gstsurfaceconverter.h gst-libs/gst/video/gstsurfacemeta.c gst-libs/gst/video/gstsurfacemeta.h gst-libs/gst/video/videocontext.c gst-libs/gst/video/videocontext.h Copyright: 2011, Collabora Ltd 2011, Intel License: LGPL-2+ Files: ext/vp8/gstvp8dec.c ext/vp8/gstvp8dec.h ext/vp8/gstvp8enc.c ext/vp8/gstvp8enc.h ext/vp8/gstvp8utils.c ext/vp8/gstvp8utils.h Copyright: 2006, David Schleef 2008-2010, Entropy Wave Inc 2010, Entropy Wave Inc 2010, Sebastian Dröge License: LGPL-2+ Files: gst/bayer/gstrgb2bayer.h gst/videofilters/gstscenechange.h sys/avc/gstavcsrc.h sys/linsys/gstlinsys.c sys/linsys/gstlinsyssdisink.h sys/linsys/gstlinsyssdisrc.h Copyright: 2010, Entropy Wave Inc 2011, Entropy Wave Inc License: LGPL-2+ Files: sys/winks/ksvideohelpers.c sys/winks/ksvideohelpers.h sys/winscreencap/gstdx9screencapsrc.c sys/winscreencap/gstgdiscreencapsrc.c sys/winscreencap/gstwinscreencap.c sys/winscreencap/gstwinscreencap.h Copyright: 2007, Haakon Sporsheim License: LGPL-2+ Files: ext/faac/gstfaac.c ext/mplex/gstmplex.cc ext/mplex/gstmplexibitstream.cc ext/mplex/gstmplexibitstream.hh ext/mplex/gstmplexoutputstream.cc ext/mplex/gstmplexoutputstream.hh Copyright: 2003, Ronald Bultje 2008, Mark Nauwelaerts 2009, Mark Nauwelaerts License: LGPL-2+ Files: tests/check/elements/h263parse.c tests/check/elements/h264parse.c tests/check/elements/mpeg4videoparse.c tests/check/elements/mpegvideoparse.c tests/check/elements/parser.c tests/check/elements/parser.h Copyright: 2008, Nokia Corporation. 2011, Nokia Corporation. License: LGPL-2+ Files: sys/acmenc/acmenc.c sys/acmmp3dec/acmmp3dec.c sys/dshowvideosink/dshowvideofakesrc.cpp sys/dshowvideosink/dshowvideofakesrc.h sys/dshowvideosink/dshowvideosink.cpp sys/dshowvideosink/dshowvideosink.h Copyright: 2008, Pioneers of the Inevitable License: LGPL-2+ Files: gst/camerabin2/gstcamerabin2.c gst/camerabin2/gstcamerabin2.h gst/camerabin2/gstviewfinderbin.c gst/camerabin2/gstviewfinderbin.h tests/check/elements/viewfinderbin.c tests/examples/camerabin2/gst-camera2.c Copyright: 2010, Thiago Santos License: LGPL-2+ Files: gst/debugutils/debugutilsbad.c gst/id3tag/id3tag.h tests/check/elements/dataurisrc.c tests/check/elements/id3mux.c tests/check/elements/neonhttpsrc.c tests/check/elements/zbar.c Copyright: 2006, Tim-Philipp Müller 2006-2007, Tim-Philipp Müller 2009, Tim-Philipp Müller 2010, Tim-Philipp Müller License: LGPL-2+ Files: gst/videomeasure/gstvideomeasure.c gst/videomeasure/gstvideomeasure.h gst/videomeasure/gstvideomeasure_collector.c gst/videomeasure/gstvideomeasure_collector.h gst/videomeasure/gstvideomeasure_ssim.c gst/videomeasure/gstvideomeasure_ssim.h Copyright: <2009> Руслан Ижбулатов License: LGPL-2.1+ Files: ext/opencv/MotionCells.cpp ext/opencv/MotionCells.h ext/opencv/gstmotioncells.c ext/opencv/gstmotioncells.h ext/opencv/motioncells_wrapper.cpp ext/opencv/motioncells_wrapper.h Copyright: 2011, Nicola Murino 2011, Robert Jobbagy License: MIT/X11 (BSD like) LGPL-2+ Files: ext/kate/gstkate.c ext/kate/gstkatedec.c ext/kate/gstkatedec.h ext/kate/gstkateenc.h ext/kate/gstkatetiger.c ext/kate/gstkatetiger.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2008, Vincent Penquerc'h 2008-2009, Vincent Penquerc'h License: MIT/X11 (BSD like) LGPL-2+ Files: sys/shm/gstshm.c sys/shm/gstshmsink.c sys/shm/gstshmsink.h sys/shm/gstshmsrc.c sys/shm/gstshmsrc.h Copyright: <2009> Collabora Ltd <2009> Nokia Inc License: LGPL-2+ Files: gst-libs/gst/codecparsers/gstmpeg4parser.c gst-libs/gst/codecparsers/gstvc1parser.c gst-libs/gst/codecparsers/gstvc1parser.h gst-libs/gst/codecparsers/parserutils.h tests/check/libs/vc1parser.c Copyright: <2011> Collabora Ltd <2011> Intel <2011> Thibault Saunier License: LGPL-2+ Files: ext/sndfile/gstsf.c ext/sndfile/gstsf.h ext/sndfile/gstsfsink.c ext/sndfile/gstsfsink.h ext/sndfile/gstsfsrc.h Copyright: 2003, Andy Wingo 2003,2007, Andy Wingo 2007, Andy Wingo License: LGPL-2+ Files: gst/debugutils/gstcompare.c gst/debugutils/gstcompare.h tests/check/elements/rtpmux.c tests/check/pipelines/colorspace.c tests/check/pipelines/mimic.c Copyright: 2009, Collabora Ltd 2009, Nokia Corp 2011, Collabora Ltd 2011, Nokia Corp License: LGPL-2+ Files: ext/apexsink/gstapexplugin.c ext/apexsink/gstapexraop.c ext/apexsink/gstapexraop.h ext/apexsink/gstapexsink.c ext/apexsink/gstapexsink.h Copyright: 2008, J?r?mie Bernard [GRemi License: LGPL-2+ Files: ext/bz2/gstbz2.c ext/bz2/gstbz2dec.c ext/bz2/gstbz2dec.h ext/bz2/gstbz2enc.c ext/bz2/gstbz2enc.h Copyright: 2006, Lutz Müller License: LGPL-2+ Files: ext/jp2k/gstjasperdec.c ext/jp2k/gstjasperdec.h ext/jp2k/gstjasperenc.c ext/jp2k/gstjasperenc.h ext/jp2k/gstjp2k.c Copyright: 2008, Mark Nauwelaerts License: LGPL-2+ Files: ext/soundtouch/gstbpmdetect.cc ext/soundtouch/gstbpmdetect.hh gst/rawparse/gstaudioparse.c gst/rawparse/gstaudioparse.h tests/check/elements/ofa.c Copyright: 2007, Sebastian Dröge 2008, Sebastian Dröge License: LGPL-2+ Files: gst/mpegtsmux/tsmux/tsmux.c gst/mpegtsmux/tsmux/tsmux.h gst/mpegtsmux/tsmux/tsmuxcommon.h gst/mpegtsmux/tsmux/tsmuxstream.c gst/mpegtsmux/tsmux/tsmuxstream.h Copyright: 2006, BBC and Fluendo S.A License: MPL-1.1 GPL GPL-2+ LGPL (v2 or later) (with incorrect FSF address) Files: gst/mpegtsmux/mpegtsmux.h gst/mpegtsmux/mpegtsmux_aac.c gst/mpegtsmux/mpegtsmux_aac.h gst/mpegtsmux/mpegtsmux_h264.c gst/mpegtsmux/mpegtsmux_h264.h Copyright: 2006-2008, Fluendo S.A 2006-2010, Fluendo S.A License: MPL-1.1 GPL GPL-2+ LGPL (v2 or later) (with incorrect FSF address) Files: sys/linsys/include/master.h sys/linsys/include/sdi.h sys/linsys/include/sdiaudio.h sys/linsys/include/sdivideo.h Copyright: 2004-2009, Linear Systems Ltd 2009, Linear Systems Ltd 2009-2010, Linear Systems Ltd License: BSD (3 clause) Files: gst/legacyresample/functable.c gst/legacyresample/resample.c gst/legacyresample/resample_functable.c gst/legacyresample/resample_ref.c Copyright: <2001> David A. Schleef License: LGPL Files: gst/videosignal/gstvideoanalyse.c gst/videosignal/gstvideoanalyse.h gst/videosignal/gstvideodetect.h gst/videosignal/gstvideomark.h Copyright: <2006> Wim Taymans License: LGPL-2+ Files: gst/dtmf/gstrtpdtmfsrc.c gst/rtpmux/gstrtpdtmfmux.h gst/rtpmux/gstrtpmux.h gst/rtpmux/gstrtpmuxer.c Copyright: 1999-2000, Erik Walthinsen <2007> Nokia Corporation License: LGPL-2+ Files: gst/hls/gstfragment.c gst/hls/gstfragment.h gst/hls/gsturidownloader.c gst/hls/gsturidownloader.h Copyright: 2011, Andoni Morales Alastruey License: LGPL-2+ Files: gst/tta/gsttta.c gst/tta/gstttadec.h gst/tta/gstttaparse.c gst/tta/gstttaparse.h Copyright: 2004, Arwed v. Merkatz License: LGPL-2+ Files: sys/vdpau/gstvdp/gstvdpoutputbufferpool.c sys/vdpau/gstvdp/gstvdpoutputbufferpool.h sys/vdpau/gstvdp/gstvdpvideobufferpool.c sys/vdpau/gstvdp/gstvdpvideobufferpool.h Copyright: Carl-Anton Ingmarsson 2010, License: LGPL-2+ Files: gst/jp2kdecimator/gstjp2kdecimator.c gst/jp2kdecimator/gstjp2kdecimator.h gst/jp2kdecimator/jp2kcodestream.c gst/jp2kdecimator/jp2kcodestream.h Copyright: 2010, Collabora Multimedia 2010, Oblong Industries, Inc License: LGPL-2+ Files: gst-libs/gst/video/gstbasevideodecoder.c gst-libs/gst/video/gstbasevideodecoder.h gst-libs/gst/video/gstbasevideoencoder.c gst-libs/gst/video/gstbasevideoencoder.h Copyright: 2008, David Schleef 2011, Mark Nauwelaerts 2011, Nokia Corporation. License: LGPL-2+ Files: sys/directdraw/gstdirectdrawplugin.c sys/directdraw/gstdirectdrawsink.c sys/directdraw/gstdirectdrawsink.h sys/directsound/gstdirectsoundplugin.c Copyright: 2005, Sebastien Moutte 2007, Pioneers of the Inevitable License: LGPL-2+ Files: ext/timidity/gsttimidity.c ext/timidity/gsttimidity.h ext/timidity/gstwildmidi.c ext/timidity/gstwildmidi.h Copyright: 2007, Wouter Paesen License: LGPL-2+ Files: sys/shm/shmalloc.c sys/shm/shmalloc.h sys/shm/shmpipe.c sys/shm/shmpipe.h Copyright: <2009> Collabora Ltd <2009> Nokia Inc License: MIT/X11 (BSD like) Files: sys/dshowdecwrapper/gstdshowaudiodec.cpp sys/dshowdecwrapper/gstdshowaudiodec.h sys/dshowdecwrapper/gstdshowvideodec.cpp sys/dshowdecwrapper/gstdshowvideodec.h Copyright: <2006-2008> Pioneers of the Inevitable <2006-2010> Fluendo <2007-2008> Sebastien Moutte License: MIT/X11 (BSD like) LGPL-2+ Files: gst/mpegpsmux/mpegpsmux_aac.c gst/mpegpsmux/mpegpsmux_aac.h gst/mpegpsmux/mpegpsmux_h264.c gst/mpegpsmux/mpegpsmux_h264.h Copyright: 2006-2008, Fluendo S.A 2008, Lin YANG License: MPL-1.1 GPL GPL-2+ LGPL (v2 or later) (with incorrect FSF address) Files: common/coverage/coverage-report-entry.pl common/coverage/coverage-report.pl common/coverage/coverage-report.xsl Copyright: 2006, Daniel Berrange License: GPL-2+ Files: tests/examples/scaletempo/demo-gui.c tests/examples/scaletempo/demo-main.c tests/examples/scaletempo/demo-player.c Copyright: 2008, Rov Juvano License: GPL-3+ Files: gst/mpegtsdemux/gstmpegdefs.h gst/mpegtsdemux/gstmpegdesc.c gst/mpegtsdemux/gstmpegdesc.h Copyright: 2005 License: LGPL-2+ Files: ext/sdl/gstsdl.c ext/sdl/sdlaudiosink.c ext/sdl/sdlaudiosink.h Copyright: <2005> Edgard Lima License: LGPL-2+ Files: gst/videosignal/gstvideodetect.c gst/videosignal/gstvideomark.c gst/videosignal/gstvideosignal.c Copyright: <2007> Wim Taymans License: LGPL-2+ Files: gst/mxf/mxf.c tests/check/elements/mxfdemux.c tests/examples/mxf/mxfdemux-structure.c Copyright: <2008> Sebastian Dröge License: LGPL-2+ Files: gst/subenc/gstsrtenc.c gst/subenc/gstsrtenc.h gst/subenc/gstwebvttenc.h Copyright: <2008> Thijs Vermeir License: LGPL-2+ Files: tests/check/elements/faac.c tests/check/elements/faad.c tests/check/elements/voaacenc.c Copyright: <2009> Mark Nauwelaerts License: LGPL-2+ Files: gst/coloreffects/gstcoloreffects.c gst/coloreffects/gstcoloreffects.h gst/coloreffects/gstplugin.c Copyright: <2010> Filippo Argiolas License: LGPL-2+ Files: gst-libs/gst/codecparsers/parserutils.c tests/check/libs/h264parser.c tests/check/libs/mpegvideoparser.c Copyright: <2011> Collabora Ltd <2011> Intel Corporation <2011> Thibault Saunier License: LGPL-2+ Files: ext/curl/gstcurl.c ext/curl/gstcurlsink.c ext/curl/gstcurlsink.h Copyright: 2011, Axis Communications License: LGPL-2+ Files: ext/gme/gstgme.h ext/spc/gstspc.c ext/spc/gstspc.h Copyright: 2004-2005, 2009 Michael Pyne 2004-2005, Michael Pyne 2004-2006, Chris Lee 2007, Brian Koropoff License: LGPL-2+ Files: gst/id3tag/gstid3mux.c gst/id3tag/gstid3mux.h gst/id3tag/id3tag.c Copyright: 2006, Christophe Fergeau 2006, Tim-Philipp Müller 2006-2009, Tim-Philipp Müller 2009, Pioneers of the Inevitable License: LGPL-2+ Files: ext/spandsp/gstspandsp.c ext/spandsp/gstspanplc.c ext/spandsp/gstspanplc.h Copyright: 2011, Collabora Ltd License: LGPL-2+ Files: gst/dtmf/gstdtmfdetect.c gst/dtmf/gstdtmfdetect.h gst/liveadder/liveadder.h Copyright: 2008, Collabora Ltd 2008, Nokia Corporation 2009, Collabora Ltd 2009, Nokia Corporation License: LGPL-2+ Files: ext/voamrwbenc/gstvoamrwb.c ext/voamrwbenc/gstvoamrwbenc.c ext/voamrwbenc/gstvoamrwbenc.h Copyright: 2006, Edgard Lima License: LGPL-2+ Files: gst/hdvparse/gsthdvparse.c gst/hdvparse/gsthdvparse.h gst/real/gstreal.c Copyright: 2009, Edward Hervey Edward Hervey License: LGPL-2+ Files: gst/dvdspu/gstdvdspu.c gst/dvdspu/gstdvdspu.h gst/dvdspu/gstspu-common.h Copyright: 2007, Fluendo S.A. License: LGPL-2+ Files: ext/mimic/gstmimdec.h ext/mimic/gstmimenc.h ext/mimic/gstmimic.c Copyright: 2005, INdT License: LGPL-2+ Files: ext/voaacenc/gstvoaac.c ext/voaacenc/gstvoaacenc.c ext/voaacenc/gstvoaacenc.h Copyright: 2011, Kan Hu License: LGPL-2+ Files: gst-libs/gst/basecamerabinsrc/gstcamerabinpreview.h tests/check/elements/camerabin2.c tests/examples/camerabin2/gst-camerabin2-test.c Copyright: 2008, Nokia Corporation 2010, Nokia Corporation 2010, Thiago Santos 2011, Thiago Santos License: LGPL-2+ Files: ext/gsm/gstgsm.c ext/gsm/gstgsmdec.c ext/gsm/gstgsmenc.c Copyright: 2005, Philippe Khalaf License: LGPL-2+ Files: ext/faad/gstfaad.c gst/cdxaparse/gstvcdparse.c gst/cdxaparse/gstvcdparse.h Copyright: 2003, Ronald Bultje 2004, Ronald Bultje 2006, Tim-Philipp Müller 2008, Tim-Philipp Müller License: LGPL-2+ Files: gst/autoconvert/gstautovideoconvert.c gst/autoconvert/gstautovideoconvert.h gst/autoconvert/plugin.c Copyright: 2010, ST-Ericsson SA License: LGPL-2+ Files: ext/celt/gstceltdec.c ext/opus/gstopusdec.c ext/opus/gstopusparse.c Copyright: 2004, Wim Taymans 2006, Tim-Philipp Müller 2008, Sebastian Dröge License: LGPL-2+ Files: gst/jpegformat/gstjpegparse.c gst/jpegformat/gstjpegparse.h tests/check/elements/jpegparse.c Copyright: <2009> Arnout Vandecappelle (Essensium/Mind) License: LGPL-2.1+ Files: gst/gaudieffects/gstchromium.h gst/gaudieffects/gstdodge.h gst/gaudieffects/gstexclusion.h Copyright: 2010, Luis de Bethencourt > License: MIT/X11 (BSD like) LGPL-2+ Files: gst/librfb/vncauth.c gst/librfb/vncauth.h Copyright: 1999, AT&T Laboratories Cambridge. License: GPL-2+ Files: sys/dvb/camconditionalaccess.c sys/dvb/camconditionalaccess.h Copyright: 2007, Alessandro Decina License: GPL-2+ Files: tests/examples/opencv/gstmotioncells_dynamic_test.c tests/examples/opencv/gstmotioncells_dynamic_test.h Copyright: 2011, Robert Jobbagy License: GPL-3+ Files: tests/examples/opencv/gst_element_print_properties.c tests/examples/opencv/gst_element_print_properties.h Copyright: 2010, Wesley Miller License: GPL-3+ Files: gst/legacyresample/functable.h gst/legacyresample/resample.h Copyright: <2001> David Schleef License: LGPL Files: sys/pvr2d/gstpvr.c sys/pvr2d/gstpvr.h Copyright: 2010, Texas Instruments Incorporated License: LGPL Files: gst/festival/gstfestival.c gst/festival/gstfestival.h Copyright: 1999, */ <1999> Erik Walthinsen License: LGPL-2+ Files: ext/cog/gstcogcolorspace.c ext/cog/gstcogdownsample.c Copyright: <1999> Erik Walthinsen <2003> David Schleef License: LGPL-2+ Files: ext/opus/gstopusenc.c ext/opus/gstopusheader.c Copyright: <1999> Erik Walthinsen <2008> Sebastian Dröge <2011> Vincent Penquerc'h License: LGPL-2+ Files: ext/neon/gstneonhttpsrc.c ext/neon/gstneonhttpsrc.h Copyright: <2005> Edgard Lima <2006> Andre Moreira Magalhaes <2006> Rosfran Borges License: LGPL-2+ Files: ext/dc1394/gstdc1394.c ext/dc1394/gstdc1394.h Copyright: <2006> Antoine Tremblay <2006> Eric Jonas License: LGPL-2+ Files: gst/nuvdemux/gstnuvdemux.c gst/nuvdemux/gstnuvdemux.h Copyright: <2006> Renato Araujo Oliveira Filho License: LGPL-2+ Files: gst/rtpmux/gstrtpdtmfmux.c gst/rtpmux/gstrtpmux.c Copyright: 1999-2000, Erik Walthinsen <2007-2010> Collabora Ltd <2007-2010> Nokia Corporation License: LGPL-2+ Files: gst-libs/gst/codecparsers/gstmpegvideoparser.c gst-libs/gst/codecparsers/gstmpegvideoparser.h Copyright: <2007> Jan Schmidt <2009> Carl-Anton Ingmarsson <2011> Collabora Ltd <2011> Intel Corporation <2011> Thibault Saunier License: LGPL-2+ Files: gst/videoparsers/gstmpegvideoparse.c gst/videoparsers/gstmpegvideoparse.h Copyright: <2007> Jan Schmidt <2011> Collabora ltd <2011> Intel Corporation <2011> Mark Nauwelaerts <2011> Nokia Corporation <2011> Thibault Saunier License: LGPL-2+ Files: gst/sdp/gstsdpdemux.h gst/sdp/gstsdpelem.c Copyright: <2007> Wim Taymans License: LGPL-2+ Files: gst/aiff/aiff.c gst/aiff/aiffparse.h Copyright: <2008> Pioneers of the Inevitable License: LGPL-2+ Files: gst/subenc/gstsubenc.c gst/subenc/gstwebvttenc.c Copyright: 2011, David Schleef <2008> Thijs Vermeir License: LGPL-2+ Files: gst/videoparsers/h263parse.c gst/videoparsers/h263parse.h Copyright: <2010> Arun Raghavan <2010> Collabora Multimedia <2010> Edward Hervey <2010> Nokia Corporation License: LGPL-2+ Files: gst/videoparsers/gsth263parse.c gst/videoparsers/gsth263parse.h Copyright: 2005, Michal Benes 2008, Wim Taymans 2009, Mark Nauwelaerts <2010> Arun Raghavan <2010> Collabora Multimedia <2010> Edward Hervey <2010> Nokia Corporation License: LGPL-2+ Files: gst-libs/gst/codecparsers/gsth264parser.c gst-libs/gst/codecparsers/gsth264parser.h Copyright: 2005, Michal Benes 2008, Wim Taymans <2010> Collabora Multimedia <2010> Mark Nauwelaerts <2010> Nokia Corporation <2011> Collabora Ltd <2011> Intel Corporation <2011> Thibault Saunier License: LGPL-2+ Files: gst/videoparsers/gsth264parse.c gst/videoparsers/gsth264parse.h Copyright: <2010> Collabora ltd <2010> Mark Nauwelaerts <2010> Nokia Corporation <2011> Intel Corporation <2011> Thibault Saunier License: LGPL-2+ Files: ext/assrender/gstassrender.c ext/assrender/gstassrender.h Copyright: 2008, Benjamin Schmitz 2009, Sebastian Dröge License: LGPL-2+ Files: ext/spc/tag.c ext/spc/tag.h Copyright: 2007, Brian Koropoff License: LGPL-2+ Files: sys/vdpau/mpeg/mpegutil.c sys/vdpau/mpeg/mpegutil.h Copyright: 2007, Jan Schmidt 2009, Carl-Anton Ingmarsson License: LGPL-2+ Files: sys/vdpau/gstvdpsink.c sys/vdpau/gstvdpsink.h Copyright: 2005, Julien Moutte 2009, Carl-Anton Ingmarsson License: LGPL-2+ Files: ext/openal/gstopenal.c ext/openal/gstopenalsink.c Copyright: 2005, Wim Taymans 2006, Tim-Philipp Müller 2009-2010, Chris Robinson License: LGPL-2+ Files: gst/dtmf/gstrtpdtmfdepay.c gst/dtmf/gstrtpdtmfdepay.h Copyright: 2008, Collabora Limited 2008, Nokia Corporation License: LGPL-2+ Files: gst/autoconvert/gstautoconvert.c gst/autoconvert/gstautoconvert.h Copyright: 2007, Collabora Ltd 2007-2008, Nokia 2007-2012, Collabora Ltd License: LGPL-2+ Files: sys/pvr2d/gstpvrvideosink.c sys/pvr2d/gstpvrvideosink.h Copyright: 2011, - Collabora Ltda 2011, - Texas Instruments 2011, Collabora Ltda 2011, Texas Instruments License: LGPL-2+ Files: gst/rawparse/gstvideoparse.c gst/rawparse/gstvideoparse.h Copyright: 2006, David A. Schleef 2007,2009, Sebastian Dröge License: LGPL-2+ Files: gst/rawparse/gstrawparse.c gst/rawparse/gstrawparse.h Copyright: 2006, David A. Schleef 2007, Sebastian Dröge License: LGPL-2+ Files: gst/real/gstrealaudiodec.c gst/real/gstrealvideodec.c Copyright: 2005, Lutz Mueller 2006, Edward Hervey 2006, Lutz Mueller License: LGPL-2+ Files: gst/mpegtsdemux/pesparse.c gst/mpegtsdemux/pesparse.h Copyright: 2011, Edward Hervey License: LGPL-2+ Files: gst/coloreffects/gstchromahold.c gst/coloreffects/gstchromahold.h Copyright: 1999, Erik Walthinsen 2007, Edward Hervey 2007, Jan Schmidt 2007, Wim Taymans 2010, Sebastian Dröge License: LGPL-2+ Files: ext/ofa/gstofa.c ext/ofa/gstofa.h Copyright: 2006, M. Derezynski 2008, Eric Buehl 2008, Sebastian Dröge License: LGPL-2+ Files: gst/adpcmdec/adpcmdec.c gst/adpcmenc/adpcmenc.c Copyright: 1999-2002, Erik de Castro Lopo License: LGPL-2+ Files: gst/dvdspu/gstdvdspu-render.c gst/dvdspu/gstspu-vobsub-render.c Copyright: 2007, Fluendo S.A. 2009, Jan Schmidt License: LGPL-2+ Files: gst/debugutils/gstdebugspy.c gst/debugutils/gstdebugspy.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2011, Igalia S.L License: LGPL-2+ Files: gst/dataurisrc/gstdataurisrc.c gst/dataurisrc/gstdataurisrc.h Copyright: 2009, Igalia S.L 2009, Sebastian Dröge License: LGPL-2+ Files: ext/wayland/gstwaylandsink.c ext/wayland/gstwaylandsink.h Copyright: 2011, Intel Corporation 2011, Sreerenj Balachandran License: LGPL-2+ Files: gst/mve/mvevideodec16.c gst/mve/mvevideodec8.c Copyright: 2003, the ffmpeg project, Mike Melanson 2006, Jens Granseuer License: LGPL-2+ Files: ext/directfb/dfbvideosink.c ext/directfb/dfbvideosink.h Copyright: 2005, Julien MOUTTE License: LGPL-2+ Files: gst/pcapparse/gstirtspparse.c gst/pcapparse/gstirtspparse.h Copyright: 2011, Mark Nauwelaerts 2011, Nokia Corporation. License: LGPL-2+ Files: gst/dvbsuboverlay/gstdvbsuboverlay.c gst/dvbsuboverlay/gstdvbsuboverlay.h Copyright: 2010, Mart Raudsepp 2010, ONELAN Ltd License: LGPL-2+ Files: sys/winks/kshelpers.c sys/winks/kshelpers.h Copyright: 2008, Ole Andr? Vadla Ravn?s License: LGPL-2+ Files: ext/rsvg/gstrsvgoverlay.c ext/rsvg/gstrsvgoverlay.h Copyright: 2010, Olivier Aubert License: LGPL-2+ Files: gst/ivfparse/gstivfparse.c gst/ivfparse/gstivfparse.h Copyright: 2010, Opera Software ASA, Philip Jägenstedt License: LGPL-2+ Files: gst/removesilence/vad_private.c gst/removesilence/vad_private.h Copyright: 2009, Paulo Pizarro 2009, Rog?rio Santos 2009, Tiago Katcipis License: LGPL-2+ Files: gst/removesilence/gstremovesilence.c gst/removesilence/gstremovesilence.h Copyright: 2011, Paulo Pizarro 2011, Tiago Katcipis License: LGPL-2+ Files: gst/scaletempo/gstscaletempo.c gst/scaletempo/gstscaletempo.h Copyright: 2008, Rov Juvano License: LGPL-2+ Files: ext/zbar/gstzbar.c ext/zbar/gstzbar.h Copyright: 2009, Stefan Kost License: LGPL-2+ Files: gst/freeverb/gstfreeverb.c gst/freeverb/gstfreeverb.h Copyright: 2011, Stefan Sauer License: LGPL-2+ Files: gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.h gst/camerabin2/gstwrappercamerabinsrc.c Copyright: 2010, Texas Instruments, Inc 2011, Thiago Santos License: LGPL-2+ Files: ext/kate/gstkatespu.c ext/kate/gstkateutil.c Copyright: 2008, Vincent Penquerc'h 2009, Vincent Penquerc'h License: LGPL-2+ Files: gst/mpegtsdemux/tsdemux.h sys/dvb/parsechannels.c Copyright: 2008, Zaheer Abbas Merali 2009, Zaheer Abbas Merali License: LGPL-2+ Files: gst/jpegformat/gstjpegformat.c gst/jpegformat/gstjpegformat.h Copyright: <2010> Stefan Kost License: LGPL-2.1+ Files: gst/tta/crc32.h gst/tta/ttadec.h Copyright: 1999-2004, Alexander Djourik. License: LGPL-2.1+ Files: gst/rtpvp8/gstrtpvp8depay.c gst/rtpvp8/gstrtpvp8pay.c Copyright: 2011, Collabora Ltd 2011, Sjoerd Simons License: LGPL-2.1+ Files: gst/rtpvp8/gstrtpvp8depay.h gst/rtpvp8/gstrtpvp8pay.h Copyright: 2011, Sjoerd Simons License: LGPL-2.1+ Files: gst/jpegformat/gstjifmux.c gst/jpegformat/gstjifmux.h Copyright: 2010, Stefan Kost License: LGPL-2.1+ Files: ext/soundtouch/gstpitch.cc ext/soundtouch/gstpitch.hh Copyright: 2006, Wouter Paesen License: LGPL-2.1+ Files: gst/freeze/gstfreeze.c gst/freeze/gstfreeze.h Copyright: 2005, Gergely Nagy License: LGPL-2.1, Files: sys/directsound/gstdirectsoundsrc.c sys/directsound/gstdirectsoundsrc.h Copyright: 2005, Ronald S. Bultje 2005, S?bastien Moutte 2005, Thomas Vander Stichele 2006, Joni Valtanen License: MIT/X11 (BSD like) LGPL-2+ Files: gst/faceoverlay/gstfaceoverlay.c gst/faceoverlay/gstfaceoverlay.h Copyright: 2011, Laura Lucas Alday License: MIT/X11 (BSD like) LGPL-2+ Files: gst/gaudieffects/gstplugin.c gst/gaudieffects/gstplugin.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2010, Luis de Bethencourt License: MIT/X11 (BSD like) LGPL-2+ Files: ext/opencv/gstfacedetect.c ext/opencv/gstfacedetect.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2008, Michael Sheldon 2011, Stefan Sauer License: MIT/X11 (BSD like) LGPL-2+ Files: gst/fieldanalysis/gstfieldanalysis.c gst/fieldanalysis/gstfieldanalysis.h Copyright: 2010, Robert Swain 2011, Robert Swain License: MIT/X11 (BSD like) LGPL-2+ Files: gst/aiff/aiffmux.c gst/aiff/aiffmux.h Copyright: 2009, Robert Swain License: MIT/X11 (BSD like) LGPL-2+ Files: ext/opencv/gsttextoverlay.c ext/opencv/gsttextoverlay.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2010, Sreerenj Balachandran License: MIT/X11 (BSD like) LGPL-2+ Files: ext/openal/gstopenalsrc.c ext/openal/gstopenalsrc.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2008, Victor Lin License: MIT/X11 (BSD like) LGPL-2+ Files: gst/librfb/d3des.c gst/librfb/d3des.h Copyright: 1988-1992, Richard Outerbridge 1999, AT&T Laboratories Cambridge. License: MIT/X11 (BSD like) Files: ext/resindvd/rsnparsetter.c ext/resindvd/rsnparsetter.h Copyright: 2008, Jan Schmidt License: LGPL-2+ Files: gst/dtmf/tone_detect.c gst/dtmf/tone_detect.h Copyright: 2001, Steve Underwood License: LGPL-2+ Files: gst/rtpvp8/dboolhuff.c gst/rtpvp8/dboolhuff.h Copyright: 2010, The WebM project authors. License: BSD (3 clause) Files: gst/inter/gstintertest.c Copyright: 2010, Entropy Wave Inc 2011, David Schleef License: BSD (2 clause) Files: sys/linsys/include/asi.h Copyright: 1999, Tony Bolger 2000-2009, Linear Systems Ltd License: BSD (3 clause) Files: ltmain.sh Copyright: 1996-2001, 2003-2006 License: GPL-2+ Files: gst/audiovisualizers/gstdrawhelpers.h Copyright: <2011> Stefan Sauer License: GPL-2+ Files: gst/tta/filters.h Copyright: 1999-2004, Alexander Djourik. License: GPL-2+ Files: gst/mpegpsmux/bits.h Copyright: 2001-2002, the VideoLAN team 2008, Lin YANG License: GPL-2+ Files: tests/examples/scaletempo/demo-gui.h Copyright: 2008, Rov Juvano License: GPL-3+ Files: tests/examples/scaletempo/demo-player.h Copyright: 2008, Rov Juvano License: GPL-3+ Files: sys/pvr2d/gstpvrbufferpool.c Copyright: 2010, Texas Instruments Incorporated 2011, Collabora Ltd License: LGPL Files: sys/pvr2d/gstpvrbufferpool.h Copyright: 2010-2011, Texas Instruments Incorporated 2011, Collabora Ltda License: LGPL Files: gst/librfb/gstrfbsrc.h Copyright: <1999> Erik Walthinsen <2004> David A. Schleef <2006> Andre Moreira Magalhaes License: LGPL-2+ Files: gst/librfb/gstrfbsrc.c Copyright: <1999> Erik Walthinsen <2004> David A. Schleef <2006> Andre Moreira Magalhaes <2007> Thijs Vermeir License: LGPL-2+ Files: gst/nsf/gstnsf.c Copyright: <1999> Erik Walthinsen <2004> Johan Dahlin <2006> Wim Taymans License: LGPL-2+ Files: ext/swfdec/gstswfdec.c Copyright: 2002-2003,2006, David A. Schleef <1999> Erik Walthinsen License: LGPL-2+ Files: ext/cog/gstcogscale.c Copyright: 2005, David Schleef <1999> Erik Walthinsen License: LGPL-2+ Files: ext/nas/nassink.c Copyright: <2001> Richard Boulton <2003> Laurent Vivier <2004> Arwed v. Merkatz License: LGPL-2+ Files: ext/kate/gstkateparse.h Copyright: <2004> Thomas Vander Stichele <2008> Vincent Penquerc'h License: LGPL-2+ Files: ext/kate/gstkateparse.c Copyright: 2006, Andy Wingo 2008, Vincent Penquerc'h <2004> Thomas Vander Stichele License: LGPL-2+ Files: tests/check/generic/states.c Copyright: <2005> Thomas Vander Stichele License: LGPL-2+ Files: tests/check/elements/legacyresample.c Copyright: <2005> Thomas Vander Stichele <2006> Tim-Philipp Müller License: LGPL-2+ Files: gst/dtmf/gstdtmfsrc.h Copyright: <2005> Wim Taymans <2007> Collabora <2007> Nokia Corporation License: LGPL-2+ Files: gst/dtmf/gstrtpdtmfsrc.h Copyright: <2005> Wim Taymans <2007> Nokia Corporation License: LGPL-2+ Files: sys/dshowdecwrapper/gstdshowutil.h Copyright: 2007, Sebastien Moutte <2006-2010> Fluendo License: LGPL-2+ Files: ext/mythtv/gstmythtvsrc.h Copyright: <2006> INdT - Rosfran Borges <2007> INdT - Rentao Filho License: LGPL-2+ Files: ext/kate/gstkatetag.h Copyright: <2006> James Livingston <2008> Vincent Penquerc'h License: LGPL-2+ Files: tests/check/elements/mpeg2enc.c Copyright: <2006> Mark Nauwelaerts License: LGPL-2+ Files: ext/mythtv/gstmythtvsrc.c Copyright: <2006> Rosfran Borges <2007> Renato Filho License: LGPL-2+ Files: gst/dtmf/gstdtmfsrc.c Copyright: 1999-2000, Erik Walthinsen <2007> Collabora <2007> Nokia Corporation License: LGPL-2+ Files: gst/videoparsers/gstmpeg4videoparse.h Copyright: <2007> Julien Moutte License: LGPL-2+ Files: gst/videoparsers/gstmpeg4videoparse.c Copyright: <2007> Julien Moutte <2008> Mindfruit B.V <2011> Collabora Ltd <2011> Intel <2011> Mark Nauwelaerts <2011> Nokia Corporation <2011> Thibault Saunier License: LGPL-2+ Files: tests/check/elements/timidity.c Copyright: <2007> Stefan Kost License: LGPL-2+ Files: tests/check/elements/kate.c Copyright: <2007> Stefan Kost <2008> ogg.k.ogg.k License: LGPL-2+ Files: gst/sdp/gstsdpdemux.c Copyright: <2007> Wim Taymans License: LGPL-2+ Files: tests/check/elements/mplex.c Copyright: <2008> Mark Nauwelaerts License: LGPL-2+ Files: tests/check/elements/asfmux.c Copyright: <2008> Thiago Santos License: LGPL-2+ Files: ext/kate/gstkateutil.h Copyright: <2008> Vincent Penquerc'h License: LGPL-2+ Files: ext/resindvd/rsndec.h Copyright: <2009> Jan Schmidt License: LGPL-2+ Files: ext/resindvd/rsndec.c Copyright: <2009> Jan Schmidt <2009> Sebastian Dröge License: LGPL-2+ Files: ext/opencv/gstopencv.c Copyright: <2009> Kapil Agrawal License: LGPL-2+ Files: ext/rsvg/gstrsvg.c Copyright: 2010, Olivier Aubert <2009> Sebastian Dröge License: LGPL-2+ Files: ext/kate/gstkatespu.h Copyright: <2009> ogg.k.ogg.k License: LGPL-2+ Files: tests/check/elements/voamrwbenc.c Copyright: <2011> Mark Nauwelaerts License: LGPL-2+ Files: tests/check/elements/baseaudiovisualizer.c Copyright: <2011> Stefan Kost License: LGPL-2+ Files: tests/check/elements/opus.c Copyright: <2011> Vincent Penquerc'h License: LGPL-2+ Files: gst/mpegtsdemux/mpegtsbase.c Copyright: 2007, Alessandro Decina 2011, Hewlett-Packard Development Company, L.P License: LGPL-2+ Files: tests/check/elements/mpegtsmux.c Copyright: 2011, Alessandro Decina License: LGPL-2+ Files: gst/mpegtsdemux/mpegtspacketizer.c Copyright: 2007-2008, Alessandro Decina, Zaheer Merali License: LGPL-2+ Files: gst/mve/mveaudioenc.c Copyright: 2003-2004, Alexander Belyakov 2006, Jens Granseuer License: LGPL-2+ Files: gst/tta/gstttadec.c Copyright: 1999-2004, Alexander Djourik 2004, Arwed v. Merkatz License: LGPL-2+ Files: sys/osxvideo/osxvideosrc.c Copyright: 2007, Ali Sabil 2007, Ole Andr? Vadla Ravnås 2008, Barracuda Networks License: LGPL-2+ Files: sys/osxvideo/osxvideosrc.h Copyright: 2007, Ali Sabil 2007, Ole Andr? Vadla Ravnås License: LGPL-2+ Files: sys/d3dvideosink/d3dvideosink.c Copyright: 2010, Andoni Morales 2010-2011, David Hoyt License: LGPL-2+ Files: gst/hls/gsthlsdemux.c Copyright: 2010, Andoni Morales Alastruey 2010, Marc-Andre Lureau 2011, Hewlett-Packard Development Company, L.P License: LGPL-2+ Files: gst/hls/gsthlsdemux.h Copyright: 2010, Andoni Morales Alastruey 2010, Marc-Andre Lureau License: LGPL-2+ Files: gst/hls/m3u8.h Copyright: 2010, Andoni Morales Alastruey 2010, Marc-Andre Lureau License: LGPL-2+ Files: gst/camerabin/gstinputselector.c Copyright: 2003, Julien Moutte 2005, Jan Schmidt 2005, Ronald S. Bultje 2007, Andy Wingo 2007, Wim Taymans 2008, Nokia Corporation. (contact ) License: LGPL-2+ Files: ext/gme/gstgme.c Copyright: 2004-2005,2009, Michael Pyne 2004-2006, Chris Lee 2007, Brian Koropoff License: LGPL-2+ Files: ext/openal/gstopenalsink.h Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2009-2010, Chris Robinson License: LGPL-2+ Files: ext/mimic/gstmimenc.c Copyright: 2005, INdT 2009, Collabora Ltd License: LGPL-2+ Files: ext/chromaprint/gstchromaprint.c Copyright: 2006, M. Derezynski 2008, Eric Buehl 2008, Sebastian Dröge 2011, Lukáš Lalinský 2012, Collabora Ltd. License: LGPL-2+ Files: gst/legacyresample/gstlegacyresample.c Copyright: 1999, Erik Walthinsen 2003-2004, David A. Schleef License: LGPL-2+ Files: gst/interlace/gstinterlace.c Copyright: 2010, David A. Schleef 2010, Robert Swain License: LGPL-2+ Files: ext/dirac/gstdiracdec.h Copyright: 2004, David A. Schleef 2004, Ronald S. Bultje License: LGPL-2+ Files: ext/vp8/plugin.c Copyright: 2006, David Schleef 2010, Entropy Wave Inc License: LGPL-2+ Files: tests/check/elements/schroenc.c Copyright: 2010, David Schleef 2010, Sebastian Dröge License: LGPL-2+ Files: ext/flite/gstflitetestsrc.c Copyright: 2005, Stefan Kost 2010, David Schleef License: LGPL-2+ Files: gst/real/gstrealvideodec.h Copyright: 2006, Edward Hervey 2006, Lutz Mueller License: LGPL-2+ Files: gst/mpegtsdemux/mpegtsbase.h Copyright: 2009, Edward Hervey 2011, Hewlett-Packard Development Company, L.P License: LGPL-2+ Files: gst/videofilters/gstscenechange.c Copyright: 2011, Entropy Wave Inc License: LGPL-2+ Files: ext/chromaprint/gstchromaprint.h Copyright: 2006, M. Derezynski 2008, Eric Buehl 2008, Sebastian Dröge 2011, Lukáš Lalinský <> License: LGPL-2+ Files: gst-libs/gst/gettext.h Copyright: 1995-1998, 2000-2002, Free Software Foundation, Inc License: LGPL-2+ Files: gst/real/gstreal.h Copyright: 2007, Hans de Goede License: LGPL-2+ Files: gst/mpegtsdemux/tsdemux.c Copyright: 2009, Zaheer Abbas Merali 2011, Hewlett-Packard Development Company, L.P License: LGPL-2+ Files: ext/mimic/gstmimdec.c Copyright: 2005, INdT Vadla Ravnås License: LGPL-2+ Files: ext/musicbrainz/gsttrm.c Copyright: 2004, Jeremy Simon 2006, James Livingston License: LGPL-2+ Files: ext/kate/gstkatetag.c Copyright: 2006, James Livingston 2008, Vincent Penquerc'h License: LGPL-2+ Files: ext/resindvd/rsnstreamselector.c Copyright: 2003, Julien Moutte 2005, Jan Schmidt 2005, Ronald S. Bultje 2007, Wim Taymans License: LGPL-2+ Files: ext/gsettings/gstswitchsink.h Copyright: 2005, Ronald S. Bultje 2007, Jan Schmidt License: LGPL-2+ Files: ext/gsettings/gstswitchsrc.h Copyright: 2005, Ronald S. Bultje 2005, Tim-Philipp Müller 2007, Jan Schmidt 2010, Sebastian Dröge License: LGPL-2+ Files: ext/gsettings/gstswitchsink.c Copyright: 2005, Ronald S. Bultje 2006, Jürg Billeter 2007, Jan Schmidt License: LGPL-2+ Files: ext/gsettings/gstswitchsrc.c Copyright: 2005, Ronald S. Bultje 2006, Jürg Billeter 2007, Jan Schmidt 2010, Sebastian Dröge License: LGPL-2+ Files: ext/dts/gstdtsdec.c Copyright: 2004, Ronald Bultje 2009, Jan Schmidt License: LGPL-2+ Files: tests/check/elements/autovideoconvert.c Copyright: 2009, Jan Schmidt 2010, ST-Ericsson SA License: LGPL-2+ Files: ext/musicbrainz/gsttrm.h Copyright: 2004, Jeremy Simon License: LGPL-2+ Files: gst/nsf/gstnsf.h Copyright: 2003, Johan Dahlin License: LGPL-2+ Files: sys/dshowsrcwrapper/gstdshowvideosrc.cpp Copyright: 2007, Sebastien Moutte 2009, Julien Isorce License: LGPL-2+ Files: gst/camerabin/gstinputselector.h Copyright: 2003, Julien Moutte 2005, Ronald S. Bultje 2008, Nokia Corporation. (contact ) License: LGPL-2+ Files: ext/resindvd/rsnstreamselector.h Copyright: 2003, Julien Moutte 2005, Ronald S. Bultje License: LGPL-2+ Files: gst/real/gstrealaudiodec.h Copyright: 2006, Lutz Mueller License: LGPL-2+ Files: gst/hls/m3u8.c Copyright: 2010, Marc-Andre Lureau License: LGPL-2+ Files: gst/videoparsers/plugin.c Copyright: 2009, Tim-Philipp Müller 2011, Mark Nauwelaerts License: LGPL-2+ Files: gst/vmnc/vmncdec.c Copyright: 2007, Michael Smith License: LGPL-2+ Files: sys/osxvideo/osxvideoplugin.c Copyright: 2004-6 Zaheer Abbas Merali 2007, Pioneers of the Inevitable License: LGPL-2+ Files: ext/musepack/gstmusepackdec.c Copyright: 2004, Ronald Bultje 2006, Tim-Philipp Müller 2008, Sebastian Dröge License: LGPL-2+ Files: sys/fbdev/gstfbdevsink.c Copyright: 2007, Sean D'Epagnier License: LGPL-2+ Files: sys/fbdev/gstfbdevsink.h Copyright: 2007, Sean D'Epagnier sean@depagnier.com License: LGPL-2+ Files: gst-libs/gst/basecamerabinsrc/gstbasecamerasrc.c Copyright: 2010, Texas Instruments, Inc License: LGPL-2+ Files: gst/camerabin2/gstwrappercamerabinsrc.h Copyright: 2010, Texas Instruments, Inc 2010, Thiago Santos License: LGPL-2+ Files: gst/mve/mveaudiodec.c Copyright: 2003, The ffmpeg Project, Mike Melanson License: LGPL-2+ Files: gst/asfmux/gstasf.c Copyright: 2009, Thiago Santos License: LGPL-2+ Files: tests/icles/pitch-test.c Copyright: 2006, Thomas Vander Stichele License: LGPL-2+ Files: gst-libs/gst/gst-i18n-plugin.h Copyright: 2004, Thomas Vander Stichele License: LGPL-2+ Files: sys/dvb/gstdvbsrc.c Copyright: 2006, Zaheer Abbas Merali 2010, Andoni Morales Alastruey License: LGPL-2.1+ Files: gst/liveadder/liveadder.c Copyright: 1999-2000, Erik Walthinsen 2008, Collabora Ltd 2008, Nokia Corporation License: LGPL-2.1+ Files: gst/dvbsuboverlay/dvb-sub.c Copyright: 2005, Ian Caulfield 2010, ONELAN Ltd Mart Raudsepp 2009, License: LGPL-2.1+ Files: gst/dvbsuboverlay/dvb-sub.h Copyright: Mart Raudsepp 2009, License: LGPL-2.1+ Files: ext/soundtouch/plugin.c Copyright: 2008, Sebastian Dröge License: LGPL-2.1+ Files: tests/examples/directfb/gstdfb.c Copyright: 2000-2002, convergence integrated media GmbH License: MIT/X11 (BSD like) Files: sys/qtwrapper/audiodecoders.c Copyright: <2006-2007> Fluendo <2006-2008> Pioneers of the Inevitable License: MIT/X11 (BSD like) LGPL-2+ Files: sys/dshowdecwrapper/gstdshowdecwrapper.cpp Copyright: <2006-2008> Fluendo <2006-2008> Pioneers of the Inevitable <2007-2008> Sebastien Moutte License: MIT/X11 (BSD like) LGPL-2+ Files: ext/kate/gstkateenc.c Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2007, Fluendo S.A. 2008-2009, Vincent Penquerc'h License: MIT/X11 (BSD like) LGPL-2+ Files: ext/opencv/gsttemplatematch.c Copyright: 2005, Ronald S. Bultje 2005, Thomas Vander Stichele 2008, Michael Sheldon 2009, Noam Lewis License: MIT/X11 (BSD like) LGPL-2+ Files: gst/scaletempo/gstscaletempoplugin.c Copyright: 2008, Rov Juvano License: MIT/X11 (BSD like) LGPL-2+ Files: ext/kate/gstkate.h Copyright: 2008, Vincent Penquerc'h License: MIT/X11 (BSD like) LGPL-2+ Files: gst/mpegdemux/gstmpegdesc.h Copyright: 2005 License: MPL-1.1 GPL Files: gst/mpegtsmux/mpegtsmux.c Copyright: 2006-2010, Fluendo S.A 2011, Jan Schmidt License: MPL-1.1 GPL GPL-2+ LGPL (v2 or later) (with incorrect FSF address) Files: ext/teletextdec/gstteletextdec.h Copyright: 2009, Sebastian Pölsterl 2010, Andoni Morales Alastruey License: LGPL-2+ Files: ext/teletextdec/teletext.c Copyright: 2009, Sebastian Pölsterl License: LGPL-2+ Files: gst/nsf/fmopl.c Copyright: 1999, Tatsuyuki Satoh , MultiArcadeMachineEmurator development License: LGPL-2+ License: This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA On Debian GNU/Linux systems, the complete text of the GNU Lesser General Public License can be found in `/usr/share/common-licenses/LGPL'. debian/watch0000664000000000000000000000014412324573056010227 0ustar version=3 http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-(0\.11\..*)\.tar\.gz debian/README.Debian0000664000000000000000000000410012324573056011233 0ustar Gstreamer for Debian ==================== This package contains the GStreamer plugin distribution. More information can be found at http://gstreamer.net/ As of GStreamer plugins version 0.8.0 all packages are versioned and parallel installable with other releases with other major.minor versions. For example, 0.8.x series is versioned as 0.8 and parallel installable with both unversioned 0.6.x series and future 0.9.x and beyond. The version part is represented as VER below. GStreamer plugins are split into a number of packages: plugins without external dependencies: gstreamerVER-plugins-bad many independent plugins documentation: gstreamerVER-plugins-bad-doc html documentation Notes ===== ChangeLog --------- The upstream ChangeLog is not included in all the plugin packages due to its large size. Please see upstream sources if you are interested in detailed source changes. Unofficial plugin packages -------------------------- Various plugins in the upstream source are not yet packaged or not officially supported. This is most likely due to: * upstream considers them too unstable * libraries they depend on are not are yet in Debian or are poorly supported To build additional unofficial plugin packages: * Get the source and Debian diff (for example, "apt-get source gst-plugins") * Add new package name to the EXTRA_PLUGINS variable in debian/rules * Add appropriate dependency and control info to debian/extra * Add a .install file for the package * Rebuild Currently available untested and unsupported info has been added for: * gstreamer-faac * gstreamer-mpeg2enc External tools support ---------------------- Your favorite codec isn't wrapped as a plugin? External programs can be used to process streams. Take a look at "pipefilter" element or try something like this (untested): $ mkfifo fifo $ gst-launch myaudiosrc ! filesink location=fifo & $ cat fifo | my_encoder > output_file David I. Lehn Tue, 23 Mar 2004 04:38:37 -0500 update: Sebastien Bacher Wed, 14 Dec 2005 17:00:21 +0100 debian/gstreamer-mpeg2enc.install0000664000000000000000000000007312324573056014256 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpeg2enc.so debian/gbp.conf0000664000000000000000000000022412324573056010614 0ustar [DEFAULT] upstream-branch = upstream debian-branch = master pristine-tar = True upstream-tag = upstream/%(version)s debian-tag = debian/%(version)s debian/build-deps.in0000664000000000000000000000316012326430732011552 0ustar @GST_LIB_DEV_DEP@ @GST_EXTRA_BUILD_DEPENDS@ libgstreamer-plugins-base@GST_ABI@-dev (>= 1.2.0) libgstreamer-plugins-good@GST_ABI@-dev (>= 1.2.0) autotools-dev dh-autoreconf automake (>= 1.11) autoconf (>= 2.62) libtool (>= 2.2.6) autopoint (>= 0.17) cdbs (>= 0.4.93) debhelper (>= 9) dpkg-dev (>= 1.15.1) pkg-config (>= 0.11.0) gtk-doc-tools (>= 1.12) libglib2.0-dev (>= 2.32) liborc-0.4-dev (>= 1:0.4.17) libbz2-dev libdca-dev libgsm1-dev libmms-dev (>= 0.4) libmpcdec-dev libsoundtouch-dev (>= 1.5.0) libgtk2.0-dev (>= 2.14.0) ladspa-sdk libsndfile1-dev (>= 1.0.16) libfaad-dev libdirectfb-dev (>= 0.9.25) libexif-dev (>= 0.6.16) libexempi-dev libiptcdata0-dev (>= 1.0.2) libwildmidi-dev (>= 0.2.3) gstreamer@GST_ABI@-plugins-base (>= 1.0.0) libofa0-dev (>= 0.9.3) libdvdnav-dev (>= 4.1.2) [!hurd-any] libssl-dev libjasper-dev libx11-dev libass-dev (>= 0.9.4) libmodplug-dev libkate-dev (>= 0.1.7) libschroedinger-dev (>= 1.0.7) libdirac-dev (>= 0.10) libmedia-dev (>= 0.1.0+git20131207+e452e83-0ubuntu3) [i386 armhf] libplatform-api1-dev [i386 armhf] libmimic-dev (>= 1.0) libgme-dev librsvg2-dev (>= 2.36) libcairo2-dev libpng-dev libslv2-dev (>= 0.6.6) flite-dev gstreamer@GST_ABI@-doc gstreamer@GST_ABI@-plugins-base-doc libzbar-dev (>= 0.9) librtmp-dev libcurl4-gnutls-dev (>= 7.21.0) libxvidcore-dev libvo-aacenc-dev libvo-amrwbenc-dev libopenal-dev (>= 1:1.14) libzvbi-dev libspandsp-dev libopus-dev (>= 0.9.4) libmpg123-dev (>= 1.13) libegl1-mesa-dev libgles2-mesa-dev libxml2-dev (>= 2.4) libfluidsynth-dev (>= 1.0) libsrtp0-dev libopencv-dev (>= 2.0.0) libopenjpeg-dev libgnutls-dev (>= 2.11.3) libchromaprint-dev libwebp-dev (>= 0.2.1) debian/mk.control0000664000000000000000000000042412324573056011210 0ustar #!/usr/bin/perl -w open BUILDDEPS, "debian/build-deps"; @builddeplist = ; close BUILDDEPS; chomp(@builddeplist); $builddeps = join(", ", @builddeplist); open CONTROLIN, "debian/control.in"; while(){ s/BUILDDEPS/$builddeps/; print; } debian/gstreamer-hybris.install0000664000000000000000000000017112216123654014050 0ustar debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstandroidmedia.so debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmirsink.so debian/rules0000775000000000000000000002111412324573056010256 0ustar #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/gnome.mk include /usr/share/cdbs/1/rules/utils.mk include /usr/share/cdbs/1/rules/autoreconf.mk DEB_BUILD_PARALLEL = 1 DEB_DH_AUTORECONF_ARGS += --as-needed # make autoreconf not call autopoint since we ship a patch for po/Makefile.in.in export AUTOPOINT=true CFLAGS += -Wno-error CXXFLAGS += -Wno-error LDFLAGS += -Wl,-z,defs -Wl,-O1 -Wl,--as-needed DEB_MAKE_CHECK_TARGET = check || true # this is for compatibility with dpkg-dev < 1.13.5, see # DEB_HOST_ARCH_CPU := $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU 2>/dev/null) DEB_HOST_ARCH_OS := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS 2>/dev/null) # Take account of old dpkg-architecture output. ifeq ($(DEB_HOST_ARCH_CPU),) DEB_HOST_ARCH_CPU := $(shell dpkg-architecture -qDEB_HOST_GNU_CPU) ifeq ($(DEB_HOST_ARCH_CPU),x86_64) DEB_HOST_ARCH_CPU := amd64 endif endif ifeq ($(DEB_HOST_ARCH_OS),) DEB_HOST_ARCH_OS := $(subst -gnu,,$(shell dpkg-architecture -qDEB_HOST_GNU_SYSTEM)) ifeq ($(DEB_HOST_ARCH_OS),gnu) DEB_HOST_ARCH_OS := hurd endif endif # end of compatibility block # debian package version version=$(shell dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2) # upstream version gst_version=$(shell echo $(version) | cut -d '-' -f 1) gst_major=1 gst_minor=0 gst_abi=$(gst_major).$(gst_minor) # gstreamer library package names gst_lib=libgstreamer$(gst_abi)-0 gst_lib_dev=libgstreamer$(gst_abi)-dev # what gstreamer version is needed gst_lib_dev_dep=$(gst_lib_dev) (>= 1.2.0) gst_pkgname=gstreamer$(gst_abi) gst_deb_abi=$(gst_abi)-0 gst_extra_build_depends = gst_extra_build_depends += libasound2-dev (>= 0.9.1) [linux-any] gst_extra_build_depends += , libcdaudio-dev [linux-any] gst_extra_build_depends += , libdc1394-22-dev (>= 2.0.0) [linux-any] gst_extra_build_depends += , libgudev-1.0-dev (>= 143) [linux-any] gst_extra_build_depends += , libusb-1.0-0-dev [linux-any] gst_extra_build_depends += , libbluetooth-dev (<< 5) [linux-any] gst_extra_build_depends += , libsbc-dev (>= 1.1) [linux-any] # The plugins are basically the same. # Link special names to a template file. # still need "*.install" to be done by hand # # EXTRA_PLUGINS: See debian/README.Debian for docs EXTRA_PLUGINS += PLUGINS += plugins-bad $(EXTRA_PLUGINS) ifeq ($(DEB_HOST_ARCH_OS),linux) PLUGINS += hybris endif VERSIONIZE= \ plugins-bad-doc.install \ plugins-bad-videoparsers.install \ plugins-bad-faad.install #debug package DEB_DH_STRIP_ARGS := --dbg-package=$(gst_pkgname)-plugins-bad-dbg # enable the real plugin on x86 ifeq ($(DEB_HOST_ARCH_CPU), i386) real = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstreal.so endif # miralloc is just enabled for i386 and armhf (need android for the other archs) android_hybris_archs := i386 armhf ifeq ($(DEB_HOST_ARCH_CPU), $(findstring $(DEB_HOST_ARCH_CPU), $(android_hybris_archs))) miralloc = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgstmiralloc-$(gst_abi).so.* mirallocdev = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgstmiralloc-$(gst_abi).so endif ifeq ($(DEB_HOST_ARCH_OS),linux) dvb = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstdvb.so fbdev = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstfbdevsink.so vcd = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstvcdsrc.so cdaudio = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstcdaudio.so dc1394 = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstdc1394.so decklink = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstdecklink.so linsys = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstlinsys.so uvch264 = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstuvch264.so bluez = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstbluez.so sbc = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstsbc.so endif ifeq ($(DEB_HOST_ARCH_OS),kfreebsd) cdaudio = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstcdaudio.so endif ifneq ($(DEB_HOST_ARCH_OS),hurd) resindvd = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstresindvd.so endif # Let's decide the package name and url depending on the distribution DISTRO = "$(shell dpkg-vendor --query vendor)" GST_PACKAGE_NAME := "GStreamer Bad Plugins (unknown Debian derivative)" GST_PACKAGE_ORIGIN="http://packages.qa.debian.org/gst-plugins-bad$(gst_abi)" ifeq ($(DISTRO),"Debian") GST_PACKAGE_NAME := "GStreamer Bad Plugins (Debian)" GST_PACKAGE_ORIGIN="http://packages.qa.debian.org/gst-plugins-bad$(gst_abi)" endif ifeq ($(DISTRO),"Ubuntu") GST_PACKAGE_NAME := "GStreamer Bad Plugins (Ubuntu)" GST_PACKAGE_ORIGIN="https://launchpad.net/distros/ubuntu/+source/gst-plugins-bad$(gst_abi)" endif # setup links for packages pre-build:: for p in $(PLUGINS); do \ rm -f debian/$(gst_pkgname)-$$p.install; \ sed \ -e 's,@real@,$(real),g' \ -e 's,@dvb@,$(dvb),g' \ -e 's,@decklink@,$(decklink),g' \ -e 's,@linsys@,$(linsys),g' \ -e 's,@fbdev@,$(fbdev),g' \ -e 's,@vcd@,$(vcd),g' \ -e 's,@dc1394@,$(dc1394),g' \ -e 's,@cdaudio@,$(cdaudio),g' \ -e 's,@resindvd@,$(resindvd),g' \ -e 's,@uvch264@,$(uvch264),g' \ -e 's,@bluez@,$(bluez),g' \ -e 's,@sbc@,$(sbc),g' \ -e 's/@GST_ABI@/$(gst_abi)/g' \ debian/gstreamer-$$p.install \ > debian/$(gst_pkgname)-$$p.install; \ done for f in $(VERSIONIZE); do \ sed 's/@GST_ABI@/$(gst_abi)/g' debian/gstreamer-$$f \ > debian/$(gst_pkgname)-$$f; \ done sed \ -e 's,@miralloc@,$(miralloc),g' \ -e 's/@GST_ABI@/$(gst_abi)/g' \ debian/libgstreamer-plugins-bad.install \ > debian/libgstreamer-plugins-bad$(gst_deb_abi).install sed \ -e 's,@mirallocdev@,$(mirallocdev),g' \ -e 's/@GST_ABI@/$(gst_abi)/g' \ debian/libgstreamer-plugins-bad-dev.install \ > debian/libgstreamer-plugins-bad$(gst_abi)-dev.install maint: debian/control debian/build-deps: debian/build-deps.in debian/rules cat $< > $@ for plugin in $(EXTRA_PLUGINS); do \ sh debian/extra deps $$plugin >> $@; \ done sort $@ -o $@ debian/control:: debian/control.in debian/build-deps debian/mk.control debian/rules perl debian/mk.control | sed \ -e 's/@GST_VERSION@/$(gst_version)/g' \ -e 's/@GST_ABI@/$(gst_abi)/g' \ -e 's/@GST_DEB_ABI@/$(gst_deb_abi)/g' \ -e 's/@GST_PKGNAME@/$(gst_pkgname)/g' \ -e 's/@GST_LIB@/$(gst_lib)/g' \ -e 's/@GST_LIB_DEV@/$(gst_lib_dev)/g' \ -e 's/@GST_LIB_DEV_DEP@/$(gst_lib_dev_dep)/g' \ -e 's/@GST_EXTRA_BUILD_DEPENDS@/$(gst_extra_build_depends)/g' \ -e '/^Build-Depends\(-Indep\)\?/s/\ *,\ */,\n /g' \ >$@ for plugin in $(EXTRA_PLUGINS); do \ sh debian/extra control $$plugin | sed \ -e 's/@GST_ABI@/$(gst_abi)/g' \ -e 's/@GST_PKGNAME@/$(gst_pkgname)/g' \ -e 's/@GST_LIB@/$(gst_lib)/g' \ -e 's/@GST_LIB_DEV@/$(gst_lib_dev)/g' \ -e 's/@GST_LIB_DEV_DEP@/$(gst_lib_dev_dep)/g' \ -e 's/@GST_PLUGINS_LIB@/$(gst_plugins_lib)/g' \ -e 's/@GST_PLUGINS_LIB_DEV@/$(gst_plugins_lib_dev)/g' \ -e 's/@GST_PLUGINS_LIB_DEV_DEP@/$(gst_plugins_lib_dev_dep)/g' \ -e 's/@GST_GCONF_LIB@/$(gst_gconf_lib)/g' \ -e 's/@GST_GCONF_LIB_DEV@/$(gst_gconf_lib_dev)/g' \ -e 's/@GST_GCONF_LIB_DEV_DEP@/$(gst_gconf_lib_dev_dep)/g' \ >> $@; \ done DEB_CONFIGURE_EXTRA_FLAGS += \ --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ --disable-examples \ --enable-DEBUG \ --enable-debug \ --enable-experimental \ --with-package-name=$(GST_PACKAGE_NAME) \ --with-package-origin=$(GST_PACKAGE_ORIGIN) \ --disable-pvr # only build the docs on arches which can ifeq (,$(findstring $(DEB_HOST_ARCH),m68k arm)) DEB_CONFIGURE_EXTRA_FLAGS += --enable-gtk-doc endif common-binary-fixup-arch:: LD_LIBRARY_PATH=debian/libgstreamer-plugins-bad1.0-0/usr/lib/$(DEB_HOST_MULTIARCH):$(LD_LIBRARY_PATH) \ dh_gstscancodecs clean:: # get rid of the sym links for i in $(PLUGINS); do \ rm -f debian/$(gst_pkgname)-$$i.install; \ rm -f debian/$(gst_pkgname)-$$i.preinst; \ done for f in $(VERSIONIZE); do \ rm -f debian/$(gst_pkgname)-$$f; \ done gst_patch = $(shell echo $(gst_version) | cut -d '.' -f 3) gst_patch_next = $(shell expr $(gst_patch) + 1) gst_version_next = $(shell echo $(gst_version) | cut -d '.' -f-2).$(gst_patch_next) DEB_DH_MAKESHLIBS_ARGS_libgstreamer-plugins-bad$(gst_deb_abi) += -V "libgstreamer-plugins-bad$(gst_deb_abi) (>= $(gst_version)), libgstreamer-plugins-bad$(gst_deb_abi) (<< $(gst_version_next))" DEB_INSTALL_DOCS_ALL += debian/README.Debian NEWS # Disable inclusion of large upstream ChangeLog DEB_INSTALL_CHANGELOGS_ALL := .PHONY: maint