├── AUTHORS ├── NEWS ├── README ├── debian ├── compat ├── .gitignore ├── README.source ├── README.Debian ├── rules ├── control ├── copyright └── changelog ├── m4 └── Makefile.am ├── gst-libs ├── Makefile.am └── gst │ ├── Makefile.am │ ├── vpudec │ └── Makefile.am │ ├── glib-compat-private.h │ ├── gst-i18n-plugin.h │ └── gettext.h ├── .gitmodules ├── Makefile.am ├── gst ├── Makefile.am ├── rkximage │ ├── Makefile.am │ ├── rkx_kmsutils.h │ ├── rkx_kmsutils.c │ └── ximagesink.h ├── kms │ ├── Makefile.am │ ├── gstkmsutils.h │ ├── gstkmsbufferpool.h │ ├── gstkmssink.h │ ├── gstkmsallocator.h │ ├── gstkmsbufferpool.c │ ├── gstkmsutils.c │ └── gstkmsallocator.c ├── vpudec │ ├── Makefile.am │ ├── gstvpu.c │ ├── gstvpudecbufferpool.h │ ├── gstvpuallocator.h │ ├── gstvpudec.h │ ├── gstvpuallocator.c │ └── gstvpudecbufferpool.c └── rockchipmpp │ ├── Makefile.am │ ├── gstmpp.c │ ├── gstmpph264enc.h │ ├── gstmppdecbufferpool.h │ ├── gstmppvideodec.h │ ├── gstmppallocator.h │ ├── gstmppvideoenc.h │ ├── gstmpph264enc.c │ ├── gstmppallocator.c │ ├── gstmppdecbufferpool.c │ └── gstmppvideoenc.c ├── README.md ├── .gitignore ├── gstreamer-rockchip.doap ├── autogen.sh ├── configure.ac └── INSTALL /AUTHORS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /m4/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = \ 2 | $(NULL) 3 | -------------------------------------------------------------------------------- /gst-libs/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = gst 2 | 3 | -include $(top_srcdir)/git.mk 4 | -------------------------------------------------------------------------------- /gst-libs/gst/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = vpudec 2 | 3 | -include $(top_srcdir)/git.mk 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "common"] 2 | path = common 3 | url = git://anongit.freedesktop.org/gstreamer/common 4 | -------------------------------------------------------------------------------- /debian/.gitignore: -------------------------------------------------------------------------------- 1 | /*.substvars 2 | /gstreamer1.0-rockchip-dbg 3 | /gstreamer1.0-rockchip1.dirs 4 | /gstreamer1.0-rockchip1 5 | /files 6 | /tmp 7 | /source 8 | /.debhelper 9 | /debhelper-build-stamp 10 | -------------------------------------------------------------------------------- /debian/README.source: -------------------------------------------------------------------------------- 1 | gstreamer-rockchip for Debian 2 | ------------------------------ 3 | 4 | https://github.com/rockchip-linux/gstreamer-rockchip 5 | 6 | -- Randy Li Thu, 17 Nov 2016 07:59:00 +0000 7 | 8 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | gstreamer-rockchip for Debian 2 | ------------------------------ 3 | 4 | gstreamer rockchip is a gstreamer plugin to work with rockchip mpp. 5 | 6 | -- Randy Li Thu, 17 Nov 2016 07:59:00 +0000 7 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = gst-libs gst common m4 2 | 3 | ACLOCAL_AMFLAGS = -I m4 -I common/m4 4 | 5 | include $(top_srcdir)/common/release.mak 6 | 7 | check-valgrind: 8 | cd tests/check && make check-valgrind 9 | 10 | include $(top_srcdir)/common/coverage/lcov.mak 11 | 12 | include $(top_srcdir)/common/cruft.mak 13 | 14 | check: check-exports 15 | 16 | all-local: check-cruft 17 | -------------------------------------------------------------------------------- /gst/Makefile.am: -------------------------------------------------------------------------------- 1 | if USE_ROCKCHIPMPP 2 | ROCKCHIPMPP_DIR=rockchipmpp 3 | else 4 | ROCKCHIPMPP_DIR= 5 | endif 6 | 7 | if USE_VPUDEC 8 | VPUDEC_DIR=vpudec 9 | else 10 | VPUDEC_DIR= 11 | endif 12 | 13 | if USE_KMS 14 | KMS_DIR=kms 15 | else 16 | KMS_DIR= 17 | endif 18 | 19 | if USE_DRMROCKCHIP 20 | RKXIMAGE_DIR=rkximage 21 | else 22 | RKXIMAGE_DIR= 23 | endif 24 | 25 | SUBDIRS = $(ROCKCHIPMPP_DIR) $(VPUDEC_DIR) $(KMS_DIR) $(RKXIMAGE_DIR) 26 | 27 | DIST_SUBDIRS = rockchipmpp vpudec kms rkximage 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gstreamer-rockchip 2 | This plugin depends on gstreamer freamwork 3 | The plugin depends on mpp, libvpu and libdrm2-rockchip 4 | Before build this, make sure you have installed them above 5 | ## build deps 6 | sudo apt install build-essential automake autoconf autopoint libtool pkg-config 7 | sudo apt install libgtk-3-dev liborc-0.4-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev 8 | ## build 9 | ./autogen.sh && make 10 | ## install 11 | sudo make install 12 | ## build a debian package 13 | sudo apt install devscripts debhelper dh-exec 14 | DEB_BUILD_OPTIONS=nocheck debuild -i -nc -us -uc -b -d -aarmhf 15 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | #export DH_VERBOSE = 1 5 | 6 | export DEB_BUILD_OPTIONS=nocheck 7 | 8 | # see FEATURE AREAS in dpkg-buildflags(1) 9 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 10 | 11 | # see ENVIRONMENT in dpkg-buildflags(1) 12 | # package maintainers to append CFLAGS 13 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 14 | # package maintainers to append LDFLAGS 15 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 16 | 17 | %: 18 | dh $@ --with autotools_dev 19 | 20 | 21 | # dh_make generated override targets 22 | # This is example for Cmake (See https://bugs.debian.org/641051 ) 23 | override_dh_auto_configure: 24 | NOCONFIGURE=true ./autogen.sh 25 | dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) 26 | 27 | -------------------------------------------------------------------------------- /gst-libs/gst/vpudec/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = \ 2 | libgstvpu-base.la \ 3 | $(NULL) 4 | 5 | nodist_libgstvpu_base_la_SOURCES = \ 6 | $(NULL) 7 | 8 | libgstvpu_base_la_CFLAGS = \ 9 | $(GST_PLUGINS_BASE_CFLAGS) \ 10 | $(GST_BASE_CFLAGS) \ 11 | $(GST_VIDEO_CFLAGS) \ 12 | $(GST_CFLAGS) \ 13 | $(ROCKCHIP_MPP_CFLAGS) \ 14 | $(ROCKCHIP_VPU_CFLAGS) \ 15 | $(NULL) 16 | 17 | libgstvpu_base_la_LIBADD = \ 18 | $(GST_PLUGINS_BASE_LIBS) \ 19 | $(GST_BASE_LIBS) \ 20 | $(GST_VIDEO_LIBS) \ 21 | $(GST_ALLOCATORS_LIBS) \ 22 | $(GST_LIBS) \ 23 | $(ROCKCHIP_MPP_LIBS) \ 24 | $(ROCKCHIP_VPU_LIBS) \ 25 | $(NULL) 26 | 27 | libgstvpu_base_la_LDFLAGS = \ 28 | $(GST_PLUGIN_LDFLAGS) \ 29 | libgstvpu_base_la_LIBTOOLFLAGS = \ 30 | $(GST_PLUGIN_LIBTOOLFLAGS) \ 31 | $(NUL) 32 | 33 | -include $(top_srcdir)/git.mk 34 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: gstreamer1.0-rockchip 2 | Priority: optional 3 | Maintainer: Randy Li 4 | Build-Depends: 5 | debhelper (>= 9), 6 | autotools-dev, 7 | autopoint, 8 | libtool, 9 | pkg-config, 10 | git, 11 | autoconf, 12 | automake, 13 | libgtk-3-dev, 14 | liborc-0.4-dev, 15 | librockchip-mpp-dev, 16 | libdrm-rockchip1, 17 | libgstreamer1.0-dev, 18 | libgstreamer-plugins-base1.0-dev 19 | Standards-Version: 3.9.8 20 | Section: libs 21 | Homepage: http://www.rock-chips.com/ 22 | #Vcs-Git: https://anonscm.debian.org/collab-maint/gst-plugins-rk-intel.git 23 | #Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/gst-plugins-rk-intel.git 24 | 25 | Package: gstreamer1.0-rockchip1 26 | Architecture: any 27 | Depends: 28 | ${shlibs:Depends}, 29 | ${misc:Depends}, 30 | libgstreamer1.0-0, 31 | libgstreamer-plugins-base1.0-0 32 | Description: The Gstreamer plugins for Rockchip RK3xxx platform. 33 | -------------------------------------------------------------------------------- /gst/rkximage/Makefile.am: -------------------------------------------------------------------------------- 1 | plugin_LTLIBRARIES = libgstrkximage.la 2 | 3 | libgstrkximage_la_SOURCES = \ 4 | ximagesink.c \ 5 | rkx_kmsutils.c \ 6 | $(NULL) 7 | 8 | libgstrkximage_la_CFLAGS = \ 9 | $(X11_CFLAGS) \ 10 | $(DRMROCKCHIP_CFLAGS) \ 11 | $(KMS_DRM_CFLAGS) \ 12 | $(GST_PLUGINS_BASE_CFLAGS) \ 13 | $(GST_BASE_CFLAGS) \ 14 | $(GST_VIDEO_CFLAGS) \ 15 | $(GST_ALLOCATORS_CFLAGS) \ 16 | $(GST_CFLAGS) \ 17 | $(NULL) 18 | 19 | libgstrkximage_la_LIBADD = \ 20 | $(X11_LIBS) \ 21 | $(DRMROCKCHIP_LIBS) \ 22 | $(KMS_DRM_LIBS) \ 23 | $(GST_PLUGINS_BASE_LIBS) \ 24 | $(GST_BASE_LIBS) \ 25 | $(GST_VIDEO_LIBS) \ 26 | $(GST_ALLOCATORS_LIBS) \ 27 | $(GST_LIBS) \ 28 | $(NULL) 29 | 30 | libgstrkximage_la_LDFLAGS = \ 31 | $(GST_PLUGIN_LDFLAGS) \ 32 | $(NULL) 33 | 34 | libgstrkximage_la_LIBTOOLFLAGS = \ 35 | $(GST_PLUGIN_LIBTOOLFLAGS) \ 36 | $(NULL) 37 | -------------------------------------------------------------------------------- /gst/kms/Makefile.am: -------------------------------------------------------------------------------- 1 | plugin_LTLIBRARIES = libgstkmssink.la 2 | 3 | libgstkmssink_la_SOURCES = \ 4 | gstkmssink.c \ 5 | gstkmsutils.c \ 6 | gstkmsallocator.c \ 7 | gstkmsbufferpool.c \ 8 | $(NUL) 9 | 10 | libgstkmssink_la_CFLAGS = \ 11 | $(GST_PLUGINS_BASE_CFLAGS) \ 12 | $(GST_BASE_CFLAGS) \ 13 | $(GST_VIDEO_CFLAGS) \ 14 | $(GST_ALLOCATORS_CFLAGS) \ 15 | $(GST_CFLAGS) \ 16 | $(KMS_DRM_CFLAGS) \ 17 | $(NULL) 18 | 19 | libgstkmssink_la_LIBADD = \ 20 | $(GST_PLUGINS_BASE_LIBS) \ 21 | $(GST_BASE_LIBS) \ 22 | $(GST_VIDEO_LIBS) \ 23 | $(GST_ALLOCATORS_LIBS) \ 24 | $(GST_LIBS) \ 25 | $(KMS_DRM_LIBS) \ 26 | $(NULL) 27 | 28 | libgstkmssink_la_LDFLAGS = \ 29 | $(GST_PLUGIN_LDFLAGS) \ 30 | $(NULL) 31 | 32 | libgstkmssink_la_LIBTOOLFLAGS = \ 33 | $(GST_PLUGIN_LIBTOOLFLAGS) \ 34 | $(NULL) 35 | 36 | noinst_HEADERS = \ 37 | gstkmssink.h \ 38 | gstkmsutils.h \ 39 | gstkmsallocator.h \ 40 | gstkmsbufferpool.h \ 41 | $(NULL) 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | aclocal.m4 2 | autom4te.cache 3 | config.h 4 | config.h.in 5 | config.h-new 6 | config.log 7 | config.status 8 | config.guess 9 | config.sub 10 | config.rpath 11 | config.guess.dh-orig 12 | config.sub.dh-orig 13 | configure 14 | gstreamer-rockchip.spec 15 | libtool 16 | stamp-h 17 | stamp-h.in 18 | stamp-h1 19 | gst-element-check-*.m4 20 | ltmain.sh 21 | missing 22 | mkinstalldirs 23 | compile 24 | install-sh 25 | depcomp 26 | autoregen.sh 27 | ABOUT-NLS 28 | /INSTALL 29 | _stdint.h 30 | gst-plugins-good-*.tar.* 31 | .dirstamp 32 | 33 | /m4 34 | 35 | .deps 36 | .libs 37 | *.lo 38 | *.la 39 | *.o 40 | Makefile.in 41 | Makefile 42 | *~ 43 | *.swp 44 | *.gc?? 45 | 46 | /m4 47 | 48 | /ext/dv/smpte_test 49 | /gst/multifile/test-splitmux-part-reader 50 | /gst/deinterlace/tvtime.h 51 | 52 | tmp-orc.c 53 | *orc.h 54 | 55 | /tests/examples/jack/jack_client 56 | 57 | Build 58 | *.user 59 | *.suo 60 | *.ipch 61 | *.sdf 62 | *.opensdf 63 | *.DS_Store 64 | 65 | /test-driver 66 | *.log 67 | *.trs 68 | 69 | /build 70 | /subprojects 71 | -------------------------------------------------------------------------------- /gst-libs/gst/glib-compat-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * glib-compat.c 3 | * Functions copied from glib 2.10 4 | * 5 | * Copyright 2005 David Schleef 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the 19 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 20 | * Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #ifndef __GLIB_COMPAT_PRIVATE_H__ 24 | #define __GLIB_COMPAT_PRIVATE_H__ 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | /* copies */ 31 | 32 | /* adaptations */ 33 | 34 | G_END_DECLS 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /gst/vpudec/Makefile.am: -------------------------------------------------------------------------------- 1 | plugin_LTLIBRARIES = libgstvpudec.la 2 | 3 | libgstvpudec_la_SOURCES = \ 4 | gstvpu.c \ 5 | gstvpudec.c \ 6 | gstvpudecbufferpool.c \ 7 | gstvpuallocator.c \ 8 | $(NULL) 9 | 10 | libgstvpudec_la_CFLAGS = \ 11 | -I$(top_srcdir)/gst-libs \ 12 | -I$(top_builddir)/gst-libs \ 13 | $(GST_PLUGINS_BASE_CFLAGS) \ 14 | $(GST_BASE_CFLAGS) \ 15 | $(GST_VIDEO_CFLAGS) \ 16 | $(GST_ALLOCATORS_CFLAGS) \ 17 | $(GST_CFLAGS) \ 18 | $(ROCKCHIP_MPP_CFLAGS) \ 19 | $(ROCKCHIP_VPU_CFLAGS) \ 20 | $(NULL) 21 | 22 | libgstvpudec_la_LIBADD = \ 23 | $(top_builddir)/gst-libs/gst/vpudec/libgstvpu-base.la \ 24 | $(GST_PLUGINS_BASE_LIBS) \ 25 | $(GST_BASE_LIBS) \ 26 | $(GST_VIDEO_LIBS) \ 27 | $(GST_ALLOCATORS_LIBS) \ 28 | $(GST_LIBS) \ 29 | $(ROCKCHIP_MPP_LIBS) \ 30 | $(ROCKCHIP_VPU_LIBS) \ 31 | $(NULL) 32 | 33 | libgstvpudec_la_LDFLAGS = \ 34 | $(GST_PLUGIN_LDFLAGS) \ 35 | $(NULL) 36 | 37 | libgstvpudec_la_LIBTOOLFLAGS = \ 38 | $(GST_PLUGIN_LIBTOOLFLAGS) \ 39 | $(NULL) 40 | 41 | noinst_HEADERS = \ 42 | gstvpuallocator.h \ 43 | gstvpudec.h \ 44 | gstvpudecbufferpool.h \ 45 | $(NULL) 46 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #include "gstvpudec.h" 22 | 23 | GST_DEBUG_CATEGORY (CAT_PERFORMANCE); 24 | 25 | static gboolean 26 | plugin_init (GstPlugin * plugin) 27 | { 28 | if (!gst_element_register (plugin, "vpudec", GST_RANK_PRIMARY + 1, 29 | GST_TYPE_VPUDEC)) 30 | return FALSE; 31 | 32 | GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); 33 | 34 | return TRUE; 35 | } 36 | 37 | 38 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 39 | GST_VERSION_MINOR, 40 | vpu, 41 | "VPU decoder", 42 | plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); 43 | -------------------------------------------------------------------------------- /gst/rockchipmpp/Makefile.am: -------------------------------------------------------------------------------- 1 | plugin_LTLIBRARIES = libgstrockchipmpp.la 2 | 3 | libgstrockchipmpp_la_SOURCES = \ 4 | gstmppvideoenc.c \ 5 | gstmpph264enc.c \ 6 | gstmppdecbufferpool.c \ 7 | gstmppallocator.c \ 8 | gstmppvideodec.c \ 9 | gstmpp.c \ 10 | $(NULL) 11 | 12 | libgstrockchipmpp_la_CFLAGS = \ 13 | -I$(top_srcdir)/gst-libs \ 14 | -I$(top_builddir)/gst-libs \ 15 | $(GST_PLUGINS_BASE_CFLAGS) \ 16 | $(GST_BASE_CFLAGS) \ 17 | $(GST_VIDEO_CFLAGS) \ 18 | $(GST_ALLOCATORS_CFLAGS) \ 19 | $(GST_CFLAGS) \ 20 | $(ROCKCHIP_MPP_CFLAGS) \ 21 | $(NULL) 22 | 23 | libgstrockchipmpp_la_LIBADD = \ 24 | $(GST_PLUGINS_BASE_LIBS) \ 25 | $(GST_BASE_LIBS) \ 26 | $(GST_VIDEO_LIBS) \ 27 | $(GST_ALLOCATORS_LIBS) \ 28 | $(GST_LIBS) \ 29 | $(ROCKCHIP_MPP_LIBS) \ 30 | $(NULL) 31 | 32 | libgstrockchipmpp_la_LDFLAGS = \ 33 | $(GST_PLUGIN_LDFLAGS) \ 34 | $(NULL) 35 | 36 | libgstrockchipmpp_la_LIBTOOLFLAGS = \ 37 | $(GST_PLUGIN_LIBTOOLFLAGS) \ 38 | $(NULL) 39 | 40 | noinst_HEADERS = \ 41 | gstmppvideoenc.h \ 42 | gstmpph264enc.h \ 43 | gstmppdecbufferpool.h \ 44 | gstmppallocator.h \ 45 | gstmppvideodec.h \ 46 | $(NULL) 47 | -------------------------------------------------------------------------------- /gst/rkximage/rkx_kmsutils.h: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifndef __RKX_KMS_UTILS_H__ 27 | #define __RKX_KMS_UTILS_H__ 28 | 29 | #include 30 | #include 31 | 32 | G_BEGIN_DECLS 33 | 34 | GstVideoFormat rkx_video_format_from_drm (guint32 drmfmt); 35 | guint32 rkx_drm_format_from_video (GstVideoFormat fmt); 36 | GstCaps * rkx_kms_sink_caps_template_fill (void); 37 | void rkx_video_calculate_device_ratio (guint dev_width, 38 | guint dev_height, 39 | guint dev_width_mm, 40 | guint dev_height_mm, 41 | guint * dpy_par_n, 42 | guint * dpy_par_d); 43 | 44 | G_END_DECLS 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmpp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | #include 25 | #include "gstmpph264enc.h" 26 | #include "gstmppvideodec.h" 27 | 28 | static gboolean 29 | plugin_init (GstPlugin * plugin) 30 | { 31 | if (!gst_element_register (plugin, "mppvideodec", GST_RANK_PRIMARY + 1, 32 | gst_mpp_video_dec_get_type ())) 33 | return FALSE; 34 | 35 | if (!gst_element_register (plugin, "mpph264enc", GST_RANK_PRIMARY + 1, 36 | gst_mpp_h264_enc_get_type ())) 37 | return FALSE; 38 | 39 | return TRUE; 40 | } 41 | 42 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 43 | GST_VERSION_MINOR, 44 | mppvideo, 45 | "Rockchip Mpp Video Plugin", 46 | plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); 47 | -------------------------------------------------------------------------------- /gst/kms/gstkmsutils.h: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifndef __GST_KMS_UTILS_H__ 27 | #define __GST_KMS_UTILS_H__ 28 | 29 | #include 30 | 31 | G_BEGIN_DECLS 32 | 33 | GstVideoFormat gst_video_format_from_drm (guint32 drmfmt); 34 | guint32 gst_drm_format_from_video (GstVideoFormat fmt); 35 | guint32 gst_drm_bpp_from_drm (guint32 drmfmt); 36 | guint32 gst_drm_height_from_drm (guint32 drmfmt, guint32 height); 37 | GstCaps * gst_kms_sink_caps_template_fill (void); 38 | void gst_video_calculate_device_ratio (guint dev_width, 39 | guint dev_height, 40 | guint dev_width_mm, 41 | guint dev_height_mm, 42 | guint * dpy_par_n, 43 | guint * dpy_par_d); 44 | 45 | G_END_DECLS 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /gst-libs/gst/gst-i18n-plugin.h: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * Copyright (C) 2004 Thomas Vander Stichele 3 | * 4 | * gst-i18n-plugins.h: internationalization macros for the GStreamer plugins 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef __GST_I18N_PLUGIN_H__ 23 | #define __GST_I18N_PLUGIN_H__ 24 | 25 | #ifndef GETTEXT_PACKAGE 26 | #error You must define GETTEXT_PACKAGE before including this header. 27 | #endif 28 | 29 | #ifdef ENABLE_NLS 30 | 31 | #include 32 | 33 | #include "gettext.h" /* included with gettext distribution and copied */ 34 | 35 | /* we want to use shorthand _() for translating and N_() for marking */ 36 | #define _(String) dgettext (GETTEXT_PACKAGE, String) 37 | #define N_(String) gettext_noop (String) 38 | /* FIXME: if we need it, we can add Q_ as well, like in glib */ 39 | 40 | #else 41 | #define _(String) String 42 | #define N_(String) String 43 | #define ngettext(Singular,Plural,Count) ((Count>1)?Plural:Singular) 44 | 45 | #endif 46 | 47 | #endif /* __GST_I18N_PLUGIN_H__ */ 48 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: gst-plugins-rk-intel 3 | Source: 4 | 5 | Files: * 6 | Copyright: 7 | 8 | License: 9 | 10 | 11 | . 12 | 13 | 14 | # If you want to use GPL v2 or later for the /debian/* files use 15 | # the following clauses, or change it to suit. Delete these two lines 16 | Files: debian/* 17 | Copyright: 2016 Randy Li 18 | License: GPL-2+ 19 | This package is free software; you can redistribute it and/or modify 20 | it under the terms of the GNU General Public License as published by 21 | the Free Software Foundation; either version 2 of the License, or 22 | (at your option) any later version. 23 | . 24 | This package is distributed in the hope that it will be useful, 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 | GNU General Public License for more details. 28 | . 29 | You should have received a copy of the GNU General Public License 30 | along with this program. If not, see 31 | . 32 | On Debian systems, the complete text of the GNU General 33 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 34 | 35 | # Please also look if there are files or directories which have a 36 | # different copyright/license attached and list them here. 37 | # Please avoid picking licenses with terms that are more restrictive than the 38 | # packaged work, as it may make Debian's contributions unacceptable upstream. 39 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmpph264enc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef __GST_MPP_H264_ENC_H__ 23 | #define __GST_MPP_H264_ENC_H__ 24 | 25 | #include "gstmppvideoenc.h" 26 | 27 | /* Begin Declaration */ 28 | G_BEGIN_DECLS 29 | #define GST_TYPE_MPP_H264_ENC (gst_mpp_h264_enc_get_type()) 30 | #define GST_MPP_H264_ENC(obj) \ 31 | (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPP_H264_ENC, GstMppH264Enc)) 32 | #define GST_MPP_H264_ENC_CLASS(klass) \ 33 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_MPP_H264_ENC, GstMppH264EncClass)) 34 | #define GST_IS_MPP_H264_ENC(obj) \ 35 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_MPP_H264_ENC)) 36 | #define GST_IS_MPP_H264_ENC_CLASS(obj) \ 37 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_MPP_H264_ENC)) 38 | typedef struct _GstMppH264Enc GstMppH264Enc; 39 | typedef struct _GstMppH264EncClass GstMppH264EncClass; 40 | 41 | struct _GstMppH264Enc 42 | { 43 | GstMppVideoEnc parent; 44 | }; 45 | 46 | struct _GstMppH264EncClass 47 | { 48 | GstMppVideoEncClass parent_class; 49 | }; 50 | 51 | GType gst_mpp_h264_enc_get_type (void); 52 | 53 | G_END_DECLS 54 | #endif /* __GST_MPP_H264_ENC_H__ */ 55 | -------------------------------------------------------------------------------- /gstreamer-rockchip.doap: -------------------------------------------------------------------------------- 1 | 7 | 8 | GStreamer Good Plug-ins 9 | gstreamer-rockchip 10 | 11 | 2016-11-23 12 | 13 | a set of rockchip plug-ins under our preferred license, LGPL 14 | 15 | 16 | GStreamer Rockchip is a set of plug-ins that are used for rockchip platform, 17 | under our preferred license (LGPL for 18 | the plug-in code, LGPL or LGPL-compatible for the supporting library). 19 | 20 | 21 | 22 | 23 | 24 | C 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 1.8.3 38 | master 39 | 40 | 2016-11-23 41 | 42 | 43 | 44 | 45 | 46 | 47 | Randy Li 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpudecbufferpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __GST_VPUDEC_BUFFER_POOL_H__ 17 | #define __GST_VPUDEC_BUFFER_POOL_H__ 18 | 19 | #include 20 | 21 | #include "gstvpuallocator.h" 22 | #include "gstvpudec.h" 23 | 24 | G_BEGIN_DECLS typedef struct _GstVpuDecBufferPool GstVpuDecBufferPool; 25 | typedef struct _GstVpuDecBufferPoolClass GstVpuDecBufferPoolClass; 26 | 27 | #define GST_TYPE_VPUDEC_BUFFER_POOL (gst_vpudec_buffer_pool_get_type()) 28 | #define GST_IS_VPUDEC_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VPUDEC_BUFFER_POOL)) 29 | #define GST_VPUDEC_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VPUDEC_BUFFER_POOL, GstVpuDecBufferPool)) 30 | #define GST_VPUDEC_BUFFER_POOL_CAST(obj) ((GstVpuDecBufferPool *)(obj)) 31 | 32 | struct _GstVpuDecBufferPool 33 | { 34 | GstBufferPool parent; 35 | GstVpuDec *dec; 36 | 37 | guint num_queued; /* number of buffers queued in the mpp/libvpu and gstvpudecbufferpool */ 38 | 39 | guint size; 40 | GstBuffer * buffers[VIDEO_MAX_FRAME]; 41 | 42 | GstVpuAllocator *vallocator; 43 | GstAllocator *allocator; 44 | GstAllocationParams params; 45 | }; 46 | 47 | struct _GstVpuDecBufferPoolClass 48 | { 49 | GstBufferPoolClass parent_class; 50 | }; 51 | 52 | GType gst_vpudec_buffer_pool_get_type (void); 53 | 54 | GstBufferPool *gst_vpudec_buffer_pool_new (GstVpuDec * dec, GstCaps * caps); 55 | 56 | G_END_DECLS 57 | #endif /*__GST_VPUDEC_BUFFER_POOL_H__ */ 58 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppdecbufferpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef __GST_MPP_DEC_BUFFER_POOL_H__ 23 | #define __GST_MPP_DEC_BUFFER_POOL_H__ 24 | 25 | #include 26 | 27 | #include "gstmppallocator.h" 28 | #include "gstmppvideodec.h" 29 | 30 | G_BEGIN_DECLS 31 | typedef struct _GstMppDecBufferPool GstMppDecBufferPool; 32 | typedef struct _GstMppDecBufferPoolClass GstMppDecBufferPoolClass; 33 | 34 | #define GST_TYPE_MPP_DEC_BUFFER_POOL (gst_mpp_dec_buffer_pool_get_type()) 35 | #define GST_IS_MPP_DEC_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MPP_DEC_BUFFER_POOL)) 36 | #define GST_MPP_DEC_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MPP_DEC_BUFFER_POOL, GstMppDecBufferPool)) 37 | #define GST_MPP_DEC_BUFFER_POOL_CAST(obj) ((GstMppDecBufferPool *)(obj)) 38 | 39 | struct _GstMppDecBufferPool 40 | { 41 | GstBufferPool parent; 42 | GstMppVideoDec *dec; 43 | 44 | guint num_queued; /* number of buffers queued in the mpp/libvpu and gstvpudecbufferpool */ 45 | 46 | guint size; 47 | GstBuffer * buffers[VIDEO_MAX_FRAME]; 48 | 49 | GstMppAllocator *vallocator; 50 | GstAllocator *allocator; 51 | GstAllocationParams params; 52 | }; 53 | 54 | struct _GstMppDecBufferPoolClass 55 | { 56 | GstBufferPoolClass parent_class; 57 | }; 58 | 59 | GType gst_mpp_dec_buffer_pool_get_type (void); 60 | 61 | GstBufferPool *gst_mpp_dec_buffer_pool_new (GstMppVideoDec * dec, GstCaps * caps); 62 | 63 | G_END_DECLS 64 | #endif /*__GST_MPP_DEC_BUFFER_POOL_H__ */ 65 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpuallocator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef _GST_VPU_MEMORY_H 17 | #define _GST_VPU_MEMORY_H 18 | 19 | #include 20 | #include 21 | 22 | G_BEGIN_DECLS 23 | #define VIDEO_MAX_FRAME 32 24 | #define GST_VPU_MEMORY_QUARK gst_vpu_memory_quark () 25 | #define GST_TYPE_VPU_ALLOCATOR (gst_vpu_allocator_get_type()) 26 | 27 | typedef struct _GstVpuMemory GstVpuMemory; 28 | typedef struct _GstVpuAllocator GstVpuAllocator; 29 | typedef struct _GstVpuAllocatorClass GstVpuAllocatorClass; 30 | 31 | #define GST_VPU_MEMORY_CAST(mem) \ 32 | ((GstVpuMemory *) (mem)) 33 | 34 | struct _GstVpuMemory 35 | { 36 | GstMemory mem; 37 | 38 | /* < private > */ 39 | VPUMemLinear_t *vpu_mem; 40 | gpointer data; 41 | gint dmafd; 42 | gsize size; 43 | }; 44 | 45 | struct _GstVpuAllocator 46 | { 47 | GstAllocator parent; 48 | gboolean active; 49 | 50 | guint32 count; /* number of buffers allocated by the vpu */ 51 | vpu_display_mem_pool *vpu_display_pool; 52 | 53 | GstVpuMemory *mems[VIDEO_MAX_FRAME]; 54 | GstAtomicQueue *free_queue; 55 | }; 56 | 57 | struct _GstVpuAllocatorClass 58 | { 59 | GstAllocatorClass parent_class; 60 | }; 61 | 62 | GType gst_vpu_allocator_get_type (void); 63 | 64 | gboolean gst_is_vpu_memory (GstMemory * mem); 65 | 66 | GQuark gst_vpu_memory_quark (void); 67 | 68 | GstVpuAllocator * 69 | gst_vpu_allocator_new (GstObject * parent); 70 | 71 | guint 72 | gst_vpu_allocator_start (GstVpuAllocator * allocator, 73 | gpointer vpool, gsize size, guint32 count); 74 | 75 | gint 76 | gst_vpu_allocator_stop (GstVpuAllocator * allocator); 77 | 78 | GstMemory * 79 | gst_vpu_allocator_alloc_dmabuf (GstVpuAllocator * allocator, 80 | GstAllocator * dmabuf_allocator); 81 | 82 | 83 | G_END_DECLS 84 | #endif 85 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpudec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef GSTVPUDEC_H 18 | #define GSTVPUDEC_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | /* Begin Declaration */ 28 | G_BEGIN_DECLS 29 | #define GST_TYPE_VPUDEC (gst_vpudec_get_type()) 30 | #define GST_VPUDEC(obj) \ 31 | (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VPUDEC, GstVpuDec)) 32 | #define GST_VPUDEC_CLASS(klass) \ 33 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VPUDEC, GstVpuDecClass)) 34 | #define GST_IS_VPUDEC(obj) \ 35 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VPUDEC)) 36 | #define GST_IS_VPUDEC_CLASS(obj) \ 37 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VPUDEC)) 38 | 39 | typedef struct _GstVpuDec GstVpuDec; 40 | typedef struct _GstVpuDecClass GstVpuDecClass; 41 | 42 | #include "gstvpudecbufferpool.h" 43 | 44 | struct _GstVpuDec 45 | { 46 | GstVideoDecoder parent; 47 | 48 | /* add private members here */ 49 | gint width; 50 | gint height; 51 | gint framesize; 52 | 53 | GstVideoCodecState *input_state; 54 | GstVideoCodecState *output_state; 55 | 56 | /* the currently format */ 57 | GstVideoInfo info; 58 | GstVideoAlignment align; 59 | 60 | /* State */ 61 | gboolean processing; 62 | gboolean active; 63 | GstFlowReturn output_flow; 64 | 65 | /* VPU definitions */ 66 | VpuCodecContext_t *vpu_codec_ctx; 67 | VPUMemLinear_t front_vpumem; 68 | VideoPacket_t access_unit; 69 | 70 | GstBufferPool *pool; /* Pool of output frames */ 71 | }; 72 | 73 | struct _GstVpuDecClass 74 | { 75 | GstVideoDecoderClass parent_class; 76 | }; 77 | 78 | GType gst_vpudec_get_type (void); 79 | 80 | 81 | G_END_DECLS 82 | #endif /* __GST_vpudec_H__ */ 83 | -------------------------------------------------------------------------------- /gst/kms/gstkmsbufferpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * GStreamer 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifndef __GST_KMS_BUFFER_POOL_H__ 27 | #define __GST_KMS_BUFFER_POOL_H__ 28 | 29 | #include 30 | #include 31 | 32 | #include "gstkmssink.h" 33 | 34 | G_BEGIN_DECLS 35 | 36 | /** 37 | * GST_BUFFER_POOL_OPTION_KMS_BUFFER: 38 | * 39 | * An option that can be activated on buffer pool to request KMS 40 | * buffers. 41 | */ 42 | #define GST_BUFFER_POOL_OPTION_KMS_BUFFER "GstBufferPoolOptionKMSBuffer" 43 | 44 | /* video bufferpool */ 45 | typedef struct _GstKMSBufferPool GstKMSBufferPool; 46 | typedef struct _GstKMSBufferPoolClass GstKMSBufferPoolClass; 47 | typedef struct _GstKMSBufferPoolPrivate GstKMSBufferPoolPrivate; 48 | 49 | #define GST_TYPE_KMS_BUFFER_POOL \ 50 | (gst_kms_buffer_pool_get_type()) 51 | #define GST_IS_KMS_BUFFER_POOL(obj) \ 52 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_KMS_BUFFER_POOL)) 53 | #define GST_KMS_BUFFER_POOL(obj) \ 54 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_KMS_BUFFER_POOL, GstKMSBufferPool)) 55 | #define GST_KMS_BUFFER_POOL_CAST(obj) \ 56 | ((GstKMSBufferPool*)(obj)) 57 | 58 | struct _GstKMSBufferPool 59 | { 60 | GstVideoBufferPool parent; 61 | GstKMSBufferPoolPrivate *priv; 62 | }; 63 | 64 | struct _GstKMSBufferPoolClass 65 | { 66 | GstVideoBufferPoolClass parent_class; 67 | }; 68 | 69 | GType gst_kms_buffer_pool_get_type (void) G_GNUC_CONST; 70 | 71 | GstBufferPool *gst_kms_buffer_pool_new (void); 72 | 73 | G_END_DECLS 74 | 75 | #endif /* __GST_KMS_BUFFER_POOL_H__ */ 76 | -------------------------------------------------------------------------------- /gst/kms/gstkmssink.h: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifndef __GST_KMS_SINK_H__ 27 | #define __GST_KMS_SINK_H__ 28 | 29 | #include 30 | 31 | G_BEGIN_DECLS 32 | 33 | #define GST_TYPE_KMS_SINK \ 34 | (gst_kms_sink_get_type()) 35 | #define GST_KMS_SINK(obj) \ 36 | (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_KMS_SINK, GstKMSSink)) 37 | #define GST_KMS_SINK_CLASS(klass) \ 38 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_KMS_SINK, GstKMSSinkClass)) 39 | #define GST_IS_KMS_SINK(obj) \ 40 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_KMS_SINK)) 41 | #define GST_IS_KMS_SINK_CLASS(klass) \ 42 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_KMS_SINK)) 43 | 44 | typedef struct _GstKMSSink GstKMSSink; 45 | typedef struct _GstKMSSinkClass GstKMSSinkClass; 46 | 47 | struct _GstKMSSink { 48 | GstVideoSink videosink; 49 | 50 | /*< private >*/ 51 | gint fd; 52 | gint conn_id; 53 | gint crtc_id; 54 | gint plane_id; 55 | guint pipe; 56 | 57 | /* crtc data */ 58 | guint16 hdisplay, vdisplay; 59 | guint32 buffer_id; 60 | 61 | /* capabilities */ 62 | gboolean has_prime_import; 63 | gboolean has_async_page_flip; 64 | 65 | gboolean modesetting_enabled; 66 | 67 | GstVideoInfo vinfo; 68 | GstCaps *allowed_caps; 69 | GstBufferPool *pool; 70 | GstAllocator *allocator; 71 | GstBuffer *last_buffer; 72 | GstMemory *tmp_kmsmem; 73 | 74 | gchar *devname; 75 | 76 | guint32 mm_width, mm_height; 77 | 78 | GstPoll *poll; 79 | GstPollFD pollfd; 80 | }; 81 | 82 | struct _GstKMSSinkClass { 83 | GstVideoSinkClass parent_class; 84 | }; 85 | 86 | GType gst_kms_sink_get_type (void) G_GNUC_CONST; 87 | 88 | G_END_DECLS 89 | 90 | #endif /* __GST_KMS_SINK_H__ */ 91 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppvideodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef _GST_MPP_VIDEO_DEC_H_ 23 | #define _GST_MPP_VIDEO_DEC_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | /* Begin Declaration */ 33 | G_BEGIN_DECLS 34 | #define GST_TYPE_MPP_VIDEO_DEC (gst_mpp_video_dec_get_type()) 35 | #define GST_MPP_VIDEO_DEC(obj) \ 36 | (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPP_VIDEO_DEC, GstMppVideoDec)) 37 | #define GST_MPP_VIDEO_DEC_CLASS(klass) \ 38 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_MPP_VIDEO_DEC, GstMppVideoDecClass)) 39 | #define GST_IS_MPP_VIDEO_DEC(obj) \ 40 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_MPP_VIDEO_DEC)) 41 | #define GST_IS_MPP_VIDEO_DEC_CLASS(obj) \ 42 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_MPP_VIDEO_DEC)) 43 | 44 | typedef struct _GstMppVideoDec GstMppVideoDec; 45 | typedef struct _GstMppVideoDecClass GstMppVideoDecClass; 46 | 47 | struct _GstMppVideoDec 48 | { 49 | GstVideoDecoder parent; 50 | 51 | /* add private members here */ 52 | gint width; 53 | gint height; 54 | gint framesize; 55 | 56 | GstVideoCodecState *input_state; 57 | GstVideoCodecState *output_state; 58 | 59 | /* the currently format */ 60 | GstVideoInfo info; 61 | GstVideoAlignment align; 62 | 63 | /* State */ 64 | gboolean processing; 65 | gboolean active; 66 | GstFlowReturn output_flow; 67 | 68 | /* Rockchip Mpp definitions */ 69 | MppCtx mpp_ctx; 70 | MppApi *mpi; 71 | 72 | GstBufferPool *pool; /* Pool of output frames */ 73 | }; 74 | 75 | struct _GstMppVideoDecClass 76 | { 77 | GstVideoDecoderClass parent_class; 78 | }; 79 | 80 | GType gst_mpp_video_dec_get_type (void); 81 | 82 | G_END_DECLS 83 | #endif /* _GST_MPP_VIDEO_DEC_H_ */ 84 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppallocator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef _GST_MPP_MEMORY_H 23 | #define _GST_MPP_MEMORY_H 24 | 25 | #include 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | #define VIDEO_MAX_FRAME 32 30 | #define GST_MPP_MEMORY_QUARK gst_mpp_memory_quark () 31 | 32 | #define GST_TYPE_MPP_ALLOCATOR (gst_mpp_allocator_get_type()) 33 | #define GST_MPP_ALLOCATOR(obj) \ 34 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_MPP_ALLOCATOR)) 35 | #define GST_MPP_ALLOCATOR_CLASS(obj) \ 36 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_MPP_ALLOCATOR)) 37 | 38 | typedef struct _GstMppMemory GstMppMemory; 39 | typedef struct _GstMppAllocator GstMppAllocator; 40 | typedef struct _GstMppAllocatorClass GstMppAllocatorClass; 41 | typedef enum _GstMppReturn GstMppReturn; 42 | 43 | enum _GstMppReturn { 44 | GST_MPP_OK = 0, 45 | GST_MPP_ERROR = -1, 46 | GST_MPP_BUSY = -2 47 | }; 48 | 49 | #define GST_MPP_MEMORY_CAST(mem) \ 50 | ((GstMppMemory *) (mem)) 51 | 52 | struct _GstMppMemory 53 | { 54 | GstMemory mem; 55 | 56 | /* < private > */ 57 | MppBuffer *mpp_buf; 58 | gpointer data; 59 | gint dmafd; 60 | gsize size; 61 | }; 62 | 63 | struct _GstMppAllocator 64 | { 65 | GstAllocator parent; 66 | gboolean active; 67 | 68 | guint32 count; /* number of buffers allocated by the mpp */ 69 | MppBufferGroup mpp_mem_pool; 70 | 71 | GstMppMemory *mems[VIDEO_MAX_FRAME]; 72 | GstAtomicQueue *free_queue; 73 | }; 74 | 75 | struct _GstMppAllocatorClass 76 | { 77 | GstAllocatorClass parent_class; 78 | }; 79 | 80 | GType gst_mpp_allocator_get_type (void); 81 | 82 | gboolean gst_is_mpp_memory (GstMemory * mem); 83 | 84 | GQuark gst_mpp_memory_quark (void); 85 | 86 | GstMppAllocator * 87 | gst_mpp_allocator_new (GstObject * parent); 88 | 89 | guint 90 | gst_mpp_allocator_start (GstMppAllocator * allocator, 91 | gsize size, guint32 count); 92 | 93 | gint 94 | gst_mpp_allocator_stop (GstMppAllocator * allocator); 95 | 96 | GstMemory * 97 | gst_mpp_allocator_alloc_dmabuf (GstMppAllocator * allocator, 98 | GstAllocator * dmabuf_allocator); 99 | 100 | 101 | G_END_DECLS 102 | #endif 103 | -------------------------------------------------------------------------------- /gst/kms/gstkmsallocator.h: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifndef __GST_KMS_ALLOCATOR_H__ 27 | #define __GST_KMS_ALLOCATOR_H__ 28 | 29 | #include 30 | #include 31 | 32 | G_BEGIN_DECLS 33 | 34 | #define GST_TYPE_KMS_ALLOCATOR \ 35 | (gst_kms_allocator_get_type()) 36 | #define GST_IS_KMS_ALLOCATOR(obj) \ 37 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_KMS_ALLOCATOR)) 38 | #define GST_IS_KMS_ALLOCATOR_CLASS(klass) \ 39 | (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_KMS_ALLOCATOR)) 40 | #define GST_KMS_ALLOCATOR_GET_CLASS(obj) \ 41 | (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_KMS_ALLOCATOR, GstKMSAllocatorClass)) 42 | #define GST_KMS_ALLOCATOR(obj) \ 43 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_KMS_ALLOCATOR, GstKMSAllocator)) 44 | #define GST_KMS_ALLOCATOR_CLASS(klass) \ 45 | (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_KMS_ALLOCATOR, GstKMSAllocatorClass)) 46 | 47 | typedef struct _GstKMSAllocator GstKMSAllocator; 48 | typedef struct _GstKMSAllocatorClass GstKMSAllocatorClass; 49 | typedef struct _GstKMSAllocatorPrivate GstKMSAllocatorPrivate; 50 | typedef struct _GstKMSMemory GstKMSMemory; 51 | 52 | struct kms_bo; 53 | 54 | struct _GstKMSMemory 55 | { 56 | GstMemory parent; 57 | 58 | guint32 fb_id; 59 | guint32 gem_handle[GST_VIDEO_MAX_PLANES]; 60 | struct kms_bo *bo; 61 | }; 62 | 63 | struct _GstKMSAllocator 64 | { 65 | GstAllocator parent; 66 | GstKMSAllocatorPrivate *priv; 67 | }; 68 | 69 | struct _GstKMSAllocatorClass { 70 | GstAllocatorClass parent_class; 71 | }; 72 | 73 | GType gst_kms_allocator_get_type (void) G_GNUC_CONST; 74 | 75 | gboolean gst_is_kms_memory (GstMemory *mem); 76 | guint32 gst_kms_memory_get_fb_id (GstMemory *mem); 77 | 78 | GstAllocator* gst_kms_allocator_new (gint fd); 79 | 80 | GstMemory* gst_kms_allocator_bo_alloc (GstAllocator *allocator, 81 | GstVideoInfo *vinfo); 82 | 83 | GstKMSMemory* gst_kms_allocator_dmabuf_import (GstAllocator *allocator, 84 | gint *prime_fds, 85 | gint n_planes, 86 | gsize offsets[GST_VIDEO_MAX_PLANES], 87 | GstVideoInfo *vinfo); 88 | 89 | G_END_DECLS 90 | 91 | 92 | #endif /* __GST_KMS_ALLOCATOR_H__ */ 93 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppvideoenc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef __GST_MPP_VIDEO_ENC_H__ 23 | #define __GST_MPP_VIDEO_ENC_H__ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | GST_DEBUG_CATEGORY_EXTERN (mppvideoenc_debug); 34 | 35 | /* Begin Declaration */ 36 | G_BEGIN_DECLS 37 | #define GST_TYPE_MPP_VIDEO_ENC (gst_mpp_video_enc_get_type()) 38 | #define GST_MPP_VIDEO_ENC(obj) \ 39 | (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPP_VIDEO_ENC, GstMppVideoEnc)) 40 | #define GST_MPP_VIDEO_ENC_CLASS(klass) \ 41 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_MPP_VIDEO_ENC, GstMppVideoEncClass)) 42 | #define GST_IS_MPP_VIDEO_ENC(obj) \ 43 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_MPP_VIDEO_ENC)) 44 | #define GST_IS_MPP_VIDEO_ENC_CLASS(obj) \ 45 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_MPP_VIDEO_ENC)) 46 | typedef struct _GstMppVideoEnc GstMppVideoEnc; 47 | typedef struct _GstMppVideoEncClass GstMppVideoEncClass; 48 | 49 | #define MPP_MAX_BUFFERS 4 50 | #define MAX_CODEC_FRAME (1<<15) /* 2^15 == 32768 */ 51 | #define MPP_ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) 52 | 53 | struct _GstMppVideoEnc 54 | { 55 | GstVideoEncoder parent; 56 | 57 | /* < private > */ 58 | MppCtx mpp_ctx; 59 | MppApi *mpi; 60 | /* Buffer */ 61 | MppBufferGroup input_group; 62 | MppBufferGroup output_group; 63 | MppBuffer input_buffer[MPP_MAX_BUFFERS]; 64 | MppBuffer output_buffer[MPP_MAX_BUFFERS]; 65 | MppFrame mpp_frame; 66 | GstCaps *outcaps; 67 | 68 | /* the currently format */ 69 | GstVideoInfo info; 70 | GstVideoAlignment align; 71 | 72 | /* pads */ 73 | GstCaps *probed_srccaps; 74 | GstCaps *probed_sinkcaps; 75 | 76 | /* State */ 77 | GstVideoCodecState *input_state; 78 | gboolean processing; 79 | gboolean active; 80 | GstFlowReturn output_flow; 81 | }; 82 | 83 | struct _GstMppVideoEncClass 84 | { 85 | GstVideoEncoderClass parent_class; 86 | gboolean (*set_format) (GstVideoEncoder * encoder, 87 | GstVideoCodecState * state); 88 | GstFlowReturn (*handle_frame) (GstVideoEncoder * encoder, 89 | GstVideoCodecFrame * frame, GstCaps * outcaps); 90 | }; 91 | 92 | GType gst_mpp_video_enc_get_type (void); 93 | 94 | 95 | G_END_DECLS 96 | #endif /* __GST_MPP_VIDEO_ENC_H__ */ 97 | -------------------------------------------------------------------------------- /gst-libs/gst/gettext.h: -------------------------------------------------------------------------------- 1 | /* Convenience header for conditional use of GNU . 2 | Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Library General Public License as published 6 | by the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Library General Public License for more details. 13 | 14 | You should have received a copy of the GNU Library General Public 15 | License along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 17 | USA. */ 18 | 19 | #ifndef _LIBGETTEXT_H 20 | #define _LIBGETTEXT_H 1 21 | 22 | /* NLS can be disabled through the configure --disable-nls option. */ 23 | #ifdef ENABLE_NLS 24 | 25 | /* Get declarations of GNU message catalog functions. */ 26 | # include 27 | 28 | #else 29 | 30 | /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which 31 | chokes if dcgettext is defined as a macro. So include it now, to make 32 | later inclusions of a NOP. We don't include 33 | as well because people using "gettext.h" will not include , 34 | and also including would fail on SunOS 4, whereas 35 | is OK. */ 36 | #if defined(__sun) 37 | # include 38 | #endif 39 | 40 | /* Disabled NLS. 41 | The casts to 'const char *' serve the purpose of producing warnings 42 | for invalid uses of the value returned from these functions. 43 | On pre-ANSI systems without 'const', the config.h file is supposed to 44 | contain "#define const". */ 45 | # define gettext(Msgid) ((const char *) (Msgid)) 46 | # define dgettext(Domainname, Msgid) ((const char *) (Msgid)) 47 | # define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) 48 | # define ngettext(Msgid1, Msgid2, N) \ 49 | ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) 50 | # define dngettext(Domainname, Msgid1, Msgid2, N) \ 51 | ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) 52 | # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ 53 | ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) 54 | # define textdomain(Domainname) ((const char *) (Domainname)) 55 | # define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) 56 | # define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) 57 | 58 | #endif 59 | 60 | /* A pseudo function call that serves as a marker for the automated 61 | extraction of messages, but does not call gettext(). The run-time 62 | translation is done at a different place in the code. 63 | The argument, String, should be a literal string. Concatenated strings 64 | and other string expressions won't work. 65 | The macro's expansion is not parenthesized, so that it is suitable as 66 | initializer for static 'char[]' or 'const char[]' variables. */ 67 | #define gettext_noop(String) String 68 | 69 | #endif /* _LIBGETTEXT_H */ 70 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # gstreamer-rockchip autogen.sh 4 | # 5 | # Run this to generate all the initial makefiles, etc. 6 | # 7 | # This file has been generated from common/autogen.sh.in via common/update-autogen 8 | 9 | 10 | test -n "$srcdir" || srcdir=`dirname "$0"` 11 | test -n "$srcdir" || srcdir=. 12 | 13 | olddir=`pwd` 14 | cd "$srcdir" 15 | 16 | package=gstreamer-rockchip 17 | srcfile=gstreamer-rockchip.doap 18 | 19 | # Make sure we have common 20 | if test ! -f common/gst-autogen.sh; 21 | then 22 | echo "+ Setting up common submodule" 23 | git submodule init 24 | fi 25 | git submodule update 26 | 27 | # source helper functions 28 | if test ! -f common/gst-autogen.sh; 29 | then 30 | echo There is something wrong with your source tree. 31 | echo You are missing common/gst-autogen.sh 32 | exit 1 33 | fi 34 | . common/gst-autogen.sh 35 | 36 | # install pre-commit hook for doing clean commits 37 | if test ! \( -x .git/hooks/pre-commit -a -L .git/hooks/pre-commit \); 38 | then 39 | rm -f .git/hooks/pre-commit 40 | if ! ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit 2> /dev/null 41 | then 42 | echo "Failed to create commit hook symlink, copying instead ..." 43 | cp common/hooks/pre-commit.hook .git/hooks/pre-commit 44 | fi 45 | fi 46 | 47 | # GNU gettext automake support doesn't get along with git. 48 | # https://bugzilla.gnome.org/show_bug.cgi?id=661128 49 | if test -d po ; then 50 | touch -t 200001010000 po/gstreamer-rockchip-1.0.pot 51 | fi 52 | 53 | CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' 54 | 55 | if test "x$package" = "xgstreamer"; then 56 | CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --enable-docbook --enable-failing-tests --enable-poisoning" 57 | elif test "x$package" = "xgst-plugins-bad"; then 58 | CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-player-tests" 59 | fi 60 | 61 | autogen_options $@ 62 | 63 | printf "+ check for build tools" 64 | if test -z "$NOCHECK"; then 65 | echo 66 | 67 | printf " checking for autoreconf ... " 68 | echo 69 | which "autoreconf" 2>/dev/null || { 70 | echo "not found! Please install the autoconf package." 71 | exit 1 72 | } 73 | 74 | printf " checking for pkg-config ... " 75 | echo 76 | which "pkg-config" 2>/dev/null || { 77 | echo "not found! Please install pkg-config." 78 | exit 1 79 | } 80 | else 81 | echo ": skipped version checks" 82 | fi 83 | 84 | # if no arguments specified then this will be printed 85 | if test -z "$*" && test -z "$NOCONFIGURE"; then 86 | echo "+ checking for autogen.sh options" 87 | echo " This autogen script will automatically run ./configure as:" 88 | echo " ./configure $CONFIGURE_DEF_OPT" 89 | echo " To pass any additional options, please specify them on the $0" 90 | echo " command line." 91 | fi 92 | 93 | toplevel_check $srcfile 94 | 95 | # autopoint 96 | if test -d po && grep ^AM_GNU_GETTEXT_VERSION configure.ac >/dev/null ; then 97 | tool_run "autopoint" "--force" 98 | fi 99 | 100 | # aclocal 101 | if test -f acinclude.m4; then rm acinclude.m4; fi 102 | 103 | autoreconf --force --install || exit 1 104 | 105 | test -n "$NOCONFIGURE" && { 106 | echo "+ skipping configure stage for package $package, as requested." 107 | echo "+ autogen.sh done." 108 | exit 0 109 | } 110 | 111 | cd "$olddir" 112 | 113 | echo "+ running configure ... " 114 | test ! -z "$CONFIGURE_DEF_OPT" && echo " default flags: $CONFIGURE_DEF_OPT" 115 | test ! -z "$CONFIGURE_EXT_OPT" && echo " external flags: $CONFIGURE_EXT_OPT" 116 | echo 117 | 118 | echo "$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT 119 | "$srcdir/configure" $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT || { 120 | echo " configure failed" 121 | exit 1 122 | } 123 | 124 | echo "Now type 'make' to compile $package." 125 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | gstreamer1.0-rockchip (1.10-5-1ubuntu1) xenial; urgency=medium 2 | 3 | [ Jacob Chen ] 4 | * build: fix egl lib link missing 5 | * rksink: HACK: drop pixel when display 4096 vdieo 6 | 7 | [ Randy Li ] 8 | * vpudec: drop the invalid buffer to avoid the screen mess 9 | * [WIP]: mppvideoenc: a multiple thread version 10 | * [WIP]: mppvideoenc: the first ugly version 11 | * rockchipmpp: add build rules 12 | * rockchipmpp: add to top build rule 13 | * rockchipmpp: make the mppvideoenc as the abstract class 14 | * rockchipmpp: add H.264 encoder class 15 | * rockchipmpp: add build rules for H.264 encoder 16 | * [WIP]: rockchipmpp: encoder: update API 17 | * rockchipmpp: add mpp buffer allocator 18 | * rockchipmpp: decoder: add a buffer pool 19 | * rockchipmpp: add video decoder 20 | * rockchipmpp: decoder: drop those invalid decoded result 21 | * rockchipmpp: register video decoder in plugin 22 | * rockchipmpp: add video decoder in build rules 23 | * build: update rules to build properly decoder plugin 24 | 25 | -- Randy Li Thu, 23 Feb 2017 07:00:56 +0000 26 | 27 | gstreamer1.0-rockchip (1.10-4) stable; urgency=medium 28 | 29 | [ Randy Li ] 30 | * videorga: vpuenc: remove stub class 31 | 32 | [ Jacob Chen ] 33 | * vpudec: add rkximagesink 34 | * vpudec: ximagesink: clean code 35 | * vpudec: ximagesink: add display ratio 36 | * vpudec: ximagesink: correct stride 37 | * vpudec: ximagesink: check display position in event thread 38 | * vpudec: ximagesink: use a timer to throttle and redraw when paused 39 | * vpudec: ximagesink: add render rectangle support 40 | * vpudec: eglglesink/ximagesink: move to child folder 41 | * vpudec: eglglessink: only use it in 1080p 42 | * vpudec: ximagesink: remove throttle 43 | * vpudec: ximagesinl: fix buffer count 44 | * vpudec: ximagesinl: clear window first when expose 45 | * vpudec: eglglessink: add zero-copy texture support for NV12 46 | * Revert "vpudec: eglglessink: only use it in 1080p" 47 | * vpudec: rkximagesink: adjust for fake 4k ui 48 | 49 | [ Randy Li ] 50 | * vpudec: remove EGL invoked video sink from this directory 51 | * kms: move to the rksink 52 | * rkvideo: move all the video sink to this plugin package 53 | * build: debian: build and install new rkvideo plugin 54 | 55 | [ Jacob Chen ] 56 | * rkvideo: rename GstXImageSink to GstRkXImageSink 57 | 58 | [ Randy Li ] 59 | * debian: install new rkvideo plugin 60 | * TEST: kmssink: print frame count 61 | 62 | [ Jacob Chen ] 63 | * rkvideo: eglglessink: use gst_data_queue_push_force 64 | * rkvideo: rkximagesink: fix display_ratio 65 | 66 | [ Randy Li ] 67 | * vpudec: support dynamic update input caps 68 | * build: debian: remove stub dbg package 69 | * vpudec: remove unused eos filed 70 | * vpudec: adjust the buffer pool lifetime 71 | * vpudec: disable force check for profile 72 | 73 | [ Jacob Chen ] 74 | * rkvideo: rkximagesink: fix display bug in fake 4k 75 | 76 | [ Randy Li ] 77 | * vpudec: clean up the code 78 | * rksink: clean up the code 79 | 80 | [ Jacob Chen ] 81 | * build: don't build eglsink and rkximagesink without x11 82 | 83 | [ Randy Li ] 84 | * vpudec: force the rockchip mpp to exit at the last packet 85 | 86 | -- Randy Li Wed, 15 Feb 2017 01:45:42 +0000 87 | 88 | gstreamer1.0-rockchip (1.10-3) testing; urgency=medium 89 | 90 | * vpudec: remove codec_data 91 | * vpudec: bufferpool: remove allocate vpu_frame every times 92 | * vpudec: add an allocator for buffers from vpu_display_pool 93 | * vpudec: use GstVpuAllocator in GstVpuBufferpool 94 | * vpudec: build: add gstvpuallocator 95 | * vpudec: rename the vpu codec context field 96 | * vpudec: adapt new buffer operating procedures 97 | * vpumeta: stop using the vpumeta data 98 | 99 | -- Randy Li Wed, 21 Dec 2016 07:31:44 +0000 100 | 101 | gstreamer1.0-rockchip (1.10-2) testing; urgency=medium 102 | 103 | * vpudec: add missing copyright information in a files 104 | * vpudec: support flush() method in decoder 105 | * vpudec: kmssink: support P010_10LE 106 | * vpumeta: change the type of index field for invalid index 107 | * vpudec: support 10 bits video color depth and P010_10LE output 108 | * vpudec: not block the stop operation 109 | * Revert "vpudec: not block the stop operation" 110 | * vpudec: put the decoder getting output frame task to pad 111 | * vpudec: add new method to handle statechange 112 | * vpumeta: free vpumem from the mpp allocator 113 | * vpudec: fix the bug in exit and cleanup 114 | 115 | -- Randy Li Thu, 15 Dec 2016 03:17:28 +0000 116 | 117 | gstreamer1.0-rockchip (1.10-1) testing; urgency=medium 118 | 119 | * build: update the package name 120 | 121 | -- Randy Li Thu, 24 Nov 2016 06:23:55 +0000 122 | 123 | gstreamer1.0-rockchip (1.8-3) unstable; urgency=medium 124 | 125 | * Initial release (Closes: #nnnn) 126 | 127 | -- Randy Li Thu, 17 Nov 2016 07:59:00 +0000 128 | -------------------------------------------------------------------------------- /gst/rkximage/rkx_kmsutils.c: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include "config.h" 28 | #endif 29 | 30 | #include 31 | 32 | #include "rkx_kmsutils.h" 33 | 34 | /* *INDENT-OFF* */ 35 | static const struct 36 | { 37 | guint32 fourcc; 38 | GstVideoFormat format; 39 | } format_map[] = { 40 | #define DEF_FMT(fourcc, fmt) \ 41 | { DRM_FORMAT_##fourcc,GST_VIDEO_FORMAT_##fmt } 42 | 43 | /* DEF_FMT (XRGB1555, ???), */ 44 | /* DEF_FMT (XBGR1555, ???), */ 45 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN 46 | DEF_FMT (ARGB8888, BGRA), 47 | DEF_FMT (XRGB8888, BGRx), 48 | DEF_FMT (ABGR8888, RGBA), 49 | DEF_FMT (XBGR8888, RGBx), 50 | #else 51 | DEF_FMT (ARGB8888, ARGB), 52 | DEF_FMT (XRGB8888, xRGB), 53 | DEF_FMT (ABGR8888, ABGR), 54 | DEF_FMT (XBGR8888, xBGR), 55 | #endif 56 | DEF_FMT (UYVY, UYVY), 57 | DEF_FMT (YUYV, YUY2), 58 | DEF_FMT (YVYU, YVYU), 59 | DEF_FMT (YUV420, I420), 60 | DEF_FMT (YVU420, YV12), 61 | DEF_FMT (YUV422, Y42B), 62 | DEF_FMT (NV12, NV12), 63 | DEF_FMT (NV21, NV21), 64 | DEF_FMT (NV16, NV16), 65 | /* FIXME should be renamed to P010_* */ 66 | 67 | #undef DEF_FMT 68 | }; 69 | /* *INDENT-ON* */ 70 | 71 | GstVideoFormat 72 | rkx_video_format_from_drm (guint32 drmfmt) 73 | { 74 | gint i; 75 | 76 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 77 | if (format_map[i].fourcc == drmfmt) 78 | return format_map[i].format; 79 | } 80 | 81 | return GST_VIDEO_FORMAT_UNKNOWN; 82 | } 83 | 84 | guint32 85 | rkx_drm_format_from_video (GstVideoFormat fmt) 86 | { 87 | gint i; 88 | 89 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 90 | if (format_map[i].format == fmt) 91 | return format_map[i].fourcc; 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | static GstStructure * 98 | rkx_video_format_to_structure (GstVideoFormat format) 99 | { 100 | GstStructure *structure; 101 | 102 | structure = NULL; 103 | if (format != GST_VIDEO_FORMAT_UNKNOWN) 104 | structure = gst_structure_new ("video/x-raw", "format", G_TYPE_STRING, 105 | gst_video_format_to_string (format), NULL); 106 | 107 | return structure; 108 | } 109 | 110 | GstCaps * 111 | rkx_kms_sink_caps_template_fill (void) 112 | { 113 | gint i; 114 | GstCaps *caps; 115 | GstStructure *template; 116 | 117 | caps = gst_caps_new_empty (); 118 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 119 | template = rkx_video_format_to_structure (format_map[i].format); 120 | gst_structure_set (template, 121 | "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, 122 | "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, 123 | "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); 124 | gst_caps_append_structure (caps, template); 125 | } 126 | return gst_caps_simplify (caps); 127 | } 128 | 129 | static const gint device_par_map[][2] = { 130 | {1, 1}, /* regular screen */ 131 | {16, 15}, /* PAL TV */ 132 | {11, 10}, /* 525 line Rec.601 video */ 133 | {54, 59}, /* 625 line Rec.601 video */ 134 | {64, 45}, /* 1280x1024 on 16:9 display */ 135 | {5, 3}, /* 1280x1024 on 4:3 display */ 136 | {4, 3} /* 800x600 on 16:9 display */ 137 | }; 138 | 139 | #define DELTA(ratio, idx, w) \ 140 | (ABS(ratio - ((gdouble)device_par_map[idx][w] / device_par_map[idx][!(w)]))) 141 | 142 | void 143 | rkx_video_calculate_device_ratio (guint dev_width, guint dev_height, 144 | guint dev_width_mm, guint dev_height_mm, 145 | guint * dpy_par_n, guint * dpy_par_d) 146 | { 147 | gdouble ratio, delta, cur_delta; 148 | gint i, j, index, windex; 149 | 150 | /* First, calculate the "real" ratio based on the X values; which is 151 | * the "physical" w/h divided by the w/h in pixels of the display */ 152 | if (dev_width == 0 || dev_height == 0 153 | || dev_width_mm == 0 || dev_height_mm == 0) 154 | ratio = 1.0; 155 | else 156 | ratio = (gdouble) (dev_width_mm * dev_height) / (dev_height_mm * dev_width); 157 | 158 | /* Now, find the one from device_par_map[][2] with the lowest delta 159 | * to the real one */ 160 | delta = DELTA (ratio, 0, 0); 161 | index = 0; 162 | windex = 0; 163 | 164 | for (i = 1; i < G_N_ELEMENTS (device_par_map); i++) { 165 | for (j = 0; j < 2; j++) { 166 | cur_delta = DELTA (ratio, i, j); 167 | if (cur_delta < delta) { 168 | index = i; 169 | windex = j; 170 | delta = cur_delta; 171 | } 172 | } 173 | } 174 | 175 | if (dpy_par_n) 176 | *dpy_par_n = device_par_map[index][windex]; 177 | 178 | if (dpy_par_d) 179 | *dpy_par_d = device_par_map[index][windex ^ 1]; 180 | } 181 | -------------------------------------------------------------------------------- /gst/rkximage/ximagesink.h: -------------------------------------------------------------------------------- 1 | #ifndef __GST_X_IMAGE_SINK_H__ 2 | #define __GST_X_IMAGE_SINK_H__ 3 | 4 | #include 5 | 6 | #ifdef HAVE_XSHM 7 | #include 8 | #include 9 | #include 10 | #endif /* HAVE_XSHM */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | /* Helper functions */ 19 | #include 20 | 21 | G_BEGIN_DECLS 22 | #define GST_TYPE_X_IMAGE_SINK \ 23 | (gst_x_image_sink_get_type()) 24 | #define GST_X_IMAGE_SINK(obj) \ 25 | (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_X_IMAGE_SINK, GstRkXImageSink)) 26 | #define GST_X_IMAGE_SINK_CLASS(klass) \ 27 | (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_X_IMAGE_SINK, GstRkXImageSinkClass)) 28 | #define GST_IS_X_IMAGE_SINK(obj) \ 29 | (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_X_IMAGE_SINK)) 30 | #define GST_IS_X_IMAGE_SINK_CLASS(klass) \ 31 | (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_X_IMAGE_SINK)) 32 | 33 | typedef struct _GstXContext GstXContext; 34 | typedef struct _GstXWindow GstXWindow; 35 | 36 | typedef struct _GstRkXImageSink GstRkXImageSink; 37 | typedef struct _GstRkXImageSinkClass GstRkXImageSinkClass; 38 | 39 | /* 40 | * GstXContext: 41 | * @disp: the X11 Display of this context 42 | * @screen: the default Screen of Display @disp 43 | * @screen_num: the Screen number of @screen 44 | * @visual: the default Visual of Screen @screen 45 | * @root: the root Window of Display @disp 46 | * @white: the value of a white pixel on Screen @screen 47 | * @black: the value of a black pixel on Screen @screen 48 | * @depth: the color depth of Display @disp 49 | * @bpp: the number of bits per pixel on Display @disp 50 | * @endianness: the endianness of image bytes on Display @disp 51 | * @width: the width in pixels of Display @disp 52 | * @height: the height in pixels of Display @disp 53 | * @widthmm: the width in millimeters of Display @disp 54 | * @heightmm: the height in millimeters of Display @disp 55 | * 56 | * Structure used to store various informations collected/calculated for a 57 | * Display. 58 | */ 59 | struct _GstXContext 60 | { 61 | Display *disp; 62 | 63 | Screen *screen; 64 | gint screen_num; 65 | 66 | Visual *visual; 67 | 68 | Window root; 69 | 70 | gulong white, black; 71 | 72 | gint depth; 73 | gint bpp; 74 | 75 | gint width, height; 76 | gint widthmm, heightmm; 77 | }; 78 | 79 | /* 80 | * GstXWindow: 81 | * @win: the Window ID of this X11 window 82 | * @width: the width in pixels of Window @win 83 | * @height: the height in pixels of Window @win 84 | * @internal: used to remember if Window @win was created internally or passed 85 | * through the #GstVideoOverlay interface 86 | * @gc: the Graphical Context of Window @win 87 | * 88 | * Structure used to store informations about a Window. 89 | */ 90 | struct _GstXWindow 91 | { 92 | Window win; 93 | gint width, height; 94 | gboolean internal; 95 | GC gc; 96 | }; 97 | 98 | /** 99 | * GstRkXImageSink: 100 | * @display_name: the name of the Display we want to render to 101 | * @xcontext: our instance's #GstXContext 102 | * @xwindow: the #GstXWindow we are rendering to 103 | * @ximage: internal #GstXImage used to store incoming buffers and render when 104 | * not using the buffer_alloc optimization mechanism 105 | * @cur_image: a reference to the last #GstXImage that was put to @xwindow. It 106 | * is used when Expose events are received to redraw the latest video frame 107 | * @event_thread: a thread listening for events on @xwindow and handling them 108 | * @running: used to inform @event_thread if it should run/shutdown 109 | * @fps_n: the framerate fraction numerator 110 | * @fps_d: the framerate fraction denominator 111 | * @x_lock: used to protect X calls as we are not using the XLib in threaded 112 | * mode 113 | * @flow_lock: used to protect data flow routines from external calls such as 114 | * events from @event_thread or methods from the #GstVideoOverlay interface 115 | * @par: used to override calculated pixel aspect ratio from @xcontext 116 | * @pool_lock: used to protect the buffer pool 117 | * @buffer_pool: a list of #GstXImageBuffer that could be reused at next buffer 118 | * allocation call 119 | * @synchronous: used to store if XSynchronous should be used or not (for 120 | * debugging purpose only) 121 | * @handle_events: used to know if we should handle select XEvents or not 122 | * 123 | * The #GstRkXImageSink data structure. 124 | */ 125 | struct _GstRkXImageSink 126 | { 127 | /* Our element stuff */ 128 | GstVideoSink videosink; 129 | 130 | gint fd; 131 | gint ctrl_fd; 132 | gint conn_id; 133 | gint crtc_id; 134 | gint plane_id; 135 | guint pipe; 136 | 137 | guint16 hdisplay, vdisplay; 138 | guint32 buffer_id; 139 | 140 | /* capabilities */ 141 | gboolean has_prime_import; 142 | gboolean has_async_page_flip; 143 | 144 | char *display_name; 145 | 146 | GstXContext *xcontext; 147 | GstXWindow *xwindow; 148 | GstBuffer *cur_image; 149 | 150 | GThread *event_thread; 151 | gboolean running; 152 | 153 | GstVideoInfo info; 154 | 155 | /* Framerate numerator and denominator */ 156 | gint fps_n; 157 | gint fps_d; 158 | gint par_n; 159 | gint par_d; 160 | 161 | GMutex x_lock; 162 | GMutex flow_lock; 163 | 164 | gboolean synchronous; 165 | gboolean handle_events; 166 | gboolean handle_expose; 167 | gboolean draw_border; 168 | 169 | /* stream metadata */ 170 | gchar *media_title; 171 | 172 | GstVideoInfo vinfo; 173 | GstCaps *allowed_caps; 174 | GstAllocator *allocator; 175 | GstBuffer *last_buffer; 176 | 177 | gchar *devname; 178 | 179 | guint32 mm_width, mm_height; 180 | 181 | GstPoll *poll; 182 | GstPollFD pollfd; 183 | 184 | guint32 last_fb_id; 185 | GstVideoRectangle save_rect; 186 | gboolean paused; 187 | }; 188 | 189 | struct _GstRkXImageSinkClass 190 | { 191 | GstVideoSinkClass parent_class; 192 | }; 193 | 194 | GType gst_x_image_sink_get_type (void); 195 | 196 | G_END_DECLS 197 | #endif /* __GST_X_IMAGE_SINK_H__ */ 198 | -------------------------------------------------------------------------------- /gst/kms/gstkmsbufferpool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * GStreamer 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include "config.h" 28 | #endif 29 | 30 | #include 31 | 32 | #include "gstkmsbufferpool.h" 33 | #include "gstkmsallocator.h" 34 | 35 | GST_DEBUG_CATEGORY_STATIC (gst_kms_buffer_pool_debug); 36 | #define GST_CAT_DEFAULT gst_kms_buffer_pool_debug 37 | 38 | struct _GstKMSBufferPoolPrivate 39 | { 40 | gint fd; 41 | GstVideoInfo vinfo; 42 | GstAllocator *allocator; 43 | gboolean add_videometa; 44 | }; 45 | 46 | #define parent_class gst_kms_buffer_pool_parent_class 47 | G_DEFINE_TYPE_WITH_CODE (GstKMSBufferPool, gst_kms_buffer_pool, 48 | GST_TYPE_VIDEO_BUFFER_POOL, G_ADD_PRIVATE (GstKMSBufferPool); 49 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "kmsbufferpool", 0, 50 | "KMS buffer pool")); 51 | 52 | static const gchar ** 53 | gst_kms_buffer_pool_get_options (GstBufferPool * pool) 54 | { 55 | static const gchar *options[] = { GST_BUFFER_POOL_OPTION_VIDEO_META, 56 | GST_BUFFER_POOL_OPTION_KMS_BUFFER, NULL 57 | }; 58 | return options; 59 | } 60 | 61 | static gboolean 62 | gst_kms_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) 63 | { 64 | GstKMSBufferPool *vpool; 65 | GstKMSBufferPoolPrivate *priv; 66 | GstCaps *caps; 67 | GstVideoInfo vinfo; 68 | GstAllocator *allocator; 69 | GstAllocationParams params; 70 | 71 | vpool = GST_KMS_BUFFER_POOL_CAST (pool); 72 | priv = vpool->priv; 73 | 74 | if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) 75 | goto wrong_config; 76 | 77 | if (!caps) 78 | goto no_caps; 79 | 80 | /* now parse the caps from the config */ 81 | if (!gst_video_info_from_caps (&vinfo, caps)) 82 | goto wrong_caps; 83 | 84 | allocator = NULL; 85 | gst_buffer_pool_config_get_allocator (config, &allocator, ¶ms); 86 | 87 | /* not our allocator, not our buffers */ 88 | if (allocator && GST_IS_KMS_ALLOCATOR (allocator)) { 89 | if (priv->allocator) 90 | gst_object_unref (priv->allocator); 91 | if ((priv->allocator = allocator)) 92 | gst_object_ref (allocator); 93 | } 94 | if (!priv->allocator) 95 | goto no_allocator; 96 | 97 | priv->vinfo = vinfo; 98 | 99 | /* enable metadata based on config of the pool */ 100 | priv->add_videometa = gst_buffer_pool_config_has_option (config, 101 | GST_BUFFER_POOL_OPTION_VIDEO_META); 102 | 103 | return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); 104 | 105 | /* ERRORS */ 106 | wrong_config: 107 | { 108 | GST_WARNING_OBJECT (pool, "invalid config"); 109 | return FALSE; 110 | } 111 | no_caps: 112 | { 113 | GST_WARNING_OBJECT (pool, "no caps in config"); 114 | return FALSE; 115 | } 116 | wrong_caps: 117 | { 118 | GST_WARNING_OBJECT (pool, 119 | "failed getting geometry from caps %" GST_PTR_FORMAT, caps); 120 | return FALSE; 121 | } 122 | no_allocator: 123 | { 124 | GST_WARNING_OBJECT (pool, "no valid allocator in pool"); 125 | return FALSE; 126 | } 127 | } 128 | 129 | static GstFlowReturn 130 | gst_kms_buffer_pool_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer, 131 | GstBufferPoolAcquireParams * params) 132 | { 133 | GstKMSBufferPool *vpool; 134 | GstKMSBufferPoolPrivate *priv; 135 | GstVideoInfo *info; 136 | GstMemory *mem; 137 | 138 | vpool = GST_KMS_BUFFER_POOL_CAST (pool); 139 | priv = vpool->priv; 140 | info = &priv->vinfo; 141 | 142 | *buffer = gst_buffer_new (); 143 | if (*buffer == NULL) 144 | goto no_memory; 145 | mem = gst_kms_allocator_bo_alloc (priv->allocator, info); 146 | if (!mem) { 147 | gst_buffer_unref (*buffer); 148 | goto no_memory; 149 | } 150 | gst_buffer_append_memory (*buffer, mem); 151 | 152 | if (priv->add_videometa) { 153 | GST_DEBUG_OBJECT (pool, "adding GstVideoMeta"); 154 | 155 | gst_buffer_add_video_meta_full (*buffer, GST_VIDEO_FRAME_FLAG_NONE, 156 | GST_VIDEO_INFO_FORMAT (info), 157 | GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), 158 | GST_VIDEO_INFO_N_PLANES (info), info->offset, info->stride); 159 | } 160 | 161 | return GST_FLOW_OK; 162 | 163 | /* ERROR */ 164 | no_memory: 165 | { 166 | GST_WARNING_OBJECT (pool, "can't create memory"); 167 | return GST_FLOW_ERROR; 168 | } 169 | } 170 | 171 | static void 172 | gst_kms_buffer_pool_finalize (GObject * object) 173 | { 174 | GstKMSBufferPool *pool; 175 | GstKMSBufferPoolPrivate *priv; 176 | 177 | pool = GST_KMS_BUFFER_POOL (object); 178 | priv = pool->priv; 179 | 180 | if (priv->allocator) 181 | gst_object_unref (priv->allocator); 182 | 183 | G_OBJECT_CLASS (parent_class)->finalize (object); 184 | } 185 | 186 | static void 187 | gst_kms_buffer_pool_init (GstKMSBufferPool * pool) 188 | { 189 | pool->priv = gst_kms_buffer_pool_get_instance_private (pool); 190 | pool->priv->fd = -1; 191 | } 192 | 193 | static void 194 | gst_kms_buffer_pool_class_init (GstKMSBufferPoolClass * klass) 195 | { 196 | GObjectClass *gobject_class; 197 | GstBufferPoolClass *gstbufferpool_class; 198 | 199 | gobject_class = (GObjectClass *) klass; 200 | gstbufferpool_class = (GstBufferPoolClass *) klass; 201 | 202 | gobject_class->finalize = gst_kms_buffer_pool_finalize; 203 | 204 | gstbufferpool_class->get_options = gst_kms_buffer_pool_get_options; 205 | gstbufferpool_class->set_config = gst_kms_buffer_pool_set_config; 206 | gstbufferpool_class->alloc_buffer = gst_kms_buffer_pool_alloc_buffer; 207 | } 208 | 209 | GstBufferPool * 210 | gst_kms_buffer_pool_new (void) 211 | { 212 | return g_object_new (GST_TYPE_KMS_BUFFER_POOL, NULL); 213 | } 214 | -------------------------------------------------------------------------------- /gst/kms/gstkmsutils.c: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include "config.h" 28 | #endif 29 | 30 | #include 31 | 32 | #include "gstkmsutils.h" 33 | 34 | /* *INDENT-OFF* */ 35 | static const struct 36 | { 37 | guint32 fourcc; 38 | GstVideoFormat format; 39 | } format_map[] = { 40 | #define DEF_FMT(fourcc, fmt) \ 41 | { DRM_FORMAT_##fourcc,GST_VIDEO_FORMAT_##fmt } 42 | 43 | /* DEF_FMT (XRGB1555, ???), */ 44 | /* DEF_FMT (XBGR1555, ???), */ 45 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN 46 | DEF_FMT (ARGB8888, BGRA), 47 | DEF_FMT (XRGB8888, BGRx), 48 | DEF_FMT (ABGR8888, RGBA), 49 | DEF_FMT (XBGR8888, RGBx), 50 | #else 51 | DEF_FMT (ARGB8888, ARGB), 52 | DEF_FMT (XRGB8888, xRGB), 53 | DEF_FMT (ABGR8888, ABGR), 54 | DEF_FMT (XBGR8888, xBGR), 55 | #endif 56 | DEF_FMT (UYVY, UYVY), 57 | DEF_FMT (YUYV, YUY2), 58 | DEF_FMT (YVYU, YVYU), 59 | DEF_FMT (YUV420, I420), 60 | DEF_FMT (YVU420, YV12), 61 | DEF_FMT (YUV422, Y42B), 62 | DEF_FMT (NV12, NV12), 63 | DEF_FMT (NV21, NV21), 64 | DEF_FMT (NV16, NV16), 65 | 66 | #undef DEF_FMT 67 | }; 68 | /* *INDENT-ON* */ 69 | 70 | GstVideoFormat 71 | gst_video_format_from_drm (guint32 drmfmt) 72 | { 73 | gint i; 74 | 75 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 76 | if (format_map[i].fourcc == drmfmt) 77 | return format_map[i].format; 78 | } 79 | 80 | return GST_VIDEO_FORMAT_UNKNOWN; 81 | } 82 | 83 | guint32 84 | gst_drm_format_from_video (GstVideoFormat fmt) 85 | { 86 | gint i; 87 | 88 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 89 | if (format_map[i].format == fmt) 90 | return format_map[i].fourcc; 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | guint32 97 | gst_drm_bpp_from_drm (guint32 drmfmt) 98 | { 99 | guint32 bpp; 100 | 101 | switch (drmfmt) { 102 | case DRM_FORMAT_YUV420: 103 | case DRM_FORMAT_YVU420: 104 | case DRM_FORMAT_YUV422: 105 | case DRM_FORMAT_NV12: 106 | case DRM_FORMAT_NV21: 107 | case DRM_FORMAT_NV16: 108 | bpp = 8; 109 | break; 110 | case DRM_FORMAT_UYVY: 111 | case DRM_FORMAT_YUYV: 112 | case DRM_FORMAT_YVYU: 113 | bpp = 16; 114 | break; 115 | default: 116 | bpp = 32; 117 | break; 118 | } 119 | 120 | return bpp; 121 | } 122 | 123 | guint32 124 | gst_drm_height_from_drm (guint32 drmfmt, guint32 height) 125 | { 126 | guint32 ret; 127 | 128 | switch (drmfmt) { 129 | case DRM_FORMAT_YUV420: 130 | case DRM_FORMAT_YVU420: 131 | case DRM_FORMAT_YUV422: 132 | case DRM_FORMAT_NV12: 133 | case DRM_FORMAT_NV21: 134 | ret = height * 3 / 2; 135 | break; 136 | case DRM_FORMAT_NV16: 137 | ret = height * 2; 138 | break; 139 | default: 140 | ret = height; 141 | break; 142 | } 143 | 144 | return ret; 145 | } 146 | 147 | static GstStructure * 148 | gst_video_format_to_structure (GstVideoFormat format) 149 | { 150 | GstStructure *structure; 151 | 152 | structure = NULL; 153 | if (format != GST_VIDEO_FORMAT_UNKNOWN) 154 | structure = gst_structure_new ("video/x-raw", "format", G_TYPE_STRING, 155 | gst_video_format_to_string (format), NULL); 156 | 157 | return structure; 158 | } 159 | 160 | GstCaps * 161 | gst_kms_sink_caps_template_fill (void) 162 | { 163 | gint i; 164 | GstCaps *caps; 165 | GstStructure *template; 166 | 167 | caps = gst_caps_new_empty (); 168 | for (i = 0; i < G_N_ELEMENTS (format_map); i++) { 169 | template = gst_video_format_to_structure (format_map[i].format); 170 | gst_structure_set (template, 171 | "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, 172 | "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, 173 | "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); 174 | gst_caps_append_structure (caps, template); 175 | } 176 | return gst_caps_simplify (caps); 177 | } 178 | 179 | static const gint device_par_map[][2] = { 180 | {1, 1}, /* regular screen */ 181 | {16, 15}, /* PAL TV */ 182 | {11, 10}, /* 525 line Rec.601 video */ 183 | {54, 59}, /* 625 line Rec.601 video */ 184 | {64, 45}, /* 1280x1024 on 16:9 display */ 185 | {5, 3}, /* 1280x1024 on 4:3 display */ 186 | {4, 3} /* 800x600 on 16:9 display */ 187 | }; 188 | 189 | #define DELTA(ratio, idx, w) \ 190 | (ABS(ratio - ((gdouble)device_par_map[idx][w] / device_par_map[idx][!(w)]))) 191 | 192 | void 193 | gst_video_calculate_device_ratio (guint dev_width, guint dev_height, 194 | guint dev_width_mm, guint dev_height_mm, 195 | guint * dpy_par_n, guint * dpy_par_d) 196 | { 197 | gdouble ratio, delta, cur_delta; 198 | gint i, j, index, windex; 199 | 200 | /* First, calculate the "real" ratio based on the X values; which is 201 | * the "physical" w/h divided by the w/h in pixels of the display */ 202 | if (dev_width == 0 || dev_height == 0 203 | || dev_width_mm == 0 || dev_height_mm == 0) 204 | ratio = 1.0; 205 | else 206 | ratio = (gdouble) (dev_width_mm * dev_height) / (dev_height_mm * dev_width); 207 | 208 | /* Now, find the one from device_par_map[][2] with the lowest delta 209 | * to the real one */ 210 | delta = DELTA (ratio, 0, 0); 211 | index = 0; 212 | windex = 0; 213 | 214 | for (i = 1; i < G_N_ELEMENTS (device_par_map); i++) { 215 | for (j = 0; j < 2; j++) { 216 | cur_delta = DELTA (ratio, i, j); 217 | if (cur_delta < delta) { 218 | index = i; 219 | windex = j; 220 | delta = cur_delta; 221 | } 222 | } 223 | } 224 | 225 | if (dpy_par_n) 226 | *dpy_par_n = device_par_map[index][windex]; 227 | 228 | if (dpy_par_d) 229 | *dpy_par_d = device_par_map[index][windex ^ 1]; 230 | } 231 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmpph264enc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | #include 25 | 26 | #include "gstmpph264enc.h" 27 | 28 | #define GST_CAT_DEFAULT mppvideoenc_debug 29 | 30 | #define parent_class gst_mpp_h264_enc_parent_class 31 | G_DEFINE_TYPE (GstMppH264Enc, gst_mpp_h264_enc, GST_TYPE_MPP_VIDEO_ENC); 32 | 33 | static GstStaticPadTemplate gst_mpp_h264_enc_src_template = 34 | GST_STATIC_PAD_TEMPLATE ("src", 35 | GST_PAD_SRC, 36 | GST_PAD_ALWAYS, 37 | GST_STATIC_CAPS ("video/x-h264, " 38 | "width = (int) [ 32, 1920 ], " 39 | "height = (int) [ 32, 1080 ], " 40 | "framerate = (fraction) [0/1, 30/1], " 41 | "stream-format = (string) { byte-stream }, " 42 | "alignment = (string) { au }, " "profile = (string) { high }") 43 | ); 44 | 45 | static gboolean 46 | gst_mpp_h264_enc_open (GstVideoEncoder * encoder) 47 | { 48 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 49 | 50 | GST_DEBUG_OBJECT (self, "Opening"); 51 | 52 | if (mpp_create (&self->mpp_ctx, &self->mpi)) 53 | goto failure; 54 | if (mpp_init (self->mpp_ctx, MPP_CTX_ENC, MPP_VIDEO_CodingAVC)) 55 | goto failure; 56 | 57 | return TRUE; 58 | 59 | failure: 60 | return FALSE; 61 | } 62 | 63 | static gboolean 64 | gst_mpp_h264_enc_set_format (GstVideoEncoder * encoder, 65 | GstVideoCodecState * state) 66 | { 67 | GstMppH264Enc *self = GST_MPP_H264_ENC (encoder); 68 | GstMppVideoEnc *mpp_video_enc = GST_MPP_VIDEO_ENC (encoder); 69 | MppEncCodecCfg codec_cfg; 70 | MppEncRcCfg rc_cfg; 71 | 72 | memset (&rc_cfg, 0, sizeof (rc_cfg)); 73 | memset (&codec_cfg, 0, sizeof (codec_cfg)); 74 | 75 | rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_ALL; 76 | rc_cfg.rc_mode = MPP_ENC_RC_MODE_CBR; 77 | rc_cfg.quality = MPP_ENC_RC_QUALITY_MEDIUM; 78 | 79 | rc_cfg.fps_in_flex = 0; 80 | rc_cfg.fps_in_num = GST_VIDEO_INFO_FPS_N (&state->info) 81 | / GST_VIDEO_INFO_FPS_D (&state->info); 82 | rc_cfg.fps_in_denorm = 1; 83 | rc_cfg.fps_out_flex = 0; 84 | rc_cfg.fps_out_num = GST_VIDEO_INFO_FPS_N (&state->info) 85 | / GST_VIDEO_INFO_FPS_D (&state->info); 86 | rc_cfg.fps_out_denorm = 1; 87 | rc_cfg.gop = GST_VIDEO_INFO_FPS_N (&state->info) 88 | / GST_VIDEO_INFO_FPS_D (&state->info); 89 | rc_cfg.skip_cnt = 0; 90 | 91 | if (mpp_video_enc->mpi->control (mpp_video_enc->mpp_ctx, MPP_ENC_SET_RC_CFG, 92 | &rc_cfg)) { 93 | GST_DEBUG_OBJECT (self, "Setting rate control for rockchip mpp failed"); 94 | return FALSE; 95 | } 96 | 97 | if (rc_cfg.rc_mode == MPP_ENC_RC_MODE_CBR) { 98 | codec_cfg.h264.qp_max = 48; 99 | codec_cfg.h264.qp_min = 4; 100 | codec_cfg.h264.qp_max_step = 16; 101 | codec_cfg.h264.qp_init = 0; 102 | 103 | rc_cfg.bps_target = GST_VIDEO_INFO_WIDTH (&state->info) 104 | * GST_VIDEO_INFO_HEIGHT (&state->info) 105 | / 8 * GST_VIDEO_INFO_FPS_N (&state->info) 106 | / GST_VIDEO_INFO_FPS_D (&state->info); 107 | rc_cfg.bps_max = rc_cfg.bps_target * 17 / 16; 108 | rc_cfg.bps_min = rc_cfg.bps_target * 15 / 16; 109 | } else if (rc_cfg.rc_mode == MPP_ENC_RC_MODE_VBR) { 110 | if (rc_cfg.quality == MPP_ENC_RC_QUALITY_CQP) { 111 | codec_cfg.h264.qp_max = 26; 112 | codec_cfg.h264.qp_min = 26; 113 | codec_cfg.h264.qp_max_step = 0; 114 | codec_cfg.h264.qp_init = 26; 115 | 116 | rc_cfg.bps_target = -1; 117 | rc_cfg.bps_max = -1; 118 | rc_cfg.bps_min = -1; 119 | 120 | } else { 121 | codec_cfg.h264.qp_max = 40; 122 | codec_cfg.h264.qp_min = 12; 123 | codec_cfg.h264.qp_max_step = 0; 124 | codec_cfg.h264.qp_init = 0; 125 | 126 | rc_cfg.bps_target = 0; 127 | rc_cfg.bps_max = rc_cfg.bps_target * 17 / 16; 128 | rc_cfg.bps_min = rc_cfg.bps_target * 1 / 16; 129 | } 130 | } 131 | 132 | codec_cfg.coding = MPP_VIDEO_CodingAVC; 133 | codec_cfg.h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE | 134 | MPP_ENC_H264_CFG_CHANGE_ENTROPY | 135 | MPP_ENC_H264_CFG_CHANGE_TRANS_8x8 | MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; 136 | codec_cfg.h264.profile = 100; 137 | codec_cfg.h264.level = 40; 138 | codec_cfg.h264.entropy_coding_mode = 1; 139 | codec_cfg.h264.cabac_init_idc = 0; 140 | codec_cfg.h264.transform8x8_mode = 1; 141 | 142 | if (mpp_video_enc->mpi->control (mpp_video_enc->mpp_ctx, 143 | MPP_ENC_SET_CODEC_CFG, &codec_cfg)) { 144 | GST_DEBUG_OBJECT (self, "Setting codec info for rockchip mpp failed"); 145 | return FALSE; 146 | } 147 | 148 | return GST_MPP_VIDEO_ENC_CLASS (parent_class)->set_format (encoder, state); 149 | } 150 | 151 | static GstFlowReturn 152 | gst_mpp_h264_enc_handle_frame (GstVideoEncoder * encoder, 153 | GstVideoCodecFrame * frame) 154 | { 155 | GstCaps *outcaps; 156 | GstStructure *structure; 157 | 158 | outcaps = gst_caps_new_empty_simple ("video/x-h264"); 159 | structure = gst_caps_get_structure (outcaps, 0); 160 | gst_structure_set (structure, "stream-format", 161 | G_TYPE_STRING, "byte-stream", NULL); 162 | gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL); 163 | 164 | return GST_MPP_VIDEO_ENC_CLASS (parent_class)->handle_frame (encoder, frame, 165 | outcaps); 166 | } 167 | 168 | static void 169 | gst_mpp_h264_enc_init (GstMppH264Enc * self) 170 | { 171 | } 172 | 173 | static void 174 | gst_mpp_h264_enc_class_init (GstMppH264EncClass * klass) 175 | { 176 | GstElementClass *element_class; 177 | GstVideoEncoderClass *video_encoder_class; 178 | 179 | element_class = (GstElementClass *) klass; 180 | video_encoder_class = (GstVideoEncoderClass *) klass; 181 | 182 | gst_element_class_set_static_metadata (element_class, 183 | "Rockchip Mpp H264 Encoder", 184 | "Codec/Encoder/Video", 185 | "Encode video streams via Rockchip Mpp", 186 | "Randy Li "); 187 | 188 | video_encoder_class->open = GST_DEBUG_FUNCPTR (gst_mpp_h264_enc_open); 189 | video_encoder_class->set_format = 190 | GST_DEBUG_FUNCPTR (gst_mpp_h264_enc_set_format); 191 | video_encoder_class->handle_frame = 192 | GST_DEBUG_FUNCPTR (gst_mpp_h264_enc_handle_frame); 193 | 194 | gst_element_class_add_pad_template (element_class, 195 | gst_static_pad_template_get (&gst_mpp_h264_enc_src_template)); 196 | } 197 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpuallocator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include "config.h" 19 | #endif 20 | 21 | #ifndef _GNU_SOURCE 22 | # define _GNU_SOURCE /* O_CLOEXEC */ 23 | #endif 24 | 25 | #include 26 | #include 27 | 28 | #include "gstvpuallocator.h" 29 | 30 | #define GST_VPU_MEMORY_TYPE "VpuMemory" 31 | 32 | #define gst_vpu_allocator_parent_class parent_class 33 | G_DEFINE_TYPE (GstVpuAllocator, gst_vpu_allocator, GST_TYPE_ALLOCATOR); 34 | 35 | GST_DEBUG_CATEGORY_STATIC (vpuallocator_debug); 36 | #define GST_CAT_DEFAULT vpuallocator_debug 37 | 38 | gboolean 39 | gst_is_vpu_memory (GstMemory * mem) 40 | { 41 | return gst_memory_is_type (mem, GST_VPU_MEMORY_TYPE); 42 | } 43 | 44 | GQuark 45 | gst_vpu_memory_quark (void) 46 | { 47 | static GQuark quark = 0; 48 | if (quark == 0) 49 | quark = g_quark_from_string ("GstVpuMemory"); 50 | 51 | return quark; 52 | } 53 | 54 | static inline GstVpuMemory * 55 | _vpumem_new (GstMemoryFlags flags, GstAllocator * allocator, 56 | GstMemory * parent, gsize maxsize, gsize align, gsize offset, gsize size, 57 | gpointer data, int dmafd, VPUMemLinear_t * vpu_mem) 58 | { 59 | GstVpuMemory *mem; 60 | 61 | mem = g_slice_new0 (GstVpuMemory); 62 | gst_memory_init (GST_MEMORY_CAST (mem), 63 | flags, allocator, parent, maxsize, align, offset, size); 64 | 65 | mem->data = data; 66 | mem->dmafd = dmafd; 67 | mem->vpu_mem = vpu_mem; 68 | mem->size = maxsize; 69 | 70 | return mem; 71 | } 72 | 73 | static void 74 | _vpumem_free (GstVpuMemory * mem) 75 | { 76 | g_slice_free (GstVpuMemory, mem); 77 | } 78 | 79 | static gpointer 80 | _vpumem_map (GstVpuMemory * mem, gsize maxsize, GstMapFlags flags) 81 | { 82 | return mem->data; 83 | } 84 | 85 | static void 86 | _vpumem_unmap (GstMemory * mem) 87 | { 88 | return; 89 | } 90 | 91 | static GstVpuMemory * 92 | _vpumem_share (GstVpuMemory * mem, gssize offset, gssize size) 93 | { 94 | GstVpuMemory *sub; 95 | GstMemory *parent; 96 | 97 | /* find the real parent */ 98 | if ((parent = mem->mem.parent) == NULL) 99 | parent = (GstMemory *) mem; 100 | 101 | if (size == -1) 102 | size = mem->mem.size - offset; 103 | 104 | /* the shared memory is always readonly */ 105 | sub = _vpumem_new (GST_MINI_OBJECT_FLAGS (parent) | 106 | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent, 107 | mem->mem.maxsize, mem->mem.align, offset, size, mem->data, 108 | -1, mem->vpu_mem); 109 | 110 | return sub; 111 | } 112 | 113 | static gboolean 114 | _vpumem_is_span (GstVpuMemory * mem1, GstVpuMemory * mem2, gsize * offset) 115 | { 116 | if (offset) 117 | *offset = mem1->mem.offset - mem1->mem.parent->offset; 118 | 119 | /* and memory is contiguous */ 120 | return mem1->mem.offset + mem1->mem.size == mem2->mem.offset; 121 | } 122 | 123 | /* 124 | * GstVpuAllocator Implementation 125 | */ 126 | 127 | /* Auto clean up methods */ 128 | static void 129 | gst_vpu_allocator_dispose (GObject * obj) 130 | { 131 | GST_LOG_OBJECT (obj, "called"); 132 | /* Don't need cleanup buffers from allocator again, 133 | * the free() method have done that */ 134 | 135 | G_OBJECT_CLASS (parent_class)->dispose (obj); 136 | } 137 | 138 | static void 139 | gst_vpu_allocator_finalize (GObject * obj) 140 | { 141 | GstVpuAllocator *allocator = (GstVpuAllocator *) obj; 142 | 143 | GST_LOG_OBJECT (obj, "called"); 144 | 145 | if (allocator->vpu_display_pool) 146 | close_vpu_memory_pool (allocator->vpu_display_pool); 147 | 148 | gst_atomic_queue_unref (allocator->free_queue); 149 | 150 | G_OBJECT_CLASS (parent_class)->finalize (obj); 151 | } 152 | 153 | /* Manually clean way */ 154 | gint 155 | gst_vpu_allocator_stop (GstVpuAllocator * allocator) 156 | { 157 | guint i = 0; 158 | gint ret = 0; 159 | GST_DEBUG_OBJECT (allocator, "stop allocator"); 160 | 161 | GST_OBJECT_LOCK (allocator); 162 | 163 | if (!g_atomic_int_get (&allocator->active)) 164 | goto done; 165 | 166 | if (gst_atomic_queue_length (allocator->free_queue) != allocator->count) { 167 | GST_DEBUG_OBJECT (allocator, "allocator is still in use"); 168 | ret = -EBUSY; 169 | goto done; 170 | } 171 | while (gst_atomic_queue_pop (allocator->free_queue)) { 172 | /* Nothing */ 173 | }; 174 | 175 | for (i = 0; i < allocator->count; i++) { 176 | GstVpuMemory *mem = allocator->mems[i]; 177 | allocator->mems[i] = NULL; 178 | if (mem) 179 | _vpumem_free (mem); 180 | } 181 | 182 | allocator->count = 0; 183 | 184 | if (allocator->vpu_display_pool) { 185 | close_vpu_memory_pool (allocator->vpu_display_pool); 186 | allocator->vpu_display_pool = NULL; 187 | } 188 | 189 | g_atomic_int_set (&allocator->active, FALSE); 190 | done: 191 | GST_OBJECT_UNLOCK (allocator); 192 | return ret; 193 | } 194 | 195 | static void 196 | gst_vpu_allocator_free (GstAllocator * gallocator, GstMemory * gmem) 197 | { 198 | GstVpuMemory *mem = (GstVpuMemory *) gmem; 199 | 200 | g_slice_free (GstVpuMemory, mem); 201 | } 202 | 203 | GstMemory * 204 | gst_vpu_allocator_alloc_dmabuf (GstVpuAllocator * allocator, 205 | GstAllocator * dmabuf_allocator) 206 | { 207 | GstVpuMemory *mem; 208 | GstMemory *dma_mem; 209 | 210 | mem = gst_atomic_queue_pop (allocator->free_queue); 211 | if (mem == NULL) 212 | return NULL; 213 | 214 | if (mem->dmafd < 0) { 215 | GST_ERROR_OBJECT (allocator, "Failed to get dmafd"); 216 | gst_atomic_queue_push (allocator->free_queue, mem); 217 | 218 | return NULL; 219 | } 220 | 221 | dma_mem = gst_dmabuf_allocator_alloc (dmabuf_allocator, mem->dmafd, 222 | mem->size); 223 | gst_mini_object_set_qdata (GST_MINI_OBJECT (dma_mem), 224 | GST_VPU_MEMORY_QUARK, mem, (GDestroyNotify) gst_memory_unref); 225 | 226 | return dma_mem; 227 | } 228 | 229 | GstVpuAllocator * 230 | gst_vpu_allocator_new (GstObject * parent) 231 | { 232 | GstVpuAllocator *allocator = NULL; 233 | gchar *name, *parent_name; 234 | 235 | parent_name = gst_object_get_name (parent); 236 | name = g_strconcat (parent_name, ":allocator", NULL); 237 | g_free (parent_name); 238 | 239 | allocator = g_object_new (GST_TYPE_VPU_ALLOCATOR, "name", name, NULL); 240 | g_free (name); 241 | 242 | return allocator; 243 | } 244 | 245 | guint 246 | gst_vpu_allocator_start (GstVpuAllocator * allocator, 247 | gpointer vpu, gsize size, guint32 count) 248 | { 249 | VpuCodecContext_t *vpu_codec_ctx = (VpuCodecContext_t *) vpu; 250 | vpu_display_mem_pool *vpu_display_pool; 251 | gint i, ret; 252 | VPU_SYNC sync; 253 | 254 | g_return_val_if_fail (count != 0, 0); 255 | g_return_val_if_fail (size != 0, 0); 256 | 257 | GST_OBJECT_LOCK (allocator); 258 | if (g_atomic_int_get (&allocator->active)) 259 | goto already_active; 260 | 261 | allocator->vpu_display_pool = open_vpu_memory_pool (); 262 | vpu_display_pool = allocator->vpu_display_pool; 263 | if (vpu_display_pool == NULL) 264 | goto vpu_display_pool_error; 265 | vpu_codec_ctx->control (vpu_codec_ctx, VPU_API_SET_VPUMEM_CONTEXT, 266 | vpu_display_pool); 267 | sync.flag = 1; 268 | /* If no buffers is ready, block the dequeue operation */ 269 | vpu_codec_ctx->control (vpu_codec_ctx, 270 | VPU_API_SET_OUTPUT_BLOCK, (void *) &sync); 271 | 272 | for (i = 0; i < count; i++) { 273 | VPUMemLinear_t *vpu_mem; 274 | VPUMemLinear_t temp_vpu_mem; 275 | /* 276 | * Create vpumem from mpp/libvpu 277 | * included mvc data 278 | */ 279 | VPUMallocLinearOutside (&temp_vpu_mem, size); 280 | vpu_mem = g_slice_copy (sizeof (VPUMemLinear_t), &temp_vpu_mem); 281 | vpu_mem->index = allocator->count; 282 | 283 | ret = vpu_display_pool->commit_vpu (allocator->vpu_display_pool, vpu_mem); 284 | /* Release the old buffer reference in the other memory group */ 285 | VPUFreeLinear (&temp_vpu_mem); 286 | if (ret > 0) 287 | vpu_display_pool->inc_used (vpu_display_pool, vpu_mem); 288 | 289 | allocator->mems[i] = _vpumem_new (0, GST_ALLOCATOR (allocator), NULL, 290 | vpu_mem->size, 0, 0, vpu_mem->size, NULL, VPUMemGetFD (vpu_mem), 291 | vpu_mem); 292 | 293 | if (gst_is_vpu_memory ((GstMemory *) allocator->mems[i])) { 294 | gst_atomic_queue_push (allocator->free_queue, allocator->mems[i]); 295 | allocator->count++; 296 | } else { 297 | GST_ERROR_OBJECT (allocator, "allocate buffer %d failed", vpu_mem->index); 298 | goto error; 299 | } 300 | } 301 | 302 | g_atomic_int_set (&allocator->active, TRUE); 303 | 304 | done: 305 | GST_OBJECT_UNLOCK (allocator); 306 | 307 | return (gst_atomic_queue_length (allocator->free_queue)); 308 | vpu_display_pool_error: 309 | { 310 | GST_ERROR_OBJECT (allocator, "failed to create vpu display pool"); 311 | goto error; 312 | } 313 | already_active: 314 | { 315 | GST_ERROR_OBJECT (allocator, "allocator already active"); 316 | goto error; 317 | } 318 | error: 319 | { 320 | allocator->count = 0; 321 | goto done; 322 | } 323 | } 324 | 325 | static void 326 | gst_vpu_allocator_class_init (GstVpuAllocatorClass * klass) 327 | { 328 | GObjectClass *object_class; 329 | GstAllocatorClass *allocator_class; 330 | 331 | allocator_class = (GstAllocatorClass *) klass; 332 | object_class = (GObjectClass *) klass; 333 | 334 | allocator_class->alloc = NULL; 335 | allocator_class->free = gst_vpu_allocator_free; 336 | 337 | object_class->dispose = gst_vpu_allocator_dispose; 338 | object_class->finalize = gst_vpu_allocator_finalize; 339 | 340 | GST_DEBUG_CATEGORY_INIT (vpuallocator_debug, "vpuallocator", 0, 341 | "VPU Allocator"); 342 | } 343 | 344 | static void 345 | gst_vpu_allocator_init (GstVpuAllocator * allocator) 346 | { 347 | GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); 348 | 349 | alloc->mem_type = GST_VPU_MEMORY_TYPE; 350 | alloc->mem_map = (GstMemoryMapFunction) _vpumem_map; 351 | alloc->mem_unmap = (GstMemoryUnmapFunction) _vpumem_unmap; 352 | alloc->mem_share = (GstMemoryShareFunction) _vpumem_share; 353 | alloc->mem_is_span = (GstMemoryIsSpanFunction) _vpumem_is_span; 354 | 355 | allocator->free_queue = gst_atomic_queue_new (VIDEO_MAX_FRAME); 356 | 357 | GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); 358 | } 359 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppallocator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #ifndef _GNU_SOURCE 27 | # define _GNU_SOURCE /* O_CLOEXEC */ 28 | #endif 29 | 30 | #include 31 | 32 | #include "gstmppallocator.h" 33 | 34 | #define GST_MPP_MEMORY_TYPE "MppMemory" 35 | 36 | #define gst_mpp_allocator_parent_class parent_class 37 | G_DEFINE_TYPE (GstMppAllocator, gst_mpp_allocator, GST_TYPE_ALLOCATOR); 38 | 39 | GST_DEBUG_CATEGORY_STATIC (mppallocator_debug); 40 | #define GST_CAT_DEFAULT mppallocator_debug 41 | 42 | gboolean 43 | gst_is_mpp_memory (GstMemory * mem) 44 | { 45 | return gst_memory_is_type (mem, GST_MPP_MEMORY_TYPE); 46 | } 47 | 48 | GQuark 49 | gst_mpp_memory_quark (void) 50 | { 51 | static GQuark quark = 0; 52 | if (quark == 0) 53 | quark = g_quark_from_string ("GstMppMemory"); 54 | 55 | return quark; 56 | } 57 | 58 | static inline GstMppMemory * 59 | _mppmem_new (GstMemoryFlags flags, GstAllocator * allocator, 60 | GstMemory * parent, gsize maxsize, gsize align, gsize offset, gsize size, 61 | gpointer data, int dmafd, MppBuffer * mpp_buf) 62 | { 63 | GstMppMemory *mem; 64 | 65 | mem = g_slice_new0 (GstMppMemory); 66 | gst_memory_init (GST_MEMORY_CAST (mem), 67 | flags, allocator, parent, maxsize, align, offset, size); 68 | 69 | mem->data = data; 70 | mem->dmafd = dmafd; 71 | mem->mpp_buf = mpp_buf; 72 | mem->size = maxsize; 73 | 74 | return mem; 75 | } 76 | 77 | static void 78 | _mppmem_free (GstMppMemory * mem) 79 | { 80 | g_slice_free (GstMppMemory, mem); 81 | } 82 | 83 | static gpointer 84 | _mppmem_map (GstMppMemory * mem, gsize maxsize, GstMapFlags flags) 85 | { 86 | return mem->data; 87 | } 88 | 89 | static void 90 | _mppmem_unmap (GstMemory * mem) 91 | { 92 | return; 93 | } 94 | 95 | static GstMppMemory * 96 | _mppmem_share (GstMppMemory * mem, gssize offset, gssize size) 97 | { 98 | GstMppMemory *sub; 99 | GstMemory *parent; 100 | 101 | /* find the real parent */ 102 | if ((parent = mem->mem.parent) == NULL) 103 | parent = (GstMemory *) mem; 104 | 105 | if (size == -1) 106 | size = mem->mem.size - offset; 107 | 108 | /* the shared memory is always readonly */ 109 | sub = _mppmem_new (GST_MINI_OBJECT_FLAGS (parent) | 110 | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent, 111 | mem->mem.maxsize, mem->mem.align, offset, size, mem->data, 112 | -1, mem->mpp_buf); 113 | 114 | return sub; 115 | } 116 | 117 | static gboolean 118 | _mppmem_is_span (GstMppMemory * mem1, GstMppMemory * mem2, gsize * offset) 119 | { 120 | if (offset) 121 | *offset = mem1->mem.offset - mem1->mem.parent->offset; 122 | 123 | /* and memory is contiguous */ 124 | return mem1->mem.offset + mem1->mem.size == mem2->mem.offset; 125 | } 126 | 127 | /* 128 | * GstVpuAllocator Implementation 129 | */ 130 | 131 | /* Auto clean up methods */ 132 | static void 133 | gst_mpp_allocator_dispose (GObject * obj) 134 | { 135 | GST_LOG_OBJECT (obj, "called"); 136 | /* Don't need cleanup buffers from allocator again, 137 | * the free() method have done that */ 138 | 139 | G_OBJECT_CLASS (parent_class)->dispose (obj); 140 | } 141 | 142 | static void 143 | gst_mpp_allocator_finalize (GObject * obj) 144 | { 145 | GstMppAllocator *allocator = (GstMppAllocator *) obj; 146 | 147 | GST_LOG_OBJECT (obj, "called"); 148 | 149 | if (allocator->mpp_mem_pool) { 150 | mpp_buffer_group_put (allocator->mpp_mem_pool); 151 | allocator->mpp_mem_pool = NULL; 152 | } 153 | 154 | gst_atomic_queue_unref (allocator->free_queue); 155 | 156 | G_OBJECT_CLASS (parent_class)->finalize (obj); 157 | } 158 | 159 | /* Manually clean way */ 160 | gint 161 | gst_mpp_allocator_stop (GstMppAllocator * allocator) 162 | { 163 | guint i = 0; 164 | gint ret = 0; 165 | GST_DEBUG_OBJECT (allocator, "stop allocator"); 166 | 167 | GST_OBJECT_LOCK (allocator); 168 | 169 | if (!g_atomic_int_get (&allocator->active)) 170 | goto done; 171 | 172 | if (gst_atomic_queue_length (allocator->free_queue) != allocator->count) { 173 | GST_DEBUG_OBJECT (allocator, "allocator is still in use"); 174 | ret = -EBUSY; 175 | goto done; 176 | } 177 | while (gst_atomic_queue_pop (allocator->free_queue)) { 178 | /* Nothing */ 179 | }; 180 | 181 | for (i = 0; i < allocator->count; i++) { 182 | GstMppMemory *mem = allocator->mems[i]; 183 | allocator->mems[i] = NULL; 184 | if (mem) 185 | _mppmem_free (mem); 186 | } 187 | 188 | allocator->count = 0; 189 | 190 | if (allocator->mpp_mem_pool) { 191 | mpp_buffer_group_put (allocator->mpp_mem_pool); 192 | allocator->mpp_mem_pool = NULL; 193 | } 194 | 195 | g_atomic_int_set (&allocator->active, FALSE); 196 | done: 197 | GST_OBJECT_UNLOCK (allocator); 198 | return ret; 199 | } 200 | 201 | static void 202 | gst_mpp_allocator_free (GstAllocator * gallocator, GstMemory * gmem) 203 | { 204 | GstMppMemory *mem = (GstMppMemory *) gmem; 205 | 206 | g_slice_free (GstMppMemory, mem); 207 | } 208 | 209 | GstMemory * 210 | gst_mpp_allocator_alloc_dmabuf (GstMppAllocator * allocator, 211 | GstAllocator * dmabuf_allocator) 212 | { 213 | GstMppMemory *mem; 214 | GstMemory *dma_mem; 215 | 216 | mem = gst_atomic_queue_pop (allocator->free_queue); 217 | if (mem == NULL) 218 | return NULL; 219 | 220 | if (mem->dmafd < 0) { 221 | GST_ERROR_OBJECT (allocator, "Failed to get dmafd"); 222 | gst_atomic_queue_push (allocator->free_queue, mem); 223 | 224 | return NULL; 225 | } 226 | 227 | dma_mem = gst_dmabuf_allocator_alloc (dmabuf_allocator, mem->dmafd, 228 | mem->size); 229 | gst_mini_object_set_qdata (GST_MINI_OBJECT (dma_mem), 230 | GST_MPP_MEMORY_QUARK, mem, (GDestroyNotify) gst_memory_unref); 231 | 232 | return dma_mem; 233 | } 234 | 235 | GstMppAllocator * 236 | gst_mpp_allocator_new (GstObject * parent) 237 | { 238 | GstMppAllocator *allocator = NULL; 239 | gchar *name, *parent_name; 240 | 241 | parent_name = gst_object_get_name (parent); 242 | name = g_strconcat (parent_name, ":allocator", NULL); 243 | g_free (parent_name); 244 | 245 | allocator = g_object_new (GST_TYPE_MPP_ALLOCATOR, "name", name, NULL); 246 | g_free (name); 247 | 248 | return allocator; 249 | } 250 | 251 | static guint 252 | gst_mpp_allocator_drm_buf (GstMppAllocator * allocator, gsize size, 253 | guint32 count) 254 | { 255 | MppBufferGroup group; 256 | MppBuffer temp_buf[VIDEO_MAX_FRAME]; 257 | 258 | /* FIXME the rockchip mpp should support DRM type properly */ 259 | mpp_buffer_group_get_internal (&group, MPP_BUFFER_TYPE_ION); 260 | 261 | mpp_buffer_group_get_external (&allocator->mpp_mem_pool, MPP_BUFFER_TYPE_ION); 262 | if (allocator->mpp_mem_pool == NULL) 263 | goto mpp_mem_pool_error; 264 | 265 | /* Create DRM buffer from rockchip mpp internally */ 266 | for (gint i = 0; i < count; i++) { 267 | /* 268 | * Create MppBuffer from Rockchip Mpp 269 | * included mvc data 270 | */ 271 | if (mpp_buffer_get (group, &temp_buf[i], size)) { 272 | GST_ERROR_OBJECT (allocator, "allocate internal buffer %d failed", i); 273 | goto error; 274 | } 275 | } 276 | 277 | for (gint i = 0; i < count; i++) { 278 | MppBuffer mpp_buf; 279 | MppBufferInfo commit; 280 | 281 | mpp_buf = temp_buf[i]; 282 | mpp_buffer_set_index (mpp_buf, i); 283 | mpp_buffer_info_get (mpp_buf, &commit); 284 | 285 | if (mpp_buffer_commit (allocator->mpp_mem_pool, &commit)) { 286 | GST_DEBUG_OBJECT (allocator, "commit buffer %d failed", i); 287 | continue; 288 | } 289 | 290 | mpp_buffer_put (mpp_buf); 291 | /* Remember to release the reference of this buffer */ 292 | if (!mpp_buffer_get (allocator->mpp_mem_pool, &mpp_buf, size)) { 293 | 294 | allocator->mems[i] = _mppmem_new (0, GST_ALLOCATOR (allocator), NULL, 295 | mpp_buffer_get_size (mpp_buf), 0, 0, mpp_buffer_get_size (mpp_buf), 296 | NULL, mpp_buffer_get_fd (mpp_buf), mpp_buf); 297 | 298 | } 299 | if (gst_is_mpp_memory ((GstMemory *) allocator->mems[i])) { 300 | gst_atomic_queue_push (allocator->free_queue, allocator->mems[i]); 301 | allocator->count++; 302 | } else { 303 | GST_ERROR_OBJECT (allocator, "allocate buffer %d failed", 304 | mpp_buffer_get_index (mpp_buf)); 305 | goto error; 306 | } 307 | } 308 | 309 | mpp_buffer_group_put (group); 310 | return (gst_atomic_queue_length (allocator->free_queue)); 311 | 312 | mpp_mem_pool_error: 313 | { 314 | GST_ERROR_OBJECT (allocator, "failed to create mpp memory pool"); 315 | goto error; 316 | } 317 | error: 318 | { 319 | allocator->count = 0; 320 | return 0; 321 | } 322 | } 323 | 324 | guint 325 | gst_mpp_allocator_start (GstMppAllocator * allocator, gsize size, guint32 count) 326 | { 327 | g_return_val_if_fail (count != 0, 0); 328 | g_return_val_if_fail (size != 0, 0); 329 | 330 | GST_OBJECT_LOCK (allocator); 331 | if (g_atomic_int_get (&allocator->active)) 332 | goto already_active; 333 | 334 | gst_mpp_allocator_drm_buf (allocator, size, count); 335 | 336 | g_atomic_int_set (&allocator->active, TRUE); 337 | 338 | done: 339 | GST_OBJECT_UNLOCK (allocator); 340 | 341 | return (gst_atomic_queue_length (allocator->free_queue)); 342 | already_active: 343 | { 344 | GST_ERROR_OBJECT (allocator, "allocator already active"); 345 | goto error; 346 | } 347 | error: 348 | { 349 | allocator->count = 0; 350 | goto done; 351 | } 352 | } 353 | 354 | static void 355 | gst_mpp_allocator_class_init (GstMppAllocatorClass * klass) 356 | { 357 | GObjectClass *object_class; 358 | GstAllocatorClass *allocator_class; 359 | 360 | allocator_class = (GstAllocatorClass *) klass; 361 | object_class = (GObjectClass *) klass; 362 | 363 | allocator_class->alloc = NULL; 364 | allocator_class->free = gst_mpp_allocator_free; 365 | 366 | object_class->dispose = gst_mpp_allocator_dispose; 367 | object_class->finalize = gst_mpp_allocator_finalize; 368 | 369 | GST_DEBUG_CATEGORY_INIT (mppallocator_debug, "mppallocator", 0, 370 | "MPP Allocator"); 371 | } 372 | 373 | static void 374 | gst_mpp_allocator_init (GstMppAllocator * allocator) 375 | { 376 | GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); 377 | 378 | alloc->mem_type = GST_MPP_MEMORY_TYPE; 379 | alloc->mem_map = (GstMemoryMapFunction) _mppmem_map; 380 | alloc->mem_unmap = (GstMemoryUnmapFunction) _mppmem_unmap; 381 | alloc->mem_share = (GstMemoryShareFunction) _mppmem_share; 382 | alloc->mem_is_span = (GstMemoryIsSpanFunction) _mppmem_is_span; 383 | 384 | allocator->free_queue = gst_atomic_queue_new (VIDEO_MAX_FRAME); 385 | 386 | GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); 387 | } 388 | -------------------------------------------------------------------------------- /gst/vpudec/gstvpudecbufferpool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Rockchip Electronics Co., Ltd 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "gstvpuallocator.h" 27 | #include "gstvpudecbufferpool.h" 28 | 29 | GST_DEBUG_CATEGORY_STATIC (vpubufferpool_debug); 30 | #define GST_CAT_DEFAULT vpubufferpool_debug 31 | 32 | /* 33 | * GstVpuDecBufferPool: 34 | */ 35 | #define gst_vpudec_buffer_pool_parent_class parent_class 36 | G_DEFINE_TYPE (GstVpuDecBufferPool, gst_vpudec_buffer_pool, 37 | GST_TYPE_BUFFER_POOL); 38 | 39 | static void gst_vpudec_buffer_pool_release_buffer (GstBufferPool * bpool, 40 | GstBuffer * buffer); 41 | 42 | static gboolean 43 | gst_vpudec_is_buffer_valid (GstBuffer * buffer, GstVpuMemory ** out_mem) 44 | { 45 | GstMemory *mem = gst_buffer_peek_memory (buffer, 0); 46 | gboolean valid = FALSE; 47 | 48 | if (gst_is_dmabuf_memory (mem)) 49 | mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem), 50 | GST_VPU_MEMORY_QUARK); 51 | else 52 | goto done; 53 | 54 | if (mem && gst_is_vpu_memory (mem)) { 55 | *out_mem = (GstVpuMemory *) mem; 56 | valid = TRUE; 57 | } 58 | 59 | done: 60 | return valid; 61 | } 62 | 63 | static gboolean 64 | gst_vpudec_buffer_pool_start (GstBufferPool * bpool) 65 | { 66 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 67 | GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class); 68 | GstStructure *config; 69 | GstCaps *caps; 70 | guint size, min_buffers, max_buffers, count; 71 | VpuCodecContext_t *vpu_codec_ctx; 72 | 73 | GST_DEBUG_OBJECT (pool, "start pool %p", pool); 74 | 75 | config = gst_buffer_pool_get_config (bpool); 76 | if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, 77 | &max_buffers)) 78 | goto wrong_config; 79 | 80 | vpu_codec_ctx = pool->dec->vpu_codec_ctx; 81 | 82 | count = gst_vpu_allocator_start (pool->vallocator, vpu_codec_ctx, 83 | size, min_buffers); 84 | 85 | if (count < min_buffers) 86 | goto no_buffers; 87 | 88 | pool->size = size; 89 | 90 | if (max_buffers != 0 && max_buffers < min_buffers) 91 | max_buffers = min_buffers; 92 | 93 | gst_buffer_pool_config_set_params (config, caps, size, min_buffers, 94 | max_buffers); 95 | pclass->set_config (bpool, config); 96 | gst_structure_free (config); 97 | 98 | /* allocate the buffers */ 99 | if (!pclass->start (bpool)) 100 | goto start_failed; 101 | 102 | return TRUE; 103 | 104 | /* ERRORS */ 105 | wrong_config: 106 | { 107 | GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config); 108 | return FALSE; 109 | } 110 | no_buffers: 111 | { 112 | GST_ERROR_OBJECT (pool, 113 | "we received %d buffer, we want at least %d", count, min_buffers); 114 | gst_structure_free (config); 115 | return FALSE; 116 | } 117 | start_failed: 118 | { 119 | GST_ERROR_OBJECT (pool, "failed to start pool %p", pool); 120 | return FALSE; 121 | } 122 | } 123 | 124 | static gboolean 125 | gst_vpudec_buffer_pool_stop (GstBufferPool * bpool) 126 | { 127 | gboolean ret; 128 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 129 | GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class); 130 | guint n; 131 | 132 | GST_DEBUG_OBJECT (pool, "stop pool %p", pool); 133 | 134 | /* free the remaining buffers */ 135 | for (n = 0; n < VIDEO_MAX_FRAME; n++) { 136 | if (pool->buffers[n]) { 137 | GstBuffer *buffer = pool->buffers[n]; 138 | 139 | pool->buffers[n] = NULL; 140 | gst_buffer_unref (buffer); 141 | 142 | g_atomic_int_add (&pool->num_queued, -1); 143 | } 144 | } 145 | /* free the buffers in the queue */ 146 | ret = pclass->stop (bpool); 147 | 148 | if (ret && pool->vallocator) { 149 | gint vret; 150 | vret = gst_vpu_allocator_stop (pool->vallocator); 151 | 152 | ret = (vret == 0); 153 | } 154 | 155 | return ret; 156 | } 157 | 158 | static GstFlowReturn 159 | gst_vpudec_buffer_pool_alloc_buffer (GstBufferPool * bpool, 160 | GstBuffer ** buffer, GstBufferPoolAcquireParams * params) 161 | { 162 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 163 | GstVpuDec *dec = pool->dec; 164 | GstMemory *mem; 165 | GstBuffer *newbuf = NULL; 166 | GstVideoInfo *info; 167 | 168 | info = &dec->info; 169 | 170 | mem = gst_vpu_allocator_alloc_dmabuf (pool->vallocator, pool->allocator); 171 | if (mem != NULL) { 172 | newbuf = gst_buffer_new (); 173 | gst_buffer_append_memory (newbuf, mem); 174 | } else { 175 | goto allocation_failed; 176 | } 177 | 178 | gst_buffer_add_video_meta_full (newbuf, GST_VIDEO_FRAME_FLAG_NONE, 179 | GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), 180 | GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info), 181 | info->offset, info->stride); 182 | 183 | *buffer = newbuf; 184 | 185 | return GST_FLOW_OK; 186 | 187 | /* ERRORS */ 188 | allocation_failed: 189 | { 190 | GST_ERROR_OBJECT (pool, "failed to allocate buffer"); 191 | return GST_FLOW_ERROR; 192 | } 193 | } 194 | 195 | static void 196 | gst_vpudec_buffer_pool_release_buffer (GstBufferPool * bpool, 197 | GstBuffer * buffer) 198 | { 199 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 200 | GstVpuMemory *mem = NULL; 201 | gint index = -1; 202 | 203 | if (!gst_vpudec_is_buffer_valid (buffer, &mem)) { 204 | GST_ERROR_OBJECT (pool, "can't release an invalid buffer"); 205 | } 206 | 207 | index = mem->vpu_mem->index; 208 | 209 | if (pool->buffers[index] != NULL) { 210 | goto already_queued; 211 | } else { 212 | /* Release the internal refcount in mpp */ 213 | VPUFreeLinear (mem->vpu_mem); 214 | pool->buffers[index] = buffer; 215 | g_atomic_int_add (&pool->num_queued, 1); 216 | } 217 | 218 | GST_DEBUG_OBJECT (pool, 219 | "released buffer %p, index %d, queued %d", buffer, index, 220 | g_atomic_int_get (&pool->num_queued)); 221 | 222 | return; 223 | /* ERRORS */ 224 | already_queued: 225 | { 226 | GST_WARNING_OBJECT (pool, "the buffer was already released"); 227 | return; 228 | } 229 | } 230 | 231 | static GstFlowReturn 232 | gst_vpudec_buffer_pool_acquire_buffer (GstBufferPool * bpool, 233 | GstBuffer ** buffer, GstBufferPoolAcquireParams * params) 234 | { 235 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 236 | GstVpuDec *dec = pool->dec; 237 | VpuCodecContext_t *ctx; 238 | GstBuffer *outbuf; 239 | DecoderOut_t dec_out; 240 | VPU_FRAME vpu_frame; 241 | VPUMemLinear_t vpu_mem; 242 | VPU_API_ERR ret; 243 | gint buf_index; 244 | 245 | memset (&dec_out, 0, sizeof (DecoderOut_t)); 246 | memset (&vpu_frame, 0, sizeof (VPU_FRAME)); 247 | dec_out.data = (guint8 *) & vpu_frame; 248 | ctx = (VpuCodecContext_t *) dec->vpu_codec_ctx; 249 | 250 | if ((ret = ctx->decode_getframe (ctx, &dec_out)) < 0) 251 | goto vpu_error; 252 | vpu_mem = vpu_frame.vpumem; 253 | /* Drop the invalid buffer */ 254 | if (vpu_frame.ErrorInfo) { 255 | VPUFreeLinear (&vpu_mem); 256 | return GST_FLOW_CUSTOM_ERROR_1; 257 | } 258 | 259 | /* get from the pool the GstBuffer associated with the index */ 260 | buf_index = vpu_mem.index; 261 | outbuf = pool->buffers[buf_index]; 262 | if (outbuf == NULL) 263 | goto no_buffer; 264 | 265 | pool->buffers[buf_index] = NULL; 266 | g_atomic_int_add (&pool->num_queued, -1); 267 | 268 | GST_DEBUG_OBJECT (pool, 269 | "acquired buffer %p (%p) , index %d, queued %d data %p", outbuf, 270 | (gpointer) vpu_mem.vir_addr, buf_index, 271 | g_atomic_int_get (&pool->num_queued), vpu_mem.offset); 272 | 273 | *buffer = outbuf; 274 | 275 | return GST_FLOW_OK; 276 | 277 | /* ERRORS */ 278 | vpu_error: 279 | { 280 | switch (ret) { 281 | case VPU_API_EOS_STREAM_REACHED: 282 | GST_DEBUG_OBJECT (pool, "eos reached at libvpu size %d data %p", 283 | dec_out.size, dec_out.data); 284 | return GST_FLOW_EOS; 285 | default: 286 | return GST_FLOW_ERROR; 287 | } 288 | } 289 | no_buffer: 290 | { 291 | GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d", 292 | buf_index); 293 | return GST_FLOW_ERROR; 294 | } 295 | } 296 | 297 | static gboolean 298 | gst_vpudec_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config) 299 | { 300 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (bpool); 301 | GstCaps *caps; 302 | guint size, min_buffers, max_buffers; 303 | gboolean updated = FALSE; 304 | gboolean ret; 305 | 306 | if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, 307 | &max_buffers)) 308 | goto wrong_config; 309 | 310 | GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); 311 | 312 | if (pool->allocator) 313 | gst_object_unref (pool->allocator); 314 | 315 | pool->allocator = gst_dmabuf_allocator_new (); 316 | 317 | if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0) { 318 | updated = TRUE; 319 | max_buffers = VIDEO_MAX_FRAME; 320 | GST_INFO_OBJECT (pool, "reducing maximum buffers to %u", max_buffers); 321 | } 322 | 323 | gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); 324 | 325 | gst_buffer_pool_config_set_params (config, caps, size, min_buffers, 326 | max_buffers); 327 | 328 | ret = GST_BUFFER_POOL_CLASS (parent_class)->set_config (bpool, config); 329 | 330 | return !updated && ret; 331 | 332 | /* ERROR */ 333 | wrong_config: 334 | { 335 | GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config); 336 | return FALSE; 337 | } 338 | } 339 | 340 | static void 341 | gst_vpudec_buffer_pool_dispose (GObject * object) 342 | { 343 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (object); 344 | 345 | if (pool->vallocator) 346 | gst_object_unref (pool->vallocator); 347 | pool->vallocator = NULL; 348 | 349 | if (pool->allocator) 350 | gst_object_unref (pool->allocator); 351 | pool->allocator = NULL; 352 | 353 | G_OBJECT_CLASS (parent_class)->dispose (object); 354 | } 355 | 356 | static void 357 | gst_vpudec_buffer_pool_finalize (GObject * object) 358 | { 359 | GstVpuDecBufferPool *pool = GST_VPUDEC_BUFFER_POOL (object); 360 | 361 | gst_object_unref (pool->dec); 362 | 363 | G_OBJECT_CLASS (parent_class)->finalize (object); 364 | } 365 | 366 | static void 367 | gst_vpudec_buffer_pool_init (GstVpuDecBufferPool * pool) 368 | { 369 | pool->dec = NULL; 370 | pool->num_queued = 0; 371 | } 372 | 373 | static void 374 | gst_vpudec_buffer_pool_class_init (GstVpuDecBufferPoolClass * klass) 375 | { 376 | GObjectClass *object_class = G_OBJECT_CLASS (klass); 377 | GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass); 378 | 379 | object_class->dispose = gst_vpudec_buffer_pool_dispose; 380 | object_class->finalize = gst_vpudec_buffer_pool_finalize; 381 | 382 | bufferpool_class->start = gst_vpudec_buffer_pool_start; 383 | bufferpool_class->stop = gst_vpudec_buffer_pool_stop; 384 | bufferpool_class->set_config = gst_vpudec_buffer_pool_set_config; 385 | bufferpool_class->alloc_buffer = gst_vpudec_buffer_pool_alloc_buffer; 386 | bufferpool_class->acquire_buffer = gst_vpudec_buffer_pool_acquire_buffer; 387 | bufferpool_class->release_buffer = gst_vpudec_buffer_pool_release_buffer; 388 | 389 | 390 | GST_DEBUG_CATEGORY_INIT (vpubufferpool_debug, "vpubufferpool", 0, 391 | "vpu bufferpool"); 392 | } 393 | 394 | /** 395 | * gst_vpudec_buffer_pool_new: 396 | * @dec: the vpu decoder owning the pool 397 | * @max: maximum buffers in the pool 398 | * @size: size of the buffer 399 | * 400 | * Construct a new buffer pool. 401 | * 402 | * Returns: the new pool, use gst_object_unref() to free resources 403 | */ 404 | GstBufferPool * 405 | gst_vpudec_buffer_pool_new (GstVpuDec * dec, GstCaps * caps) 406 | { 407 | GstVpuDecBufferPool *pool; 408 | GstStructure *config; 409 | gchar *name, *parent_name; 410 | 411 | /* setting a significant unique name */ 412 | parent_name = gst_object_get_name (GST_OBJECT (dec)); 413 | name = g_strconcat (parent_name, ":", "pool:", "src", NULL); 414 | g_free (parent_name); 415 | 416 | pool = 417 | (GstVpuDecBufferPool *) g_object_new (GST_TYPE_VPUDEC_BUFFER_POOL, 418 | "name", name, NULL); 419 | g_free (name); 420 | /* take a reference on vpudec to be sure that it will be released 421 | * after the pool */ 422 | 423 | pool->dec = gst_object_ref (dec); 424 | pool->vallocator = gst_vpu_allocator_new (GST_OBJECT (pool)); 425 | if (!pool->vallocator) 426 | goto allocator_failed; 427 | 428 | config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); 429 | gst_buffer_pool_config_set_params (config, caps, dec->info.size, 0, 0); 430 | /* This will simply set a default config, but will not configure the pool 431 | * because min and max are not valid */ 432 | gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config); 433 | 434 | return GST_BUFFER_POOL (pool); 435 | /* ERROR */ 436 | allocator_failed: 437 | { 438 | GST_ERROR_OBJECT (pool, "Failed to create vpu allocator"); 439 | gst_object_unref (pool); 440 | return NULL; 441 | } 442 | } 443 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppdecbufferpool.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include 24 | #endif 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "gstmppdecbufferpool.h" 32 | 33 | GST_DEBUG_CATEGORY_STATIC (mppdecbufferpool_debug); 34 | #define GST_CAT_DEFAULT mppdecbufferpool_debug 35 | 36 | /* 37 | * GstMppDecBufferPool: 38 | */ 39 | #define parent_class gst_mpp_dec_buffer_pool_parent_class 40 | G_DEFINE_TYPE (GstMppDecBufferPool, gst_mpp_dec_buffer_pool, 41 | GST_TYPE_BUFFER_POOL); 42 | 43 | static gboolean 44 | gst_mpp_dec_is_buffer_valid (GstBuffer * buffer, GstMppMemory ** out_mem) 45 | { 46 | GstMemory *mem = gst_buffer_peek_memory (buffer, 0); 47 | gboolean valid = FALSE; 48 | 49 | if (gst_is_dmabuf_memory (mem)) 50 | mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem), 51 | GST_MPP_MEMORY_QUARK); 52 | else 53 | goto done; 54 | 55 | if (mem && gst_is_mpp_memory (mem)) { 56 | *out_mem = (GstMppMemory *) mem; 57 | valid = TRUE; 58 | } 59 | 60 | done: 61 | return valid; 62 | } 63 | 64 | static gboolean 65 | gst_mpp_dec_buffer_pool_start (GstBufferPool * bpool) 66 | { 67 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 68 | GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class); 69 | GstStructure *config; 70 | GstCaps *caps; 71 | guint size, min_buffers, max_buffers, count; 72 | 73 | GST_DEBUG_OBJECT (pool, "start pool %p", pool); 74 | 75 | config = gst_buffer_pool_get_config (bpool); 76 | if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, 77 | &max_buffers)) 78 | goto wrong_config; 79 | 80 | count = gst_mpp_allocator_start (pool->vallocator, size, min_buffers); 81 | if (count < min_buffers) 82 | goto no_buffers; 83 | 84 | pool->dec->mpi->control (pool->dec->mpp_ctx, MPP_DEC_SET_EXT_BUF_GROUP, 85 | (gpointer) pool->vallocator->mpp_mem_pool); 86 | 87 | pool->size = size; 88 | 89 | if (max_buffers != 0 && max_buffers < min_buffers) 90 | max_buffers = min_buffers; 91 | 92 | gst_buffer_pool_config_set_params (config, caps, size, min_buffers, 93 | max_buffers); 94 | pclass->set_config (bpool, config); 95 | gst_structure_free (config); 96 | 97 | /* allocate the buffers */ 98 | if (!pclass->start (bpool)) 99 | goto start_failed; 100 | 101 | return TRUE; 102 | 103 | /* ERRORS */ 104 | wrong_config: 105 | { 106 | GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config); 107 | return FALSE; 108 | } 109 | no_buffers: 110 | { 111 | GST_ERROR_OBJECT (pool, 112 | "we received %d buffer, we want at least %d", count, min_buffers); 113 | gst_structure_free (config); 114 | return FALSE; 115 | } 116 | start_failed: 117 | { 118 | GST_ERROR_OBJECT (pool, "failed to start pool %p", pool); 119 | return FALSE; 120 | } 121 | } 122 | 123 | static gboolean 124 | gst_mpp_dec_buffer_pool_stop (GstBufferPool * bpool) 125 | { 126 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 127 | GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class); 128 | gboolean ret; 129 | guint n; 130 | 131 | GST_DEBUG_OBJECT (pool, "stop pool %p", pool); 132 | 133 | /* free the remaining buffers */ 134 | for (n = 0; n < VIDEO_MAX_FRAME; n++) { 135 | if (pool->buffers[n]) { 136 | GstBuffer *buffer = pool->buffers[n]; 137 | 138 | pool->buffers[n] = NULL; 139 | gst_buffer_unref (buffer); 140 | 141 | g_atomic_int_add (&pool->num_queued, -1); 142 | } 143 | } 144 | /* free the buffers in the queue */ 145 | ret = pclass->stop (bpool); 146 | 147 | if (ret && pool->vallocator) { 148 | gint vret; 149 | vret = gst_mpp_allocator_stop (pool->vallocator); 150 | 151 | ret = (vret == 0); 152 | } 153 | 154 | return ret; 155 | } 156 | 157 | static GstFlowReturn 158 | gst_mpp_dec_buffer_pool_alloc_buffer (GstBufferPool * bpool, 159 | GstBuffer ** buffer, GstBufferPoolAcquireParams * params) 160 | { 161 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 162 | GstMppVideoDec *dec = pool->dec; 163 | GstMemory *mem; 164 | GstBuffer *newbuf = NULL; 165 | GstVideoInfo *info; 166 | 167 | info = &dec->info; 168 | 169 | mem = gst_mpp_allocator_alloc_dmabuf (pool->vallocator, pool->allocator); 170 | if (mem != NULL) { 171 | newbuf = gst_buffer_new (); 172 | gst_buffer_append_memory (newbuf, mem); 173 | } else { 174 | goto allocation_failed; 175 | } 176 | 177 | gst_buffer_add_video_meta_full (newbuf, GST_VIDEO_FRAME_FLAG_NONE, 178 | GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), 179 | GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info), 180 | info->offset, info->stride); 181 | 182 | *buffer = newbuf; 183 | 184 | return GST_FLOW_OK; 185 | 186 | /* ERRORS */ 187 | allocation_failed: 188 | { 189 | GST_ERROR_OBJECT (pool, "failed to allocate buffer"); 190 | return GST_FLOW_ERROR; 191 | } 192 | } 193 | 194 | static void 195 | gst_mpp_dec_buffer_pool_release_buffer (GstBufferPool * bpool, 196 | GstBuffer * buffer) 197 | { 198 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 199 | GstMppMemory *mem = NULL; 200 | gint index = -1; 201 | 202 | if (!gst_mpp_dec_is_buffer_valid (buffer, &mem)) 203 | GST_ERROR_OBJECT (pool, "can't release an invalid buffer"); 204 | 205 | index = mpp_buffer_get_index (mem->mpp_buf); 206 | 207 | if (pool->buffers[index] != NULL) { 208 | goto already_queued; 209 | } else { 210 | /* Release the internal refcount in mpp */ 211 | mpp_buffer_put (mem->mpp_buf); 212 | pool->buffers[index] = buffer; 213 | g_atomic_int_add (&pool->num_queued, 1); 214 | } 215 | 216 | GST_DEBUG_OBJECT (pool, 217 | "released buffer %p, index %d, queued %d", buffer, index, 218 | g_atomic_int_get (&pool->num_queued)); 219 | 220 | return; 221 | /* ERRORS */ 222 | already_queued: 223 | { 224 | GST_WARNING_OBJECT (pool, "the buffer was already released"); 225 | return; 226 | } 227 | } 228 | 229 | static GstFlowReturn 230 | gst_mpp_dec_buffer_pool_acquire_buffer (GstBufferPool * bpool, 231 | GstBuffer ** buffer, GstBufferPoolAcquireParams * params) 232 | { 233 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 234 | GstMppVideoDec *dec = pool->dec; 235 | GstBuffer *outbuf; 236 | MppFrame mframe = NULL; 237 | MppBuffer mpp_buf; 238 | gint buf_index, ret; 239 | 240 | ret = dec->mpi->decode_get_frame (dec->mpp_ctx, &mframe); 241 | if (ret || NULL == mframe) 242 | goto mpp_error; 243 | 244 | if (mpp_frame_get_discard (mframe) || mpp_frame_get_errinfo (mframe)) 245 | goto drop_frame; 246 | /* get from the pool the GstBuffer associated with the index */ 247 | mpp_buf = mpp_frame_get_buffer (mframe); 248 | if (NULL == mpp_buf) 249 | goto mpp_eos; 250 | buf_index = mpp_buffer_get_index (mpp_buf); 251 | outbuf = pool->buffers[buf_index]; 252 | if (outbuf == NULL) 253 | goto no_buffer; 254 | 255 | /* 256 | * Increase the reference of the buffer or the destroy the mpp frame 257 | * would decrease the reference and put it back to unused status 258 | */ 259 | mpp_buffer_inc_ref (mpp_buf); 260 | mpp_frame_deinit (&mframe); 261 | 262 | pool->buffers[buf_index] = NULL; 263 | g_atomic_int_add (&pool->num_queued, -1); 264 | 265 | GST_DEBUG_OBJECT (pool, 266 | "acquired buffer %p (%p) , index %d, queued %d", outbuf, 267 | (gpointer) mpp_buffer_get_ptr (mpp_buf), buf_index, 268 | g_atomic_int_get (&pool->num_queued)); 269 | 270 | *buffer = outbuf; 271 | 272 | return GST_FLOW_OK; 273 | 274 | /* ERRORS */ 275 | mpp_eos: 276 | { 277 | GST_ERROR_OBJECT (pool, "got eos or %d", ret); 278 | return GST_FLOW_EOS; 279 | } 280 | mpp_error: 281 | { 282 | GST_ERROR_OBJECT (pool, "mpp error %d", ret); 283 | return GST_FLOW_ERROR; 284 | } 285 | no_buffer: 286 | { 287 | GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d", 288 | buf_index); 289 | return GST_FLOW_ERROR; 290 | } 291 | drop_frame: 292 | { 293 | mpp_frame_deinit (&mframe); 294 | return GST_FLOW_CUSTOM_ERROR_1; 295 | } 296 | } 297 | 298 | static gboolean 299 | gst_mpp_dec_buffer_pool_set_config (GstBufferPool * bpool, 300 | GstStructure * config) 301 | { 302 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (bpool); 303 | GstCaps *caps; 304 | guint size, min_buffers, max_buffers; 305 | gboolean updated = FALSE; 306 | gboolean ret; 307 | 308 | if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, 309 | &max_buffers)) 310 | goto wrong_config; 311 | 312 | GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config); 313 | 314 | if (pool->allocator) 315 | gst_object_unref (pool->allocator); 316 | 317 | pool->allocator = gst_dmabuf_allocator_new (); 318 | 319 | if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0) { 320 | updated = TRUE; 321 | max_buffers = VIDEO_MAX_FRAME; 322 | GST_INFO_OBJECT (pool, "reducing maximum buffers to %u", max_buffers); 323 | } 324 | 325 | gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); 326 | 327 | gst_buffer_pool_config_set_params (config, caps, size, min_buffers, 328 | max_buffers); 329 | 330 | ret = GST_BUFFER_POOL_CLASS (parent_class)->set_config (bpool, config); 331 | 332 | return !updated && ret; 333 | 334 | /* ERROR */ 335 | wrong_config: 336 | { 337 | GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config); 338 | return FALSE; 339 | } 340 | } 341 | 342 | static void 343 | gst_mpp_dec_buffer_pool_dispose (GObject * object) 344 | { 345 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (object); 346 | 347 | if (pool->vallocator) 348 | gst_object_unref (pool->vallocator); 349 | pool->vallocator = NULL; 350 | 351 | if (pool->allocator) 352 | gst_object_unref (pool->allocator); 353 | pool->allocator = NULL; 354 | 355 | G_OBJECT_CLASS (parent_class)->dispose (object); 356 | } 357 | 358 | static void 359 | gst_mpp_dec_buffer_pool_finalize (GObject * object) 360 | { 361 | GstMppDecBufferPool *pool = GST_MPP_DEC_BUFFER_POOL (object); 362 | 363 | gst_object_unref (pool->dec); 364 | 365 | G_OBJECT_CLASS (parent_class)->finalize (object); 366 | } 367 | 368 | static void 369 | gst_mpp_dec_buffer_pool_init (GstMppDecBufferPool * pool) 370 | { 371 | pool->dec = NULL; 372 | pool->num_queued = 0; 373 | } 374 | 375 | static void 376 | gst_mpp_dec_buffer_pool_class_init (GstMppDecBufferPoolClass * klass) 377 | { 378 | GObjectClass *object_class = G_OBJECT_CLASS (klass); 379 | GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass); 380 | 381 | object_class->dispose = gst_mpp_dec_buffer_pool_dispose; 382 | object_class->finalize = gst_mpp_dec_buffer_pool_finalize; 383 | 384 | bufferpool_class->start = gst_mpp_dec_buffer_pool_start; 385 | bufferpool_class->stop = gst_mpp_dec_buffer_pool_stop; 386 | bufferpool_class->set_config = gst_mpp_dec_buffer_pool_set_config; 387 | bufferpool_class->alloc_buffer = gst_mpp_dec_buffer_pool_alloc_buffer; 388 | bufferpool_class->acquire_buffer = gst_mpp_dec_buffer_pool_acquire_buffer; 389 | bufferpool_class->release_buffer = gst_mpp_dec_buffer_pool_release_buffer; 390 | 391 | 392 | GST_DEBUG_CATEGORY_INIT (mppdecbufferpool_debug, "mppdecbufferpool", 0, 393 | "mpp decoder bufferpool"); 394 | } 395 | 396 | /** 397 | * gst_mpp_dec_buffer_pool_new: 398 | * @dec: the mpp decoder owning the pool 399 | * @max: maximum buffers in the pool 400 | * @size: size of the buffer 401 | * 402 | * Construct a new buffer pool. 403 | * 404 | * Returns: the new pool, use gst_object_unref() to free resources 405 | */ 406 | GstBufferPool * 407 | gst_mpp_dec_buffer_pool_new (GstMppVideoDec * dec, GstCaps * caps) 408 | { 409 | GstMppDecBufferPool *pool; 410 | GstStructure *config; 411 | gchar *name, *parent_name; 412 | 413 | /* setting a significant unique name */ 414 | parent_name = gst_object_get_name (GST_OBJECT (dec)); 415 | name = g_strconcat (parent_name, ":", "pool:", "src", NULL); 416 | g_free (parent_name); 417 | 418 | pool = 419 | (GstMppDecBufferPool *) g_object_new (GST_TYPE_MPP_DEC_BUFFER_POOL, 420 | "name", name, NULL); 421 | g_free (name); 422 | /* take a reference on vpudec to be sure that it will be released 423 | * after the pool */ 424 | 425 | pool->dec = gst_object_ref (dec); 426 | pool->vallocator = gst_mpp_allocator_new (GST_OBJECT (pool)); 427 | if (!pool->vallocator) 428 | goto allocator_failed; 429 | 430 | config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); 431 | gst_buffer_pool_config_set_params (config, caps, dec->info.size, 0, 0); 432 | /* This will simply set a default config, but will not configure the pool 433 | * because min and max are not valid */ 434 | gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config); 435 | 436 | return GST_BUFFER_POOL (pool); 437 | /* ERROR */ 438 | allocator_failed: 439 | { 440 | GST_ERROR_OBJECT (pool, "Failed to create vpu allocator"); 441 | gst_object_unref (pool); 442 | return NULL; 443 | } 444 | } 445 | -------------------------------------------------------------------------------- /gst/kms/gstkmsallocator.c: -------------------------------------------------------------------------------- 1 | /* GStreamer 2 | * 3 | * Copyright (C) 2016 Igalia 4 | * 5 | * Authors: 6 | * Víctor Manuel Jáquez Leal 7 | * Javier Martin 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 22 | * Boston, MA 02110-1301, USA. 23 | * 24 | */ 25 | 26 | #ifdef HAVE_CONFIG_H 27 | #include "config.h" 28 | #endif 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /* it needs to be below because is internal to libdrm */ 38 | #include 39 | 40 | #include "gstkmsallocator.h" 41 | #include "gstkmsutils.h" 42 | 43 | #define GST_CAT_DEFAULT kmsallocator_debug 44 | GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); 45 | 46 | #define GST_KMS_MEMORY_TYPE "KMSMemory" 47 | 48 | struct kms_bo 49 | { 50 | void *ptr; 51 | size_t size; 52 | size_t offset; 53 | size_t pitch; 54 | unsigned handle; 55 | unsigned int refs; 56 | }; 57 | 58 | struct _GstKMSAllocatorPrivate 59 | { 60 | int fd; 61 | }; 62 | 63 | #define parent_class gst_kms_allocator_parent_class 64 | G_DEFINE_TYPE_WITH_CODE (GstKMSAllocator, gst_kms_allocator, GST_TYPE_ALLOCATOR, 65 | G_ADD_PRIVATE (GstKMSAllocator); 66 | GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "kmsallocator", 0, 67 | "KMS allocator")); 68 | 69 | enum 70 | { 71 | PROP_DRM_FD = 1, 72 | PROP_N, 73 | }; 74 | 75 | static GParamSpec *g_props[PROP_N] = { NULL, }; 76 | 77 | gboolean 78 | gst_is_kms_memory (GstMemory * mem) 79 | { 80 | return gst_memory_is_type (mem, GST_KMS_MEMORY_TYPE); 81 | } 82 | 83 | guint32 84 | gst_kms_memory_get_fb_id (GstMemory * mem) 85 | { 86 | if (!gst_is_kms_memory (mem)) 87 | return 0; 88 | return ((GstKMSMemory *) mem)->fb_id; 89 | } 90 | 91 | static gboolean 92 | check_fd (GstKMSAllocator * alloc) 93 | { 94 | return alloc->priv->fd > -1; 95 | } 96 | 97 | static void 98 | gst_kms_allocator_memory_reset (GstKMSAllocator * allocator, GstKMSMemory * mem) 99 | { 100 | int err; 101 | struct drm_mode_destroy_dumb arg = { 0, }; 102 | 103 | if (!check_fd (allocator)) 104 | return; 105 | 106 | if (mem->fb_id) { 107 | GST_DEBUG_OBJECT (allocator, "removing fb id %d", mem->fb_id); 108 | drmModeRmFB (allocator->priv->fd, mem->fb_id); 109 | mem->fb_id = 0; 110 | } 111 | 112 | if (!mem->bo) 113 | return; 114 | 115 | if (mem->bo->ptr != NULL) { 116 | GST_WARNING_OBJECT (allocator, "destroying mapped bo (refcount=%d)", 117 | mem->bo->refs); 118 | munmap (mem->bo->ptr, mem->bo->size); 119 | mem->bo->ptr = NULL; 120 | } 121 | 122 | arg.handle = mem->bo->handle; 123 | 124 | err = drmIoctl (allocator->priv->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); 125 | if (err) 126 | GST_WARNING_OBJECT (allocator, 127 | "Failed to destroy dumb buffer object: %s %d", strerror (errno), errno); 128 | 129 | g_free (mem->bo); 130 | mem->bo = NULL; 131 | } 132 | 133 | static gboolean 134 | gst_kms_allocator_memory_create (GstKMSAllocator * allocator, 135 | GstKMSMemory * kmsmem, GstVideoInfo * vinfo) 136 | { 137 | gint ret; 138 | struct drm_mode_create_dumb arg = { 0, }; 139 | guint32 fmt; 140 | 141 | if (kmsmem->bo) 142 | return TRUE; 143 | 144 | if (!check_fd (allocator)) 145 | return FALSE; 146 | 147 | kmsmem->bo = g_malloc0 (sizeof (*kmsmem->bo)); 148 | if (!kmsmem->bo) 149 | return FALSE; 150 | 151 | fmt = gst_drm_format_from_video (GST_VIDEO_INFO_FORMAT (vinfo)); 152 | arg.bpp = gst_drm_bpp_from_drm (fmt); 153 | arg.width = GST_VIDEO_INFO_WIDTH (vinfo); 154 | arg.height = gst_drm_height_from_drm (fmt, GST_VIDEO_INFO_HEIGHT (vinfo)); 155 | 156 | ret = drmIoctl (allocator->priv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); 157 | if (ret) 158 | goto create_failed; 159 | 160 | kmsmem->bo->handle = arg.handle; 161 | kmsmem->bo->size = arg.size; 162 | kmsmem->bo->pitch = arg.pitch; 163 | 164 | return TRUE; 165 | 166 | /* ERRORS */ 167 | create_failed: 168 | { 169 | GST_ERROR_OBJECT (allocator, "Failed to create buffer object: %s (%d)", 170 | strerror (-ret), ret); 171 | g_free (kmsmem->bo); 172 | kmsmem->bo = NULL; 173 | return FALSE; 174 | } 175 | } 176 | 177 | static void 178 | gst_kms_allocator_free (GstAllocator * allocator, GstMemory * mem) 179 | { 180 | GstKMSAllocator *alloc; 181 | GstKMSMemory *kmsmem; 182 | 183 | alloc = GST_KMS_ALLOCATOR (allocator); 184 | kmsmem = (GstKMSMemory *) mem; 185 | 186 | gst_kms_allocator_memory_reset (alloc, kmsmem); 187 | g_slice_free (GstKMSMemory, kmsmem); 188 | } 189 | 190 | static void 191 | gst_kms_allocator_set_property (GObject * object, guint prop_id, 192 | const GValue * value, GParamSpec * pspec) 193 | { 194 | GstKMSAllocator *alloc; 195 | 196 | alloc = GST_KMS_ALLOCATOR (object); 197 | 198 | switch (prop_id) { 199 | case PROP_DRM_FD:{ 200 | int fd = g_value_get_int (value); 201 | if (fd > -1) 202 | alloc->priv->fd = dup (fd); 203 | break; 204 | } 205 | default: 206 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 207 | break; 208 | } 209 | } 210 | 211 | static void 212 | gst_kms_allocator_get_property (GObject * object, guint prop_id, 213 | GValue * value, GParamSpec * pspec) 214 | { 215 | GstKMSAllocator *alloc; 216 | 217 | alloc = GST_KMS_ALLOCATOR (object); 218 | 219 | switch (prop_id) { 220 | case PROP_DRM_FD: 221 | g_value_set_int (value, alloc->priv->fd); 222 | break; 223 | default: 224 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 225 | break; 226 | } 227 | } 228 | 229 | static void 230 | gst_kms_allocator_finalize (GObject * obj) 231 | { 232 | GstKMSAllocator *alloc; 233 | 234 | alloc = GST_KMS_ALLOCATOR (obj); 235 | 236 | if (check_fd (alloc)) 237 | close (alloc->priv->fd); 238 | 239 | G_OBJECT_CLASS (parent_class)->finalize (obj); 240 | } 241 | 242 | static void 243 | gst_kms_allocator_class_init (GstKMSAllocatorClass * klass) 244 | { 245 | GObjectClass *gobject_class; 246 | GstAllocatorClass *allocator_class; 247 | 248 | allocator_class = GST_ALLOCATOR_CLASS (klass); 249 | gobject_class = G_OBJECT_CLASS (klass); 250 | 251 | allocator_class->free = gst_kms_allocator_free; 252 | 253 | gobject_class->set_property = gst_kms_allocator_set_property; 254 | gobject_class->get_property = gst_kms_allocator_get_property; 255 | gobject_class->finalize = gst_kms_allocator_finalize; 256 | 257 | g_props[PROP_DRM_FD] = g_param_spec_int ("drm-fd", "DRM fd", 258 | "DRM file descriptor", -1, G_MAXINT, -1, 259 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT); 260 | 261 | g_object_class_install_properties (gobject_class, PROP_N, g_props); 262 | } 263 | 264 | static gpointer 265 | gst_kms_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) 266 | { 267 | GstKMSMemory *kmsmem; 268 | GstKMSAllocator *alloc; 269 | int err; 270 | gpointer out; 271 | struct drm_mode_map_dumb arg = { 0, }; 272 | 273 | alloc = (GstKMSAllocator *) mem->allocator; 274 | 275 | if (!check_fd (alloc)) 276 | return NULL; 277 | 278 | kmsmem = (GstKMSMemory *) mem; 279 | if (!kmsmem->bo) 280 | return NULL; 281 | 282 | /* Reuse existing buffer object mapping if possible */ 283 | if (kmsmem->bo->ptr != NULL) { 284 | goto out; 285 | } 286 | 287 | arg.handle = kmsmem->bo->handle; 288 | 289 | err = drmIoctl (alloc->priv->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); 290 | if (err) { 291 | GST_ERROR_OBJECT (alloc, "Failed to get offset of buffer object: %s %d", 292 | strerror (-err), err); 293 | return NULL; 294 | } 295 | 296 | out = mmap (0, kmsmem->bo->size, 297 | PROT_READ | PROT_WRITE, MAP_SHARED, alloc->priv->fd, arg.offset); 298 | if (out == MAP_FAILED) { 299 | GST_ERROR_OBJECT (alloc, "Failed to map dumb buffer object: %s %d", 300 | strerror (errno), errno); 301 | return NULL; 302 | } 303 | kmsmem->bo->ptr = out; 304 | 305 | out: 306 | g_atomic_int_inc (&kmsmem->bo->refs); 307 | return kmsmem->bo->ptr; 308 | } 309 | 310 | static void 311 | gst_kms_memory_unmap (GstMemory * mem) 312 | { 313 | GstKMSMemory *kmsmem; 314 | 315 | if (!check_fd ((GstKMSAllocator *) mem->allocator)) 316 | return; 317 | 318 | kmsmem = (GstKMSMemory *) mem; 319 | if (!kmsmem->bo) 320 | return; 321 | 322 | if (g_atomic_int_dec_and_test (&kmsmem->bo->refs)) { 323 | munmap (kmsmem->bo->ptr, kmsmem->bo->size); 324 | kmsmem->bo->ptr = NULL; 325 | } 326 | } 327 | 328 | static void 329 | gst_kms_allocator_init (GstKMSAllocator * allocator) 330 | { 331 | GstAllocator *alloc; 332 | 333 | alloc = GST_ALLOCATOR_CAST (allocator); 334 | 335 | allocator->priv = gst_kms_allocator_get_instance_private (allocator); 336 | allocator->priv->fd = -1; 337 | 338 | alloc->mem_type = GST_KMS_MEMORY_TYPE; 339 | alloc->mem_map = gst_kms_memory_map; 340 | alloc->mem_unmap = gst_kms_memory_unmap; 341 | /* Use the default, fallback copy function */ 342 | 343 | GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); 344 | } 345 | 346 | GstAllocator * 347 | gst_kms_allocator_new (int fd) 348 | { 349 | return g_object_new (GST_TYPE_KMS_ALLOCATOR, "name", 350 | "KMSMemory::allocator", "drm-fd", fd, NULL); 351 | } 352 | 353 | /* The mem_offsets are relative to the GstMemory start, unlike the vinfo->offset 354 | * which are relative to the GstBuffer start. */ 355 | static gboolean 356 | gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem, 357 | gsize mem_offsets[GST_VIDEO_MAX_PLANES], GstVideoInfo * vinfo) 358 | { 359 | int i, ret; 360 | gint num_planes = GST_VIDEO_INFO_N_PLANES (vinfo); 361 | guint32 w, h, fmt, pitch = 0, bo_handles[4] = { 0, }; 362 | guint32 offsets[4] = { 0, }; 363 | guint32 pitches[4] = { 0, }; 364 | 365 | if (kmsmem->fb_id) 366 | return TRUE; 367 | 368 | w = GST_VIDEO_INFO_WIDTH (vinfo); 369 | h = GST_VIDEO_INFO_HEIGHT (vinfo); 370 | fmt = gst_drm_format_from_video (GST_VIDEO_INFO_FORMAT (vinfo)); 371 | 372 | if (kmsmem->bo) { 373 | bo_handles[0] = kmsmem->bo->handle; 374 | for (i = 1; i < num_planes; i++) 375 | bo_handles[i] = bo_handles[0]; 376 | 377 | /* Get the bo pitch calculated by the kms driver. 378 | * If it's defined, it will overwrite the video info's stride. 379 | * Since the API is completely undefined for planar formats, 380 | * only do this for interleaved formats. 381 | */ 382 | if (num_planes == 1) 383 | pitch = kmsmem->bo->pitch; 384 | } else { 385 | for (i = 0; i < num_planes; i++) 386 | bo_handles[i] = kmsmem->gem_handle[i]; 387 | } 388 | 389 | GST_DEBUG_OBJECT (alloc, "bo handles: %d, %d, %d, %d", bo_handles[0], 390 | bo_handles[1], bo_handles[2], bo_handles[3]); 391 | 392 | for (i = 0; i < num_planes; i++) { 393 | offsets[i] = mem_offsets[i]; 394 | if (pitch) 395 | GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i) = pitch; 396 | pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i); 397 | GST_DEBUG_OBJECT (alloc, "Create FB plane %i with stride %u and offset %u", 398 | i, pitches[i], offsets[i]); 399 | } 400 | 401 | ret = drmModeAddFB2 (alloc->priv->fd, w, h, fmt, bo_handles, pitches, 402 | offsets, &kmsmem->fb_id, 0); 403 | if (ret) { 404 | GST_ERROR_OBJECT (alloc, "Failed to bind to framebuffer: %s (%d)", 405 | strerror (-ret), ret); 406 | return FALSE; 407 | } 408 | return TRUE; 409 | } 410 | 411 | static GstMemory * 412 | gst_kms_allocator_alloc_empty (GstAllocator * allocator, GstVideoInfo * vinfo) 413 | { 414 | GstKMSMemory *kmsmem; 415 | GstMemory *mem; 416 | 417 | kmsmem = g_slice_new0 (GstKMSMemory); 418 | if (!kmsmem) 419 | return NULL; 420 | mem = GST_MEMORY_CAST (kmsmem); 421 | 422 | gst_memory_init (mem, GST_MEMORY_FLAG_NO_SHARE, allocator, NULL, 423 | GST_VIDEO_INFO_SIZE (vinfo), 0, 0, GST_VIDEO_INFO_SIZE (vinfo)); 424 | 425 | return mem; 426 | } 427 | 428 | GstMemory * 429 | gst_kms_allocator_bo_alloc (GstAllocator * allocator, GstVideoInfo * vinfo) 430 | { 431 | GstKMSAllocator *alloc; 432 | GstKMSMemory *kmsmem; 433 | GstMemory *mem; 434 | 435 | mem = gst_kms_allocator_alloc_empty (allocator, vinfo); 436 | if (!mem) 437 | return NULL; 438 | 439 | alloc = GST_KMS_ALLOCATOR (allocator); 440 | kmsmem = (GstKMSMemory *) mem; 441 | if (!gst_kms_allocator_memory_create (alloc, kmsmem, vinfo)) 442 | goto fail; 443 | if (!gst_kms_allocator_add_fb (alloc, kmsmem, vinfo->offset, vinfo)) 444 | goto fail; 445 | 446 | return mem; 447 | 448 | /* ERRORS */ 449 | fail: 450 | gst_memory_unref (mem); 451 | return NULL; 452 | } 453 | 454 | GstKMSMemory * 455 | gst_kms_allocator_dmabuf_import (GstAllocator * allocator, gint * prime_fds, 456 | gint n_planes, gsize offsets[GST_VIDEO_MAX_PLANES], GstVideoInfo * vinfo) 457 | { 458 | GstKMSAllocator *alloc; 459 | GstMemory *mem; 460 | GstKMSMemory *tmp; 461 | gint i, ret; 462 | 463 | g_return_val_if_fail (n_planes <= GST_VIDEO_MAX_PLANES, FALSE); 464 | 465 | mem = gst_kms_allocator_alloc_empty (allocator, vinfo); 466 | if (!mem) 467 | return FALSE; 468 | 469 | tmp = (GstKMSMemory *) mem; 470 | alloc = GST_KMS_ALLOCATOR (allocator); 471 | for (i = 0; i < n_planes; i++) { 472 | ret = drmPrimeFDToHandle (alloc->priv->fd, prime_fds[i], 473 | &tmp->gem_handle[i]); 474 | if (ret) 475 | goto import_fd_failed; 476 | } 477 | 478 | if (!gst_kms_allocator_add_fb (alloc, tmp, offsets, vinfo)) 479 | goto failed; 480 | 481 | return tmp; 482 | 483 | /* ERRORS */ 484 | import_fd_failed: 485 | { 486 | GST_ERROR_OBJECT (alloc, "Failed to import prime fd %d: %s (%d)", 487 | prime_fds[i], strerror (-ret), ret); 488 | /* fallback */ 489 | } 490 | 491 | failed: 492 | { 493 | gst_memory_unref (mem); 494 | return NULL; 495 | } 496 | } 497 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.62) 2 | 3 | dnl please read gstreamer/docs/random/autotools before changing this file 4 | 5 | dnl initialize autoconf 6 | dnl releases only do -Wall, git and prerelease does -Werror too 7 | dnl use a three digit version number for releases, and four for git/pre 8 | AC_INIT([GStreamer Plug-ins], [1.10.0], [https://github.com/rockchip-linux/gstreamer-rockchip], [gstreamer-rockchip]) 9 | 10 | AG_GST_INIT 11 | 12 | dnl initialize automake 13 | AM_INIT_AUTOMAKE([-Wno-portability 1.14 no-dist-gzip dist-xz tar-ustar subdir-objects]) 14 | 15 | dnl define PACKAGE_VERSION_* variables 16 | AS_VERSION 17 | 18 | dnl check if this is a release version 19 | AS_NANO(GST_GIT="no", GST_GIT="yes") 20 | 21 | dnl define the output header for config 22 | AM_CONFIG_HEADER([config.h]) 23 | 24 | dnl AM_MAINTAINER_MODE only provides the option to configure to enable it 25 | AM_MAINTAINER_MODE([enable]) 26 | 27 | dnl sets host_* variables 28 | AC_CANONICAL_HOST 29 | 30 | dnl use pretty build output with automake >= 1.11 31 | m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])], 32 | [AM_DEFAULT_VERBOSITY=1 33 | AC_SUBST(AM_DEFAULT_VERBOSITY)]) 34 | 35 | dnl PKG_CONFIG_SYSROOT_DIR is a valid environment variable 36 | m4_pattern_allow(PKG_CONFIG_SYSROOT_DIR) 37 | 38 | dnl our libraries and install dirs use GST_API_VERSION in the filename 39 | dnl to allow side-by-side installation of different API versions 40 | GST_API_VERSION=1.0 41 | AC_SUBST(GST_API_VERSION) 42 | AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION", 43 | [GStreamer API Version]) 44 | 45 | AG_GST_LIBTOOL_PREPARE 46 | AS_LIBTOOL(GST, 801, 0, 801) 47 | 48 | dnl *** required versions of GStreamer stuff *** 49 | GST_REQ=1.8.0 50 | GSTPB_REQ=1.8.2 51 | 52 | dnl *** autotools stuff **** 53 | 54 | dnl allow for different autotools 55 | AS_AUTOTOOLS_ALTERNATE 56 | 57 | dnl Add parameters for aclocal 58 | AC_SUBST(ACLOCAL_AMFLAGS, "-I m4 -I common/m4") 59 | 60 | dnl PKG_CONFIG_SYSROOT_DIR is a valid environment variable 61 | m4_pattern_allow(PKG_CONFIG_SYSROOT_DIR) 62 | 63 | dnl set up gettext 64 | dnl the version check needs to stay here because autopoint greps for it 65 | AM_GNU_GETTEXT_VERSION([0.17]) 66 | AM_GNU_GETTEXT([external]) 67 | AG_GST_GETTEXT([gstreamer-rockchip-$GST_API_VERSION]) 68 | 69 | AG_GST_ARG_DISABLE_FATAL_WARNINGS 70 | 71 | AG_GST_ARG_DEBUG 72 | AG_GST_ARG_PROFILING 73 | AG_GST_ARG_VALGRIND 74 | AG_GST_ARG_GCOV 75 | 76 | AG_GST_ARG_EXAMPLES 77 | 78 | AG_GST_ARG_WITH_PKG_CONFIG_PATH 79 | AG_GST_ARG_WITH_PACKAGE_NAME 80 | AG_GST_ARG_WITH_PACKAGE_ORIGIN 81 | 82 | AG_GST_ARG_WITH_PLUGINS 83 | 84 | AG_GST_ARG_ENABLE_EXTERNAL 85 | 86 | AG_GST_ARG_ENABLE_EXPERIMENTAL 87 | 88 | dnl *** checks for platform *** 89 | 90 | dnl * hardware/architecture * 91 | 92 | dnl common/m4/gst-arch.m4 93 | dnl check CPU type 94 | AG_GST_ARCH 95 | 96 | dnl Determine endianness 97 | AC_C_BIGENDIAN 98 | 99 | dnl *** checks for programs *** 100 | 101 | dnl find a compiler 102 | AC_PROG_CC 103 | AC_PROG_CC_STDC 104 | 105 | dnl determine c++ compiler 106 | AC_PROG_CXX 107 | dnl determine if c++ is available on this system 108 | AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) 109 | 110 | AC_PROG_OBJC 111 | 112 | dnl check if the compiler supports '-c' and '-o' options 113 | AM_PROG_CC_C_O 114 | 115 | dnl find an assembler 116 | AM_PROG_AS 117 | 118 | dnl check if the compiler supports do while(0) macros 119 | AG_GST_CHECK_DOWHILE_MACROS 120 | 121 | AC_PATH_PROG(VALGRIND_PATH, valgrind, no) 122 | AM_CONDITIONAL(HAVE_VALGRIND, test ! "x$VALGRIND_PATH" = "xno") 123 | 124 | dnl *** checks for libraries *** 125 | 126 | dnl check for libm, for sin() 127 | LT_LIB_M 128 | AC_SUBST(LIBM) 129 | 130 | dnl *** checks for header files *** 131 | 132 | dnl check if we have ANSI C header files 133 | AC_HEADER_STDC 134 | 135 | dnl *** checks for types/defines *** 136 | 137 | dnl *** checks for structures *** 138 | 139 | dnl *** checks for compiler characteristics *** 140 | 141 | dnl check if we have GCC inline-asm 142 | AS_GCC_INLINE_ASSEMBLY([HAVE_GCC_ASM=yes], [HAVE_GCC_ASM=no]) 143 | if test x$HAVE_GCC_ASM = xyes ; then 144 | AC_DEFINE(HAVE_GCC_ASM, 1, 145 | [Define if compiler supports gcc inline assembly]) 146 | fi 147 | AM_CONDITIONAL(HAVE_GCC_ASM, test "x$HAVE_GCC_ASM" = "xyes") 148 | 149 | dnl *** checks for library functions *** 150 | 151 | LIBS_SAVE=$LIBS 152 | LIBS="$LIBS $LIBM" 153 | AC_CHECK_FUNCS(rint sinh cosh asinh fpclass) 154 | LIBS=$LIBS_SAVE 155 | 156 | dnl Check whether isinf() is defined by math.h 157 | AC_CACHE_CHECK([for isinf], ac_cv_have_isinf, 158 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[float f = 0.0; int i=isinf(f)]])],[ac_cv_have_isinf="yes"],[ac_cv_have_isinf="no"])) 159 | if test "$ac_cv_have_isinf" = "yes" 160 | then 161 | AC_DEFINE(HAVE_ISINF, 1, [Define to 1 if you have the `isinf' function.]) 162 | fi 163 | 164 | dnl Check for mmap (needed by electricfence plugin) 165 | AC_FUNC_MMAP 166 | AM_CONDITIONAL(GST_HAVE_MMAP, test "x$ac_cv_func_mmap_fixed_mapped" = "xyes") 167 | 168 | dnl Check for mmap (needed by electricfence plugin) 169 | 170 | AC_CHECK_TYPE([struct ip_mreqn], [ 171 | AC_DEFINE(HAVE_IP_MREQN,, [Define if we have struct ip_mreqn])],, 172 | [#include ]) 173 | 174 | dnl *** checks for dependency libraries *** 175 | 176 | 177 | dnl GLib 178 | GLIB_REQ=2.32.0 179 | AG_GST_GLIB_CHECK([$GLIB_REQ]) 180 | 181 | dnl Orc 182 | ORC_CHECK([0.4.16]) 183 | 184 | dnl checks for gstreamer 185 | dnl uninstalled is selected preferentially -- see pkg-config(1) 186 | AG_GST_CHECK_GST($GST_API_VERSION, [$GST_REQ], yes) 187 | AG_GST_CHECK_GST_BASE($GST_API_VERSION, [$GST_REQ], yes) 188 | AG_GST_CHECK_GST_PLUGINS_BASE($GST_API_VERSION, [$GSTPB_REQ], yes) 189 | 190 | GST_TOOLS_DIR=`$PKG_CONFIG --variable=toolsdir gstreamer-$GST_API_VERSION` 191 | if test -z $GST_TOOLS_DIR; then 192 | AC_MSG_ERROR([no tools dir defined in GStreamer pkg-config file; core upgrade needed.]) 193 | fi 194 | AC_SUBST(GST_TOOLS_DIR) 195 | 196 | AC_MSG_NOTICE(Using GStreamer Core Plugins in $GST_PLUGINS_DIR) 197 | AC_MSG_NOTICE(Using GStreamer Base Plugins in $GSTPB_PLUGINS_DIR) 198 | 199 | dnl Check for documentation xrefs 200 | GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`" 201 | GST_PREFIX="`$PKG_CONFIG --variable=prefix gstreamer-$GST_API_VERSION`" 202 | GSTPB_PREFIX="`$PKG_CONFIG --variable=prefix gstreamer-plugins-base-$GST_API_VERSION`" 203 | AC_SUBST(GLIB_PREFIX) 204 | AC_SUBST(GST_PREFIX) 205 | AC_SUBST(GSTPB_PREFIX) 206 | 207 | dnl GTK is optional and used in examples 208 | HAVE_GTK=no 209 | GTK_REQ=3.0.0 210 | 211 | dnl *** set variables based on configure arguments *** 212 | 213 | dnl set license and copyright notice 214 | GST_LICENSE="GPL" 215 | AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license]) 216 | AC_SUBST(GST_LICENSE) 217 | 218 | dnl set location of plugin directory 219 | AG_GST_SET_PLUGINDIR 220 | 221 | dnl define an ERROR_CFLAGS Makefile variable 222 | dnl -Wundef: too many broken headers 223 | AG_GST_SET_ERROR_CFLAGS($FATAL_WARNINGS, [ 224 | -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls 225 | -Wwrite-strings -Wold-style-definition -Waggregate-return 226 | -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar 227 | -Wnested-externs $NO_WARNINGS]) 228 | 229 | dnl define an ERROR_CXXFLAGS Makefile variable 230 | AG_GST_SET_ERROR_CXXFLAGS($FATAL_WARNINGS, [ 231 | -Wmissing-declarations -Wredundant-decls 232 | -Wwrite-strings 233 | -Winit-self -Wmissing-include-dirs -Waddress -Wno-multichar 234 | $NO_WARNINGS]) 235 | 236 | dnl define an ERROR_OBJCFLAGS Makefile variable 237 | AG_GST_SET_ERROR_OBJCFLAGS($FATAL_WARNINGS, [ 238 | -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls 239 | -Wwrite-strings -Wold-style-definition 240 | -Winit-self -Wmissing-include-dirs -Wno-multichar 241 | -Wnested-externs $NO_WARNINGS]) 242 | 243 | dnl define correct level for debugging messages 244 | AG_GST_SET_LEVEL_DEFAULT($GST_GIT) 245 | 246 | dnl used in examples 247 | AG_GST_DEFAULT_ELEMENTS 248 | 249 | dnl *** plug-ins to include *** 250 | 251 | dnl Non ported plugins (non-dependant, then dependant) 252 | dnl Make sure you have a space before and after all plugins 253 | 254 | dnl these are all the gst plug-ins, compilable without additional libs 255 | 256 | dnl of EXT plugins 257 | AM_CONDITIONAL(USE_ROCKCHIPMPP, false) 258 | AM_CONDITIONAL(USE_VPUDEC, false) 259 | AM_CONDITIONAL(USE_KMS, false) 260 | AM_CONDITIONAL(USE_X11, false) 261 | AM_CONDITIONAL(USE_DRMROCKCHIP, false) 262 | AM_CONDITIONAL(USE_ARMMALI, false) 263 | 264 | dnl *** finalize CFLAGS, LDFLAGS, LIBS 265 | 266 | dnl Overview: 267 | dnl GST_OPTION_CFLAGS: common flags for profiling, debugging, errors, ... 268 | dnl GST_*: flags shared by all built objects 269 | dnl GST_ALL_LDFLAGS: linker flags shared by all 270 | dnl GST_LIB_LDFLAGS: not needed, we don't install libraries 271 | dnl GST_LT_LDFLAGS: library versioning of our libraries 272 | dnl GST_PLUGIN_LDFLAGS: flags to be used for all plugins 273 | 274 | dnl GST_OPTION_CFLAGS 275 | if test "x$USE_DEBUG" = xyes; then 276 | PROFILE_CFLAGS="-g" 277 | fi 278 | AC_SUBST(PROFILE_CFLAGS) 279 | 280 | if test "x$PACKAGE_VERSION_NANO" = "x1"; then 281 | dnl Define _only_ for git (not pre-releases or releases) 282 | DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED" 283 | else 284 | DEPRECATED_CFLAGS="" 285 | fi 286 | AC_SUBST(DEPRECATED_CFLAGS) 287 | 288 | dnl every flag in GST_OPTION_CFLAGS, GST_OPTION_CXXFLAGS and GST_OPTION_OBJCFLAGS can be overridden 289 | dnl at make time with e.g. make ERROR_CFLAGS="" 290 | GST_OPTION_CFLAGS="\$(WARNING_CFLAGS) \$(ERROR_CFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)" 291 | GST_OPTION_CXXFLAGS="\$(WARNING_CXXFLAGS) \$(ERROR_CXXFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)" 292 | GST_OPTION_OBJCFLAGS="\$(WARNING_OBJCFLAGS) \$(ERROR_OBJCFLAGS) \$(DEBUG_CFLAGS) \$(PROFILE_CFLAGS) \$(GCOV_CFLAGS) \$(OPT_CFLAGS) \$(DEPRECATED_CFLAGS)" 293 | AC_SUBST(GST_OPTION_CFLAGS) 294 | AC_SUBST(GST_OPTION_CXXFLAGS) 295 | AC_SUBST(GST_OPTION_OBJCFLAGS) 296 | 297 | dnl our libraries need to be versioned correctly 298 | AC_SUBST(GST_LT_LDFaLAGS) 299 | 300 | dnl FIXME: do we want to rename to GST_ALL_* ? 301 | dnl prefer internal headers to already installed ones 302 | dnl also add builddir include for enumtypes and marshal 303 | dnl add ERROR_CFLAGS, but overridable 304 | GST_CFLAGS="$GST_CFLAGS -DGST_USE_UNSTABLE_API" 305 | GST_CXXFLAGS="$GST_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CXXFLAGS)" 306 | GST_OBJCFLAGS="$GST_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_OBJCFLAGS)" 307 | GST_CFLAGS="$GST_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS)" 308 | AC_SUBST(GST_CFLAGS) 309 | AC_SUBST(GST_CXXFLAGS) 310 | AC_SUBST(GST_OBJCFLAGS) 311 | AC_SUBST(GST_LIBS) 312 | 313 | dnl LDFLAGS really should only contain flags, not libs - they get added before 314 | dnl whatevertarget_LIBS and -L flags here affect the rest of the linking 315 | GST_ALL_LDFLAGS="-Wl,-no-undefined" 316 | AC_SUBST(GST_ALL_LDFLAGS) 317 | 318 | dnl this really should only contain flags, not libs - they get added before 319 | dnl whatevertarget_LIBS and -L flags here affect the rest of the linking 320 | GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc.*' $GST_ALL_LDFLAGS" 321 | AC_SUBST(GST_PLUGIN_LDFLAGS) 322 | 323 | dnl *** output files *** 324 | PKG_CHECK_MODULES(GST_ALLOCATORS, gstreamer-allocators-1.0, 325 | HAVE_GST_ALLOCATORS=yes, ) 326 | PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-[$GST_API_VERSION], [$GST_REQ], yes) 327 | 328 | dnl *** rockchip mpp *** 329 | translit(dnm, m, l) AM_CONDITIONAL(USE_ROCKCHIPMPP, true) 330 | AG_GST_CHECK_FEATURE(ROCKCHIPMPP, [rockchip mpp libraries], rockchipmpp, [ 331 | PKG_CHECK_MODULES([ROCKCHIP_MPP], [rockchip_mpp >= 1.3.0], 332 | HAVE_ROCKCHIPMPP=yes, HAVE_ROCKCHIPMPP=no) 333 | ]) 334 | 335 | dnl *** rockchip vpu dec *** 336 | translit(dnm, m, l) AM_CONDITIONAL(USE_VPUDEC, true) 337 | AG_GST_CHECK_FEATURE(VPUDEC, [rockchip vpu legacy libraries], vpudec, [ 338 | PKG_CHECK_MODULES([ROCKCHIP_VPU], [rockchip_vpu < 0.3.0], 339 | HAVE_VPUDEC=yes, HAVE_VPUDEC=no) 340 | ]) 341 | 342 | dnl *** kms *** 343 | translit(dnm, m, l) AM_CONDITIONAL(USE_KMS, true) 344 | AG_GST_CHECK_FEATURE(KMS, [drm/kms libraries], kms, [ 345 | AG_GST_PKG_CHECK_MODULES(GST_ALLOCATORS, gstreamer-allocators-1.0) 346 | PKG_CHECK_MODULES([KMS_DRM], [libdrm >= 2.4.55], HAVE_KMS=yes, HAVE_KMS=no) 347 | ]) 348 | 349 | translit(dnm, m, l) AM_CONDITIONAL(USE_DRMROCKCHIP, true) 350 | AG_GST_CHECK_FEATURE(DRMROCKCHIP, [rockchip drm/kms libraries], drmrockchip, [ 351 | PKG_CHECK_MODULES([X11], [x11], HAVE_X11=yes, HAVE_X11=no) 352 | PKG_CHECK_MODULES([DRMROCKCHIP], [libdrm_rockchip], 353 | HAVE_DRMROCKCHIP=yes, HAVE_DRMROCKCHIP=no) 354 | ]) 355 | 356 | dnl keep this alphabetic per directory, please 357 | AC_CONFIG_FILES( 358 | Makefile 359 | gst-libs/Makefile 360 | gst-libs/gst/Makefile 361 | gst-libs/gst/vpudec/Makefile 362 | gst/Makefile 363 | gst/vpudec/Makefile 364 | gst/rockchipmpp/Makefile 365 | gst/rkximage/Makefile 366 | gst/kms/Makefile 367 | common/Makefile 368 | common/m4/Makefile 369 | m4/Makefile 370 | ) 371 | 372 | dnl Create the config.h file for Visual Studio builds 373 | dnl Beware of spaces and /'s in some of the shell variable contents. 374 | sed \ 375 | -e 's/.*config.h.in.*autoheader.*/\/* Autogenerated config.h created for win32 Visual Studio builds *\/\n\n\/* PREFIX -- specifically added for Windows for easier moving *\/\n#define PREFIX "C:\\\\gstreamer"\n\n#define GST_INSTALL_PLUGINS_HELPER PREFIX "\\\\libexec\\\\gst-install-plugins-helper.exe"/' \ 376 | -e 's/.* GETTEXT_PACKAGE$/#define GETTEXT_PACKAGE "'$GETTEXT_PACKAGE'"/' \ 377 | -e 's/.* GST_DATADIR$/#define GST_DATADIR PREFIX "\\\\share"/' \ 378 | -e 's/.* GST_LEVEL_DEFAULT$/#define GST_LEVEL_DEFAULT GST_LEVEL_ERROR/' \ 379 | -e 's/.* GST_LICENSE$/#define GST_LICENSE "'$GST_LICENSE'"/' \ 380 | -e 's/.* GST_API_VERSION$/#define GST_API_VERSION "'$GST_API_VERSION'"/' \ 381 | -e "s,.* GST_PACKAGE_NAME$,#define GST_PACKAGE_NAME \"${GST_PACKAGE_NAME}\"," \ 382 | -e 's/.* GST_PACKAGE_ORIGIN$/#define GST_PACKAGE_ORIGIN "Unknown package origin"/' \ 383 | -e "s,.* GST_PACKAGE_RELEASE_DATETIME$,#define GST_PACKAGE_RELEASE_DATETIME \"${GST_PACKAGE_RELEASE_DATETIME}\"," \ 384 | -e 's/.* HAVE_CPU_I386$/#define HAVE_CPU_I386 1/' \ 385 | -e 's/.* HAVE_FGETPOS$/#define HAVE_FGETPOS 1/' \ 386 | -e 's/.* HAVE_FSETPOS$/#define HAVE_FSETPOS 1/' \ 387 | -e 's/.* HAVE_LIBXML2$/#define HAVE_LIBXML2 1/' \ 388 | -e 's/.* HAVE_PROCESS_H$/#define HAVE_PROCESS_H 1/' \ 389 | -e 's/.* HAVE_STDLIB_H$/#define HAVE_STDLIB_H 1/' \ 390 | -e 's/.* HAVE_STRING_H$/#define HAVE_STRING_H 1/' \ 391 | -e 's/.* HAVE_SYS_STAT_H$/#define HAVE_SYS_STAT_H 1/' \ 392 | -e 's/.* HAVE_SYS_TYPES_H$/#define HAVE_SYS_TYPES_H 1/' \ 393 | -e 's/.* HAVE_WIN32$/#define HAVE_WIN32 1/' \ 394 | -e 's/.* HOST_CPU$/#define HOST_CPU "i686"/' \ 395 | -e 's/.* LIBDIR$/#ifdef _DEBUG\n# define LIBDIR PREFIX "\\\\debug\\\\lib"\n#else\n# define LIBDIR PREFIX "\\\\lib"\n#endif/' \ 396 | -e 's/.* LOCALEDIR$/#define LOCALEDIR PREFIX "\\\\share\\\\locale"/' \ 397 | -e "s/.* PACKAGE$/#define PACKAGE \"$PACKAGE\"/" \ 398 | -e 's/.* PACKAGE_BUGREPORT$/#define PACKAGE_BUGREPORT "http:\/\/bugzilla.gnome.org\/enter_bug.cgi?product=GStreamer"/' \ 399 | -e "s/.* PACKAGE_NAME$/#define PACKAGE_NAME \"$PACKAGE_NAME\"/" \ 400 | -e "s/.* PACKAGE_STRING$/#define PACKAGE_STRING \"$PACKAGE_STRING\"/" \ 401 | -e 's/.* PACKAGE_TARNAME$/#define PACKAGE_TARNAME "'$PACKAGE_TARNAME'"/' \ 402 | -e 's/.* PACKAGE_VERSION$/#define PACKAGE_VERSION "'$PACKAGE_VERSION'"/' \ 403 | -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n# define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.11"\n#else\n# define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.11"\n#endif/' \ 404 | -e 's/.* USE_BINARY_REGISTRY$/#define USE_BINARY_REGISTRY/' \ 405 | -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \ 406 | -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directsoundsink\"/" \ 407 | -e "s/.* DEFAULT_AUDIOSRC$/#define DEFAULT_AUDIOSRC \"audiotestsrc\"/" \ 408 | -e "s/.* DEFAULT_VIDEOSRC$/#define DEFAULT_VIDEOSRC \"videotestsrc\"/" \ 409 | -e "s/.* DEFAULT_VISUALIZER$/#define DEFAULT_VISUALIZER \"goom\"/" \ 410 | config.h.in >win32/common/config.h-new 411 | 412 | AC_OUTPUT 413 | AG_GST_OUTPUT_PLUGINS 414 | ORC_OUTPUT 415 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, 5 | Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell command `./configure && make && make install' 16 | should configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | HP-UX `make' updates targets which have the same time stamps as 230 | their prerequisites, which makes it generally unusable when shipped 231 | generated files such as `configure' are involved. Use GNU `make' 232 | instead. 233 | 234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 235 | parse its `' header file. The option `-nodtk' can be used as 236 | a workaround. If GNU CC is not installed, it is therefore recommended 237 | to try 238 | 239 | ./configure CC="cc" 240 | 241 | and if that doesn't work, try 242 | 243 | ./configure CC="cc -nodtk" 244 | 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 246 | directory contains several dysfunctional programs; working variants of 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 248 | in your `PATH', put it _after_ `/usr/bin'. 249 | 250 | On Haiku, software installed for all users goes in `/boot/common', 251 | not `/usr/local'. It is recommended to use the following options: 252 | 253 | ./configure --prefix=/boot/common 254 | 255 | Specifying the System Type 256 | ========================== 257 | 258 | There may be some features `configure' cannot figure out 259 | automatically, but needs to determine by the type of machine the package 260 | will run on. Usually, assuming the package is built to be run on the 261 | _same_ architectures, `configure' can figure that out, but if it prints 262 | a message saying it cannot guess the machine type, give it the 263 | `--build=TYPE' option. TYPE can either be a short name for the system 264 | type, such as `sun4', or a canonical name which has the form: 265 | 266 | CPU-COMPANY-SYSTEM 267 | 268 | where SYSTEM can have one of these forms: 269 | 270 | OS 271 | KERNEL-OS 272 | 273 | See the file `config.sub' for the possible values of each field. If 274 | `config.sub' isn't included in this package, then this package doesn't 275 | need to know the machine type. 276 | 277 | If you are _building_ compiler tools for cross-compiling, you should 278 | use the option `--target=TYPE' to select the type of system they will 279 | produce code for. 280 | 281 | If you want to _use_ a cross compiler, that generates code for a 282 | platform different from the build platform, you should specify the 283 | "host" platform (i.e., that on which the generated programs will 284 | eventually be run) with `--host=TYPE'. 285 | 286 | Sharing Defaults 287 | ================ 288 | 289 | If you want to set default values for `configure' scripts to share, 290 | you can create a site shell script called `config.site' that gives 291 | default values for variables like `CC', `cache_file', and `prefix'. 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the 294 | `CONFIG_SITE' environment variable to the location of the site script. 295 | A warning: not all `configure' scripts look for a site script. 296 | 297 | Defining Variables 298 | ================== 299 | 300 | Variables not defined in a site shell script can be set in the 301 | environment passed to `configure'. However, some packages may run 302 | configure again during the build, and the customized values of these 303 | variables may be lost. In order to avoid this problem, you should set 304 | them in the `configure' command line, using `VAR=value'. For example: 305 | 306 | ./configure CC=/usr/local2/bin/gcc 307 | 308 | causes the specified `gcc' to be used as the C compiler (unless it is 309 | overridden in the site shell script). 310 | 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 312 | an Autoconf limitation. Until the limitation is lifted, you can use 313 | this workaround: 314 | 315 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 316 | 317 | `configure' Invocation 318 | ====================== 319 | 320 | `configure' recognizes the following options to control how it 321 | operates. 322 | 323 | `--help' 324 | `-h' 325 | Print a summary of all of the options to `configure', and exit. 326 | 327 | `--help=short' 328 | `--help=recursive' 329 | Print a summary of the options unique to this package's 330 | `configure', and exit. The `short' variant lists options used 331 | only in the top level, while the `recursive' variant lists options 332 | also present in any nested packages. 333 | 334 | `--version' 335 | `-V' 336 | Print the version of Autoconf used to generate the `configure' 337 | script, and exit. 338 | 339 | `--cache-file=FILE' 340 | Enable the cache: use and save the results of the tests in FILE, 341 | traditionally `config.cache'. FILE defaults to `/dev/null' to 342 | disable caching. 343 | 344 | `--config-cache' 345 | `-C' 346 | Alias for `--cache-file=config.cache'. 347 | 348 | `--quiet' 349 | `--silent' 350 | `-q' 351 | Do not print messages saying which checks are being made. To 352 | suppress all normal output, redirect it to `/dev/null' (any error 353 | messages will still be shown). 354 | 355 | `--srcdir=DIR' 356 | Look for the package's source code in directory DIR. Usually 357 | `configure' can determine that directory automatically. 358 | 359 | `--prefix=DIR' 360 | Use DIR as the installation prefix. *note Installation Names:: 361 | for more details, including other options available for fine-tuning 362 | the installation locations. 363 | 364 | `--no-create' 365 | `-n' 366 | Run the configure checks, but stop before creating any output 367 | files. 368 | 369 | `configure' also accepts some other, not widely useful, options. Run 370 | `configure --help' for more details. 371 | -------------------------------------------------------------------------------- /gst/rockchipmpp/gstmppvideoenc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Rockchip Electronics Co., Ltd 3 | * Author: Randy Li 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Library General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Library General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Library General Public 16 | * License along with this library; if not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 18 | * Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | #include 25 | 26 | #include "gstmppvideoenc.h" 27 | 28 | GST_DEBUG_CATEGORY (mppvideoenc_debug); 29 | #define GST_CAT_DEFAULT mppvideoenc_debug 30 | 31 | #define parent_class gst_mpp_video_enc_parent_class 32 | G_DEFINE_ABSTRACT_TYPE (GstMppVideoEnc, gst_mpp_video_enc, 33 | GST_TYPE_VIDEO_ENCODER); 34 | 35 | static GstStaticPadTemplate gst_mpp_video_enc_sink_template = 36 | GST_STATIC_PAD_TEMPLATE ("sink", 37 | GST_PAD_SINK, 38 | GST_PAD_ALWAYS, 39 | GST_STATIC_CAPS ("video/x-raw," 40 | "format = (string) NV12, " 41 | "width = (int) [ 32, 1920 ], " 42 | "height = (int) [ 32, 1088 ], " 43 | "framerate = (fraction) [0/1, 60/1]" 44 | ";" 45 | "video/x-raw," 46 | "format = (string) I420, " 47 | "width = (int) [ 32, 1920 ], " 48 | "height = (int) [ 32, 1088 ], " 49 | "framerate = (fraction) [0/1, 60/1]" ";")); 50 | 51 | static gboolean 52 | gst_mpp_video_enc_close (GstVideoEncoder * encoder) 53 | { 54 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 55 | 56 | if (self->mpp_ctx) 57 | mpp_destroy (self->mpp_ctx); 58 | 59 | return TRUE; 60 | } 61 | 62 | static gboolean 63 | gst_mpp_video_enc_start (GstVideoEncoder * encoder) 64 | { 65 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 66 | 67 | GST_DEBUG_OBJECT (self, "Starting"); 68 | g_atomic_int_set (&self->active, TRUE); 69 | self->output_flow = GST_FLOW_OK; 70 | 71 | return TRUE; 72 | } 73 | 74 | static void 75 | gst_mpp_video_enc_process_buffer_stopped (GstMppVideoEnc * self) 76 | { 77 | if (g_atomic_int_get (&self->processing)) { 78 | GST_DEBUG_OBJECT (self, "Early stop of encoding thread"); 79 | self->output_flow = GST_FLOW_FLUSHING; 80 | g_atomic_int_set (&self->processing, FALSE); 81 | } 82 | 83 | GST_DEBUG_OBJECT (self, "Encoding task destroyed: %s", 84 | gst_flow_get_name (self->output_flow)); 85 | } 86 | 87 | 88 | static gboolean 89 | gst_mpp_video_enc_stop (GstVideoEncoder * encoder) 90 | { 91 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 92 | gint8 i; 93 | 94 | GST_DEBUG_OBJECT (self, "Stopping"); 95 | 96 | gst_mpp_video_enc_process_buffer_stopped (self); 97 | 98 | GST_VIDEO_ENCODER_STREAM_LOCK (encoder); 99 | self->output_flow = GST_FLOW_OK; 100 | GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); 101 | 102 | g_assert (g_atomic_int_get (&self->active) == FALSE); 103 | g_assert (g_atomic_int_get (&self->processing) == FALSE); 104 | 105 | if (self->input_state) { 106 | gst_video_codec_state_unref (self->input_state); 107 | self->input_state = NULL; 108 | } 109 | 110 | for (i = 0; i < MPP_MAX_BUFFERS; i++) { 111 | if (self->input_buffer[i]) { 112 | mpp_buffer_put (self->input_buffer[i]); 113 | self->input_buffer[i] = NULL; 114 | } 115 | if (self->output_buffer[i]) { 116 | mpp_buffer_put (self->output_buffer[i]); 117 | self->output_buffer[i] = NULL; 118 | } 119 | } 120 | 121 | /* Must be destroy before input_group */ 122 | if (self->mpp_frame) 123 | mpp_frame_deinit (&self->mpp_frame); 124 | 125 | if (self->input_group) { 126 | mpp_buffer_group_put (self->input_group); 127 | self->input_group = NULL; 128 | } 129 | 130 | if (self->output_group) { 131 | mpp_buffer_group_put (self->output_group); 132 | self->output_group = NULL; 133 | } 134 | 135 | GST_DEBUG_OBJECT (self, "Stopped"); 136 | 137 | return TRUE; 138 | } 139 | 140 | static MppFrameFormat 141 | to_mpp_pixel (GstCaps * caps, GstVideoInfo * info) 142 | { 143 | GstStructure *structure; 144 | const gchar *mimetype; 145 | 146 | structure = gst_caps_get_structure (caps, 0); 147 | mimetype = gst_structure_get_name (structure); 148 | 149 | if (g_str_equal (mimetype, "video/x-raw")) { 150 | switch (GST_VIDEO_INFO_FORMAT (info)) { 151 | case GST_VIDEO_FORMAT_I420: 152 | return MPP_FMT_YUV420P; 153 | break; 154 | case GST_VIDEO_FORMAT_NV12: 155 | return MPP_FMT_YUV420SP; 156 | break; 157 | default: 158 | break; 159 | } 160 | } 161 | return MPP_FMT_BUTT; 162 | } 163 | 164 | static gboolean 165 | gst_mpp_video_enc_set_format (GstVideoEncoder * encoder, 166 | GstVideoCodecState * state) 167 | { 168 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 169 | GstVideoInfo *info; 170 | GstVideoAlignment *align; 171 | MppEncPrepCfg prep_cfg; 172 | 173 | GST_DEBUG_OBJECT (self, "Setting format: %" GST_PTR_FORMAT, state->caps); 174 | 175 | if (self->input_state) { 176 | if (gst_caps_is_strictly_equal (self->input_state->caps, state->caps)) { 177 | GST_DEBUG_OBJECT (self, "Compatible caps"); 178 | goto done; 179 | } 180 | } 181 | 182 | memset (&prep_cfg, 0, sizeof (prep_cfg)); 183 | prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | 184 | MPP_ENC_PREP_CFG_CHANGE_FORMAT; 185 | prep_cfg.width = GST_VIDEO_INFO_WIDTH (&state->info); 186 | prep_cfg.height = GST_VIDEO_INFO_HEIGHT (&state->info); 187 | prep_cfg.format = to_mpp_pixel (state->caps, &state->info); 188 | prep_cfg.hor_stride = MPP_ALIGN (prep_cfg.width, 8); 189 | prep_cfg.ver_stride = MPP_ALIGN (prep_cfg.height, 8); 190 | 191 | if (self->mpi->control (self->mpp_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg)) { 192 | GST_DEBUG_OBJECT (self, "Setting input format for rockchip mpp failed"); 193 | return FALSE; 194 | } 195 | 196 | info = &self->info; 197 | gst_video_info_init (info); 198 | info->finfo = state->info.finfo; 199 | info->width = prep_cfg.width; 200 | info->height = prep_cfg.height; 201 | /* FIXME only work for NV12 */ 202 | info->offset[0] = 0; 203 | info->offset[1] = prep_cfg.hor_stride * prep_cfg.ver_stride; 204 | info->stride[0] = prep_cfg.hor_stride; 205 | info->stride[1] = prep_cfg.hor_stride; 206 | info->size = (info->stride[0] * info->stride[1]) * 3 / 2; 207 | 208 | align = &self->align; 209 | gst_video_alignment_reset (align); 210 | align->padding_right = prep_cfg.hor_stride - prep_cfg.width; 211 | align->padding_bottom = prep_cfg.ver_stride - prep_cfg.height; 212 | 213 | self->input_state = gst_video_codec_state_ref (state); 214 | 215 | done: 216 | return TRUE; 217 | } 218 | 219 | static gboolean 220 | gst_mpp_video_enc_flush (GstVideoEncoder * encoder) 221 | { 222 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 223 | 224 | GST_DEBUG_OBJECT (self, "Flushing"); 225 | 226 | if (g_atomic_int_get (&self->processing)) { 227 | GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); 228 | self->mpi->reset (self->mpp_ctx); 229 | 230 | gst_mpp_video_enc_process_buffer_stopped (self); 231 | 232 | GST_VIDEO_ENCODER_STREAM_LOCK (encoder); 233 | } 234 | self->output_flow = GST_FLOW_OK; 235 | 236 | self->mpi->reset (self->mpp_ctx); 237 | 238 | return TRUE; 239 | } 240 | 241 | static GstVideoCodecFrame * 242 | gst_mpp_video_enc_get_oldest_frame (GstVideoEncoder * encoder) 243 | { 244 | GstVideoCodecFrame *frame = NULL; 245 | GList *frames, *l; 246 | gint count = 0; 247 | 248 | frames = gst_video_encoder_get_frames (encoder); 249 | 250 | for (l = frames; l != NULL; l = l->next) { 251 | GstVideoCodecFrame *f = l->data; 252 | 253 | if (!frame || frame->pts > f->pts) 254 | frame = f; 255 | 256 | count++; 257 | } 258 | if (frame) { 259 | GST_LOG_OBJECT (encoder, 260 | "Oldest frame is %d %" GST_TIME_FORMAT 261 | " and %d frames left", 262 | frame->system_frame_number, GST_TIME_ARGS (frame->pts), count - 1); 263 | gst_video_codec_frame_ref (frame); 264 | } 265 | 266 | g_list_free_full (frames, (GDestroyNotify) gst_video_codec_frame_unref); 267 | 268 | return frame; 269 | } 270 | 271 | static GstFlowReturn 272 | gst_mpp_video_enc_process_buffer (GstMppVideoEnc * self, GstBuffer * buffer) 273 | { 274 | GstVideoEncoder *encoder = GST_VIDEO_ENCODER (self); 275 | GstBuffer *new_buffer = NULL; 276 | static gint8 current_index = 0; 277 | GstVideoCodecFrame *frame; 278 | gpointer ptr = NULL; 279 | MppFrame mpp_frame = self->mpp_frame; 280 | MppTask task = NULL; 281 | MppBuffer frame_in = self->input_buffer[current_index]; 282 | MppBuffer pkt_buf_out = self->output_buffer[current_index]; 283 | MppPacket packet = NULL; 284 | GstFlowReturn ret; 285 | 286 | static gint sps_flag = 0; 287 | MppPacket sps_packet = NULL; 288 | 289 | /* Eos buffer */ 290 | mpp_frame_set_buffer (mpp_frame, frame_in); 291 | if (0 == gst_buffer_get_size (buffer)) { 292 | mpp_frame_set_eos (mpp_frame, 1); 293 | } else { 294 | ptr = mpp_buffer_get_ptr (frame_in); 295 | gst_buffer_extract (buffer, 0, ptr, gst_buffer_get_size (buffer)); 296 | mpp_frame_set_eos (mpp_frame, 0); 297 | } 298 | 299 | do { 300 | if (self->mpi->dequeue (self->mpp_ctx, MPP_PORT_INPUT, &task)) { 301 | GST_ERROR_OBJECT (self, "mpp task input dequeue failed"); 302 | return GST_FLOW_ERROR; 303 | } 304 | if (NULL == task) { 305 | GST_LOG_OBJECT (self, "mpp input failed, try again"); 306 | g_usleep (1000); 307 | } else { 308 | break; 309 | } 310 | } while (1); 311 | mpp_task_meta_set_frame (task, KEY_INPUT_FRAME, mpp_frame); 312 | 313 | mpp_packet_init_with_buffer (&packet, pkt_buf_out); 314 | mpp_task_meta_set_packet (task, KEY_OUTPUT_PACKET, packet); 315 | 316 | if (self->mpi->enqueue (self->mpp_ctx, MPP_PORT_INPUT, task)) { 317 | GST_ERROR_OBJECT (self, "mpp task input enqueu failed"); 318 | } 319 | 320 | GST_LOG_OBJECT (self, "Allocate output buffer"); 321 | new_buffer = gst_video_encoder_allocate_output_buffer (encoder, 322 | MAX_CODEC_FRAME); 323 | if (NULL == new_buffer) { 324 | ret = GST_FLOW_FLUSHING; 325 | goto beach; 326 | } 327 | 328 | GST_LOG_OBJECT (self, "Process output buffer"); 329 | 330 | do { 331 | MppFrame packet_out = NULL; 332 | ret = GST_FLOW_OK; 333 | 334 | if (self->mpi->dequeue (self->mpp_ctx, MPP_PORT_OUTPUT, &task)) { 335 | g_usleep (1000); 336 | continue; 337 | } 338 | 339 | if (task) { 340 | mpp_task_meta_get_packet (task, KEY_OUTPUT_PACKET, &packet_out); 341 | g_assert (packet_out == packet); 342 | 343 | /* Get result */ 344 | if (packet) { 345 | gconstpointer *ptr = mpp_packet_get_pos (packet); 346 | gsize len = mpp_packet_get_length (packet); 347 | 348 | if (mpp_packet_get_eos (packet)) 349 | ret = GST_FLOW_EOS; 350 | 351 | /* Fill the buffer */ 352 | if (sps_flag) { 353 | gst_buffer_fill (new_buffer, 0, ptr, len); 354 | } else { 355 | if (!self->mpi->control (self->mpp_ctx, MPP_ENC_GET_EXTRA_INFO, 356 | &sps_packet)) { 357 | const gpointer *sps_ptr = mpp_packet_get_pos (sps_packet); 358 | gsize sps_len = mpp_packet_get_length (sps_packet); 359 | 360 | gst_buffer_fill (new_buffer, 0, sps_ptr, sps_len); 361 | 362 | gst_buffer_fill (new_buffer, sps_len, ptr, len); 363 | sps_flag = 1; 364 | 365 | } else { 366 | GST_ERROR_OBJECT (self, "Get Mpp extra data failed\n"); 367 | return GST_FLOW_ERROR; 368 | } 369 | } 370 | 371 | mpp_packet_deinit (&packet); 372 | } 373 | 374 | if (self->mpi->enqueue (self->mpp_ctx, MPP_PORT_OUTPUT, task)) { 375 | GST_ERROR_OBJECT (self, "mpp task output enqueue failed"); 376 | ret = GST_FLOW_ERROR; 377 | } 378 | current_index++; 379 | if (current_index >= MPP_MAX_BUFFERS) 380 | current_index = 0; 381 | break; 382 | } 383 | } while (1); 384 | if (ret != GST_FLOW_OK) 385 | goto beach; 386 | 387 | frame = gst_mpp_video_enc_get_oldest_frame (encoder); 388 | if (frame) { 389 | frame->output_buffer = new_buffer; 390 | new_buffer = NULL; 391 | ret = gst_video_encoder_finish_frame (encoder, frame); 392 | 393 | if (ret != GST_FLOW_OK) 394 | goto beach; 395 | } else { 396 | GST_WARNING_OBJECT (self, "Encoder is producing too many buffers"); 397 | gst_buffer_unref (new_buffer); 398 | } 399 | return GST_FLOW_OK; 400 | 401 | beach: 402 | GST_DEBUG_OBJECT (self, "Leaving output thread"); 403 | 404 | gst_buffer_replace (&buffer, NULL); 405 | self->output_flow = ret; 406 | g_atomic_int_set (&self->processing, FALSE); 407 | /* FIXME maybe I need to inform the rockchip mpp */ 408 | return ret; 409 | } 410 | 411 | 412 | static GstFlowReturn 413 | gst_mpp_video_enc_handle_frame (GstVideoEncoder * encoder, 414 | GstVideoCodecFrame * frame, GstCaps * outcaps) 415 | { 416 | 417 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 418 | GstFlowReturn ret = GST_FLOW_OK; 419 | 420 | GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number); 421 | 422 | if (G_UNLIKELY (!g_atomic_int_get (&self->active))) 423 | goto flushing; 424 | 425 | /* FIXME don't use this as a flag */ 426 | if (self->outcaps == NULL) { 427 | gint i = 0; 428 | gsize packet_size; 429 | 430 | GST_DEBUG_OBJECT (self, "Filling src caps with output dimensions %ux%u", 431 | self->info.width, self->info.height); 432 | packet_size = self->info.width * self->info.height; 433 | 434 | if (!outcaps) 435 | goto not_negotiated; 436 | 437 | gst_caps_set_simple (outcaps, 438 | "width", G_TYPE_INT, self->input_state->info.width, 439 | "height", G_TYPE_INT, self->input_state->info.height, NULL); 440 | 441 | /* Allocator buffers */ 442 | if (mpp_buffer_group_get_internal (&self->input_group, MPP_BUFFER_TYPE_ION)) 443 | goto activate_failed; 444 | if (mpp_buffer_group_get_internal (&self->output_group, 445 | MPP_BUFFER_TYPE_ION)) 446 | goto activate_failed; 447 | 448 | for (i = 0; i < MPP_MAX_BUFFERS; i++) { 449 | if (mpp_buffer_get (self->input_group, &self->input_buffer[i], 450 | self->info.size)) 451 | goto activate_failed; 452 | if (mpp_buffer_get (self->output_group, &self->output_buffer[i], 453 | packet_size)) 454 | goto activate_failed; 455 | } 456 | 457 | if (mpp_frame_init (&self->mpp_frame)) { 458 | GST_DEBUG_OBJECT (self, "failed to set up mpp frame"); 459 | goto activate_failed; 460 | } 461 | 462 | mpp_frame_set_width (self->mpp_frame, self->info.width); 463 | mpp_frame_set_height (self->mpp_frame, self->info.height); 464 | mpp_frame_set_hor_stride (self->mpp_frame, self->info.stride[0]); 465 | mpp_frame_set_ver_stride (self->mpp_frame, 466 | self->info.height + self->align.padding_bottom); 467 | 468 | if (self->mpi->poll (self->mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK)) 469 | GST_ERROR_OBJECT (self, "mpp input poll failed"); 470 | 471 | gst_video_encoder_set_output_state (encoder, outcaps, self->input_state); 472 | self->outcaps = outcaps; 473 | 474 | if (!gst_video_encoder_negotiate (encoder)) { 475 | if (GST_PAD_IS_FLUSHING (GST_VIDEO_ENCODER_SRC_PAD (encoder))) 476 | goto flushing; 477 | else 478 | goto not_negotiated; 479 | } 480 | 481 | } 482 | if (g_atomic_int_get (&self->processing) == FALSE) { 483 | g_atomic_int_set (&self->processing, TRUE); 484 | } 485 | 486 | if (frame->input_buffer) { 487 | GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); 488 | ret = gst_mpp_video_enc_process_buffer (self, frame->input_buffer); 489 | GST_VIDEO_ENCODER_STREAM_LOCK (encoder); 490 | 491 | if (ret == GST_FLOW_FLUSHING) { 492 | if (g_atomic_int_get (&self->processing) == FALSE) 493 | ret = self->output_flow; 494 | goto drop; 495 | } else if (ret != GST_FLOW_OK) { 496 | goto process_failed; 497 | } 498 | gst_buffer_replace (&frame->input_buffer, NULL); 499 | } 500 | gst_video_codec_frame_unref (frame); 501 | 502 | return ret; 503 | /* ERROR */ 504 | not_negotiated: 505 | { 506 | GST_ERROR_OBJECT (self, "not negotiated"); 507 | ret = GST_FLOW_NOT_NEGOTIATED; 508 | goto drop; 509 | } 510 | activate_failed: 511 | { 512 | GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, 513 | ("Failed to allocate required memory."), 514 | ("Buffer pool activation failed")); 515 | return GST_FLOW_ERROR; 516 | } 517 | flushing: 518 | { 519 | ret = GST_FLOW_FLUSHING; 520 | goto drop; 521 | } 522 | process_failed: 523 | { 524 | GST_ELEMENT_ERROR (self, RESOURCE, FAILED, 525 | ("Failed to process frame."), 526 | ("Maybe be due to not enough memory or failing driver")); 527 | ret = GST_FLOW_ERROR; 528 | goto drop; 529 | } 530 | drop: 531 | { 532 | gst_video_encoder_finish_frame (encoder, frame); 533 | return ret; 534 | } 535 | } 536 | 537 | static gboolean 538 | gst_mpp_video_enc_propose_allocation (GstVideoEncoder * encoder, 539 | GstQuery * query) 540 | { 541 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 542 | GstBufferPool *pool; 543 | GstCaps *caps; 544 | GstStructure *config; 545 | GstVideoInfo info; 546 | guint size; 547 | 548 | gst_query_parse_allocation (query, &caps, NULL); 549 | if (caps == NULL) 550 | return FALSE; 551 | if (!gst_video_info_from_caps (&info, caps)) 552 | return FALSE; 553 | 554 | size = GST_VIDEO_INFO_SIZE (&self->info); 555 | 556 | pool = gst_video_buffer_pool_new (); 557 | 558 | gst_query_add_allocation_pool (query, pool, size, 0, 0); 559 | config = gst_buffer_pool_get_config (pool); 560 | gst_buffer_pool_config_set_params (config, caps, size, 1, 0); 561 | gst_buffer_pool_config_set_video_alignment (config, &self->align); 562 | gst_buffer_pool_set_config (pool, config); 563 | 564 | gst_object_unref (pool); 565 | gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); 566 | 567 | return TRUE; 568 | } 569 | 570 | static gboolean 571 | gst_mpp_video_enc_finish (GstVideoEncoder * encoder) 572 | { 573 | GstMppVideoEnc *self = GST_MPP_VIDEO_ENC (encoder); 574 | GstBuffer *buffer; 575 | 576 | if (!g_atomic_int_get (&self->processing)) 577 | goto done; 578 | 579 | GST_DEBUG_OBJECT (self, "Finishing encoding"); 580 | 581 | GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); 582 | 583 | /* Send a empty buffer to send eos frame to rockchip mpp */ 584 | buffer = gst_buffer_new (); 585 | /* buffer would be release here */ 586 | gst_mpp_video_enc_process_buffer (self, buffer); 587 | 588 | /* Wait the task in srcpad get eos package */ 589 | while (g_atomic_int_get (&self->processing)); 590 | 591 | gst_mpp_video_enc_process_buffer_stopped (self); 592 | GST_VIDEO_ENCODER_STREAM_LOCK (encoder); 593 | 594 | GST_DEBUG_OBJECT (encoder, "Done draning buffers"); 595 | 596 | done: 597 | return TRUE; 598 | } 599 | 600 | static void 601 | gst_mpp_video_enc_init (GstMppVideoEnc * self) 602 | { 603 | } 604 | 605 | static void 606 | gst_mpp_video_enc_class_init (GstMppVideoEncClass * klass) 607 | { 608 | GstElementClass *element_class; 609 | GstVideoEncoderClass *video_encoder_class; 610 | 611 | element_class = (GstElementClass *) klass; 612 | video_encoder_class = (GstVideoEncoderClass *) klass; 613 | 614 | GST_DEBUG_CATEGORY_INIT (mppvideoenc_debug, "mppvideoenc", 0, 615 | "Rockchip MPP Video Encoder"); 616 | 617 | video_encoder_class->close = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_close); 618 | video_encoder_class->start = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_start); 619 | video_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_stop); 620 | video_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_flush); 621 | video_encoder_class->finish = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_finish); 622 | video_encoder_class->propose_allocation = 623 | GST_DEBUG_FUNCPTR (gst_mpp_video_enc_propose_allocation); 624 | klass->handle_frame = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_handle_frame); 625 | klass->set_format = GST_DEBUG_FUNCPTR (gst_mpp_video_enc_set_format); 626 | 627 | gst_element_class_add_pad_template (element_class, 628 | gst_static_pad_template_get (&gst_mpp_video_enc_sink_template)); 629 | 630 | } 631 | --------------------------------------------------------------------------------