aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Hart <dvhart@linux.intel.com>2015-06-23 13:19:06 -0700
committerDarren Hart <dvhart@linux.intel.com>2015-06-23 16:08:05 -0700
commit0c59da11108f01db26b7627bdccffcc984288295 (patch)
tree290e5d9f0bcc7102622984e3e5c1dbb1c5a15b3f
parenta8ce648bf3b7ee40a6056bdaa31388e1d69d00f5 (diff)
downloadmeta-minnow-testing.tar.gz
meta-minnow-testing.tar.bz2
meta-minnow-testing.zip
EMGD Forklift from meta-intel/daisy plus "fixes" (TEMP)testing
Horrible forklift to get EMGD working in meta-minnow. Temporary as POC and testing. Needs to be refactored before inclusion into master. Signed-off-by: Darren Hart <dvhart@linux.intel.com>
-rw-r--r--classes/emgd-gl.bbclass11
-rw-r--r--conf/machine/include/meta-intel-emgd.inc23
-rw-r--r--conf/machine/minnow-emgd.conf53
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin/egl.pc12
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin/glchar.patch17
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin/gles_cm.pc12
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin/glesv2.pc12
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin_1.16.bb186
-rw-r--r--recipes-graphics/xorg-driver/emgd-driver-bin_1.18.bb188
-rw-r--r--recipes-graphics/xorg-driver/xf86-input-evdev_2.6.0.bb20
-rw-r--r--recipes-graphics/xorg-driver/xf86-input-synaptics_1.6.3.bb23
-rw-r--r--recipes-graphics/xorg-driver/xorg-driver-common.inc33
-rw-r--r--recipes-graphics/xorg-driver/xorg-driver-video.inc4
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xf86-config/minnow-emgd/xorg.conf (renamed from recipes-graphics/xorg-xserver/xserver-xf86-config/minnow/xorg.conf)2
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3.inc20
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/crosscompile.patch22
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/fix_open_max_preprocessor_error.patch15
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/macro_tweak.patch30
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/nodolt.patch14
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/ptr-to-int-cast-fix.patch92
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/werror-address-fix.patch49
-rw-r--r--recipes-graphics/xorg-xserver/xserver-xorg_1.9.3.bb4
-rw-r--r--recipes-kernel/linux/linux-yocto_3.10.bbappend37
-rw-r--r--recipes-multimedia/gstreamer/gst-va-intel.bb56
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi-0.10_0.5.8.bb14
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi-1.0_0.5.8.bb5
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi.inc41
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.c1712
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.h308
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi/install-tests.patch31
-rw-r--r--recipes-multimedia/gstreamer/gstreamer-vaapi_0.4.3.bb24
-rw-r--r--recipes-multimedia/libva/libva-intel-driver/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch440
-rw-r--r--recipes-multimedia/libva/libva-intel-driver/wayland-include.patch30
-rw-r--r--recipes-multimedia/libva/libva-intel-driver_1.3.2.bb31
-rw-r--r--recipes-multimedia/libva/libva.inc46
-rw-r--r--recipes-multimedia/libva/libva_1.0.16.bb11
-rw-r--r--recipes-multimedia/libva/libva_1.3.1.bb6
-rw-r--r--recipes-multimedia/libva/va-intel.bb30
38 files changed, 3646 insertions, 18 deletions
diff --git a/classes/emgd-gl.bbclass b/classes/emgd-gl.bbclass
new file mode 100644
index 0000000..ef1df69
--- /dev/null
+++ b/classes/emgd-gl.bbclass
@@ -0,0 +1,11 @@
+# give a different PACKAGE_ARCH to the recipes involved with opengl
+python __anonymous () {
+ provides = set((d.getVar("PROVIDES", True) or "").split())
+ depends = set((d.getVar("DEPENDS", True) or "").split())
+
+ glp = set([ "virtual/libgles1", "virtual/libgles2", "virtual/egl", "virtual/mesa" , "virtual/libgl"])
+ if list(glp & (provides | depends)): # set union & intersection operations
+ # matched
+ d.appendVar("PACKAGE_ARCH", "${GLSUFFIX}")
+ return
+}
diff --git a/conf/machine/include/meta-intel-emgd.inc b/conf/machine/include/meta-intel-emgd.inc
new file mode 100644
index 0000000..55050dc
--- /dev/null
+++ b/conf/machine/include/meta-intel-emgd.inc
@@ -0,0 +1,23 @@
+INHERIT += "emgd-gl"
+GLSUFFIX = "-emgd"
+PACKAGE_EXTRA_ARCHS_append = " ${TUNE_PKGARCH}${GLSUFFIX}"
+
+
+#
+# XSERVER subcomponents, used to build the XSERVER variable
+#
+
+# for Xserver older than 1.13.0
+OLD_XSERVER_X86_EXT = "xserver-xorg-extension-dri \
+ xserver-xorg-extension-dri2 \
+ xserver-xorg-extension-extmod \
+ xserver-xorg-extension-dbe \
+ "
+XSERVER_X86_EMGD = "emgd-driver-bin \
+ ${OLD_XSERVER_X86_EXT} \
+ "
+PREFERRED_PROVIDER_virtual/mesa ?= "mesa-gl"
+PREFERRED_PROVIDER_virtual/libgl ?= "mesa-gl"
+PREFERRED_PROVIDER_virtual/libgles1 ?= "emgd-driver-bin"
+PREFERRED_PROVIDER_virtual/libgles2 ?= "emgd-driver-bin"
+PREFERRED_PROVIDER_virtual/egl ?= "emgd-driver-bin"
diff --git a/conf/machine/minnow-emgd.conf b/conf/machine/minnow-emgd.conf
new file mode 100644
index 0000000..d4351e0
--- /dev/null
+++ b/conf/machine/minnow-emgd.conf
@@ -0,0 +1,53 @@
+#@TYPE: Machine
+#@NAME: minnow-emgd
+
+#@WEBTITLE: Intel Atom E640T Processor with Intel EG20T Controller Hub Development Kit (Queens Bay) with Proprietary IEMGD Accelerated Graphics.
+
+#@DESCRIPTION: Machine configuration for MinnowBoard v1 (Intel Atom E640T). For the MinnowBoard MAX (Intel Atom E38xx), please use the meta-intel intel-corei7-64 BSP: http://www.elinux.org/Minnowboard:MinnowMaxYoctoProject
+
+require conf/machine/include/intel-core2-32-common.inc
+require conf/machine/include/meta-intel.inc
+require conf/machine/include/meta-intel-emgd.inc
+
+MACHINE_HWCODECS ?= "va-intel"
+
+MACHINE_FEATURES += "efi va-impl-mixvideo wifi"
+
+PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
+PREFERRED_VERSION_linux-yocto = "3.10%"
+
+XSERVER ?= "${XSERVER_X86_BASE} \
+ ${XSERVER_X86_EXT} \
+ ${XSERVER_X86_EMGD} \
+ "
+
+XSERVERCODECS ?= "emgd-driver-video emgd-gst-plugins-va \
+ emgd-gst-plugins-mixvideo gst-va-intel"
+
+APPEND += "console=ttyPCH0,115200 console=tty0 vmalloc=256MB \
+ snd-hda-intel.enable_msi=0 \
+ "
+SERIAL_CONSOLE = "115200 ttyPCH0"
+GRUB_OPTS = "terminal_input console"
+
+# Linux kernel drivers for onboard hardware
+MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += " \
+kernel-module-snd-hda-intel \
+kernel-module-lpc-sch \
+kernel-module-gpio-sch \
+kernel-module-pch-gbe \
+kernel-module-pch-udc \
+kernel-module-gpio-pch \
+kernel-module-leds-gpio \
+kernel-module-input-polldev \
+kernel-module-gpio-keys-polled \
+kernel-module-minnowboard \
+kernel-module-minnowboard-gpio \
+kernel-module-minnowboard-keys \
+kernel-module-spidev \
+kernel-module-i2c-dev \
+kernel-module-iwlwifi \
+"
+
+# Include all firmware packages for the most compatible experience
+MACHINE_EXTRA_RRECOMMENDS += "linux-firmware"
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin/egl.pc b/recipes-graphics/xorg-driver/emgd-driver-bin/egl.pc
new file mode 100644
index 0000000..42efd64
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin/egl.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=/usr/lib
+includedir=/usr/include
+
+Name: egl
+Description: EMGD EGL library
+Requires.private:
+Version: 1.16
+Libs: -L${libdir} -lEGL
+Libs.private: -lm -lpthread -ldl
+Cflags: -I${includedir}
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin/glchar.patch b/recipes-graphics/xorg-driver/emgd-driver-bin/glchar.patch
new file mode 100644
index 0000000..2781ec9
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin/glchar.patch
@@ -0,0 +1,17 @@
+EMGD's gl2.h is missing the GLchar typedef, so add it.
+
+Upstream-Status: Submitted
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+
+diff --git a/usr/include/GLES2/gl2.h b/usr/include/GLES2/gl2.h
+index 8b83f3f..4fbd12e 100644
+--- a/usr/include/GLES2/gl2.h
++++ b/usr/include/GLES2/gl2.h
+@@ -21,6 +21,7 @@ typedef unsigned int GLenum;
+ typedef unsigned char GLboolean;
+ typedef unsigned int GLbitfield;
+ typedef khronos_int8_t GLbyte;
++typedef char GLchar;
+ typedef short GLshort;
+ typedef int GLint;
+ typedef int GLsizei;
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin/gles_cm.pc b/recipes-graphics/xorg-driver/emgd-driver-bin/gles_cm.pc
new file mode 100644
index 0000000..a0c828f
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin/gles_cm.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=/usr/lib
+includedir=/usr/include
+
+Name: gles_cm
+Description: EMGD OpenGL ES 1.1 CM library
+Requires.private:
+Version: 1.16
+Libs: -L${libdir} -lGLES_CM
+Libs.private: -lm -lpthread -ldl
+Cflags: -I${includedir}
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin/glesv2.pc b/recipes-graphics/xorg-driver/emgd-driver-bin/glesv2.pc
new file mode 100644
index 0000000..02171fa
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin/glesv2.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=/usr/lib
+includedir=/usr/include
+
+Name: glesv2
+Description: EMGD OpenGL ES 2.0 library
+Requires.private:
+Version: 1.16
+Libs: -L${libdir} -lGLESv2
+Libs.private: -lm -lpthread -ldl
+Cflags: -I${includedir}
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin_1.16.bb b/recipes-graphics/xorg-driver/emgd-driver-bin_1.16.bb
new file mode 100644
index 0000000..963536f
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin_1.16.bb
@@ -0,0 +1,186 @@
+SUMMARY = "EMGD 1.16 xserver binaries"
+DESCRIPTION = "EMGD 1.16 includes some userspace binaries that use non-free \
+licensing, which are now available via a non-click-through downloadable \
+tarball, and is what this recipe now uses. Since it is a non-free license, \
+this recipe is marked as 'License_emgd-driver-bin_1.16' and you need to add \
+to LICENSE_FLAGS_WHITELIST += \"license_emgd-driver-bin_1.16\" to your \
+local.conf in order to enable it in a build."
+LICENSE = "Intel-software-license-emgd-1.16 & Intel-user-space-graphics-driver-binary-license-emgd-1.16 & MIT"
+LICENSE_FLAGS = "license_${PN}_${PV}"
+PR = "r0"
+
+COMPATIBLE_HOST = "(i.86).*-linux"
+
+EMGD_LIC_DIR = "IEMGD_HEAD_Linux/License"
+EMGD_RPM_DIR = "IEMGD_HEAD_Linux/MeeGo1.2"
+EMGD_VIDEO_PLUGIN_DIR = "../common/video_plugin"
+
+LIC_FILES_CHKSUM = "file://${WORKDIR}/${EMGD_LIC_DIR}/License.txt;md5=b54f01caaf8483b3cb60c0c40f2bf22d \
+ file://${WORKDIR}/${EMGD_LIC_DIR}/readme.txt;md5=73cbec7a0d2bc22faf567238e055bfc8"
+
+DEPENDS = "rpm-native xz-native"
+RDEPENDS_${PN} = "libxcb-dri2 cairo xserver-xorg"
+RDEPENDS_emgd-gst-plugins-mixvideo = "libva-tpi"
+
+# These libraries shouldn't get installed in world builds unless something
+# explicitly depends upon them.
+EXCLUDE_FROM_WORLD = "1"
+PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
+
+# Add the ABI dependency at package generation time, as otherwise bitbake will
+# attempt to find a provider for it (and fail) when it does the parse.
+#
+# This version *must* be kept correct.
+python populate_packages_prepend() {
+ pn = d.getVar("PN", True)
+ d.appendVar("RDEPENDS_" + pn, " xorg-abi-video-8")
+}
+
+inherit distro_features_check
+REQUIRED_DISTRO_FEATURES = "opengl"
+
+SRC_URI = "https://edc.intel.com/App_Shared/Downloads/LIN_IEMGD_1_16_GOLD_3228.tgz \
+ file://egl.pc \
+ file://gles_cm.pc \
+ file://glesv2.pc \
+ "
+
+SRC_URI[md5sum] = "339c902baeac0a5816108bea827b3685"
+SRC_URI[sha256sum] = "33ef38b83914ef7d1e12a430ec009352b415b9d5840c9d0db25744b7dc6a2473"
+
+
+# make sure generated rpm packages get non conflicting names
+PKG_${PN} = "emgd-driver"
+PKG_${PN}-dev = "emgd-driver-dev"
+PKG_${PN}-dbg = "emgd-driver-dbg"
+PKG_${PN}-doc = "emgd-driver-doc"
+
+PACKAGES =+ "emgd-libmixcommon emgd-libmixvideo emgd-libmixvbp \
+ emgd-gst-vabuffer emgd-gst-plugins-mixvideo \
+ emgd-gst-plugins-va emgd-driver-video"
+
+# These are closed binaries generated elsewhere so don't check ldflags & text relocations
+INSANE_SKIP_emgd-driver-video = "ldflags textrel"
+# Inhibit warnings about files being stripped, we can't do anything about it.
+INHIBIT_PACKAGE_STRIP = "1"
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+
+# Avoid auto renaming of these packages
+DEBIAN_NOAUTONAME_emgd-libmixcommon = "1"
+DEBIAN_NOAUTONAME_emgd-libmixvideo = "1"
+DEBIAN_NOAUTONAME_emgd-libmixvbp = "1"
+DEBIAN_NOAUTONAME_emgd-gst-vabuffer = "1"
+
+FILES_emgd-libmixcommon = "${libdir}/libmixcommon.so.0.10.8 ${libdir}/libmixcommon.so.0"
+FILES_emgd-libmixvideo = "${libdir}/libmixvideo.so.0.10.10 ${libdir}/libmixvideo.so.0"
+FILES_emgd-libmixvbp = "${libdir}/libmixvbp.so.0.10.9 ${libdir}/libmixvbp.so.0 \
+ ${libdir}/libmixvbp_h264.so.0.10.9 ${libdir}/libmixvbp_h264.so.0 \
+ ${libdir}/libmixvbp_mpeg4.so.0.10.9 ${libdir}/libmixvbp_mpeg4.so.0 \
+ ${libdir}/libmixvbp_vc1.so.0.10.9 ${libdir}/libmixvbp_vc1.so.0 "
+FILES_emgd-gst-vabuffer = "${libdir}/libgstvabuffer.so.0.10.8 ${libdir}/libgstvabuffer.so.0"
+FILES_emgd-gst-plugins-mixvideo = "${libdir}/gstreamer-0.10/libgstmixvideoplugin.so"
+FILES_emgd-gst-plugins-va = "${libdir}/gstreamer-0.10/libgstvaplugin.so"
+FILES_emgd-driver-video = "${libdir}/dri/emgd_drv_video.so"
+FILES_${PN} += "${libdir}/dri ${libdir}/xorg/modules/drivers"
+FILES_${PN}-dbg += "${libdir}/xorg/modules/drivers/.debug ${libdir}/dri/.debug ${libdir}/gstreamer-0.10/.debug"
+
+S = "${WORKDIR}/${EMGD_RPM_DIR}"
+
+RPM2CPIO = "${COREBASE}/scripts/rpm2cpio.sh"
+
+do_install () {
+ # cleanup previous files if any
+ rm -rf usr
+
+ # A gstreamer VA buffer library
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-vabuffer*.rpm | cpio -id
+
+ # MIX Common contains common classes, datatype, header files used by other MIX components
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixcommon*.rpm | cpio -id
+
+ # MIX Video Bitstream Parser is an user library interface for various video format bitstream parsing
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixvbp*.rpm | cpio -id
+
+ # MIX Video is an user library interface for various video codecs available on the platform.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixvideo*.rpm | cpio -id
+
+ install -d -m 0755 ${D}${libdir}/gstreamer-0.10
+ install -m 0755 ${S}/usr/lib/* ${D}${libdir}/
+
+ # A gstreamer plugin that uses MIX Video for hardware accelerated video decoding and rendering.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-plugins-mixvideo*.rpm | cpio -id
+
+ # A collection of gstreamer plugins that uses VA libraries for hardware accelerated video rendering and text overlay.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-plugins-va*.rpm | cpio -id
+
+ install -m 0755 ${S}/usr/lib/gstreamer-0.10/* ${D}${libdir}/gstreamer-0.10/
+
+ # EMGD runtime graphics libraries
+ ${RPM2CPIO} ${S}/emgd-bin*.rpm | cpio -id
+
+ install -d -m 0755 ${D}${libdir}/dri
+ install -d -m 0755 ${D}${libdir}/xorg/modules/drivers
+ install -d -m 0755 ${D}${sysconfdir}
+ install -d -m 0755 ${D}${mandir}/man4
+ install -m 0755 ${S}/usr/lib/*.so.* ${D}${libdir}/
+ install -m 0755 ${S}/usr/lib/dri/* ${D}${libdir}/dri/
+ install -m 0755 ${S}/usr/lib/xorg/modules/drivers/* ${D}${libdir}/xorg/modules/drivers/
+ install -m 0755 ${S}/etc/* ${D}${sysconfdir}/
+ install -m 0755 ${S}/usr/share/man/man4/* ${D}${mandir}/man4/
+
+ # Khronos development headers needed for EGL, OpenGL-ES, and OpenVG development
+ ${RPM2CPIO} ${S}/emgd-devel*.rpm | cpio -id
+
+ install -d -m 0755 ${D}${includedir}/EGL
+ install -m 0755 ${S}/usr/include/EGL/*.h ${D}${includedir}/EGL/
+ install -d -m 0755 ${D}${includedir}/GLES
+ install -m 0755 ${S}/usr/include/GLES/*.h ${D}${includedir}/GLES/
+ install -d -m 0755 ${D}${includedir}/GLES2
+ install -m 0755 ${S}/usr/include/GLES2/*.h ${D}${includedir}/GLES2/
+ install -d -m 0755 ${D}${includedir}/KHR
+ install -m 0755 ${S}/usr/include/KHR/*.h ${D}${includedir}/KHR/
+ install -d -m 0755 ${D}${includedir}/VG
+ install -m 0755 ${S}/usr/include/VG/*.h ${D}${includedir}/VG/
+
+ EMGD_SNAPSHOT="1.5.15.3226"
+ ln -sf libEGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEGL.so.1
+ ln -sf libEGL.so.1 ${D}${libdir}/libEGL.so
+ ln -sf libGLES_CM.so.${EMGD_SNAPSHOT} ${D}${libdir}/libGLES_CM.so.1
+ ln -sf libGLES_CM.so.1 ${D}${libdir}/libGLES_CM.so
+ ln -sf libGLESv2.so.${EMGD_SNAPSHOT} ${D}${libdir}/libGLESv2.so.2
+ ln -sf libGLESv2.so.2 ${D}${libdir}/libGLESv2.so
+ ln -sf libOpenVG.so.${EMGD_SNAPSHOT} ${D}${libdir}/libOpenVG.so.1
+ ln -sf libOpenVG.so.1 ${D}${libdir}/libOpenVG.so
+ ln -sf libOpenVGU.so.${EMGD_SNAPSHOT} ${D}${libdir}/libOpenVGU.so.1
+ ln -sf libOpenVGU.so.1 ${D}${libdir}/libOpenVGU.so
+ ln -sf libEMGD2d.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGD2d.so
+ ln -sf libEMGDegl.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDegl.so
+ ln -sf libemgdglslcompiler.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdglslcompiler.so
+ ln -sf libEMGDOGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDOGL.so
+ ln -sf libemgdPVR2D_DRIWSEGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdPVR2D_DRIWSEGL.so
+ ln -sf libEMGDScopeServices.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDScopeServices.so
+ ln -sf libemgdsrv_init.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdsrv_init.so
+ ln -sf libemgdsrv_um.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdsrv_um.so
+
+ #Replace duplicate files with symlinks
+ rm -f ${D}${libdir}/libmixvideo.so.0
+ ln -sf libmixvideo.so.0.10.10 ${D}${libdir}/libmixvideo.so.0
+ rm -f ${D}${libdir}/libmixvbp_h264.so.0
+ ln -sf libmixvbp_h264.so.0.10.9 ${D}${libdir}/libmixvbp_h264.so.0
+ rm -f ${D}${libdir}/libmixvbp.so.0
+ ln -sf libmixvbp.so.0.10.9 ${D}${libdir}/libmixvbp.so.0
+ rm -f ${D}${libdir}/libmixvbp_vc1.so.0
+ ln -sf libmixvbp_vc1.so.0.10.9 ${D}${libdir}/libmixvbp_vc1.so.0
+ rm -f ${D}${libdir}/libmixvbp_mpeg4.so.0
+ ln -sf libmixvbp_mpeg4.so.0.10.9 ${D}${libdir}/libmixvbp_mpeg4.so.0
+ rm -f ${D}${libdir}/libmixcommon.so.0
+ ln -sf libmixcommon.so.0.10.8 ${D}${libdir}/libmixcommon.so.0
+ rm -f ${D}${libdir}/libgstvabuffer.so.0
+ ln -sf libgstvabuffer.so.0.10.8 ${D}${libdir}/libgstvabuffer.so.0
+
+ # Copy the .pc files
+ install -d -m 0755 ${D}${libdir}/pkgconfig
+ install -m 0644 ${WORKDIR}/*.pc ${D}${libdir}/pkgconfig/
+}
+
+LEAD_SONAME = "libEGL.so"
diff --git a/recipes-graphics/xorg-driver/emgd-driver-bin_1.18.bb b/recipes-graphics/xorg-driver/emgd-driver-bin_1.18.bb
new file mode 100644
index 0000000..150663e
--- /dev/null
+++ b/recipes-graphics/xorg-driver/emgd-driver-bin_1.18.bb
@@ -0,0 +1,188 @@
+SUMMARY = "EMGD 1.18 xserver binaries"
+DESCRIPTION = "EMGD 1.18 includes some userspace binaries that use non-free \
+licensing, which are now available via a non-click-through downloadable \
+tarball, and is what this recipe now uses. Since it is a non-free license, \
+this recipe is marked as 'License_emgd-driver-bin_1.18' and you need to add \
+to LICENSE_FLAGS_WHITELIST += \"license_emgd-driver-bin_1.18\" to your \
+local.conf in order to enable it in a build."
+LICENSE = "Intel-software-license-emgd-1.18 & Intel-user-space-graphics-driver-binary-license-emgd-1.18 & MIT"
+LICENSE_FLAGS = "license_${PN}_${PV}"
+PR = "r1"
+
+COMPATIBLE_HOST = "(i.86).*-linux"
+
+EMGD_LIC_DIR = "IEMGD_HEAD_Linux/License"
+EMGD_RPM_DIR = "IEMGD_HEAD_Linux/MeeGo1.2"
+EMGD_VIDEO_PLUGIN_DIR = "../common/video_plugin"
+
+LIC_FILES_CHKSUM = "file://${WORKDIR}/${EMGD_LIC_DIR}/License.txt;md5=7ce256e6a32a208bb3e509ef8febc6e4 \
+ file://${WORKDIR}/${EMGD_LIC_DIR}/readme.txt;md5=73cbec7a0d2bc22faf567238e055bfc8"
+
+DEPENDS = "rpm-native xz-native"
+RDEPENDS_${PN} = "libxcb-dri2 cairo xserver-xorg"
+RDEPENDS_emgd-gst-plugins-mixvideo = "libva-tpi"
+
+# These libraries shouldn't get installed in world builds unless something
+# explicitly depends upon them.
+EXCLUDE_FROM_WORLD = "1"
+PROVIDES = "virtual/libgles1 virtual/libgles2 virtual/egl"
+
+# Add the ABI dependency at package generation time, as otherwise bitbake will
+# attempt to find a provider for it (and fail) when it does the parse.
+#
+# This version *must* be kept correct.
+python populate_packages_prepend() {
+ pn = d.getVar("PN", True)
+ d.appendVar("RDEPENDS_" + pn, " xorg-abi-video-8")
+}
+
+inherit distro_features_check
+REQUIRED_DISTRO_FEATURES = "opengl"
+
+SRC_URI = "http://downloadmirror.intel.com/22865/eng/LIN_IEMGD_1_18_GOLD_3398.tgz \
+ file://egl.pc \
+ file://gles_cm.pc \
+ file://glesv2.pc \
+ file://glchar.patch;apply=0 \
+ "
+
+SRC_URI[md5sum] = "a165c397866d3fb70ddab318c834e49a"
+SRC_URI[sha256sum] = "2d709deecda595983b0d8f1d3c7bd0b4d5c79ae665c621b3b9b11c366b34873f"
+
+# make sure generated rpm packages get non conflicting names
+PKG_${PN} = "emgd-driver"
+PKG_${PN}-dev = "emgd-driver-dev"
+PKG_${PN}-dbg = "emgd-driver-dbg"
+PKG_${PN}-doc = "emgd-driver-doc"
+
+PACKAGES =+ "emgd-libmixcommon emgd-libmixvideo emgd-libmixvbp \
+ emgd-gst-vabuffer emgd-gst-plugins-mixvideo \
+ emgd-gst-plugins-va emgd-driver-video"
+
+# These are closed binaries generated elsewhere so don't check ldflags & text relocations
+INSANE_SKIP_emgd-driver-video = "ldflags textrel"
+# Inhibit warnings about files being stripped, we can't do anything about it.
+INHIBIT_PACKAGE_STRIP = "1"
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+
+# Avoid auto renaming of these packages
+DEBIAN_NOAUTONAME_emgd-libmixcommon = "1"
+DEBIAN_NOAUTONAME_emgd-libmixvideo = "1"
+DEBIAN_NOAUTONAME_emgd-libmixvbp = "1"
+DEBIAN_NOAUTONAME_emgd-gst-vabuffer = "1"
+
+FILES_emgd-libmixcommon = "${libdir}/libmixcommon.so.0.10.8 ${libdir}/libmixcommon.so.0"
+FILES_emgd-libmixvideo = "${libdir}/libmixvideo.so.0.10.10 ${libdir}/libmixvideo.so.0"
+FILES_emgd-libmixvbp = "${libdir}/libmixvbp.so.0.10.9 ${libdir}/libmixvbp.so.0 \
+ ${libdir}/libmixvbp_h264.so.0.10.9 ${libdir}/libmixvbp_h264.so.0 \
+ ${libdir}/libmixvbp_mpeg4.so.0.10.9 ${libdir}/libmixvbp_mpeg4.so.0 \
+ ${libdir}/libmixvbp_vc1.so.0.10.9 ${libdir}/libmixvbp_vc1.so.0 "
+FILES_emgd-gst-vabuffer = "${libdir}/libgstvabuffer.so.0.10.8 ${libdir}/libgstvabuffer.so.0"
+FILES_emgd-gst-plugins-mixvideo = "${libdir}/gstreamer-0.10/libgstmixvideoplugin.so"
+FILES_emgd-gst-plugins-va = "${libdir}/gstreamer-0.10/libgstvaplugin.so"
+FILES_emgd-driver-video = "${libdir}/dri/emgd_drv_video.so"
+FILES_${PN} += "${libdir}/dri ${libdir}/xorg/modules/drivers"
+FILES_${PN}-dbg += "${libdir}/xorg/modules/drivers/.debug ${libdir}/dri/.debug ${libdir}/gstreamer-0.10/.debug"
+
+S = "${WORKDIR}/${EMGD_RPM_DIR}"
+
+RPM2CPIO = "${COREBASE}/scripts/rpm2cpio.sh"
+
+do_install () {
+ # cleanup previous files if any
+ rm -rf usr
+
+ # A gstreamer VA buffer library
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-vabuffer*.rpm | cpio -id
+
+ # MIX Common contains common classes, datatype, header files used by other MIX components
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixcommon*.rpm | cpio -id
+
+ # MIX Video Bitstream Parser is an user library interface for various video format bitstream parsing
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixvbp*.rpm | cpio -id
+
+ # MIX Video is an user library interface for various video codecs available on the platform.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/mixvideo*.rpm | cpio -id
+
+ install -d -m 0755 ${D}${libdir}/gstreamer-0.10
+ install -m 0755 ${S}/usr/lib/* ${D}${libdir}/
+
+ # A gstreamer plugin that uses MIX Video for hardware accelerated video decoding and rendering.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-plugins-mixvideo*.rpm | cpio -id
+
+ # A collection of gstreamer plugins that uses VA libraries for hardware accelerated video rendering and text overlay.
+ ${RPM2CPIO} ${S}/${EMGD_VIDEO_PLUGIN_DIR}/gst-plugins-va*.rpm | cpio -id
+
+ install -m 0755 ${S}/usr/lib/gstreamer-0.10/* ${D}${libdir}/gstreamer-0.10/
+
+ # EMGD runtime graphics libraries
+ ${RPM2CPIO} ${S}/emgd-bin*.rpm | cpio -id
+
+ install -d -m 0755 ${D}${libdir}/dri
+ install -d -m 0755 ${D}${libdir}/xorg/modules/drivers
+ install -d -m 0755 ${D}${sysconfdir}
+ install -d -m 0755 ${D}${mandir}/man4
+ install -m 0755 ${S}/usr/lib/*.so.* ${D}${libdir}/
+ install -m 0755 ${S}/usr/lib/dri/* ${D}${libdir}/dri/
+ install -m 0755 ${S}/usr/lib/xorg/modules/drivers/* ${D}${libdir}/xorg/modules/drivers/
+ install -m 0755 ${S}/etc/* ${D}${sysconfdir}/
+ install -m 0755 ${S}/usr/share/man/man4/* ${D}${mandir}/man4/
+
+ # Khronos development headers needed for EGL, OpenGL-ES, and OpenVG development
+ ${RPM2CPIO} ${S}/emgd-devel*.rpm | cpio -id
+
+ patch -d ${S} -p1 < ${WORKDIR}/glchar.patch
+
+ install -d -m 0755 ${D}${includedir}/EGL
+ install -m 0755 ${S}/usr/include/EGL/*.h ${D}${includedir}/EGL/
+ install -d -m 0755 ${D}${includedir}/GLES
+ install -m 0755 ${S}/usr/include/GLES/*.h ${D}${includedir}/GLES/
+ install -d -m 0755 ${D}${includedir}/GLES2
+ install -m 0755 ${S}/usr/include/GLES2/*.h ${D}${includedir}/GLES2/
+ install -d -m 0755 ${D}${includedir}/KHR
+ install -m 0755 ${S}/usr/include/KHR/*.h ${D}${includedir}/KHR/
+ install -d -m 0755 ${D}${includedir}/VG
+ install -m 0755 ${S}/usr/include/VG/*.h ${D}${includedir}/VG/
+
+ EMGD_SNAPSHOT="1.5.15.3226"
+ ln -sf libEGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEGL.so.1
+ ln -sf libEGL.so.1 ${D}${libdir}/libEGL.so
+ ln -sf libGLES_CM.so.${EMGD_SNAPSHOT} ${D}${libdir}/libGLES_CM.so.1
+ ln -sf libGLES_CM.so.1 ${D}${libdir}/libGLES_CM.so
+ ln -sf libGLESv2.so.${EMGD_SNAPSHOT} ${D}${libdir}/libGLESv2.so.2
+ ln -sf libGLESv2.so.2 ${D}${libdir}/libGLESv2.so
+ ln -sf libOpenVG.so.${EMGD_SNAPSHOT} ${D}${libdir}/libOpenVG.so.1
+ ln -sf libOpenVG.so.1 ${D}${libdir}/libOpenVG.so
+ ln -sf libOpenVGU.so.${EMGD_SNAPSHOT} ${D}${libdir}/libOpenVGU.so.1
+ ln -sf libOpenVGU.so.1 ${D}${libdir}/libOpenVGU.so
+ ln -sf libEMGD2d.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGD2d.so
+ ln -sf libEMGDegl.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDegl.so
+ ln -sf libemgdglslcompiler.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdglslcompiler.so
+ ln -sf libEMGDOGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDOGL.so
+ ln -sf libemgdPVR2D_DRIWSEGL.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdPVR2D_DRIWSEGL.so
+ ln -sf libEMGDScopeServices.so.${EMGD_SNAPSHOT} ${D}${libdir}/libEMGDScopeServices.so
+ ln -sf libemgdsrv_init.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdsrv_init.so
+ ln -sf libemgdsrv_um.so.${EMGD_SNAPSHOT} ${D}${libdir}/libemgdsrv_um.so
+
+ #Replace duplicate files with symlinks
+ rm -f ${D}${libdir}/libmixvideo.so.0
+ ln -sf libmixvideo.so.0.10.10 ${D}${libdir}/libmixvideo.so.0
+ rm -f ${D}${libdir}/libmixvbp_h264.so.0
+ ln -sf libmixvbp_h264.so.0.10.9 ${D}${libdir}/libmixvbp_h264.so.0
+ rm -f ${D}${libdir}/libmixvbp.so.0
+ ln -sf libmixvbp.so.0.10.9 ${D}${libdir}/libmixvbp.so.0
+ rm -f ${D}${libdir}/libmixvbp_vc1.so.0
+ ln -sf libmixvbp_vc1.so.0.10.9 ${D}${libdir}/libmixvbp_vc1.so.0
+ rm -f ${D}${libdir}/libmixvbp_mpeg4.so.0
+ ln -sf libmixvbp_mpeg4.so.0.10.9 ${D}${libdir}/libmixvbp_mpeg4.so.0
+ rm -f ${D}${libdir}/libmixcommon.so.0
+ ln -sf libmixcommon.so.0.10.8 ${D}${libdir}/libmixcommon.so.0
+ rm -f ${D}${libdir}/libgstvabuffer.so.0
+ ln -sf libgstvabuffer.so.0.10.8 ${D}${libdir}/libgstvabuffer.so.0
+
+ # Copy the .pc files
+ install -d -m 0755 ${D}${libdir}/pkgconfig
+ install -m 0644 ${WORKDIR}/*.pc ${D}${libdir}/pkgconfig/
+}
+
+LEAD_SONAME = "libEGL.so"
diff --git a/recipes-graphics/xorg-driver/xf86-input-evdev_2.6.0.bb b/recipes-graphics/xorg-driver/xf86-input-evdev_2.6.0.bb
new file mode 100644
index 0000000..ab43ef5
--- /dev/null
+++ b/recipes-graphics/xorg-driver/xf86-input-evdev_2.6.0.bb
@@ -0,0 +1,20 @@
+require recipes-graphics/xorg-driver/xorg-driver-input.inc
+
+SUMMARY = "X.Org X server -- event devices (evdev) input driver"
+
+DESCRIPTION = "evdev is an Xorg input driver for Linux's generic event \
+devices. It therefore supports all input devices that the kernel knows \
+about, including most mice and keyboards. \
+\
+The evdev driver can serve as both a pointer and a keyboard input \
+device, and may be used as both the core keyboard and the core pointer. \
+Multiple input devices are supported by multiple instances of this \
+driver, with one Load directive for evdev in the Module section of your \
+xorg.conf for each input device that will use this driver. "
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=fefe33b1cf0cacba0e72e3b0fa0f0e16"
+
+PR = "${INC_PR}.0"
+
+SRC_URI[md5sum] = "f33fe9413bde68936d8909206a13e8a1"
+SRC_URI[sha256sum] = "b0e7f3991a8183a4743196c3e16d7184d439b80bf43653aa2f45b0756a6753ac"
diff --git a/recipes-graphics/xorg-driver/xf86-input-synaptics_1.6.3.bb b/recipes-graphics/xorg-driver/xf86-input-synaptics_1.6.3.bb
new file mode 100644
index 0000000..cc582a1
--- /dev/null
+++ b/recipes-graphics/xorg-driver/xf86-input-synaptics_1.6.3.bb
@@ -0,0 +1,23 @@
+require recipes-graphics/xorg-driver/xorg-driver-input.inc
+
+#SRC_URI += "file://configurefix.patch"
+
+SUMMARY = "X.Org X server -- synaptics touchpad input driver"
+
+DESCRIPTION = "synaptics is an Xorg input driver for the touchpads from \
+Synaptics Incorporated. Even though these touchpads (by default, \
+operating in a compatibility mode emulating a standard mouse) can be \
+handled by the normal evdev or mouse drivers, this driver allows more \
+advanced features of the touchpad to become available."
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=e395e21f3c21d4fc3a243783e85e9ab5"
+
+PR = "${INC_PR}.0"
+
+SRC_URI[md5sum] = "3568930b0bda522e00272b64c0ca2ca2"
+SRC_URI[sha256sum] = "b40c9dbd5f743ff1eb2ac81a23b9676df72e76ed3fa6408de3f8a3a260248604"
+
+DEPENDS += "libxi mtdev"
+
+FILES_${PN} += "${datadir}/X11/xorg.conf.d"
+
diff --git a/recipes-graphics/xorg-driver/xorg-driver-common.inc b/recipes-graphics/xorg-driver/xorg-driver-common.inc
new file mode 100644
index 0000000..1ed2742
--- /dev/null
+++ b/recipes-graphics/xorg-driver/xorg-driver-common.inc
@@ -0,0 +1,33 @@
+DESCRIPTION = "X driver"
+HOMEPAGE = "http://www.x.org"
+BUGTRACKER = "https://bugs.freedesktop.org"
+SECTION = "x11/drivers"
+LICENSE = "MIT-X"
+
+PE = "2"
+INC_PR = "r0"
+
+DEPENDS = "virtual/xserver xproto randrproto util-macros"
+
+SRC_URI = "${XORG_MIRROR}/individual/driver/${BPN}-${PV}.tar.bz2"
+
+S = "${WORKDIR}/${BPN}-${PV}"
+
+FILES_${PN} += " ${libdir}/xorg/modules/drivers/*.so"
+FILES_${PN}-dbg += " ${libdir}/xorg/modules/drivers/.debug"
+
+inherit autotools pkgconfig
+
+# AC_CHECK_FILE doesn't work when cross compiling, so we create a replacement
+# macro that simply assumes the test succeeds.
+do_configure_prepend () {
+ echo 'AC_DEFUN(CC_AC_CHECK_FILE, $2)' > configure.ac.new
+ sed 's/AC_CHECK_FILE/CC_AC_CHECK_FILE/g' configure.ac >> configure.ac.new
+ mv configure.ac.new configure.ac
+}
+
+# FIXME: We don't want to include the libtool archives (*.la) from modules
+# directory, as they serve no useful purpose. Upstream should fix Makefile.am
+do_install_append() {
+ find ${D}${libdir}/xorg/modules -regex ".*\.la$" | xargs rm -f --
+}
diff --git a/recipes-graphics/xorg-driver/xorg-driver-video.inc b/recipes-graphics/xorg-driver/xorg-driver-video.inc
new file mode 100644
index 0000000..57c80d1
--- /dev/null
+++ b/recipes-graphics/xorg-driver/xorg-driver-video.inc
@@ -0,0 +1,4 @@
+include xorg-driver-common.inc
+
+DEPENDS =+ "renderproto videoproto xextproto fontsproto"
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xf86-config/minnow/xorg.conf b/recipes-graphics/xorg-xserver/xserver-xf86-config/minnow-emgd/xorg.conf
index c8befc3..d371227 100644
--- a/recipes-graphics/xorg-xserver/xserver-xf86-config/minnow/xorg.conf
+++ b/recipes-graphics/xorg-xserver/xserver-xf86-config/minnow-emgd/xorg.conf
@@ -9,6 +9,8 @@ Section "Screen"
Device "IntelEMGD-0"
Monitor "Monitor0"
SubSection "Display"
+ Depth "24"
+ Modes "1366x768"
EndSubSection
EndSection
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3.inc b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3.inc
new file mode 100644
index 0000000..1c71d7b
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3.inc
@@ -0,0 +1,20 @@
+SRC_URI += "file://nodolt.patch \
+ file://crosscompile.patch"
+
+# Misc build failure for master HEAD
+SRC_URI += "file://fix_open_max_preprocessor_error.patch"
+
+# What once were warnings now are errors, fix those up
+SRC_URI += "file://werror-address-fix.patch \
+ file://ptr-to-int-cast-fix.patch"
+
+PROTO_DEPS += "xf86driproto dri2proto"
+DEPENDS += "font-util"
+EXTRA_OECONF += "--enable-dri --enable-dri2 --enable-dga"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=3dd2bbe3563837f80ed8926b06c1c353"
+
+SRC_URI[md5sum] = "5bef6839a76d029204ab31aa2fcb5201"
+SRC_URI[sha256sum] = "864831f51e841ff37f2445d1c85b86b559c8860a435fb496aead4f256a2b141d"
+
+PR = "r2"
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/crosscompile.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/crosscompile.patch
new file mode 100644
index 0000000..2f98bb8
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/crosscompile.patch
@@ -0,0 +1,22 @@
+Upstream-Status: Inappropriate [configuration]
+
+diff --git a/configure.ac b/configure.ac
+index b3b752c..600500b 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -523,13 +523,9 @@ dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d,
+ dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross
+ dnl compiling, assume default font path uses standard FONTROOTDIR directories.
+ DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/"
+-if test "$cross_compiling" != yes; then
+- AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d],
+- [DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'],
+- [case $host_os in
++ case $host_os in
+ darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;;
+- esac])
+-fi
++ esac
+ AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]),
+ [ FONTPATH="$withval" ],
+ [ FONTPATH="${DEFAULT_FONT_PATH}" ])
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/fix_open_max_preprocessor_error.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/fix_open_max_preprocessor_error.patch
new file mode 100644
index 0000000..9c33072
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/fix_open_max_preprocessor_error.patch
@@ -0,0 +1,15 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+Index: git/os/osdep.h
+===================================================================
+--- git.orig/os/osdep.h 2008-10-07 18:38:21.000000000 +0100
++++ git/os/osdep.h 2008-10-07 18:39:36.000000000 +0100
+@@ -92,7 +92,7 @@
+ * like sysconf(_SC_OPEN_MAX) is not supported.
+ */
+
+-#if OPEN_MAX <= 256
++#if 0
+ #define MAXSOCKS (OPEN_MAX - 1)
+ #else
+ #define MAXSOCKS 256
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/macro_tweak.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/macro_tweak.patch
new file mode 100644
index 0000000..2b75427
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/macro_tweak.patch
@@ -0,0 +1,30 @@
+This is the revised version of files/macro_tweak.patch for
+xorg-server 1.8.99.904.
+
+the files/macro_tweak.patch can not removed now since it is used by
+xserver-kdrive-1.7.99.2 and xserver-xf86-lite_1.7.99.2. Once they
+are all upgraded to 1.8.99.904, the the files/macro_tweak.patch
+can be safely replace by this patch.
+
+Upstream-Status: Pending
+
+Signed-off-by: Yu Ke <ke.yu@intel.com>
+
+diff --git a/xorg-server.m4 b/xorg-server.m4
+index bdecf62..040fdb8 100644
+--- a/xorg-server.m4
++++ b/xorg-server.m4
+@@ -28,10 +28,12 @@ dnl
+ # Checks for the $1 define in xorg-server.h (from the sdk). If it
+ # is defined, then add $1 to $REQUIRED_MODULES.
+
++m4_pattern_allow(PKG_CONFIG_SYSROOT_DIR)
++
+ AC_DEFUN([XORG_DRIVER_CHECK_EXT],[
+ AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+ SAVE_CFLAGS="$CFLAGS"
+- CFLAGS="$CFLAGS -I`$PKG_CONFIG --variable=sdkdir xorg-server`"
++ CFLAGS="$CFLAGS -I$PKG_CONFIG_SYSROOT_DIR`$PKG_CONFIG --variable=sdkdir xorg-server`"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include "xorg-server.h"
+ #if !defined $1
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/nodolt.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/nodolt.patch
new file mode 100644
index 0000000..9cd7f93
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/nodolt.patch
@@ -0,0 +1,14 @@
+Upstream-Status: Inappropriate [configuration]
+
+Index: git/configure.ac
+===================================================================
+--- git.orig/configure.ac 2009-01-15 20:35:31.000000000 +0000
++++ git/configure.ac 2009-01-15 20:35:38.000000000 +0000
+@@ -62,7 +62,6 @@
+ AC_LIBTOOL_WIN32_DLL
+ AC_DISABLE_STATIC
+ AC_PROG_LIBTOOL
+-DOLT
+ AC_PROG_MAKE_SET
+ PKG_PROG_PKG_CONFIG
+ AC_PROG_LEX
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/ptr-to-int-cast-fix.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/ptr-to-int-cast-fix.patch
new file mode 100644
index 0000000..705cffc
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/ptr-to-int-cast-fix.patch
@@ -0,0 +1,92 @@
+Upstream-Status: Inappropriate [already upstream]
+
+It's broken for devices with BARs above 4G, and the sysfs method should
+work everywhere anyway. As a pleasant side effect, this fixes some
+warnings:
+
+fbdevhw.c: In function 'fbdev_open_pci':
+fbdevhw.c:333:4: warning: cast from pointer to integer of different size
+fbdevhw.c:334:4: warning: cast from pointer to integer of different size
+fbdevhw.c:336:4: warning: cast from pointer to integer of different size
+fbdevhw.c:337:4: warning: cast from pointer to integer of different size
+
+Signed-off-by: Adam Jackson <ajax (a] redhat.com>
+Integrated-by: Tom Zanussi <tom.zanussi (a] intel.com>
+
+Index: xorg-server-1.9.3/hw/xfree86/fbdevhw/fbdevhw.c
+===================================================================
+--- xorg-server-1.9.3.orig/hw/xfree86/fbdevhw/fbdevhw.c 2012-01-12 10:32:07.097729262 -0600
++++ xorg-server-1.9.3/hw/xfree86/fbdevhw/fbdevhw.c 2012-01-12 10:32:55.076732780 -0600
+@@ -291,14 +291,7 @@
+ {
+ struct fb_fix_screeninfo fix;
+ char filename[256];
+- int fd,i,j;
+-
+-
+- /* There are two ways to that we can determine which fb device is
+- * associated with this PCI device. The more modern way is to look in
+- * the sysfs directory for the PCI device for a file named
+- * "graphics/fb*"
+- */
++ int fd, i;
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,
+@@ -331,55 +324,10 @@
+ }
+ }
+
+-
+- /* The other way is to examine the resources associated with each fb
+- * device and see if there is a match with the PCI device. This technique
+- * has some problems on certain mixed 64-bit / 32-bit architectures.
+- * There is a flaw in the fb_fix_screeninfo structure in that it only
+- * returns the low 32-bits of the address of the resources associated with
+- * a device. However, on a mixed architecture the base addresses of PCI
+- * devices, even for 32-bit applications, may be higher than 0x0f0000000.
+- */
+-
+- for (i = 0; i < 8; i++) {
+- sprintf(filename,"/dev/fb%d",i);
+- if (-1 == (fd = open(filename,O_RDWR,0))) {
+- xf86DrvMsg(-1, X_WARNING,
+- "open %s: %s\n", filename, strerror(errno));
+- continue;
+- }
+- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
+- close(fd);
+- continue;
+- }
+- for (j = 0; j < 6; j++) {
+- const pciaddr_t res_start = pPci->regions[j].base_addr;
+- const pciaddr_t res_end = res_start + pPci->regions[j].size;
+-
+- if ((0 != fix.smem_len &&
+- (pciaddr_t) fix.smem_start >= res_start &&
+- (pciaddr_t) fix.smem_start < res_end) ||
+- (0 != fix.mmio_len &&
+- (pciaddr_t) fix.mmio_start >= res_start &&
+- (pciaddr_t) fix.mmio_start < res_end))
+- break;
+- }
+- if (j == 6) {
+- close(fd);
+- continue;
+- }
+- if (namep) {
+- *namep = xnfalloc(16);
+- strncpy(*namep,fix.id,16);
+- }
+- return fd;
+- }
+-
+ if (namep)
+ *namep = NULL;
+
+- xf86DrvMsg(-1, X_ERROR,
+- "Unable to find a valid framebuffer device\n");
++ xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n");
+ return -1;
+ }
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/werror-address-fix.patch b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/werror-address-fix.patch
new file mode 100644
index 0000000..49d3f94
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg-1.9.3/werror-address-fix.patch
@@ -0,0 +1,49 @@
+Upstream-Status: Inappropriate [yocto-specific]
+
+This is fixed upstream by actually making these tests meaningful.
+As they stand, the warning is correct and they're no-ops, so remove
+them.
+
+Signed-off-by: Tom Zanussi <tom.zanussi (a] intel.com>
+
+Index: xorg-server-1.9.3/Xext/xvmc.c
+===================================================================
+--- xorg-server-1.9.3.orig/Xext/xvmc.c 2012-01-12 09:57:36.306947860 -0600
++++ xorg-server-1.9.3/Xext/xvmc.c 2012-01-12 10:24:59.286729946 -0600
+@@ -467,7 +467,6 @@
+ return Success;
+ }
+
+-
+ static int
+ ProcXvMCListSubpictureTypes(ClientPtr client)
+ {
+@@ -487,9 +486,6 @@
+
+ pScreen = pPort->pAdaptor->pScreen;
+
+- if(XvMCScreenKey == NULL) /* No XvMC adaptors */
+- return BadMatch;
+-
+ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
+ return BadMatch; /* None this screen */
+
+@@ -668,9 +664,6 @@
+ {
+ ExtensionEntry *extEntry;
+
+- if(XvMCScreenKey == NULL) /* nobody supports it */
+- return;
+-
+ if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes,
+ "XvMCRTContext")))
+ return;
+@@ -746,8 +739,6 @@
+ XvMCAdaptorPtr adaptor = NULL;
+ int i;
+
+- if(XvMCScreenKey == NULL) return NULL;
+-
+ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
+ return NULL;
+
diff --git a/recipes-graphics/xorg-xserver/xserver-xorg_1.9.3.bb b/recipes-graphics/xorg-xserver/xserver-xorg_1.9.3.bb
new file mode 100644
index 0000000..f62cad2
--- /dev/null
+++ b/recipes-graphics/xorg-xserver/xserver-xorg_1.9.3.bb
@@ -0,0 +1,4 @@
+require recipes-graphics/xorg-xserver/xserver-xorg.inc
+require xserver-xorg-${PV}.inc
+
+PE = "1"
diff --git a/recipes-kernel/linux/linux-yocto_3.10.bbappend b/recipes-kernel/linux/linux-yocto_3.10.bbappend
index a1fb6ac..e1bcc7a 100644
--- a/recipes-kernel/linux/linux-yocto_3.10.bbappend
+++ b/recipes-kernel/linux/linux-yocto_3.10.bbappend
@@ -1,24 +1,25 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-KBRANCH_minnow = "standard/base"
+KERNEL_FEATURES_MINNOW_COMMON = "features/netfilter/netfilter.scc \
+ features/usb-net/usb-net.scc \
+ features/wifi/wifi-all.scc \
+ features/minnow-io/minnow-io.scc \
+ features/media/media-all.scc"
+# Autoload modules for on-board hardware
+KERNEL_MODULE_AUTOLOAD_COMMON = "snd_hda_intel pch_gbe \
+ minnowboard minnowboard-gpio minnowboard-keys"
+
+# MinnowBoard v1 w/ FBDEV Unaccelerated Graphics Driver
COMPATIBLE_MACHINE_minnow = "minnow"
KMACHINE_minnow = "minnow"
-KERNEL_FEATURES_append_minnow = " features/drm-emgd/drm-emgd-1.18 \
- features/netfilter/netfilter.scc \
- features/usb-net/usb-net.scc \
- features/wifi/wifi-all.scc \
- features/minnow-io/minnow-io.scc \
- features/media/media-all.scc \
- "
-
-
-SRC_URI_minnow = "git://git.yoctoproject.org/linux-yocto-3.10;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},emgd-1.18;name=machine,meta,emgd"
+KERNEL_FEATURES_append_minnow = " ${KERNEL_FEATURES_MINNOW_COMMON}"
+KERNEL_MODULE_AUTOLOAD_minnow += "${KERNEL_MODULE_AUTOLOAD_MINNOW_COMMON}"
-
-SRCREV_emgd_pn-linux-yocto_minnow ?= "42d5e4548e8e79e094fa8697949eed4cf6af00a3"
-
-# Autoload modules for on-board hardware
-KERNEL_MODULE_AUTOLOAD_minnow += "snd_hda_intel"
-KERNEL_MODULE_AUTOLOAD_minnow += "pch_gbe"
-KERNEL_MODULE_AUTOLOAD_minnow += "minnowboard minnowboard-gpio minnowboard-keys"
+# MinnowBoard v1 w/ EMGD Proprietary Graphics Driver
+COMPATIBLE_MACHINE_minnow-emgd = "minnow"
+KMACHINE_minnow-emgd = "minnow"
+KERNEL_FEATURES_append_minnow-emgd = " ${KERNEL_FEATURES_MINNOW_COMMON} features/drm-emgd/drm-emgd-1.18"
+SRC_URI_minnow-emgd = "git://git.yoctoproject.org/linux-yocto-3.10;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},emgd-1.18;name=machine,meta,emgd"
+SRCREV_emgd_pn-linux-yocto_minnow-emgd ?= "42d5e4548e8e79e094fa8697949eed4cf6af00a3"
+KERNEL_MODULE_AUTOLOAD_minnow-emgd += "${KERNEL_MODULE_AUTOLOAD_MINNOW_COMMON}"
diff --git a/recipes-multimedia/gstreamer/gst-va-intel.bb b/recipes-multimedia/gstreamer/gst-va-intel.bb
new file mode 100644
index 0000000..5e4dd99
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gst-va-intel.bb
@@ -0,0 +1,56 @@
+DESCRIPTION = "GStreamer Video Acceleration Add-ons for Intel BSPs"
+LICENSE = "MIT"
+DEPENDS = "gst-meta-base"
+LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \
+ file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+PR = "r2"
+
+def map_gst_vaapi(d):
+ if base_contains('MACHINE_FEATURES', 'va-impl-mixvideo', "1", "0", d) == "1":
+ return "gst-va-mixvideo-vaapi"
+ if base_contains('MACHINE_FEATURES', 'va-impl-intel', "1", "0", d) == "1":
+ return "gst-va-intel-vaapi"
+ return ""
+
+VAAPI_IMPL = "${@map_gst_vaapi(d)}"
+
+PACKAGES = "\
+ gst-va-intel \
+ gst-va-intel-general \
+ gst-va-intel-video \
+ ${VAAPI_IMPL} \
+ "
+
+ALLOW_EMPTY_gst-va-intel = "1"
+ALLOW_EMPTY_gst-va-intel-general = "1"
+ALLOW_EMPTY_gst-va-intel-video = "1"
+ALLOW_EMPTY_gst-va-intel-vaapi = "1"
+ALLOW_EMPTY_gst-va-mixvideo-vaapi = "1"
+
+RDEPENDS_gst-va-intel = "\
+ gst-va-intel-general \
+ gst-va-intel-video \
+ ${VAAPI_IMPL} \
+ "
+
+RDEPENDS_gst-va-intel-general = "\
+ ${@bb.utils.contains("LICENSE_FLAGS_WHITELIST", \
+ "commercial", "gst-ffmpeg", "", d)} \
+ "
+
+RDEPENDS_gst-va-intel-video = "\
+ gst-plugins-good-isomp4 \
+ "
+
+# The gstreamer-vaapi package contains the vaapi implementation
+#
+RDEPENDS_gst-va-intel-vaapi = "\
+ gstreamer-vaapi \
+ "
+
+# The emgd driver contains the vaapi implementation
+#
+RDEPENDS_gst-va-mixvideo-vaapi = "\
+ emgd-driver-bin \
+ "
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi-0.10_0.5.8.bb b/recipes-multimedia/gstreamer/gstreamer-vaapi-0.10_0.5.8.bb
new file mode 100644
index 0000000..98e475d
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi-0.10_0.5.8.bb
@@ -0,0 +1,14 @@
+require gstreamer-vaapi.inc
+
+DEPENDS += "gstreamer gst-plugins-base gst-plugins-bad"
+
+GST_API_VERSION = "0.10"
+
+SRC_URI += "file://gstvideoencoder.c file://gstvideoencoder.h"
+
+PACKAGECONFIG_remove = "wayland"
+
+# SRC_URI subdir parameter is broken for files, when fixed do the move there
+do_compile_prepend() {
+ cp -f ${WORKDIR}/gstvideoencoder.[ch] ${S}/ext/videoutils/gst-libs/gst/video/
+}
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi-1.0_0.5.8.bb b/recipes-multimedia/gstreamer/gstreamer-vaapi-1.0_0.5.8.bb
new file mode 100644
index 0000000..886b3c1
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi-1.0_0.5.8.bb
@@ -0,0 +1,5 @@
+require gstreamer-vaapi.inc
+
+DEPENDS += "gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad"
+
+GST_API_VERSION = "1.2"
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi.inc b/recipes-multimedia/gstreamer/gstreamer-vaapi.inc
new file mode 100644
index 0000000..2f5b6f1
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi.inc
@@ -0,0 +1,41 @@
+SUMMARY = "VA-API support to GStreamer"
+DESCRIPTION = "gstreamer-vaapi consists of a collection of VA-API \
+based plugins for GStreamer and helper libraries: `vaapidecode', \
+`vaapiconvert', and `vaapisink'."
+
+REALPN = "gstreamer-vaapi"
+FILESPATH = "${@base_set_filespath(["${FILE_DIRNAME}/${REALPN}", "${FILE_DIRNAME}/${REALPN}"], d)}"
+
+LICENSE = "LGPLv2.1+"
+LIC_FILES_CHKSUM = "file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
+
+DEPENDS = "libva"
+
+SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/${REALPN}/${REALPN}-${PV}.tar.bz2 \
+ file://install-tests.patch"
+
+SRC_URI[md5sum] = "375ddbab556e53ccc311b792f2c649a7"
+SRC_URI[sha256sum] = "24fee8a1ca4cb99ed7739d876b17a4085e81b28550350867dee5105300d343c6"
+
+S = "${WORKDIR}/${REALPN}-${PV}"
+
+inherit autotools pkgconfig gtk-doc
+
+PACKAGES =+ "${PN}-tests"
+
+EXTRA_OECONF += "--with-gstreamer-api=${GST_API_VERSION}"
+
+PACKAGECONFIG ??= "drm \
+ ${@base_contains("DISTRO_FEATURES", "opengl x11", "glx", "", d)} \
+ ${@base_contains("DISTRO_FEATURES", "wayland", "wayland", "", d)} \
+ ${@base_contains("DISTRO_FEATURES", "x11", "x11", "", d)}"
+
+PACKAGECONFIG[drm] = "--enable-drm,--disable-drm,udev libdrm"
+PACKAGECONFIG[glx] = "--enable-glx,--disable-glx,virtual/mesa"
+PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland"
+PACKAGECONFIG[x11] = "--enable-x11,--disable-x11,virtual/libx11 libxrandr libxrender"
+
+FILES_${PN} += "${libdir}/gstreamer-*/*.so"
+FILES_${PN}-dbg += "${libdir}/gstreamer-*/.debug"
+FILES_${PN}-dev += "${libdir}/gstreamer-*/*.la ${libdir}/gstreamer-*/*.a"
+FILES_${PN}-tests = "${bindir}/*"
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.c b/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.c
new file mode 100644
index 0000000..7ca6aab
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.c
@@ -0,0 +1,1712 @@
+/* GStreamer
+ * Copyright (C) 2008 David Schleef <ds@schleef.org>
+ * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
+ * Copyright (C) 2011 Nokia Corporation. All rights reserved.
+ * Contact: Stefan Kost <stefan.kost@nokia.com>
+ * Copyright (C) 2012 Collabora Ltd.
+ * Author : Edward Hervey <edward@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstvideoencoder
+ * @short_description: Base class for video encoders
+ * @see_also:
+ *
+ * This base class is for video encoders turning raw video into
+ * encoded video data.
+ *
+ * GstVideoEncoder and subclass should cooperate as follows.
+ * <orderedlist>
+ * <listitem>
+ * <itemizedlist><title>Configuration</title>
+ * <listitem><para>
+ * Initially, GstVideoEncoder calls @start when the encoder element
+ * is activated, which allows subclass to perform any global setup.
+ * </para></listitem>
+ * <listitem><para>
+ * GstVideoEncoder calls @set_format to inform subclass of the format
+ * of input video data that it is about to receive. Subclass should
+ * setup for encoding and configure base class as appropriate
+ * (e.g. latency). While unlikely, it might be called more than once,
+ * if changing input parameters require reconfiguration. Baseclass
+ * will ensure that processing of current configuration is finished.
+ * </para></listitem>
+ * <listitem><para>
+ * GstVideoEncoder calls @stop at end of all processing.
+ * </para></listitem>
+ * </itemizedlist>
+ * </listitem>
+ * <listitem>
+ * <itemizedlist>
+ * <title>Data processing</title>
+ * <listitem><para>
+ * Base class collects input data and metadata into a frame and hands
+ * this to subclass' @handle_frame.
+ * </para></listitem>
+ * <listitem><para>
+ * If codec processing results in encoded data, subclass should call
+ * @gst_video_encoder_finish_frame to have encoded data pushed
+ * downstream.
+ * </para></listitem>
+ * <listitem><para>
+ * If implemented, baseclass calls subclass @pre_push just prior to
+ * pushing to allow subclasses to modify some metadata on the buffer.
+ * If it returns GST_FLOW_OK, the buffer is pushed downstream.
+ * </para></listitem>
+ * <listitem><para>
+ * GstVideoEncoderClass will handle both srcpad and sinkpad events.
+ * Sink events will be passed to subclass if @event callback has been
+ * provided.
+ * </para></listitem>
+ * </itemizedlist>
+ * </listitem>
+ * <listitem>
+ * <itemizedlist><title>Shutdown phase</title>
+ * <listitem><para>
+ * GstVideoEncoder class calls @stop to inform the subclass that data
+ * parsing will be stopped.
+ * </para></listitem>
+ * </itemizedlist>
+ * </listitem>
+ * </orderedlist>
+ *
+ * Subclass is responsible for providing pad template caps for
+ * source and sink pads. The pads need to be named "sink" and "src". It should
+ * also be able to provide fixed src pad caps in @getcaps by the time it calls
+ * @gst_video_encoder_finish_frame.
+ *
+ * Things that subclass need to take care of:
+ * <itemizedlist>
+ * <listitem><para>Provide pad templates</para></listitem>
+ * <listitem><para>
+ * Provide source pad caps before pushing the first buffer
+ * </para></listitem>
+ * <listitem><para>
+ * Accept data in @handle_frame and provide encoded results to
+ * @gst_video_encoder_finish_frame.
+ * </para></listitem>
+ * </itemizedlist>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* TODO
+ *
+ * * Change _set_output_format() to steal the reference of the provided caps
+ * * Calculate actual latency based on input/output timestamp/frame_number
+ * and if it exceeds the recorded one, save it and emit a GST_MESSAGE_LATENCY
+ */
+
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#include "gstvideoencoder.h"
+#include "gstvideoutils.h"
+
+#include <string.h>
+
+GST_DEBUG_CATEGORY (videoencoder_debug);
+#define GST_CAT_DEFAULT videoencoder_debug
+
+#define GST_VIDEO_ENCODER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_VIDEO_ENCODER, \
+ GstVideoEncoderPrivate))
+
+struct _GstVideoEncoderPrivate
+{
+ guint64 presentation_frame_number;
+ int distance_from_sync;
+
+ /* FIXME : (and introduce a context ?) */
+ gboolean drained;
+ gboolean at_eos;
+
+ gint64 min_latency;
+ gint64 max_latency;
+
+ GList *current_frame_events;
+
+ GList *headers;
+ gboolean new_headers; /* Whether new headers were just set */
+
+ GList *force_key_unit; /* List of pending forced keyunits */
+
+ guint32 system_frame_number;
+
+ GList *frames; /* Protected with OBJECT_LOCK */
+ GstVideoCodecState *input_state;
+ GstVideoCodecState *output_state;
+ gboolean output_state_changed;
+
+ gint64 bytes;
+ gint64 time;
+};
+
+typedef struct _ForcedKeyUnitEvent ForcedKeyUnitEvent;
+struct _ForcedKeyUnitEvent
+{
+ GstClockTime running_time;
+ gboolean pending; /* TRUE if this was requested already */
+ gboolean all_headers;
+ guint count;
+};
+
+static void
+forced_key_unit_event_free (ForcedKeyUnitEvent * evt)
+{
+ g_slice_free (ForcedKeyUnitEvent, evt);
+}
+
+static ForcedKeyUnitEvent *
+forced_key_unit_event_new (GstClockTime running_time, gboolean all_headers,
+ guint count)
+{
+ ForcedKeyUnitEvent *evt = g_slice_new0 (ForcedKeyUnitEvent);
+
+ evt->running_time = running_time;
+ evt->all_headers = all_headers;
+ evt->count = count;
+
+ return evt;
+}
+
+static void gst_video_encoder_finalize (GObject * object);
+
+static gboolean gst_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_video_encoder_sink_getcaps (GstPad * pad);
+static gboolean gst_video_encoder_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_video_encoder_sink_event (GstPad * pad, GstEvent * event);
+static GstFlowReturn gst_video_encoder_chain (GstPad * pad, GstBuffer * buf);
+static GstStateChangeReturn gst_video_encoder_change_state (GstElement *
+ element, GstStateChange transition);
+static const GstQueryType *gst_video_encoder_get_query_types (GstPad * pad);
+static gboolean gst_video_encoder_src_query (GstPad * pad, GstQuery * query);
+static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
+ encoder, GstBuffer * buf, GstClockTime timestamp, GstClockTime duration);
+
+static void
+_do_init (GType object_type)
+{
+ const GInterfaceInfo preset_interface_info = {
+ NULL, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
+ g_type_add_interface_static (object_type, GST_TYPE_PRESET,
+ &preset_interface_info);
+}
+
+GST_BOILERPLATE_FULL (GstVideoEncoder, gst_video_encoder,
+ GstElement, GST_TYPE_ELEMENT, _do_init);
+
+static void
+gst_video_encoder_base_init (gpointer g_class)
+{
+ GST_DEBUG_CATEGORY_INIT (videoencoder_debug, "videoencoder", 0,
+ "Base Video Encoder");
+}
+
+static void
+gst_video_encoder_class_init (GstVideoEncoderClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gstelement_class = GST_ELEMENT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstVideoEncoderPrivate));
+
+ gobject_class->finalize = gst_video_encoder_finalize;
+
+ gstelement_class->change_state =
+ GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);
+}
+
+static void
+gst_video_encoder_reset (GstVideoEncoder * encoder)
+{
+ GstVideoEncoderPrivate *priv = encoder->priv;
+ GList *g;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+
+ priv->presentation_frame_number = 0;
+ priv->distance_from_sync = 0;
+
+ g_list_foreach (priv->force_key_unit, (GFunc) forced_key_unit_event_free,
+ NULL);
+ g_list_free (priv->force_key_unit);
+ priv->force_key_unit = NULL;
+
+ priv->drained = TRUE;
+ priv->min_latency = 0;
+ priv->max_latency = 0;
+
+ g_list_foreach (priv->headers, (GFunc) gst_event_unref, NULL);
+ g_list_free (priv->headers);
+ priv->headers = NULL;
+ priv->new_headers = FALSE;
+
+ g_list_foreach (priv->current_frame_events, (GFunc) gst_event_unref, NULL);
+ g_list_free (priv->current_frame_events);
+ priv->current_frame_events = NULL;
+
+ for (g = priv->frames; g; g = g->next) {
+ gst_video_codec_frame_unref ((GstVideoCodecFrame *) g->data);
+ }
+ g_list_free (priv->frames);
+ priv->frames = NULL;
+
+ priv->bytes = 0;
+ priv->time = 0;
+
+ if (priv->input_state)
+ gst_video_codec_state_unref (priv->input_state);
+ priv->input_state = NULL;
+ if (priv->output_state)
+ gst_video_codec_state_unref (priv->output_state);
+ priv->output_state = NULL;
+
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+}
+
+static void
+gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
+{
+ GstVideoEncoderPrivate *priv;
+ GstPadTemplate *pad_template;
+ GstPad *pad;
+
+ GST_DEBUG_OBJECT (encoder, "gst_video_encoder_init");
+
+ priv = encoder->priv = GST_VIDEO_ENCODER_GET_PRIVATE (encoder);
+
+ pad_template =
+ gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "sink");
+ g_return_if_fail (pad_template != NULL);
+
+ encoder->sinkpad = pad = gst_pad_new_from_template (pad_template, "sink");
+
+ gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_video_encoder_chain));
+ gst_pad_set_event_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_sink_event));
+ gst_pad_set_setcaps_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_sink_setcaps));
+ gst_pad_set_getcaps_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_sink_getcaps));
+ gst_element_add_pad (GST_ELEMENT (encoder), encoder->sinkpad);
+
+ pad_template =
+ gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass), "src");
+ g_return_if_fail (pad_template != NULL);
+
+ encoder->srcpad = pad = gst_pad_new_from_template (pad_template, "src");
+
+ gst_pad_set_query_type_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_get_query_types));
+ gst_pad_set_query_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_src_query));
+ gst_pad_set_event_function (pad,
+ GST_DEBUG_FUNCPTR (gst_video_encoder_src_event));
+ gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad);
+
+ gst_segment_init (&encoder->input_segment, GST_FORMAT_TIME);
+ gst_segment_init (&encoder->output_segment, GST_FORMAT_TIME);
+
+ g_static_rec_mutex_init (&encoder->stream_lock);
+
+ priv->at_eos = FALSE;
+ priv->headers = NULL;
+ priv->new_headers = FALSE;
+
+ gst_video_encoder_reset (encoder);
+}
+
+static gboolean
+gst_video_encoded_video_convert (gint64 bytes, gint64 time,
+ GstFormat src_format, gint64 src_value, GstFormat * dest_format,
+ gint64 * dest_value)
+{
+ gboolean res = FALSE;
+
+ g_return_val_if_fail (dest_format != NULL, FALSE);
+ g_return_val_if_fail (dest_value != NULL, FALSE);
+
+ if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
+ src_value == -1)) {
+ if (dest_value)
+ *dest_value = src_value;
+ return TRUE;
+ }
+
+ if (bytes <= 0 || time <= 0) {
+ GST_DEBUG ("not enough metadata yet to convert");
+ goto exit;
+ }
+
+ switch (src_format) {
+ case GST_FORMAT_BYTES:
+ switch (*dest_format) {
+ case GST_FORMAT_TIME:
+ *dest_value = gst_util_uint64_scale (src_value, time, bytes);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (*dest_format) {
+ case GST_FORMAT_BYTES:
+ *dest_value = gst_util_uint64_scale (src_value, bytes, time);
+ res = TRUE;
+ break;
+ default:
+ res = FALSE;
+ }
+ break;
+ default:
+ GST_DEBUG ("unhandled conversion from %d to %d", src_format,
+ *dest_format);
+ res = FALSE;
+ }
+
+exit:
+ return res;
+}
+
+/**
+ * gst_video_encoder_set_headers:
+ * @encoder: a #GstVideoEncoder
+ * @headers: (transfer full) (element-type GstBuffer): a list of #GstBuffer containing the codec header
+ *
+ * Set the codec headers to be sent downstream whenever requested.
+ *
+ * Since: 0.10.37
+ */
+void
+gst_video_encoder_set_headers (GstVideoEncoder * video_encoder, GList * headers)
+{
+ GST_VIDEO_ENCODER_STREAM_LOCK (video_encoder);
+
+ GST_DEBUG_OBJECT (video_encoder, "new headers %p", headers);
+ if (video_encoder->priv->headers) {
+ g_list_foreach (video_encoder->priv->headers, (GFunc) gst_buffer_unref,
+ NULL);
+ g_list_free (video_encoder->priv->headers);
+ }
+ video_encoder->priv->headers = headers;
+ video_encoder->priv->new_headers = TRUE;
+
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (video_encoder);
+}
+
+static gboolean
+gst_video_encoder_drain (GstVideoEncoder * enc)
+{
+ GstVideoEncoderPrivate *priv;
+ GstVideoEncoderClass *enc_class;
+ gboolean ret = TRUE;
+
+ enc_class = GST_VIDEO_ENCODER_GET_CLASS (enc);
+ priv = enc->priv;
+
+ GST_DEBUG_OBJECT (enc, "draining");
+
+ if (priv->drained) {
+ GST_DEBUG_OBJECT (enc, "already drained");
+ return TRUE;
+ }
+
+ if (enc_class->reset) {
+ GST_DEBUG_OBJECT (enc, "requesting subclass to finish");
+ ret = enc_class->reset (enc, TRUE);
+ }
+ /* everything should be away now */
+ if (priv->frames) {
+ /* not fatal/impossible though if subclass/enc eats stuff */
+ g_list_foreach (priv->frames, (GFunc) gst_video_codec_frame_unref, NULL);
+ g_list_free (priv->frames);
+ priv->frames = NULL;
+ }
+
+ return ret;
+}
+
+static GstVideoCodecState *
+_new_output_state (GstCaps * caps, GstVideoCodecState * reference)
+{
+ GstVideoCodecState *state;
+
+ state = g_slice_new0 (GstVideoCodecState);
+ state->ref_count = 1;
+ gst_video_info_init (&state->info);
+ gst_video_info_set_format (&state->info, GST_VIDEO_FORMAT_ENCODED, 0, 0);
+
+ state->caps = caps;
+
+ if (reference) {
+ GstVideoInfo *tgt, *ref;
+
+ tgt = &state->info;
+ ref = &reference->info;
+
+ /* Copy over extra fields from reference state */
+ tgt->interlace_mode = ref->interlace_mode;
+ tgt->flags = ref->flags;
+ tgt->width = ref->width;
+ tgt->height = ref->height;
+ tgt->chroma_site = ref->chroma_site;
+ tgt->colorimetry = ref->colorimetry;
+ tgt->par_n = ref->par_n;
+ tgt->par_d = ref->par_d;
+ tgt->fps_n = ref->fps_n;
+ tgt->fps_d = ref->fps_d;
+ }
+
+ return state;
+}
+
+static GstVideoCodecState *
+_new_input_state (GstCaps * caps)
+{
+ GstVideoCodecState *state;
+
+ state = g_slice_new0 (GstVideoCodecState);
+ state->ref_count = 1;
+ gst_video_info_init (&state->info);
+ if (G_UNLIKELY (!gst_video_info_from_caps (&state->info, caps)))
+ goto parse_fail;
+ state->caps = gst_caps_ref (caps);
+
+ return state;
+
+parse_fail:
+ {
+ g_slice_free (GstVideoCodecState, state);
+ return NULL;
+ }
+}
+
+static gboolean
+gst_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstVideoEncoder *encoder;
+ GstVideoEncoderClass *encoder_class;
+ GstVideoCodecState *state;
+ gboolean ret;
+ gboolean samecaps = FALSE;
+
+ encoder = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ /* subclass should do something here ... */
+ g_return_val_if_fail (encoder_class->set_format != NULL, FALSE);
+
+ GST_DEBUG_OBJECT (encoder, "setcaps %" GST_PTR_FORMAT, caps);
+
+ state = _new_input_state (caps);
+ if (G_UNLIKELY (!state))
+ goto parse_fail;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+
+ if (encoder->priv->input_state)
+ samecaps =
+ gst_video_info_is_equal (&state->info,
+ &encoder->priv->input_state->info);
+
+ if (!samecaps) {
+ /* arrange draining pending frames */
+ gst_video_encoder_drain (encoder);
+
+ /* and subclass should be ready to configure format at any time around */
+ ret = encoder_class->set_format (encoder, state);
+ if (ret) {
+ if (encoder->priv->input_state)
+ gst_video_codec_state_unref (encoder->priv->input_state);
+ encoder->priv->input_state = state;
+ } else
+ gst_video_codec_state_unref (state);
+ } else {
+ /* no need to stir things up */
+ GST_DEBUG_OBJECT (encoder,
+ "new video format identical to configured format");
+ gst_video_codec_state_unref (state);
+ ret = TRUE;
+ }
+
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ if (!ret)
+ GST_WARNING_OBJECT (encoder, "rejected caps %" GST_PTR_FORMAT, caps);
+
+ gst_object_unref (encoder);
+
+ return ret;
+
+parse_fail:
+ {
+ GST_WARNING_OBJECT (encoder, "Failed to parse caps");
+ gst_object_unref (encoder);
+ return FALSE;
+ }
+}
+
+/**
+ * gst_video_encoder_proxy_getcaps:
+ * @enc: a #GstVideoEncoder
+ * @caps: initial caps
+ *
+ * Returns caps that express @caps (or sink template caps if @caps == NULL)
+ * restricted to resolution/format/... combinations supported by downstream
+ * elements (e.g. muxers).
+ *
+ * Returns: a #GstCaps owned by caller
+ *
+ * Since: 0.10.37
+ */
+GstCaps *
+gst_video_encoder_proxy_getcaps (GstVideoEncoder * encoder, GstCaps * caps)
+{
+ const GstCaps *templ_caps;
+ GstCaps *allowed;
+ GstCaps *fcaps, *filter_caps;
+ gint i, j;
+
+ /* Allow downstream to specify width/height/framerate/PAR constraints
+ * and forward them upstream for video converters to handle
+ */
+ templ_caps = caps ? caps : gst_pad_get_pad_template_caps (encoder->sinkpad);
+ allowed = gst_pad_get_allowed_caps (encoder->srcpad);
+
+ if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
+ fcaps = gst_caps_copy (templ_caps);
+ goto done;
+ }
+
+ GST_LOG_OBJECT (encoder, "template caps %" GST_PTR_FORMAT, templ_caps);
+ GST_LOG_OBJECT (encoder, "allowed caps %" GST_PTR_FORMAT, allowed);
+
+ filter_caps = gst_caps_new_empty ();
+
+ for (i = 0; i < gst_caps_get_size (templ_caps); i++) {
+ GQuark q_name =
+ gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
+
+ for (j = 0; j < gst_caps_get_size (allowed); j++) {
+ const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
+ const GValue *val;
+ GstStructure *s;
+
+ s = gst_structure_id_empty_new (q_name);
+ if ((val = gst_structure_get_value (allowed_s, "width")))
+ gst_structure_set_value (s, "width", val);
+ if ((val = gst_structure_get_value (allowed_s, "height")))
+ gst_structure_set_value (s, "height", val);
+ if ((val = gst_structure_get_value (allowed_s, "framerate")))
+ gst_structure_set_value (s, "framerate", val);
+ if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
+ gst_structure_set_value (s, "pixel-aspect-ratio", val);
+
+ gst_caps_merge_structure (filter_caps, s);
+ }
+ }
+
+ fcaps = gst_caps_intersect (filter_caps, templ_caps);
+ gst_caps_unref (filter_caps);
+
+done:
+ gst_caps_replace (&allowed, NULL);
+
+ GST_LOG_OBJECT (encoder, "proxy caps %" GST_PTR_FORMAT, fcaps);
+
+ return fcaps;
+}
+
+static GstCaps *
+gst_video_encoder_sink_getcaps (GstPad * pad)
+{
+ GstVideoEncoder *encoder;
+ GstVideoEncoderClass *klass;
+ GstCaps *caps;
+
+ encoder = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ if (klass->getcaps)
+ caps = klass->getcaps (encoder);
+ else
+ caps = gst_video_encoder_proxy_getcaps (encoder, NULL);
+
+ GST_LOG_OBJECT (encoder, "Returning caps %" GST_PTR_FORMAT, caps);
+
+ gst_object_unref (encoder);
+
+ return caps;
+}
+
+static void
+gst_video_encoder_finalize (GObject * object)
+{
+ GstVideoEncoder *encoder;
+
+ GST_DEBUG_OBJECT (object, "finalize");
+
+ encoder = GST_VIDEO_ENCODER (object);
+ if (encoder->priv->headers) {
+ g_list_foreach (encoder->priv->headers, (GFunc) gst_buffer_unref, NULL);
+ g_list_free (encoder->priv->headers);
+ }
+ g_static_rec_mutex_free (&encoder->stream_lock);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
+{
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:
+ {
+ gboolean update;
+ double rate;
+ double applied_rate;
+ GstFormat format;
+ gint64 start;
+ gint64 stop;
+ gint64 position;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
+ &format, &start, &stop, &position);
+
+ GST_DEBUG_OBJECT (encoder, "newseg rate %g, applied rate %g, "
+ "format %d, start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
+ ", pos = %" GST_TIME_FORMAT, rate, applied_rate, format,
+ GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
+ GST_TIME_ARGS (position));
+
+ if (format != GST_FORMAT_TIME) {
+ GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ break;
+ }
+
+ gst_segment_set_newsegment_full (&encoder->output_segment, update, rate,
+ applied_rate, format, start, stop, position);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return gst_pad_push_event (encoder->srcpad, event);
+}
+
+static gboolean
+gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
+{
+ GstVideoEncoderClass *encoder_class;
+ gboolean ret = FALSE;
+
+ encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_EOS:
+ {
+ GstFlowReturn flow_ret;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ encoder->priv->at_eos = TRUE;
+
+ if (encoder_class->finish) {
+ flow_ret = encoder_class->finish (encoder);
+ } else {
+ flow_ret = GST_FLOW_OK;
+ }
+
+ ret = (flow_ret == GST_VIDEO_ENCODER_FLOW_DROPPED);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ break;
+ }
+ case GST_EVENT_NEWSEGMENT:
+ {
+ gboolean update;
+ double rate;
+ double applied_rate;
+ GstFormat format;
+ gint64 start;
+ gint64 stop;
+ gint64 position;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
+ &format, &start, &stop, &position);
+
+ GST_DEBUG_OBJECT (encoder, "newseg rate %g, applied rate %g, "
+ "format %d, start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
+ ", pos = %" GST_TIME_FORMAT, rate, applied_rate, format,
+ GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
+ GST_TIME_ARGS (position));
+
+ if (format != GST_FORMAT_TIME) {
+ GST_DEBUG_OBJECT (encoder, "received non TIME newsegment");
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ break;
+ }
+
+ encoder->priv->at_eos = FALSE;
+
+ gst_segment_set_newsegment_full (&encoder->input_segment, update, rate,
+ applied_rate, format, start, stop, position);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ break;
+ }
+ case GST_EVENT_CUSTOM_DOWNSTREAM:
+ {
+ if (gst_video_event_is_force_key_unit (event)) {
+ GstClockTime running_time;
+ gboolean all_headers;
+ guint count;
+
+ if (gst_video_event_parse_downstream_force_key_unit (event,
+ NULL, NULL, &running_time, &all_headers, &count)) {
+ ForcedKeyUnitEvent *fevt;
+
+ GST_OBJECT_LOCK (encoder);
+ fevt = forced_key_unit_event_new (running_time, all_headers, count);
+ encoder->priv->force_key_unit =
+ g_list_append (encoder->priv->force_key_unit, fevt);
+ GST_OBJECT_UNLOCK (encoder);
+
+ GST_DEBUG_OBJECT (encoder,
+ "force-key-unit event: running-time %" GST_TIME_FORMAT
+ ", all_headers %d, count %u",
+ GST_TIME_ARGS (running_time), all_headers, count);
+ }
+ gst_event_unref (event);
+ ret = TRUE;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static gboolean
+gst_video_encoder_sink_event (GstPad * pad, GstEvent * event)
+{
+ GstVideoEncoder *enc;
+ GstVideoEncoderClass *klass;
+ gboolean handled = FALSE;
+ gboolean ret = TRUE;
+
+ enc = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ klass = GST_VIDEO_ENCODER_GET_CLASS (enc);
+
+ GST_DEBUG_OBJECT (enc, "received event %d, %s", GST_EVENT_TYPE (event),
+ GST_EVENT_TYPE_NAME (event));
+
+ if (klass->sink_event)
+ handled = klass->sink_event (enc, event);
+
+ if (!handled)
+ handled = gst_video_encoder_sink_eventfunc (enc, event);
+
+ if (!handled) {
+ /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
+ * For EOS this is required because no buffer or serialized event
+ * will come after EOS and nothing could trigger another
+ * _finish_frame() call. *
+ * If the subclass handles sending of EOS manually it can return
+ * _DROPPED from ::finish() and all other subclasses should have
+ * decoded/flushed all remaining data before this
+ *
+ * For FLUSH_STOP this is required because it is expected
+ * to be forwarded immediately and no buffers are queued anyway.
+ */
+ if (!GST_EVENT_IS_SERIALIZED (event)
+ || GST_EVENT_TYPE (event) == GST_EVENT_EOS
+ || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
+ ret = gst_video_encoder_push_event (enc, event);
+ } else {
+ GST_VIDEO_ENCODER_STREAM_LOCK (enc);
+ enc->priv->current_frame_events =
+ g_list_prepend (enc->priv->current_frame_events, event);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (enc);
+ ret = TRUE;
+ }
+ }
+
+ GST_DEBUG_OBJECT (enc, "event handled");
+
+ gst_object_unref (enc);
+ return ret;
+}
+
+static gboolean
+gst_video_encoder_src_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
+{
+ gboolean handled = FALSE;
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CUSTOM_UPSTREAM:
+ {
+ if (gst_video_event_is_force_key_unit (event)) {
+ GstClockTime running_time;
+ gboolean all_headers;
+ guint count;
+
+ if (gst_video_event_parse_upstream_force_key_unit (event,
+ &running_time, &all_headers, &count)) {
+ ForcedKeyUnitEvent *fevt;
+
+ GST_OBJECT_LOCK (encoder);
+ fevt = forced_key_unit_event_new (running_time, all_headers, count);
+ encoder->priv->force_key_unit =
+ g_list_append (encoder->priv->force_key_unit, fevt);
+ GST_OBJECT_UNLOCK (encoder);
+
+ GST_DEBUG_OBJECT (encoder,
+ "force-key-unit event: running-time %" GST_TIME_FORMAT
+ ", all_headers %d, count %u",
+ GST_TIME_ARGS (running_time), all_headers, count);
+ }
+ gst_event_unref (event);
+ handled = TRUE;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return handled;
+}
+
+static gboolean
+gst_video_encoder_src_event (GstPad * pad, GstEvent * event)
+{
+ GstVideoEncoder *encoder;
+ GstVideoEncoderClass *klass;
+ gboolean ret = FALSE;
+ gboolean handled = FALSE;
+
+ encoder = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);
+
+ if (klass->src_event)
+ handled = klass->src_event (encoder, event);
+
+ if (!handled)
+ handled = gst_video_encoder_src_eventfunc (encoder, event);
+
+ if (!handled)
+ ret = gst_pad_event_default (pad, event);
+
+ gst_object_unref (encoder);
+
+ return ret;
+}
+
+static const GstQueryType *
+gst_video_encoder_get_query_types (GstPad * pad)
+{
+ static const GstQueryType query_types[] = {
+ GST_QUERY_CONVERT,
+ GST_QUERY_LATENCY,
+ 0
+ };
+
+ return query_types;
+}
+
+static gboolean
+gst_video_encoder_src_query (GstPad * pad, GstQuery * query)
+{
+ GstVideoEncoderPrivate *priv;
+ GstVideoEncoder *enc;
+ gboolean res;
+ GstPad *peerpad;
+
+ enc = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ priv = enc->priv;
+ peerpad = gst_pad_get_peer (enc->sinkpad);
+
+ GST_LOG_OBJECT (enc, "handling query: %" GST_PTR_FORMAT, query);
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CONVERT:
+ {
+ GstFormat src_fmt, dest_fmt;
+ gint64 src_val, dest_val;
+
+ gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
+ res =
+ gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
+ src_val, &dest_fmt, &dest_val);
+ if (!res)
+ goto error;
+ gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
+ break;
+ }
+ case GST_QUERY_LATENCY:
+ {
+ gboolean live;
+ GstClockTime min_latency, max_latency;
+
+ res = gst_pad_query (peerpad, query);
+ if (res) {
+ gst_query_parse_latency (query, &live, &min_latency, &max_latency);
+ GST_DEBUG_OBJECT (enc, "Peer latency: live %d, min %"
+ GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
+ GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
+
+ GST_OBJECT_LOCK (enc);
+ min_latency += priv->min_latency;
+ if (enc->priv->max_latency == GST_CLOCK_TIME_NONE) {
+ max_latency = GST_CLOCK_TIME_NONE;
+ } else if (max_latency != GST_CLOCK_TIME_NONE) {
+ max_latency += enc->priv->max_latency;
+ }
+ GST_OBJECT_UNLOCK (enc);
+
+ gst_query_set_latency (query, live, min_latency, max_latency);
+ }
+ }
+ break;
+ default:
+ res = gst_pad_query_default (pad, query);
+ }
+ gst_object_unref (peerpad);
+ gst_object_unref (enc);
+ return res;
+
+error:
+ GST_DEBUG_OBJECT (enc, "query failed");
+ gst_object_unref (peerpad);
+ gst_object_unref (enc);
+ return res;
+}
+
+static GstVideoCodecFrame *
+gst_video_encoder_new_frame (GstVideoEncoder * encoder, GstBuffer * buf,
+ GstClockTime timestamp, GstClockTime duration)
+{
+ GstVideoEncoderPrivate *priv = encoder->priv;
+ GstVideoCodecFrame *frame;
+
+ frame = g_slice_new0 (GstVideoCodecFrame);
+
+ frame->ref_count = 1;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ frame->system_frame_number = priv->system_frame_number;
+ priv->system_frame_number++;
+
+ frame->presentation_frame_number = priv->presentation_frame_number;
+ priv->presentation_frame_number++;
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ frame->events = priv->current_frame_events;
+ priv->current_frame_events = NULL;
+ frame->input_buffer = buf;
+ frame->pts = timestamp;
+ frame->duration = duration;
+
+ if (GST_VIDEO_INFO_IS_INTERLACED (&encoder->priv->input_state->info)) {
+ if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_TFF)) {
+ GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, GST_VIDEO_CODEC_FRAME_FLAG_TFF);
+ } else {
+ GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame, GST_VIDEO_CODEC_FRAME_FLAG_TFF);
+ }
+ if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_RFF)) {
+ GST_VIDEO_CODEC_FRAME_FLAG_SET (frame, GST_VIDEO_CODEC_FRAME_FLAG_RFF);
+ } else {
+ GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame, GST_VIDEO_CODEC_FRAME_FLAG_RFF);
+ }
+ if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_ONEFIELD)) {
+ GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
+ GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD);
+ } else {
+ GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
+ GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD);
+ }
+ }
+
+ return frame;
+}
+
+
+static GstFlowReturn
+gst_video_encoder_chain (GstPad * pad, GstBuffer * buf)
+{
+ GstVideoEncoder *encoder;
+ GstVideoEncoderPrivate *priv;
+ GstVideoEncoderClass *klass;
+ GstVideoCodecFrame *frame;
+ GstFlowReturn ret = GST_FLOW_OK;
+ gint64 start, stop = GST_CLOCK_TIME_NONE, cstart, cstop;
+
+ encoder = GST_VIDEO_ENCODER (gst_pad_get_parent (pad));
+ priv = encoder->priv;
+ klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+
+ /* .... ?? */
+ if (!GST_PAD_CAPS (pad)) {
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ goto done;
+ }
+
+ start = GST_BUFFER_TIMESTAMP (buf);
+ if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buf)))
+ stop = start + GST_BUFFER_DURATION (buf);
+
+ GST_LOG_OBJECT (encoder,
+ "received buffer of size %d with ts %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf),
+ GST_TIME_ARGS (start), GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
+
+ if (priv->at_eos) {
+ ret = GST_FLOW_UNEXPECTED;
+ goto done;
+ }
+
+ /* Drop buffers outside of segment */
+ if (!gst_segment_clip (&encoder->input_segment,
+ GST_FORMAT_TIME, start, stop, &cstart, &cstop)) {
+ GST_DEBUG_OBJECT (encoder, "clipping to segment dropped frame");
+ gst_buffer_unref (buf);
+ goto done;
+ }
+
+ frame = gst_video_encoder_new_frame (encoder, buf, cstart, cstop - cstart);
+
+ GST_OBJECT_LOCK (encoder);
+ if (priv->force_key_unit) {
+ ForcedKeyUnitEvent *fevt = NULL;
+ GstClockTime running_time;
+ GList *l;
+
+ running_time =
+ gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
+ GST_BUFFER_TIMESTAMP (buf));
+
+ for (l = priv->force_key_unit; l; l = l->next) {
+ ForcedKeyUnitEvent *tmp = l->data;
+
+ /* Skip pending keyunits */
+ if (tmp->pending)
+ continue;
+
+ /* Simple case, keyunit ASAP */
+ if (tmp->running_time == GST_CLOCK_TIME_NONE) {
+ fevt = tmp;
+ break;
+ }
+
+ /* Event for before this frame */
+ if (tmp->running_time <= running_time) {
+ fevt = tmp;
+ break;
+ }
+ }
+
+ if (fevt) {
+ GST_DEBUG_OBJECT (encoder,
+ "Forcing a key unit at running time %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (running_time));
+ GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME (frame);
+ if (fevt->all_headers)
+ GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME_HEADERS (frame);
+ fevt->pending = TRUE;
+ }
+ }
+ GST_OBJECT_UNLOCK (encoder);
+
+ priv->frames = g_list_append (priv->frames, frame);
+
+ /* new data, more finish needed */
+ priv->drained = FALSE;
+
+ GST_LOG_OBJECT (encoder, "passing frame pfn %d to subclass",
+ frame->presentation_frame_number);
+
+ gst_video_codec_frame_ref (frame);
+ ret = klass->handle_frame (encoder, frame);
+
+done:
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ gst_object_unref (encoder);
+
+ return ret;
+}
+
+static GstStateChangeReturn
+gst_video_encoder_change_state (GstElement * element, GstStateChange transition)
+{
+ GstVideoEncoder *encoder;
+ GstVideoEncoderClass *encoder_class;
+ GstStateChangeReturn ret;
+
+ encoder = GST_VIDEO_ENCODER (element);
+ encoder_class = GST_VIDEO_ENCODER_GET_CLASS (element);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ /* open device/library if needed */
+ if (encoder_class->open && !encoder_class->open (encoder))
+ goto open_failed;
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ /* Initialize device/library if needed */
+ if (encoder_class->start && !encoder_class->start (encoder))
+ goto start_failed;
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_video_encoder_reset (encoder);
+ if (encoder_class->stop && !encoder_class->stop (encoder))
+ goto stop_failed;
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ /* close device/library if needed */
+ if (encoder_class->close && !encoder_class->close (encoder))
+ goto close_failed;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+
+ /* Errors */
+
+open_failed:
+ {
+ GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
+ ("Failed to open encoder"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+
+start_failed:
+ {
+ GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
+ ("Failed to start encoder"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+
+stop_failed:
+ {
+ GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
+ ("Failed to stop encoder"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+
+close_failed:
+ {
+ GST_ELEMENT_ERROR (encoder, LIBRARY, INIT, (NULL),
+ ("Failed to close encoder"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+}
+
+static gboolean
+gst_video_encoder_set_src_caps (GstVideoEncoder * encoder)
+{
+ gboolean ret;
+ GstVideoCodecState *state = encoder->priv->output_state;
+ GstVideoInfo *info = &state->info;
+
+ g_return_val_if_fail (state->caps != NULL, FALSE);
+
+ if (encoder->priv->output_state_changed) {
+ state->caps = gst_caps_make_writable (state->caps);
+
+ /* Fill caps */
+ gst_caps_set_simple (state->caps, "width", G_TYPE_INT, info->width,
+ "height", G_TYPE_INT, info->height,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION,
+ info->par_n, info->par_d, NULL);
+ if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
+ /* variable fps with a max-framerate */
+ gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION, 0, 1,
+ "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
+ } else {
+ /* no variable fps or no max-framerate */
+ gst_caps_set_simple (state->caps, "framerate", GST_TYPE_FRACTION,
+ info->fps_n, info->fps_d, NULL);
+ }
+ if (state->codec_data)
+ gst_caps_set_simple (state->caps, "codec_data", GST_TYPE_BUFFER,
+ state->codec_data, NULL);
+ encoder->priv->output_state_changed = FALSE;
+ }
+
+ ret = gst_pad_set_caps (encoder->srcpad, state->caps);
+
+ return ret;
+}
+
+/**
+ * gst_video_encoder_finish_frame:
+ * @encoder: a #GstVideoEncoder
+ * @frame: (transfer full): an encoded #GstVideoCodecFrame
+ *
+ * @frame must have a valid encoded data buffer, whose metadata fields
+ * are then appropriately set according to frame data or no buffer at
+ * all if the frame should be dropped.
+ * It is subsequently pushed downstream or provided to @pre_push.
+ * In any case, the frame is considered finished and released.
+ *
+ * Returns: a #GstFlowReturn resulting from sending data downstream
+ *
+ * Since: 0.10.37
+ */
+GstFlowReturn
+gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
+ GstVideoCodecFrame * frame)
+{
+ GstVideoEncoderPrivate *priv = encoder->priv;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstVideoEncoderClass *encoder_class;
+ GList *l;
+ gboolean send_headers = FALSE;
+ gboolean discont = (frame->presentation_frame_number == 0);
+
+ encoder_class = GST_VIDEO_ENCODER_GET_CLASS (encoder);
+
+ GST_LOG_OBJECT (encoder,
+ "finish frame fpn %d", frame->presentation_frame_number);
+
+ GST_LOG_OBJECT (encoder, "frame PTS %" GST_TIME_FORMAT
+ ", DTS %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts),
+ GST_TIME_ARGS (frame->dts));
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+
+ if (G_UNLIKELY (priv->output_state_changed))
+ gst_video_encoder_set_src_caps (encoder);
+
+ if (G_UNLIKELY (priv->output_state == NULL))
+ goto no_output_state;
+
+ /* Push all pending events that arrived before this frame */
+ for (l = priv->frames; l; l = l->next) {
+ GstVideoCodecFrame *tmp = l->data;
+
+ if (tmp->events) {
+ GList *k;
+
+ for (k = g_list_last (tmp->events); k; k = k->prev)
+ gst_video_encoder_push_event (encoder, k->data);
+ g_list_free (tmp->events);
+ tmp->events = NULL;
+ }
+
+ if (tmp == frame)
+ break;
+ }
+
+ /* no buffer data means this frame is skipped/dropped */
+ if (!frame->output_buffer) {
+ GST_DEBUG_OBJECT (encoder, "skipping frame %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (frame->pts));
+ goto done;
+ }
+
+ if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame) && priv->force_key_unit) {
+ GstClockTime stream_time, running_time;
+ GstEvent *ev;
+ ForcedKeyUnitEvent *fevt = NULL;
+ GList *l;
+
+ running_time =
+ gst_segment_to_running_time (&encoder->output_segment, GST_FORMAT_TIME,
+ frame->pts);
+
+ GST_OBJECT_LOCK (encoder);
+ for (l = priv->force_key_unit; l; l = l->next) {
+ ForcedKeyUnitEvent *tmp = l->data;
+
+ /* Skip non-pending keyunits */
+ if (!tmp->pending)
+ continue;
+
+ /* Simple case, keyunit ASAP */
+ if (tmp->running_time == GST_CLOCK_TIME_NONE) {
+ fevt = tmp;
+ break;
+ }
+
+ /* Event for before this frame */
+ if (tmp->running_time <= running_time) {
+ fevt = tmp;
+ break;
+ }
+ }
+
+ if (fevt) {
+ priv->force_key_unit = g_list_remove (priv->force_key_unit, fevt);
+ }
+ GST_OBJECT_UNLOCK (encoder);
+
+ if (fevt) {
+ stream_time =
+ gst_segment_to_stream_time (&encoder->output_segment, GST_FORMAT_TIME,
+ frame->pts);
+
+ ev = gst_video_event_new_downstream_force_key_unit
+ (frame->pts, stream_time, running_time,
+ fevt->all_headers, fevt->count);
+
+ gst_video_encoder_push_event (encoder, ev);
+
+ if (fevt->all_headers)
+ send_headers = TRUE;
+
+ GST_DEBUG_OBJECT (encoder,
+ "Forced key unit: running-time %" GST_TIME_FORMAT
+ ", all_headers %d, count %u",
+ GST_TIME_ARGS (running_time), fevt->all_headers, fevt->count);
+ forced_key_unit_event_free (fevt);
+ }
+ }
+
+ if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
+ priv->distance_from_sync = 0;
+ GST_BUFFER_FLAG_UNSET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ /* For keyframes, DTS = PTS */
+ if (!GST_CLOCK_TIME_IS_VALID (frame->dts)) {
+ frame->dts = frame->pts;
+ } else if (GST_CLOCK_TIME_IS_VALID (frame->pts) && frame->pts != frame->dts) {
+ GST_WARNING_OBJECT (encoder, "keyframe PTS != DTS");
+ }
+ } else {
+ GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ }
+
+ frame->distance_from_sync = priv->distance_from_sync;
+ priv->distance_from_sync++;
+
+ GST_BUFFER_TIMESTAMP (frame->output_buffer) = frame->pts;
+ GST_BUFFER_DURATION (frame->output_buffer) = frame->duration;
+
+ /* update rate estimate */
+ priv->bytes += GST_BUFFER_SIZE (frame->output_buffer);
+ if (GST_CLOCK_TIME_IS_VALID (frame->duration)) {
+ priv->time += frame->duration;
+ } else {
+ /* better none than nothing valid */
+ priv->time = GST_CLOCK_TIME_NONE;
+ }
+
+ if (G_UNLIKELY (send_headers || priv->new_headers)) {
+ GList *tmp, *copy = NULL;
+
+ GST_DEBUG_OBJECT (encoder, "Sending headers");
+
+ /* First make all buffers metadata-writable */
+ for (tmp = priv->headers; tmp; tmp = tmp->next) {
+ GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
+
+ copy = g_list_append (copy, gst_buffer_make_metadata_writable (tmpbuf));
+ }
+ g_list_free (priv->headers);
+ priv->headers = copy;
+
+ for (tmp = priv->headers; tmp; tmp = tmp->next) {
+ GstBuffer *tmpbuf = GST_BUFFER (tmp->data);
+
+ gst_buffer_set_caps (tmpbuf, GST_PAD_CAPS (encoder->srcpad));
+ gst_buffer_ref (tmpbuf);
+ priv->bytes += GST_BUFFER_SIZE (tmpbuf);
+ if (G_UNLIKELY (discont)) {
+ GST_LOG_OBJECT (encoder, "marking discont");
+ GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT);
+ discont = FALSE;
+ }
+
+ gst_pad_push (encoder->srcpad, tmpbuf);
+ }
+ priv->new_headers = FALSE;
+ }
+
+ if (G_UNLIKELY (discont)) {
+ GST_LOG_OBJECT (encoder, "marking discont");
+ GST_BUFFER_FLAG_SET (frame->output_buffer, GST_BUFFER_FLAG_DISCONT);
+ }
+
+ gst_buffer_set_caps (GST_BUFFER (frame->output_buffer),
+ GST_PAD_CAPS (encoder->srcpad));
+
+ if (encoder_class->pre_push)
+ ret = encoder_class->pre_push (encoder, frame);
+
+ if (ret == GST_FLOW_OK)
+ ret = gst_pad_push (encoder->srcpad, frame->output_buffer);
+
+ frame->output_buffer = NULL;
+
+done:
+ /* handed out */
+
+ /* unref once from the list */
+ l = g_list_find (priv->frames, frame);
+ if (l) {
+ gst_video_codec_frame_unref (frame);
+ priv->frames = g_list_delete_link (priv->frames, l);
+ }
+ /* unref because this function takes ownership */
+ gst_video_codec_frame_unref (frame);
+
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return ret;
+
+ /* ERRORS */
+no_output_state:
+ {
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+ GST_ERROR_OBJECT (encoder, "Output state was not configured");
+ return GST_FLOW_ERROR;
+ }
+}
+
+/**
+ * gst_video_encoder_get_output_state:
+ * @encoder: a #GstVideoEncoder
+ *
+ * Get the current #GstVideoCodecState
+ *
+ * Returns: (transfer full): #GstVideoCodecState describing format of video data.
+ *
+ * Since: 0.10.37
+ */
+GstVideoCodecState *
+gst_video_encoder_get_output_state (GstVideoEncoder * encoder)
+{
+ GstVideoCodecState *state;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ state = gst_video_codec_state_ref (encoder->priv->output_state);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return state;
+}
+
+/**
+ * gst_video_encoder_set_output_state:
+ * @encoder: a #GstVideoEncoder
+ * @caps: (transfer full): the #GstCaps to use for the output
+ * @reference: (allow-none) (transfer none): An optional reference @GstVideoCodecState
+ *
+ * Creates a new #GstVideoCodecState with the specified caps as the output state
+ * for the encoder.
+ * Any previously set output state on @decoder will be replaced by the newly
+ * created one.
+ *
+ * The specified @caps should not contain any resolution, pixel-aspect-ratio,
+ * framerate, codec-data, .... Those should be specified instead in the returned
+ * #GstVideoCodecState.
+ *
+ * If the subclass wishes to copy over existing fields (like pixel aspect ratio,
+ * or framerate) from an existing #GstVideoCodecState, it can be provided as a
+ * @reference.
+ *
+ * If the subclass wishes to override some fields from the output state (like
+ * pixel-aspect-ratio or framerate) it can do so on the returned #GstVideoCodecState.
+ *
+ * The new output state will only take effect (set on pads and buffers) starting
+ * from the next call to #gst_video_encoder_finish_frame().
+ *
+ * Returns: (transfer full): the newly configured output state.
+ *
+ * Since: 0.10.37
+ */
+GstVideoCodecState *
+gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps,
+ GstVideoCodecState * reference)
+{
+ GstVideoEncoderPrivate *priv = encoder->priv;
+ GstVideoCodecState *state;
+
+ g_return_val_if_fail (caps != NULL, NULL);
+
+ state = _new_output_state (caps, reference);
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ if (priv->output_state)
+ gst_video_codec_state_unref (priv->output_state);
+ priv->output_state = gst_video_codec_state_ref (state);
+
+ priv->output_state_changed = TRUE;
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return state;
+}
+
+/**
+ * gst_video_encoder_set_latency:
+ * @encoder: a #GstVideoEncoder
+ * @min_latency: minimum latency
+ * @max_latency: maximum latency
+ *
+ * Informs baseclass of encoding latency.
+ *
+ * Since: 0.10.37
+ */
+void
+gst_video_encoder_set_latency (GstVideoEncoder * encoder,
+ GstClockTime min_latency, GstClockTime max_latency)
+{
+ g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
+ g_return_if_fail (max_latency >= min_latency);
+
+ GST_OBJECT_LOCK (encoder);
+ encoder->priv->min_latency = min_latency;
+ encoder->priv->max_latency = max_latency;
+ GST_OBJECT_UNLOCK (encoder);
+
+ gst_element_post_message (GST_ELEMENT_CAST (encoder),
+ gst_message_new_latency (GST_OBJECT_CAST (encoder)));
+}
+
+/**
+ * gst_video_encoder_get_latency:
+ * @encoder: a #GstVideoEncoder
+ * @min_latency: (out) (allow-none): the configured minimum latency
+ * @max_latency: (out) (allow-none): the configured maximum latency
+ *
+ * Returns the configured encoding latency.
+ *
+ * Since: 0.10.37
+ */
+void
+gst_video_encoder_get_latency (GstVideoEncoder * encoder,
+ GstClockTime * min_latency, GstClockTime * max_latency)
+{
+ GST_OBJECT_LOCK (encoder);
+ if (min_latency)
+ *min_latency = encoder->priv->min_latency;
+ if (max_latency)
+ *max_latency = encoder->priv->max_latency;
+ GST_OBJECT_UNLOCK (encoder);
+}
+
+/**
+ * gst_video_encoder_get_oldest_frame:
+ * @encoder: a #GstVideoEncoder
+ *
+ * Get the oldest unfinished pending #GstVideoCodecFrame
+ *
+ * Returns: (transfer full): oldest unfinished pending #GstVideoCodecFrame
+ *
+ * Since: 0.10.37
+ */
+GstVideoCodecFrame *
+gst_video_encoder_get_oldest_frame (GstVideoEncoder * encoder)
+{
+ GstVideoCodecFrame *frame = NULL;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ if (encoder->priv->frames)
+ frame = gst_video_codec_frame_ref (encoder->priv->frames->data);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return (GstVideoCodecFrame *) frame;
+}
+
+/**
+ * gst_video_encoder_get_frame:
+ * @encoder: a #GstVideoEnccoder
+ * @frame_number: system_frame_number of a frame
+ *
+ * Get a pending unfinished #GstVideoCodecFrame
+ *
+ * Returns: (transfer full): pending unfinished #GstVideoCodecFrame identified by @frame_number.
+ *
+ * Since: 0.10.37
+ */
+GstVideoCodecFrame *
+gst_video_encoder_get_frame (GstVideoEncoder * encoder, int frame_number)
+{
+ GList *g;
+ GstVideoCodecFrame *frame = NULL;
+
+ GST_DEBUG_OBJECT (encoder, "frame_number : %d", frame_number);
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ for (g = encoder->priv->frames; g; g = g->next) {
+ GstVideoCodecFrame *tmp = g->data;
+
+ if (tmp->system_frame_number == frame_number) {
+ frame = tmp;
+ gst_video_codec_frame_ref (frame);
+ break;
+ }
+ }
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return frame;
+}
+
+/**
+ * gst_video_encoder_get_frames:
+ * @encoder: a #GstVideoEncoder
+ *
+ * Get all pending unfinished #GstVideoCodecFrame
+ *
+ * Returns: (transfer full) (element-type GstVideoCodecFrame): pending unfinished #GstVideoCodecFrame.
+ */
+GList *
+gst_video_encoder_get_frames (GstVideoEncoder * encoder)
+{
+ GList *frames;
+
+ GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
+ frames = g_list_copy (encoder->priv->frames);
+ g_list_foreach (frames, (GFunc) gst_video_codec_frame_ref, NULL);
+ GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
+
+ return frames;
+}
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.h b/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.h
new file mode 100644
index 0000000..9ae3516
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi/gstvideoencoder.h
@@ -0,0 +1,308 @@
+/* GStreamer
+ * Copyright (C) 2008 David Schleef <ds@schleef.org>
+ * Copyright (C) 2011 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>.
+ * Copyright (C) 2011 Nokia Corporation. All rights reserved.
+ * Contact: Stefan Kost <stefan.kost@nokia.com>
+ * Copyright (C) 2012 Collabora Ltd.
+ * Author : Edward Hervey <edward@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_VIDEO_ENCODER_H_
+#define _GST_VIDEO_ENCODER_H_
+
+#include <gst/video/gstvideoutils.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VIDEO_ENCODER \
+ (gst_video_encoder_get_type())
+#define GST_VIDEO_ENCODER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEO_ENCODER,GstVideoEncoder))
+#define GST_VIDEO_ENCODER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEO_ENCODER,GstVideoEncoderClass))
+#define GST_VIDEO_ENCODER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VIDEO_ENCODER,GstVideoEncoderClass))
+#define GST_IS_VIDEO_ENCODER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_ENCODER))
+#define GST_IS_VIDEO_ENCODER_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_ENCODER))
+#define GST_VIDEO_ENCODER_CAST(enc) ((GstVideoEncoder*)enc)
+
+/**
+ * GST_VIDEO_ENCODER_SINK_NAME:
+ *
+ * The name of the templates for the sink pad.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_SINK_NAME "sink"
+/**
+ * GST_VIDEO_ENCODER_SRC_NAME:
+ *
+ * The name of the templates for the source pad.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_SRC_NAME "src"
+
+/**
+ * GST_VIDEO_ENCODER_FLOW_DROPPED:
+ *
+ * Returned when the event/buffer should be dropped.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS_1
+
+/**
+ * GST_VIDEO_ENCODER_SRC_PAD:
+ * @obj: a #GstVideoEncoder
+ *
+ * Gives the pointer to the source #GstPad object of the element.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_SRC_PAD(obj) (((GstVideoEncoder *) (obj))->srcpad)
+
+/**
+ * GST_VIDEO_ENCODER_SINK_PAD:
+ * @obj: a #GstVideoEncoder
+ *
+ * Gives the pointer to the sink #GstPad object of the element.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_SINK_PAD(obj) (((GstVideoEncoder *) (obj))->sinkpad)
+
+/**
+ * GST_VIDEO_ENCODER_FLOW_NEED_DATA:
+ *
+ * Returned while parsing to indicate more data is needed.
+ *
+ * Since: 0.10.37
+ **/
+#define GST_VIDEO_ENCODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
+
+/**
+ * GST_VIDEO_ENCODER_FLOW_DROPPED:
+ *
+ * Returned when the event/buffer should be dropped.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS_1
+
+/**
+ * GST_VIDEO_ENCODER_INPUT_SEGMENT:
+ * @obj: base parse instance
+ *
+ * Gives the segment of the element.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_INPUT_SEGMENT(obj) (GST_VIDEO_ENCODER_CAST (obj)->input_segment)
+
+/**
+ * GST_VIDEO_ENCODER_OUTPUT_SEGMENT:
+ * @obj: base parse instance
+ *
+ * Gives the segment of the element.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_OUTPUT_SEGMENT(obj) (GST_VIDEO_ENCODER_CAST (obj)->output_segment)
+
+/**
+ * GST_VIDEO_ENCODER_STREAM_LOCK:
+ * @encoder: video encoder instance
+ *
+ * Obtain a lock to protect the encoder function from concurrent access.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_STREAM_LOCK(encoder) g_static_rec_mutex_lock (&GST_VIDEO_ENCODER (encoder)->stream_lock)
+
+/**
+ * GST_VIDEO_ENCODER_STREAM_UNLOCK:
+ * @encoder: video encoder instance
+ *
+ * Release the lock that protects the encoder function from concurrent access.
+ *
+ * Since: 0.10.37
+ */
+#define GST_VIDEO_ENCODER_STREAM_UNLOCK(encoder) g_static_rec_mutex_unlock (&GST_VIDEO_ENCODER (encoder)->stream_lock)
+
+typedef struct _GstVideoEncoder GstVideoEncoder;
+typedef struct _GstVideoEncoderPrivate GstVideoEncoderPrivate;
+typedef struct _GstVideoEncoderClass GstVideoEncoderClass;
+
+/**
+ * GstVideoEncoder:
+ *
+ * The opaque #GstVideoEncoder data structure.
+ *
+ * Since: 0.10.37
+ */
+struct _GstVideoEncoder
+{
+ /*< private >*/
+ GstElement element;
+
+ /*< protected >*/
+ GstPad *sinkpad;
+ GstPad *srcpad;
+
+ /* protects all data processing, i.e. is locked
+ * in the chain function, finish_frame and when
+ * processing serialized events */
+ GStaticRecMutex stream_lock;
+
+ /* MT-protected (with STREAM_LOCK) */
+ GstSegment input_segment;
+ GstSegment output_segment;
+
+ GstVideoEncoderPrivate *priv;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+/**
+ * GstVideoEncoderClass:
+ * @open: Optional.
+ * Called when the element changes to GST_STATE_READY.
+ * Allows opening external resources. Since: 0.10.37.
+ * @close: Optional.
+ * Called when the element changes to GST_STATE_NULL.
+ * Allows closing external resources. Since: 0.10.37.
+ * @start: Optional.
+ * Called when the element starts processing.
+ * Allows opening external resources.
+ * @stop: Optional.
+ * Called when the element stops processing.
+ * Allows closing external resources.
+ * @set_format: Optional.
+ * Notifies subclass of incoming data format.
+ * GstVideoCodecState fields have already been
+ * set according to provided caps.
+ * @handle_frame: Provides input frame to subclass.
+ * @reset: Optional.
+ * Allows subclass (encoder) to perform post-seek semantics reset.
+ * @finish: Optional.
+ * Called to request subclass to dispatch any pending remaining
+ * data (e.g. at EOS).
+ * @pre_push: Optional.
+ * Allows subclass to push frame downstream in whatever
+ * shape or form it deems appropriate. If not provided,
+ * provided encoded frame data is simply pushed downstream.
+ * @getcaps: Optional.
+ * Allows for a custom sink getcaps implementation (e.g.
+ * for multichannel input specification). If not implemented,
+ * default returns gst_video_encoder_proxy_getcaps
+ * applied to sink template caps.
+ * @sink_event: Optional.
+ * Event handler on the sink pad. This function should return
+ * TRUE if the event was handled and should be discarded
+ * (i.e. not unref'ed).
+ * @src_event: Optional.
+ * Event handler on the source pad. This function should return
+ * TRUE if the event was handled and should be discarded
+ * (i.e. not unref'ed).
+ *
+ * Subclasses can override any of the available virtual methods or not, as
+ * needed. At minimum @handle_frame needs to be overridden, and @set_format
+ * and @get_caps are likely needed as well.
+ *
+ * Since: 0.10.37
+ */
+struct _GstVideoEncoderClass
+{
+ /*< private >*/
+ GstElementClass element_class;
+
+ /*< public >*/
+ /* virtual methods for subclasses */
+ gboolean (*open) (GstVideoEncoder *encoder);
+
+ gboolean (*close) (GstVideoEncoder *encoder);
+
+ gboolean (*start) (GstVideoEncoder *encoder);
+
+ gboolean (*stop) (GstVideoEncoder *encoder);
+
+ gboolean (*set_format) (GstVideoEncoder *encoder,
+ GstVideoCodecState *state);
+
+ GstFlowReturn (*handle_frame) (GstVideoEncoder *encoder,
+ GstVideoCodecFrame *frame);
+
+ gboolean (*reset) (GstVideoEncoder *encoder,
+ gboolean hard);
+
+ GstFlowReturn (*finish) (GstVideoEncoder *encoder);
+
+ GstFlowReturn (*pre_push) (GstVideoEncoder *encoder,
+ GstVideoCodecFrame *frame);
+
+ GstCaps * (*getcaps) (GstVideoEncoder *enc);
+
+ gboolean (*sink_event) (GstVideoEncoder *encoder,
+ GstEvent *event);
+
+ gboolean (*src_event) (GstVideoEncoder *encoder,
+ GstEvent *event);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING_LARGE];
+};
+
+GType gst_video_encoder_get_type (void);
+
+GstVideoCodecState* gst_video_encoder_get_output_state (GstVideoEncoder *encoder);
+
+GstVideoCodecState* gst_video_encoder_set_output_state (GstVideoEncoder * encoder,
+ GstCaps * caps,
+ GstVideoCodecState * reference);
+
+GstVideoCodecFrame* gst_video_encoder_get_frame (GstVideoEncoder *encoder,
+ int frame_number);
+GstVideoCodecFrame* gst_video_encoder_get_oldest_frame (GstVideoEncoder *encoder);
+
+GList * gst_video_encoder_get_frames (GstVideoEncoder *encoder);
+
+GstFlowReturn gst_video_encoder_finish_frame (GstVideoEncoder *encoder,
+ GstVideoCodecFrame *frame);
+
+GstCaps * gst_video_encoder_proxy_getcaps (GstVideoEncoder * enc,
+ GstCaps * caps);
+void gst_video_encoder_set_discont (GstVideoEncoder *encoder);
+gboolean gst_video_encoder_get_discont (GstVideoEncoder *encoder);
+
+void gst_video_encoder_set_latency (GstVideoEncoder *encoder,
+ GstClockTime min_latency,
+ GstClockTime max_latency);
+void gst_video_encoder_get_latency (GstVideoEncoder *encoder,
+ GstClockTime *min_latency,
+ GstClockTime *max_latency);
+
+void gst_video_encoder_set_headers (GstVideoEncoder *encoder,
+ GList *headers);
+G_END_DECLS
+
+#endif
+
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi/install-tests.patch b/recipes-multimedia/gstreamer/gstreamer-vaapi/install-tests.patch
new file mode 100644
index 0000000..9281b04
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi/install-tests.patch
@@ -0,0 +1,31 @@
+Install tests.
+
+Upstream-Status: Inappropriate
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+
+---
+ tests/Makefile.am | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 2e7f191..8f65446 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -1,4 +1,4 @@
+-noinst_PROGRAMS = \
++bin_PROGRAMS = \
+ simple-decoder \
+ test-decode \
+ test-display \
+@@ -9,7 +9,7 @@ noinst_PROGRAMS = \
+ $(NULL)
+
+ if USE_GLX
+-noinst_PROGRAMS += \
++bin_PROGRAMS += \
+ test-textures \
+ $(NULL)
+ endif
+--
+1.7.10.4
+
diff --git a/recipes-multimedia/gstreamer/gstreamer-vaapi_0.4.3.bb b/recipes-multimedia/gstreamer/gstreamer-vaapi_0.4.3.bb
new file mode 100644
index 0000000..93e0fbc
--- /dev/null
+++ b/recipes-multimedia/gstreamer/gstreamer-vaapi_0.4.3.bb
@@ -0,0 +1,24 @@
+SUMMARY = "VA-API support to GStreamer"
+DESCRIPTION = "gstreamer-vaapi consists of a collection of VA-API \
+based plugins for GStreamer and helper libraries: `vaapidecode', \
+`vaapiconvert', and `vaapisink'."
+
+LICENSE = "LGPLv2.1+"
+LIC_FILES_CHKSUM = "file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"
+
+DEPENDS = "gstreamer gst-plugins-base gst-plugins-bad libva"
+
+SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/${BPN}/${BPN}-${PV}.tar.bz2"
+SRC_URI[md5sum] = "7b1ede7193bc5a0aca921c490684f7b5"
+SRC_URI[sha256sum] = "68e0598456fe17085f6b8b1ce3da066322cc02c363955fb319776a5404d2b0da"
+
+inherit autotools pkgconfig gtk-doc
+
+PACKAGECONFIG ??= "${@base_contains("DISTRO_FEATURES", "x11", "x11", "", d)} \
+ ${@base_contains("DISTRO_FEATURES", "wayland", "wayland", "", d)}"
+PACKAGECONFIG[x11] = "--enable-x11,--disable-x11,virtual/libx11 libxrandr"
+PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland"
+
+FILES_${PN} += "${libdir}/gstreamer-0.10/*.so"
+FILES_${PN}-dbg += "${libdir}/gstreamer-0.10/.debug"
+FILES_${PN}-dev += "${libdir}/gstreamer-0.10/*.la ${libdir}/gstreamer-0.10/*.a"
diff --git a/recipes-multimedia/libva/libva-intel-driver/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch b/recipes-multimedia/libva/libva-intel-driver/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch
new file mode 100644
index 0000000..e000632
--- /dev/null
+++ b/recipes-multimedia/libva/libva-intel-driver/0001-Workaround-for-concurrently-playing-VC1-and-H264-vid.patch
@@ -0,0 +1,440 @@
+Upstream-Status: Pending
+
+From 43c3fd3ea485a0b9ad12c248a0a94a959ab4d5ee Mon Sep 17 00:00:00 2001
+From: "Xiang, Haihao" <haihao.xiang@intel.com>
+Date: Mon, 29 Oct 2012 10:01:16 +0800
+Subject: [PATCH] Workaround for concurrently playing VC1 and H264 video on SNB
+
+Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
+---
+ src/gen6_mfd.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/gen6_mfd.h | 3 +
+ 2 files changed, 380 insertions(+), 2 deletions(-)
+
+diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
+index fa2f128..b8c671b 100755
+--- a/src/gen6_mfd.c
++++ b/src/gen6_mfd.c
+@@ -50,6 +50,377 @@ static const uint32_t zigzag_direct[64] = {
+ 53, 60, 61, 54, 47, 55, 62, 63
+ };
+
++/* Workaround for VC1 decoding */
++
++VAStatus
++i965_DestroySurfaces(VADriverContextP ctx,
++ VASurfaceID *surface_list,
++ int num_surfaces);
++VAStatus
++i965_CreateSurfaces(VADriverContextP ctx,
++ int width,
++ int height,
++ int format,
++ int num_surfaces,
++ VASurfaceID *surfaces);
++
++static struct {
++ int width;
++ int height;
++ int mb_count;
++ unsigned char data[32];
++ int data_size;
++ int data_bit_offset;
++
++ unsigned int f_code:16;
++ unsigned int intra_dc_precision:2;
++ unsigned int picture_structure:2;
++ unsigned int top_field_first:1;
++ unsigned int frame_pred_frame_dct:1;
++ unsigned int concealment_motion_vectors:1;
++ unsigned int q_scale_type:1;
++ unsigned int intra_vlc_format:1;
++ unsigned int alternate_scan:1;
++ unsigned int picture_coding_type:1;
++ unsigned int pad0: 5;
++
++ unsigned int quantiser_scale_code;
++
++ unsigned char qm[2][64];
++} gen6_dwa_clip = {
++ width: 32,
++ height: 16,
++ mb_count: 2,
++ data: {
++ 0x00, 0x00, 0x01, 0x01, 0x1b, 0xfb, 0xfd, 0xf8,
++ 0x02, 0x97, 0xef, 0xf8, 0x8b, 0x97, 0xe0, 0x0a,
++ 0x5f, 0xbf, 0xe2, 0x20, 0x00, 0x00, 0x01, 0x00
++ },
++ data_size: 20,
++ data_bit_offset: 38,
++
++ f_code: 0xffff,
++ intra_dc_precision: 0,
++ picture_structure: 3,
++ top_field_first: 0,
++ frame_pred_frame_dct: 1,
++ concealment_motion_vectors: 0,
++ q_scale_type: 0,
++ intra_vlc_format: 0,
++ alternate_scan: 0,
++ picture_coding_type: 1, /* I frame */
++
++ quantiser_scale_code: 3,
++
++ qm: {
++ {
++ 8, 16, 19, 22, 26, 27, 29, 34,
++ 16, 16, 22, 24, 27, 29, 34, 37,
++ 19, 22, 26, 27, 29, 34, 34, 38,
++ 22, 22, 26, 27, 29, 34, 37, 40,
++ 22, 26, 27, 29, 32, 35, 40, 48,
++ 26, 27, 29, 32, 35, 40, 48, 58,
++ 26, 27, 29, 34, 38, 46, 56, 69,
++ 27, 29, 35, 38, 46, 56, 69, 83
++ },
++
++ {
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ 16, 16, 16, 16, 16, 16, 16, 16,
++ }
++ },
++};
++
++static void
++gen6_dwa_init(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct i965_driver_data *i965 = i965_driver_data(ctx);
++ VAStatus status;
++ struct object_surface *obj_surface;
++
++ if (gen6_mfd_context->dwa_surface_id != VA_INVALID_SURFACE)
++ i965_DestroySurfaces(ctx,
++ &gen6_mfd_context->dwa_surface_id,
++ 1);
++
++ status = i965_CreateSurfaces(ctx,
++ gen6_dwa_clip.width,
++ gen6_dwa_clip.height,
++ VA_RT_FORMAT_YUV420,
++ 1,
++ &gen6_mfd_context->dwa_surface_id);
++ assert(status == VA_STATUS_SUCCESS);
++
++ obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
++ assert(obj_surface);
++ i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
++
++ if (!gen6_mfd_context->dwa_slice_data_bo)
++ dri_bo_unreference(gen6_mfd_context->dwa_slice_data_bo);
++
++ gen6_mfd_context->dwa_slice_data_bo = dri_bo_alloc(i965->intel.bufmgr,
++ "WA data",
++ 0x1000,
++ 0x1000);
++ dri_bo_subdata(gen6_mfd_context->dwa_slice_data_bo,
++ 0,
++ gen6_dwa_clip.data_size,
++ gen6_dwa_clip.data);
++}
++
++static void
++gen6_dwa_pipe_mode_select(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++
++ BEGIN_BCS_BATCH(batch, 4);
++ OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (4 - 2));
++ OUT_BCS_BATCH(batch,
++ (MFD_MODE_VLD << 16) | /* VLD mode */
++ (0 << 10) | /* disable Stream-Out */
++ (0 << 9) | /* Post Deblocking Output */
++ (1 << 8) | /* Pre Deblocking Output */
++ (0 << 7) | /* disable TLB prefectch */
++ (0 << 5) | /* not in stitch mode */
++ (MFX_CODEC_DECODE << 4) | /* decoding mode */
++ (MFX_FORMAT_MPEG2 << 0));
++ OUT_BCS_BATCH(batch,
++ (0 << 20) | /* round flag in PB slice */
++ (0 << 19) | /* round flag in Intra8x8 */
++ (0 << 7) | /* expand NOA bus flag */
++ (1 << 6) | /* must be 1 */
++ (0 << 5) | /* disable clock gating for NOA */
++ (0 << 4) | /* terminate if AVC motion and POC table error occurs */
++ (0 << 3) | /* terminate if AVC mbdata error occurs */
++ (0 << 2) | /* terminate if AVC CABAC/CAVLC decode error occurs */
++ (0 << 1) | /* AVC long field motion vector */
++ (0 << 0)); /* always calculate AVC ILDB boundary strength */
++ OUT_BCS_BATCH(batch, 0);
++ ADVANCE_BCS_BATCH(batch);
++}
++
++static void
++gen6_dwa_surface_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ struct i965_driver_data *i965 = i965_driver_data(ctx);
++ struct object_surface *obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
++
++ BEGIN_BCS_BATCH(batch, 6);
++ OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch,
++ ((obj_surface->orig_width - 1) << 19) |
++ ((obj_surface->orig_height - 1) << 6));
++ OUT_BCS_BATCH(batch,
++ (MFX_SURFACE_PLANAR_420_8 << 28) | /* 420 planar YUV surface */
++ (1 << 27) | /* interleave chroma */
++ (0 << 22) | /* surface object control state, ignored */
++ ((obj_surface->width - 1) << 3) | /* pitch */
++ (0 << 2) | /* must be 0 */
++ (1 << 1) | /* must be tiled */
++ (I965_TILEWALK_YMAJOR << 0)); /* tile walk, must be 1 */
++ OUT_BCS_BATCH(batch,
++ (0 << 16) | /* X offset for U(Cb), must be 0 */
++ (obj_surface->y_cb_offset << 0)); /* Y offset for U(Cb) */
++ OUT_BCS_BATCH(batch,
++ (0 << 16) | /* X offset for V(Cr), must be 0 */
++ (0 << 0)); /* Y offset for V(Cr), must be 0 for video codec */
++ ADVANCE_BCS_BATCH(batch);
++}
++
++static void
++gen6_dwa_pipe_buf_addr_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ struct i965_driver_data *i965 = i965_driver_data(ctx);
++ struct object_surface *obj_surface = SURFACE(gen6_mfd_context->dwa_surface_id);
++ dri_bo *intra_bo;
++ int i;
++
++ intra_bo = dri_bo_alloc(i965->intel.bufmgr,
++ "intra row store",
++ 128 * 64,
++ 0x1000);
++
++ BEGIN_BCS_BATCH(batch, 24);
++ OUT_BCS_BATCH(batch, MFX_PIPE_BUF_ADDR_STATE | (24 - 2));
++ OUT_BCS_RELOC(batch,
++ obj_surface->bo,
++ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
++ 0);
++
++ OUT_BCS_BATCH(batch, 0); /* post deblocking */
++
++ OUT_BCS_BATCH(batch, 0); /* ignore for decoding */
++ OUT_BCS_BATCH(batch, 0); /* ignore for decoding */
++
++ OUT_BCS_RELOC(batch,
++ intra_bo,
++ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
++ 0);
++
++ OUT_BCS_BATCH(batch, 0);
++
++ /* DW 7..22 */
++ for (i = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) {
++ OUT_BCS_BATCH(batch, 0);
++ }
++
++ OUT_BCS_BATCH(batch, 0); /* ignore DW23 for decoding */
++ ADVANCE_BCS_BATCH(batch);
++
++ dri_bo_unreference(intra_bo);
++}
++
++static void
++gen6_dwa_bsp_buf_base_addr_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct i965_driver_data *i965 = i965_driver_data(ctx);
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ dri_bo *bsd_mpc_bo;
++
++ bsd_mpc_bo = dri_bo_alloc(i965->intel.bufmgr,
++ "bsd mpc row store",
++ 11520, /* 1.5 * 120 * 64 */
++ 0x1000);
++
++ BEGIN_BCS_BATCH(batch, 4);
++ OUT_BCS_BATCH(batch, MFX_BSP_BUF_BASE_ADDR_STATE | (4 - 2));
++
++ OUT_BCS_RELOC(batch,
++ bsd_mpc_bo,
++ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
++ 0);
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch, 0);
++ ADVANCE_BCS_BATCH(batch);
++
++ dri_bo_unreference(bsd_mpc_bo);
++}
++
++static void
++gen6_dwa_mpeg2_pic_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ unsigned int width_in_mbs = ALIGN(gen6_dwa_clip.width, 16) / 16;
++ unsigned int height_in_mbs = ALIGN(gen6_dwa_clip.height, 16) / 16;
++
++ BEGIN_BCS_BATCH(batch, 4);
++ OUT_BCS_BATCH(batch, MFX_MPEG2_PIC_STATE | (4 - 2));
++ OUT_BCS_BATCH(batch,
++ gen6_dwa_clip.f_code << 16 |
++ gen6_dwa_clip.intra_dc_precision << 14 |
++ gen6_dwa_clip.picture_structure << 12 |
++ gen6_dwa_clip.top_field_first << 11 |
++ gen6_dwa_clip.frame_pred_frame_dct << 10 |
++ gen6_dwa_clip.concealment_motion_vectors << 9 |
++ gen6_dwa_clip.q_scale_type << 8 |
++ gen6_dwa_clip.intra_vlc_format << 7 |
++ gen6_dwa_clip.alternate_scan << 6);
++ OUT_BCS_BATCH(batch,
++ gen6_dwa_clip.picture_coding_type << 9);
++ OUT_BCS_BATCH(batch,
++ height_in_mbs << 16 |
++ width_in_mbs);
++ ADVANCE_BCS_BATCH(batch);
++}
++
++static void
++gen6_dwa_mpeg2_qm_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ int i;
++
++ for (i = 0; i < 2; i++) {
++ BEGIN_BCS_BATCH(batch, 18);
++ OUT_BCS_BATCH(batch, MFX_MPEG2_QM_STATE | (18 - 2));
++ OUT_BCS_BATCH(batch, i);
++ intel_batchbuffer_data(batch, gen6_dwa_clip.qm[i], 64);
++ ADVANCE_BCS_BATCH(batch);
++ }
++}
++
++static void
++gen6_dwa_ind_obj_base_addr_state(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++
++ BEGIN_BCS_BATCH(batch, 11);
++ OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (11 - 2));
++ OUT_BCS_RELOC(batch,
++ gen6_mfd_context->dwa_slice_data_bo,
++ I915_GEM_DOMAIN_INSTRUCTION, 0,
++ 0);
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
++ OUT_BCS_BATCH(batch, 0);
++ OUT_BCS_BATCH(batch, 0); /* ignore for VLD mode */
++ OUT_BCS_BATCH(batch, 0);
++ ADVANCE_BCS_BATCH(batch);
++}
++
++static void
++gen6_dwa_mpeg2_bsd_object(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++
++ BEGIN_BCS_BATCH(batch, 5);
++ OUT_BCS_BATCH(batch, MFD_MPEG2_BSD_OBJECT | (5 - 2));
++ OUT_BCS_BATCH(batch,
++ gen6_dwa_clip.data_size - (gen6_dwa_clip.data_bit_offset >> 3));
++ OUT_BCS_BATCH(batch, gen6_dwa_clip.data_bit_offset >> 3);
++ OUT_BCS_BATCH(batch,
++ (0 << 24) |
++ (0 << 16) |
++ (gen6_dwa_clip.mb_count << 8) |
++ (1 << 5) |
++ (1 << 3) |
++ (gen6_dwa_clip.data_bit_offset & 0x7));
++ OUT_BCS_BATCH(batch,
++ gen6_dwa_clip.quantiser_scale_code << 24);
++ ADVANCE_BCS_BATCH(batch);
++}
++
++static void
++gen6_mfd_dwa(VADriverContextP ctx,
++ struct gen6_mfd_context *gen6_mfd_context)
++{
++ struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
++ gen6_dwa_init(ctx, gen6_mfd_context);
++ intel_batchbuffer_emit_mi_flush(batch);
++ gen6_dwa_pipe_mode_select(ctx, gen6_mfd_context);
++ gen6_dwa_surface_state(ctx, gen6_mfd_context);
++ gen6_dwa_pipe_buf_addr_state(ctx, gen6_mfd_context);
++ gen6_dwa_bsp_buf_base_addr_state(ctx, gen6_mfd_context);
++ gen6_dwa_mpeg2_qm_state(ctx, gen6_mfd_context);
++ gen6_dwa_mpeg2_pic_state(ctx, gen6_mfd_context);
++ gen6_dwa_ind_obj_base_addr_state(ctx, gen6_mfd_context);
++ gen6_dwa_mpeg2_bsd_object(ctx, gen6_mfd_context);
++}
++
++/* end of workaround */
++
+ static void
+ gen6_mfd_avc_frame_store_index(VADriverContextP ctx,
+ VAPictureParameterBufferH264 *pic_param,
+@@ -1055,7 +1426,8 @@ gen6_mfd_avc_decode_picture(VADriverContextP ctx,
+ }
+ }
+
+- gen6_mfd_avc_phantom_slice(ctx, pic_param, gen6_mfd_context);
++ gen6_mfd_dwa(ctx, gen6_mfd_context);
++
+ intel_batchbuffer_end_atomic(batch);
+ intel_batchbuffer_flush(batch);
+ }
+@@ -1944,6 +2316,8 @@ gen6_mfd_vc1_decode_picture(VADriverContextP ctx,
+ }
+ }
+
++ gen6_mfd_dwa(ctx, gen6_mfd_context);
++
+ intel_batchbuffer_end_atomic(batch);
+ intel_batchbuffer_flush(batch);
+ }
+@@ -2031,6 +2405,7 @@ gen6_dec_hw_context_init(VADriverContextP ctx, VAProfile profile)
+ }
+
+ gen6_mfd_context->wa_mpeg2_slice_vertical_position = -1;
+-
++ gen6_mfd_context->dwa_surface_id = VA_INVALID_ID;
++
+ return (struct hw_context *)gen6_mfd_context;
+ }
+diff --git a/src/gen6_mfd.h b/src/gen6_mfd.h
+index de131d6..7c4a619 100644
+--- a/src/gen6_mfd.h
++++ b/src/gen6_mfd.h
+@@ -72,6 +72,9 @@ struct gen6_mfd_context
+ GenBuffer bitplane_read_buffer;
+
+ int wa_mpeg2_slice_vertical_position;
++
++ VASurfaceID dwa_surface_id;
++ dri_bo *dwa_slice_data_bo;
+ };
+
+ #endif /* _GEN6_MFD_H_ */
+--
+1.7.9.5
+
diff --git a/recipes-multimedia/libva/libva-intel-driver/wayland-include.patch b/recipes-multimedia/libva/libva-intel-driver/wayland-include.patch
new file mode 100644
index 0000000..4a46773
--- /dev/null
+++ b/recipes-multimedia/libva/libva-intel-driver/wayland-include.patch
@@ -0,0 +1,30 @@
+Fix a compile error when building without X11.
+
+Upstream-Status: Submitted
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+
+From a5c44e48dc73b2892f161bd21591c7ee0a3b7842 Mon Sep 17 00:00:00 2001
+From: Ross Burton <ross.burton@intel.com>
+Date: Mon, 21 Oct 2013 16:25:18 +0100
+Subject: [PATCH] i965_output_wayland: add missing include
+
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+---
+ src/i965_output_wayland.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/i965_output_wayland.h b/src/i965_output_wayland.h
+index 61ca39f..acea8d9 100644
+--- a/src/i965_output_wayland.h
++++ b/src/i965_output_wayland.h
+@@ -26,6 +26,7 @@
+ #define I965_OUTPUT_WAYLAND_H
+
+ #include <stdbool.h>
++#include <va/va_backend.h>
+
+ bool
+ i965_output_wayland_init(VADriverContextP ctx);
+--
+1.7.10.4
+
diff --git a/recipes-multimedia/libva/libva-intel-driver_1.3.2.bb b/recipes-multimedia/libva/libva-intel-driver_1.3.2.bb
new file mode 100644
index 0000000..9a44669
--- /dev/null
+++ b/recipes-multimedia/libva/libva-intel-driver_1.3.2.bb
@@ -0,0 +1,31 @@
+SUMMARY = "VA driver for Intel G45 & HD Graphics family"
+DESCRIPTION = "libva-driver-intel is the VA-API implementation \
+for Intel G45 chipsets and Intel HD Graphics for Intel Core \
+processor family."
+
+HOMEPAGE = "http://www.freedesktop.org/wiki/Software/vaapi"
+BUGTRACKER = "https://bugs.freedesktop.org"
+
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://COPYING;md5=2e48940f94acb0af582e5ef03537800f"
+
+COMPATIBLE_HOST = '(i.86|x86_64).*-linux'
+
+DEPENDS = "libva libdrm"
+
+SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/${BPN}/${BPN}-${PV}.tar.bz2"
+SRC_URI += "file://wayland-include.patch"
+
+SRC_URI[md5sum] = "3f4f08f1d42ee451b2fb9c239ee0b8d7"
+SRC_URI[sha256sum] = "11d956ce11cb85bb009c8eb1ebb768403da2cb82675a6d66649f9c49ef4908d1"
+
+inherit autotools pkgconfig
+
+PACKAGECONFIG ??= "${@base_contains("DISTRO_FEATURES", "x11", "x11", "", d)} \
+ ${@base_contains("DISTRO_FEATURES", "opengl wayland", "wayland", "", d)}"
+PACKAGECONFIG[x11] = "--enable-x11,--disable-x11"
+PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland virtual/egl"
+
+FILES_${PN} += "${libdir}/dri/*.so"
+FILES_${PN}-dev += "${libdir}/dri/*.la"
+FILES_${PN}-dbg += "${libdir}/dri/.debug"
diff --git a/recipes-multimedia/libva/libva.inc b/recipes-multimedia/libva/libva.inc
new file mode 100644
index 0000000..f7f5002
--- /dev/null
+++ b/recipes-multimedia/libva/libva.inc
@@ -0,0 +1,46 @@
+SUMMARY = "Video Acceleration (VA) API for Linux"
+DESCRIPTION = "Video Acceleration API (VA API) is a library (libVA) \
+and API specification which enables and provides access to graphics \
+hardware (GPU) acceleration for video processing on Linux and UNIX \
+based operating systems. Accelerated processing includes video \
+decoding, video encoding, subpicture blending and rendering. The \
+specification was originally designed by Intel for its GMA (Graphics \
+Media Accelerator) series of GPU hardware, the API is however not \
+limited to GPUs or Intel specific hardware, as other hardware and \
+manufacturers can also freely use this API for hardware accelerated \
+video decoding."
+
+HOMEPAGE = "http://www.freedesktop.org/wiki/Software/vaapi"
+BUGTRACKER = "https://bugs.freedesktop.org"
+
+SECTION = "x11"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://COPYING;md5=2e48940f94acb0af582e5ef03537800f"
+
+INC_PR = "r1"
+
+DEPENDS = "libdrm virtual/mesa virtual/libgles1 virtual/libgles2 virtual/egl"
+
+inherit autotools-brokensep pkgconfig
+
+EXTRA_OECONF = "--disable-dummy-driver"
+
+PACKAGECONFIG ??= "${@base_contains("DISTRO_FEATURES", "x11", "x11", "", d)} \
+ ${@base_contains("DISTRO_FEATURES", "wayland", "wayland", "", d)}"
+PACKAGECONFIG[x11] = "--enable-x11,--disable-x11,virtual/libx11 libxext libxfixes"
+PACKAGECONFIG[wayland] = "--enable-wayland,--disable-wayland,wayland"
+
+PACKAGES =+ "${PN}-x11 ${PN}-tpi ${PN}-glx ${PN}-egl ${PN}-wayland"
+
+RDEPENDS_${PN}-tpi =+ "${PN}"
+RDEPENDS_${PN}-x11 =+ "${PN}"
+RDEPENDS_${PN}-glx =+ "${PN}-x11"
+RDEPENDS_${PN}-egl =+ "${PN}-x11"
+
+FILES_${PN}-dbg += "${libdir}/dri/.debug"
+
+FILES_${PN}-x11 =+ "${libdir}/libva-x11*${SOLIBS}"
+FILES_${PN}-tpi =+ "${libdir}/libva-tpi*${SOLIBS}"
+FILES_${PN}-glx =+ "${libdir}/libva-glx*${SOLIBS}"
+FILES_${PN}-egl =+ "${libdir}/libva-egl*${SOLIBS}"
+FILES_${PN}-wayland =+ "${libdir}/libva-wayland*${SOLIBS}"
diff --git a/recipes-multimedia/libva/libva_1.0.16.bb b/recipes-multimedia/libva/libva_1.0.16.bb
new file mode 100644
index 0000000..4c8ab14
--- /dev/null
+++ b/recipes-multimedia/libva/libva_1.0.16.bb
@@ -0,0 +1,11 @@
+require libva.inc
+
+PACKAGECONFIG[x11] = ",,virtual/libx11 libxext libxfixes"
+PACKAGECONFIG[wayland] = ",,"
+
+PR = "${INC_PR}.0"
+
+SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/libva/libva-${PV}.tar.bz2"
+
+SRC_URI[md5sum] = "99343b27cf24e99abc0c5db2d09e30c8"
+SRC_URI[sha256sum] = "03e46f8f48f252e6b6112c495745100bc217ddded801fdb393384aab1fafeaa2"
diff --git a/recipes-multimedia/libva/libva_1.3.1.bb b/recipes-multimedia/libva/libva_1.3.1.bb
new file mode 100644
index 0000000..9f80b6d
--- /dev/null
+++ b/recipes-multimedia/libva/libva_1.3.1.bb
@@ -0,0 +1,6 @@
+require libva.inc
+
+SRC_URI = "http://www.freedesktop.org/software/vaapi/releases/libva/${BP}.tar.bz2"
+
+SRC_URI[md5sum] = "eb4db967f068854444b597071c66b480"
+SRC_URI[sha256sum] = "8789b1f1ca9cbc2c1ae477323ec8f5fb269b9360410d4d5e9ec96d679b3cc297" \ No newline at end of file
diff --git a/recipes-multimedia/libva/va-intel.bb b/recipes-multimedia/libva/va-intel.bb
new file mode 100644
index 0000000..57a1609
--- /dev/null
+++ b/recipes-multimedia/libva/va-intel.bb
@@ -0,0 +1,30 @@
+DESCRIPTION = "Video Acceleration Add-ons for Intel BSPs"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \
+ file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+PR = "r1"
+
+def map_valibs(d):
+ # The emgd mixvideo implementation requires libva-x11/tpi/glx/egl
+ if base_contains('MACHINE_FEATURES', 'va-impl-mixvideo', "1", "0", d) == "1":
+ return "libva libva-x11 libva-tpi libva-glx libva-egl"
+ # The intel implementation requires the libva-intel-driver package
+ if base_contains('MACHINE_FEATURES', 'va-impl-intel', "1", "0", d) == "1":
+ return "libva libva-intel-driver"
+ # All meta-intel video acceleration requires libva
+ return "libva"
+
+VA_IMPL = "${@map_valibs(d)}"
+
+PACKAGES = "\
+ va-intel \
+ "
+
+ALLOW_EMPTY_va-intel = "1"
+
+RDEPENDS_va-intel = " \
+ ${VA_IMPL} \
+ "
+
+COMPATIBLE_HOST = '(i.86|x86_64).*-linux*'