Adds a sunxi-cedrus-drv-video libVA backend
This VA backend uses v4l2's Frame API proposal to interface with the "sunxi-cedrus" video driver on Allwinner SoC. Only a few parts of the code are really dependent on sunxi-cedrus and this VA backend could be reused for other v4l drivers using the Frame API.
This commit is contained in:
+45
@@ -0,0 +1,45 @@
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Misc
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
*.loT
|
||||
*.bin
|
||||
*.pc
|
||||
*.g[4-7]s
|
||||
.deps
|
||||
.libs
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
compile
|
||||
missing
|
||||
Makefile
|
||||
Makefile.in
|
||||
config.h
|
||||
config.h.in
|
||||
stamp-h1
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
TAGS
|
||||
@@ -0,0 +1,19 @@
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sub license, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,9 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
SUBDIRS = src
|
||||
|
||||
# Extra clean files so that maintainer-clean removes *everything*
|
||||
MAINTAINERCLEANFILES = \
|
||||
aclocal.m4 compile config.guess config.sub \
|
||||
configure depcomp install-sh ltmain.sh \
|
||||
Makefile.in missing
|
||||
@@ -0,0 +1,12 @@
|
||||
Sunxi Cedrus VA backend
|
||||
=======================
|
||||
|
||||
This libVA video driver is designed to work with the v4l2 "sunxi-cedrus" kernel
|
||||
driver. However, the only sunxi-cedrus specific part is the format conversion
|
||||
from tiled to planar, otherwise it would be generic enough to be used with other
|
||||
v4l2 drivers using the "Frame API".
|
||||
|
||||
You can try this driver with VLC but don't forget to tell libVA to use this
|
||||
backend:
|
||||
|
||||
export LIBVA_DRIVER_NAME=sunxi_cedrus
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
|
||||
autoreconf -v --install
|
||||
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
./configure "$@"
|
||||
fi
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
# intel-driver package version number
|
||||
m4_define([sunxi_cedrus_major_version], [1])
|
||||
m4_define([sunxi_cedrus_minor_version], [0])
|
||||
m4_define([sunxi_cedrus_micro_version], [0])
|
||||
m4_define([sunxi_cedrus_pre_version], [0])
|
||||
m4_define([sunxi_cedrus_version],
|
||||
[sunxi_cedrus_major_version.sunxi_cedrus_minor_version.sunxi_cedrus_micro_version])
|
||||
m4_if(sunxi_cedrus_pre_version, [0], [], [
|
||||
m4_append([sunxi_cedrus_version], sunxi_cedrus_pre_version, [.pre])
|
||||
])
|
||||
|
||||
# libva minimum version requirement
|
||||
m4_define([libva_package_version], [1.2.2])
|
||||
m4_define([va_api_version], [0.34.0])
|
||||
|
||||
# libdrm minimum version requirement
|
||||
m4_define([libdrm_version], [2.4.45])
|
||||
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([liva_wrapper], [sunxi_cedrus_version],
|
||||
[florent.revest@free-electrons.com], [sunxi_cedrus])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AM_INIT_AUTOMAKE([1.9 tar-ustar])
|
||||
|
||||
AC_CONFIG_HEADERS([src/config.h])
|
||||
|
||||
SUNXI_CEDRUS_MAJOR_VERSION=sunxi_cedrus_major_version
|
||||
SUNXI_CEDRUS_MINOR_VERSION=sunxi_cedrus_minor_version
|
||||
SUNXI_CEDRUS_MICRO_VERSION=sunxi_cedrus_micro_version
|
||||
AC_DEFINE([SUNXI_CEDRUS_MAJOR_VERSION], [sunxi_cedrus_major_version], [Major version of the driver])
|
||||
AC_DEFINE([SUNXI_CEDRUS_MINOR_VERSION], [sunxi_cedrus_minor_version], [Minor version of the driver])
|
||||
AC_DEFINE([SUNXI_CEDRUS_MICRO_VERSION], [sunxi_cedrus_micro_version], [Micro version of the driver])
|
||||
AC_DEFINE([SUNXI_CEDRUS_PRE_VERSION], [sunxi_cedrus_pre_version], [Preversion of the driver])
|
||||
|
||||
SUNXI_CEDRUS_LT_LDFLAGS="-avoid-version"
|
||||
AC_SUBST(SUNXI_CEDRUS_LT_LDFLAGS)
|
||||
|
||||
dnl Use pretty build output with automake >= 1.11
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [
|
||||
AM_DEFAULT_VERBOSITY=1
|
||||
AC_SUBST(AM_DEFAULT_VERBOSITY)
|
||||
])
|
||||
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_AS
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_STDC
|
||||
AC_SYS_LARGEFILE
|
||||
AC_CHECK_LIB([m], [sin])
|
||||
|
||||
LIBVA_PACKAGE_VERSION=libva_package_version
|
||||
AC_SUBST(LIBVA_PACKAGE_VERSION)
|
||||
|
||||
dnl Check for recent enough DRM
|
||||
LIBDRM_VERSION=libdrm_version
|
||||
PKG_CHECK_MODULES([DRM], [libdrm >= $LIBDRM_VERSION])
|
||||
AC_SUBST(LIBDRM_VERSION)
|
||||
|
||||
dnl Check for gen4asm
|
||||
PKG_CHECK_MODULES(GEN4ASM, [intel-gen4asm >= 1.3], [gen4asm=yes], [gen4asm=no])
|
||||
AM_CONDITIONAL(HAVE_GEN4ASM, test x$gen4asm = xyes)
|
||||
AC_PATH_PROG([GEN4ASM], [intel-gen4asm])
|
||||
|
||||
dnl Check for VA-API
|
||||
PKG_CHECK_MODULES(LIBVA_DEPS, [libva >= va_api_version])
|
||||
PKG_CHECK_MODULES(X11_DEPS, [x11])
|
||||
|
||||
dnl Check for VA/DRM API
|
||||
PKG_CHECK_MODULES(LIBVA_DRM_DEPS, [libva-drm],
|
||||
[AC_DEFINE([HAVE_VA_DRM], [1], [Defined to 1 if VA/DRM API is enabled])],
|
||||
[USE_DRM="no"])
|
||||
|
||||
# Check for <drm_fourcc.h>
|
||||
if test "$USE_DRM" = "yes"; then
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $DRM_CFLAGS"
|
||||
AC_CHECK_HEADERS([drm_fourcc.h], [:], [USE_DRM="no"])
|
||||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
fi
|
||||
|
||||
VA_VERSION=`$PKG_CONFIG --modversion libva`
|
||||
VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1`
|
||||
VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2`
|
||||
VA_MICRO_VERSION=`echo "$VA_VERSION" | cut -d'.' -f3`
|
||||
VA_VERSION_STR="$VA_VERSION"
|
||||
|
||||
va_full_version_int=`expr ${VA_MAJOR_VERSION:-0} "*" 1000000 + \
|
||||
${VA_MINOR_VERSION:-0} "*" 10000 + \
|
||||
${VA_MICRO_VERSION:-0} "*" 100 + \
|
||||
0`
|
||||
VA_DRIVER_INIT_FUNC="__vaDriverInit_${VA_MAJOR_VERSION}_${VA_MINOR_VERSION}"
|
||||
AC_DEFINE_UNQUOTED([VA_DRIVER_INIT_FUNC], [$VA_DRIVER_INIT_FUNC],
|
||||
[Define driver entry-point])
|
||||
|
||||
dnl Check for VA-API drivers path
|
||||
AC_MSG_CHECKING([for VA drivers path])
|
||||
LIBVA_DRIVERS_PATH=`$PKG_CONFIG libva --variable driverdir`
|
||||
if test -z "$LIBVA_DRIVERS_PATH"; then
|
||||
LIBVA_DRIVERS_PATH="/usr/lib/dri/"
|
||||
fi
|
||||
AC_MSG_RESULT([$LIBVA_DRIVERS_PATH])
|
||||
AC_SUBST(LIBVA_DRIVERS_PATH)
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
src/Makefile
|
||||
])
|
||||
|
||||
echo
|
||||
echo $PACKAGE configuration summary:
|
||||
echo
|
||||
echo VA-API version ................... : $VA_VERSION_STR
|
||||
echo VA-API drivers path .............. : $LIBVA_DRIVERS_PATH
|
||||
echo
|
||||
@@ -0,0 +1,40 @@
|
||||
AM_CPPFLAGS = \
|
||||
-DPTHREADS \
|
||||
$(X11_DEPS_CFLAGS)\
|
||||
$(DRM_CFLAGS) \
|
||||
$(LIBVA_DEPS_CFLAGS)
|
||||
|
||||
driver_cflags = \
|
||||
-Wall \
|
||||
-fvisibility=hidden
|
||||
|
||||
driver_ldflags = \
|
||||
-module -avoid-version \
|
||||
-no-undefined \
|
||||
-Wl,--no-undefined
|
||||
|
||||
driver_libs = \
|
||||
-lpthread -ldl \
|
||||
$(DRM_LIBS) \
|
||||
$(X11_DEPS_LIBS) \
|
||||
$(LIBVA_DEPS_LIBS)
|
||||
|
||||
source_c = sunxi_cedrus_drv_video.c object_heap.c buffer.c va_config.c \
|
||||
context.c image.c picture.c subpicture.c surface.c
|
||||
|
||||
source_s = \
|
||||
tiled_yuv.S
|
||||
|
||||
source_h = sunxi_cedrus_drv_video.h object_heap.h buffer.h va_config.h \
|
||||
context.h image.h picture.h subpicture.h surface.h \
|
||||
tiled_yuv.h
|
||||
|
||||
sunxi_cedrus_drv_video_la_LTLIBRARIES = sunxi_cedrus_drv_video.la
|
||||
sunxi_cedrus_drv_video_ladir = $(LIBVA_DRIVERS_PATH)
|
||||
sunxi_cedrus_drv_video_la_CFLAGS = $(driver_cflags)
|
||||
sunxi_cedrus_drv_video_la_LDFLAGS = $(driver_ldflags)
|
||||
sunxi_cedrus_drv_video_la_LIBADD = $(driver_libs)
|
||||
sunxi_cedrus_drv_video_la_SOURCES = $(source_c) $(source_s)
|
||||
noinst_HEADERS = $(source_h)
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in config.h.in
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "buffer.h"
|
||||
#include "context.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
/*
|
||||
* A Buffer is a memory zone used to handle all kind of data, for example an IQ
|
||||
* matrix or image buffer (which are allocated using realloc) or slice data
|
||||
* (which are mmapped from v4l's kernel space)
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_CreateBuffer(VADriverContextP ctx, VAContextID context,
|
||||
VABufferType type, unsigned int size, unsigned int num_elements,
|
||||
void *data, VABufferID *buf_id)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
int bufferID;
|
||||
struct v4l2_plane plane[1];
|
||||
object_buffer_p obj_buffer;
|
||||
|
||||
/* Validate type */
|
||||
switch (type)
|
||||
{
|
||||
case VAPictureParameterBufferType:
|
||||
case VAIQMatrixBufferType: /* Ignored */
|
||||
case VASliceParameterBufferType:
|
||||
case VASliceDataBufferType:
|
||||
case VAImageBufferType:
|
||||
/* Ok */
|
||||
break;
|
||||
default:
|
||||
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
bufferID = object_heap_allocate(&driver_data->buffer_heap);
|
||||
obj_buffer = BUFFER(bufferID);
|
||||
if (NULL == obj_buffer)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
obj_buffer->buffer_data = NULL;
|
||||
obj_buffer->type = type;
|
||||
|
||||
if(obj_buffer->type == VASliceDataBufferType) {
|
||||
object_context_p obj_context;
|
||||
|
||||
obj_context = CONTEXT(context);
|
||||
assert(obj_context);
|
||||
|
||||
struct v4l2_buffer buf;
|
||||
memset(&(buf), 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = obj_context->num_rendered_surfaces%INPUT_BUFFERS_NB;
|
||||
buf.length = 1;
|
||||
buf.m.planes = plane;
|
||||
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_QUERYBUF, &buf)==0);
|
||||
|
||||
obj_buffer->buffer_data = mmap(NULL, size * num_elements,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
driver_data->mem2mem_fd, buf.m.planes[0].m.mem_offset);
|
||||
} else
|
||||
obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size * num_elements);
|
||||
|
||||
if (obj_buffer->buffer_data == NULL)
|
||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
|
||||
if (VA_STATUS_SUCCESS == vaStatus)
|
||||
{
|
||||
obj_buffer->max_num_elements = num_elements;
|
||||
obj_buffer->num_elements = num_elements;
|
||||
obj_buffer->size = size;
|
||||
|
||||
if (data)
|
||||
memcpy(obj_buffer->buffer_data, data,
|
||||
size * num_elements);
|
||||
}
|
||||
|
||||
if (VA_STATUS_SUCCESS == vaStatus)
|
||||
*buf_id = bufferID;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_BufferSetNumElements(VADriverContextP ctx,
|
||||
VABufferID buf_id, unsigned int num_elements)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_buffer_p obj_buffer = BUFFER(buf_id);
|
||||
assert(obj_buffer);
|
||||
|
||||
if ((num_elements < 0) || (num_elements > obj_buffer->max_num_elements))
|
||||
vaStatus = VA_STATUS_ERROR_UNKNOWN;
|
||||
if (VA_STATUS_SUCCESS == vaStatus)
|
||||
obj_buffer->num_elements = num_elements;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_MapBuffer(VADriverContextP ctx, VABufferID buf_id,
|
||||
void **pbuf)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
|
||||
object_buffer_p obj_buffer = BUFFER(buf_id);
|
||||
assert(obj_buffer);
|
||||
if (NULL == obj_buffer)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
if (NULL != obj_buffer->buffer_data)
|
||||
{
|
||||
*pbuf = obj_buffer->buffer_data;
|
||||
vaStatus = VA_STATUS_SUCCESS;
|
||||
}
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
|
||||
{
|
||||
/* Do nothing */
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void sunxi_cedrus_destroy_buffer(struct sunxi_cedrus_driver_data *driver_data,
|
||||
object_buffer_p obj_buffer)
|
||||
{
|
||||
if (NULL != obj_buffer->buffer_data)
|
||||
{
|
||||
if(obj_buffer->type == VASliceDataBufferType)
|
||||
munmap(obj_buffer->buffer_data, obj_buffer->size);
|
||||
else
|
||||
free(obj_buffer->buffer_data);
|
||||
|
||||
obj_buffer->buffer_data = NULL;
|
||||
}
|
||||
|
||||
object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_buffer_p obj_buffer = BUFFER(buffer_id);
|
||||
assert(obj_buffer);
|
||||
|
||||
sunxi_cedrus_destroy_buffer(driver_data, obj_buffer);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* sunxi-cedrus doesn't support buffer info */
|
||||
VAStatus sunxi_cedrus_BufferInfo(VADriverContextP ctx, VABufferID buf_id,
|
||||
VABufferType *type, unsigned int *size,
|
||||
unsigned int *num_elements)
|
||||
{ return VA_STATUS_ERROR_UNIMPLEMENTED; }
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BUFFER_H_
|
||||
#define _BUFFER_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
|
||||
#define BUFFER(id) ((object_buffer_p) object_heap_lookup(&driver_data->buffer_heap, id))
|
||||
#define BUFFER_ID_OFFSET 0x08000000
|
||||
|
||||
struct object_buffer {
|
||||
struct object_base base;
|
||||
void *buffer_data;
|
||||
int max_num_elements;
|
||||
int num_elements;
|
||||
VABufferType type;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
typedef struct object_buffer *object_buffer_p;
|
||||
|
||||
VAStatus sunxi_cedrus_CreateBuffer(VADriverContextP ctx, VAContextID context,
|
||||
VABufferType type, unsigned int size, unsigned int num_elements,
|
||||
void *data, VABufferID *buf_id);
|
||||
|
||||
VAStatus sunxi_cedrus_BufferSetNumElements(VADriverContextP ctx,
|
||||
VABufferID buf_id, unsigned int num_elements);
|
||||
|
||||
VAStatus sunxi_cedrus_MapBuffer(VADriverContextP ctx, VABufferID buf_id,
|
||||
void **pbuf);
|
||||
|
||||
VAStatus sunxi_cedrus_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id);
|
||||
|
||||
void sunxi_cedrus_destroy_buffer(struct sunxi_cedrus_driver_data *driver_data,
|
||||
object_buffer_p obj_buffer);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id);
|
||||
|
||||
VAStatus sunxi_cedrus_BufferInfo(VADriverContextP ctx, VABufferID buf_id,
|
||||
VABufferType *type, unsigned int *size,
|
||||
unsigned int *num_elements);
|
||||
|
||||
#endif /* _BUFFER_H_ */
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "context.h"
|
||||
#include "va_config.h"
|
||||
#include "surface.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
/*
|
||||
* A Context is a global data structure used for rendering a video of a certain
|
||||
* format. When a context is created, input buffers are created and v4l's output
|
||||
* (which is the compressed data input queue, since capture is the real output)
|
||||
* format is set.
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_CreateContext(VADriverContextP ctx, VAConfigID config_id,
|
||||
int picture_width, int picture_height, int flag,
|
||||
VASurfaceID *render_targets, int num_render_targets,
|
||||
VAContextID *context)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_config_p obj_config;
|
||||
int i;
|
||||
struct v4l2_create_buffers create_bufs;
|
||||
struct v4l2_format fmt;
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
obj_config = CONFIG(config_id);
|
||||
if (NULL == obj_config)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
int contextID = object_heap_allocate(&driver_data->context_heap);
|
||||
object_context_p obj_context = CONTEXT(contextID);
|
||||
if (NULL == obj_context)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
obj_context->context_id = contextID;
|
||||
*context = contextID;
|
||||
obj_context->current_render_target = -1;
|
||||
obj_context->config_id = config_id;
|
||||
obj_context->picture_width = picture_width;
|
||||
obj_context->picture_height = picture_height;
|
||||
obj_context->num_render_targets = num_render_targets;
|
||||
obj_context->render_targets = (VASurfaceID *) malloc(num_render_targets * sizeof(VASurfaceID));
|
||||
obj_context->num_rendered_surfaces = 0;
|
||||
|
||||
if (obj_context->render_targets == NULL)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
for(i = 0; i < num_render_targets; i++)
|
||||
{
|
||||
if (NULL == SURFACE(render_targets[i]))
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
|
||||
break;
|
||||
}
|
||||
obj_context->render_targets[i] = render_targets[i];
|
||||
}
|
||||
obj_context->flags = flag;
|
||||
|
||||
/* Error recovery */
|
||||
if (VA_STATUS_SUCCESS != vaStatus)
|
||||
{
|
||||
obj_context->context_id = -1;
|
||||
obj_context->config_id = -1;
|
||||
free(obj_context->render_targets);
|
||||
obj_context->render_targets = NULL;
|
||||
obj_context->num_render_targets = 0;
|
||||
obj_context->flags = 0;
|
||||
object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
|
||||
}
|
||||
|
||||
memset(&(fmt), 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
fmt.fmt.pix_mp.width = picture_width;
|
||||
fmt.fmt.pix_mp.height = picture_height;
|
||||
fmt.fmt.pix_mp.plane_fmt[0].sizeimage = INPUT_BUFFER_MAX_SIZE;
|
||||
switch(obj_config->profile) {
|
||||
default:
|
||||
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
return vaStatus;
|
||||
break;
|
||||
}
|
||||
fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
|
||||
fmt.fmt.pix_mp.num_planes = 1;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_S_FMT, &fmt)==0);
|
||||
|
||||
memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers));
|
||||
create_bufs.count = INPUT_BUFFERS_NB;
|
||||
create_bufs.memory = V4L2_MEMORY_MMAP;
|
||||
create_bufs.format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_G_FMT, &create_bufs.format)==0);
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_CREATE_BUFS, &create_bufs)==0);
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type)==0);
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMON, &type)==0);
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyContext(VADriverContextP ctx, VAContextID context)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_context_p obj_context = CONTEXT(context);
|
||||
assert(obj_context);
|
||||
|
||||
obj_context->context_id = -1;
|
||||
obj_context->config_id = -1;
|
||||
obj_context->picture_width = 0;
|
||||
obj_context->picture_height = 0;
|
||||
if (obj_context->render_targets)
|
||||
free(obj_context->render_targets);
|
||||
obj_context->render_targets = NULL;
|
||||
obj_context->num_render_targets = 0;
|
||||
obj_context->flags = 0;
|
||||
|
||||
obj_context->current_render_target = -1;
|
||||
|
||||
object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _CONTEXT_H_
|
||||
#define _CONTEXT_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
|
||||
/* We can't dynamically call VIDIOC_REQBUFS for every MPEG slice we create.
|
||||
* Indeed, the queue might be busy processing a previous buffer, so we need to
|
||||
* pre-allocate a set of buffers with a max size */
|
||||
#define INPUT_BUFFER_MAX_SIZE 131072
|
||||
#define INPUT_BUFFERS_NB 4
|
||||
|
||||
#define CONTEXT(id) ((object_context_p) object_heap_lookup(&driver_data->context_heap, id))
|
||||
#define CONTEXT_ID_OFFSET 0x02000000
|
||||
|
||||
struct object_context {
|
||||
struct object_base base;
|
||||
VAContextID context_id;
|
||||
VAConfigID config_id;
|
||||
VASurfaceID current_render_target;
|
||||
int picture_width;
|
||||
int picture_height;
|
||||
int num_render_targets;
|
||||
int flags;
|
||||
VASurfaceID *render_targets;
|
||||
uint32_t num_rendered_surfaces;
|
||||
};
|
||||
|
||||
typedef struct object_context *object_context_p;
|
||||
|
||||
VAStatus sunxi_cedrus_CreateContext(VADriverContextP ctx, VAConfigID config_id,
|
||||
int picture_width, int picture_height, int flag,
|
||||
VASurfaceID *render_targets, int num_render_targets,
|
||||
VAContextID *context);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyContext(VADriverContextP ctx, VAContextID context);
|
||||
|
||||
#endif /* _CONTEXT_H_ */
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "image.h"
|
||||
#include "surface.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "tiled_yuv.h"
|
||||
|
||||
/*
|
||||
* An Image is a standard data structure containing rendered frames in a usable
|
||||
* pixel format. Here we only use NV12 buffers which are converted from sunxi's
|
||||
* proprietary tiled pixel format with tiled_yuv when deriving an Image from a
|
||||
* Surface.
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_QueryImageFormats(VADriverContextP ctx,
|
||||
VAImageFormat *format_list, int *num_formats)
|
||||
{
|
||||
format_list[0].fourcc = VA_FOURCC_NV12;
|
||||
*num_formats = 1;
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_CreateImage(VADriverContextP ctx, VAImageFormat *format,
|
||||
int width, int height, VAImage *image)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
int sizeY, sizeUV;
|
||||
object_image_p obj_img;
|
||||
|
||||
image->format = *format;
|
||||
image->buf = VA_INVALID_ID;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
|
||||
sizeY = image->width * image->height;
|
||||
sizeUV = ((image->width+1) * (image->height+1)/2);
|
||||
|
||||
image->num_planes = 2;
|
||||
image->pitches[0] = (image->width+31)&~31;
|
||||
image->pitches[1] = (image->width+31)&~31;
|
||||
image->offsets[0] = 0;
|
||||
image->offsets[1] = sizeY;
|
||||
image->data_size = sizeY + sizeUV;
|
||||
|
||||
image->image_id = object_heap_allocate(&driver_data->image_heap);
|
||||
if (image->image_id == VA_INVALID_ID)
|
||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
obj_img = IMAGE(image->image_id);
|
||||
|
||||
if (sunxi_cedrus_CreateBuffer(ctx, 0, VAImageBufferType, image->data_size,
|
||||
1, NULL, &image->buf) != VA_STATUS_SUCCESS)
|
||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
obj_img->buf = image->buf;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DeriveImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
VAImage *image)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_surface_p obj_surface;
|
||||
VAImageFormat fmt;
|
||||
object_buffer_p obj_buffer;
|
||||
VAStatus ret;
|
||||
|
||||
obj_surface = SURFACE(surface);
|
||||
fmt.fourcc = VA_FOURCC_NV12;
|
||||
|
||||
ret = sunxi_cedrus_CreateImage(ctx, &fmt, obj_surface->width,
|
||||
obj_surface->height, image);
|
||||
if(ret != VA_STATUS_SUCCESS)
|
||||
return ret;
|
||||
|
||||
obj_buffer = BUFFER(image->buf);
|
||||
if (NULL == obj_buffer)
|
||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
|
||||
/* TODO: Use an appropriate DRM plane instead */
|
||||
tiled_to_planar(driver_data->luma_bufs[obj_surface->output_buf_index], obj_buffer->buffer_data, image->pitches[0], image->width, image->height);
|
||||
tiled_to_planar(driver_data->chroma_bufs[obj_surface->output_buf_index], obj_buffer->buffer_data + image->width*image->height, image->pitches[1], image->width, image->height/2);
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyImage(VADriverContextP ctx, VAImageID image)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_image_p obj_img;
|
||||
|
||||
obj_img = IMAGE(image);
|
||||
assert(obj_img);
|
||||
|
||||
sunxi_cedrus_DestroyBuffer(ctx, obj_img->buf);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_SetImagePalette(VADriverContextP ctx, VAImageID image,
|
||||
unsigned char *palette)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_GetImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
int x, int y, unsigned int width, unsigned int height,
|
||||
VAImageID image)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_PutImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
VAImageID image, int src_x, int src_y, unsigned int src_width,
|
||||
unsigned int src_height, int dest_x, int dest_y,
|
||||
unsigned int dest_width, unsigned int dest_height)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _IMAGE_H_
|
||||
#define _IMAGE_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
|
||||
#define IMAGE(id) ((object_image_p) object_heap_lookup(&driver_data->image_heap, id))
|
||||
#define IMAGE_ID_OFFSET 0x10000000
|
||||
|
||||
struct object_image {
|
||||
struct object_base base;
|
||||
VABufferID buf;
|
||||
};
|
||||
|
||||
typedef struct object_image *object_image_p;
|
||||
|
||||
VAStatus sunxi_cedrus_QueryImageFormats(VADriverContextP ctx,
|
||||
VAImageFormat *format_list, int *num_formats);
|
||||
|
||||
VAStatus sunxi_cedrus_CreateImage(VADriverContextP ctx, VAImageFormat *format,
|
||||
int width, int height, VAImage *image);
|
||||
|
||||
VAStatus sunxi_cedrus_DeriveImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
VAImage *image);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyImage(VADriverContextP ctx, VAImageID image);
|
||||
|
||||
VAStatus sunxi_cedrus_SetImagePalette(VADriverContextP ctx, VAImageID image,
|
||||
unsigned char *palette);
|
||||
|
||||
VAStatus sunxi_cedrus_GetImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
int x, int y, unsigned int width, unsigned int height,
|
||||
VAImageID image);
|
||||
|
||||
VAStatus sunxi_cedrus_PutImage(VADriverContextP ctx, VASurfaceID surface,
|
||||
VAImageID image, int src_x, int src_y, unsigned int src_width,
|
||||
unsigned int src_height, int dest_x, int dest_y,
|
||||
unsigned int dest_width, unsigned int dest_height);
|
||||
|
||||
#endif /* _IMAGE_H_ */
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "object_heap.h"
|
||||
|
||||
#define ASSERT assert
|
||||
|
||||
#define LAST_FREE -1
|
||||
#define ALLOCATED -2
|
||||
|
||||
/*
|
||||
* Expands the heap
|
||||
* Return 0 on success, -1 on error
|
||||
*/
|
||||
static int object_heap_expand(object_heap_p heap)
|
||||
{
|
||||
int i;
|
||||
void *new_heap_index;
|
||||
int next_free;
|
||||
int new_heap_size = heap->heap_size + heap->heap_increment;
|
||||
int bucket_index = new_heap_size / heap->heap_increment - 1;
|
||||
|
||||
if (bucket_index >= heap->num_buckets) {
|
||||
int new_num_buckets = heap->num_buckets + 8;
|
||||
void **new_bucket;
|
||||
|
||||
new_bucket = realloc(heap->bucket, new_num_buckets * sizeof(void *));
|
||||
if (NULL == new_bucket) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
heap->num_buckets = new_num_buckets;
|
||||
heap->bucket = new_bucket;
|
||||
}
|
||||
|
||||
new_heap_index = (void *) malloc(heap->heap_increment * heap->object_size);
|
||||
if (NULL == new_heap_index) {
|
||||
return -1; /* Out of memory */
|
||||
}
|
||||
|
||||
heap->bucket[bucket_index] = new_heap_index;
|
||||
next_free = heap->next_free;
|
||||
for (i = new_heap_size; i-- > heap->heap_size;) {
|
||||
object_base_p obj = (object_base_p)(new_heap_index + (i - heap->heap_size) * heap->object_size);
|
||||
obj->id = i + heap->id_offset;
|
||||
obj->next_free = next_free;
|
||||
next_free = i;
|
||||
}
|
||||
heap->next_free = next_free;
|
||||
heap->heap_size = new_heap_size;
|
||||
return 0; /* Success */
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 on success, -1 on error
|
||||
*/
|
||||
int object_heap_init(object_heap_p heap, int object_size, int id_offset)
|
||||
{
|
||||
pthread_mutex_init(&heap->mutex, NULL);
|
||||
heap->object_size = object_size;
|
||||
heap->id_offset = id_offset & OBJECT_HEAP_OFFSET_MASK;
|
||||
heap->heap_size = 0;
|
||||
heap->heap_increment = 16;
|
||||
heap->next_free = LAST_FREE;
|
||||
heap->num_buckets = 0;
|
||||
heap->bucket = NULL;
|
||||
return object_heap_expand(heap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates an object
|
||||
* Returns the object ID on success, returns -1 on error
|
||||
*/
|
||||
static int object_heap_allocate_unlocked(object_heap_p heap)
|
||||
{
|
||||
object_base_p obj;
|
||||
int bucket_index, obj_index;
|
||||
|
||||
if (LAST_FREE == heap->next_free) {
|
||||
if (-1 == object_heap_expand(heap)) {
|
||||
return -1; /* Out of memory */
|
||||
}
|
||||
}
|
||||
ASSERT(heap->next_free >= 0);
|
||||
|
||||
bucket_index = heap->next_free / heap->heap_increment;
|
||||
obj_index = heap->next_free % heap->heap_increment;
|
||||
|
||||
obj = (object_base_p)(heap->bucket[bucket_index] + obj_index * heap->object_size);
|
||||
heap->next_free = obj->next_free;
|
||||
obj->next_free = ALLOCATED;
|
||||
return obj->id;
|
||||
}
|
||||
|
||||
int object_heap_allocate(object_heap_p heap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pthread_mutex_lock(&heap->mutex);
|
||||
ret = object_heap_allocate_unlocked(heap);
|
||||
pthread_mutex_unlock(&heap->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup an object by object ID
|
||||
* Returns a pointer to the object on success, returns NULL on error
|
||||
*/
|
||||
static object_base_p object_heap_lookup_unlocked(object_heap_p heap, int id)
|
||||
{
|
||||
object_base_p obj;
|
||||
int bucket_index, obj_index;
|
||||
|
||||
if ((id < heap->id_offset) || (id > (heap->heap_size + heap->id_offset))) {
|
||||
return NULL;
|
||||
}
|
||||
id &= OBJECT_HEAP_ID_MASK;
|
||||
bucket_index = id / heap->heap_increment;
|
||||
obj_index = id % heap->heap_increment;
|
||||
obj = (object_base_p)(heap->bucket[bucket_index] + obj_index * heap->object_size);
|
||||
|
||||
/* Check if the object has in fact been allocated */
|
||||
if (obj->next_free != ALLOCATED) {
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
object_base_p object_heap_lookup(object_heap_p heap, int id)
|
||||
{
|
||||
object_base_p obj;
|
||||
|
||||
pthread_mutex_lock(&heap->mutex);
|
||||
obj = object_heap_lookup_unlocked(heap, id);
|
||||
pthread_mutex_unlock(&heap->mutex);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all objects in the heap.
|
||||
* Returns a pointer to the first object on the heap, returns NULL if heap is empty.
|
||||
*/
|
||||
object_base_p object_heap_first(object_heap_p heap, object_heap_iterator *iter)
|
||||
{
|
||||
*iter = -1;
|
||||
return object_heap_next(heap, iter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all objects in the heap.
|
||||
* Returns a pointer to the next object on the heap, returns NULL if heap is empty.
|
||||
*/
|
||||
static object_base_p object_heap_next_unlocked(object_heap_p heap, object_heap_iterator *iter)
|
||||
{
|
||||
object_base_p obj;
|
||||
int bucket_index, obj_index;
|
||||
int i = *iter + 1;
|
||||
|
||||
while (i < heap->heap_size) {
|
||||
bucket_index = i / heap->heap_increment;
|
||||
obj_index = i % heap->heap_increment;
|
||||
|
||||
obj = (object_base_p)(heap->bucket[bucket_index] + obj_index * heap->object_size);
|
||||
if (obj->next_free == ALLOCATED) {
|
||||
*iter = i;
|
||||
return obj;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*iter = i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object_base_p object_heap_next(object_heap_p heap, object_heap_iterator *iter)
|
||||
{
|
||||
object_base_p obj;
|
||||
|
||||
pthread_mutex_lock(&heap->mutex);
|
||||
obj = object_heap_next_unlocked(heap, iter);
|
||||
pthread_mutex_unlock(&heap->mutex);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees an object
|
||||
*/
|
||||
static void object_heap_free_unlocked(object_heap_p heap, object_base_p obj)
|
||||
{
|
||||
/* Check if the object has in fact been allocated */
|
||||
ASSERT(obj->next_free == ALLOCATED);
|
||||
|
||||
obj->next_free = heap->next_free;
|
||||
heap->next_free = obj->id & OBJECT_HEAP_ID_MASK;
|
||||
}
|
||||
|
||||
void object_heap_free(object_heap_p heap, object_base_p obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
pthread_mutex_lock(&heap->mutex);
|
||||
object_heap_free_unlocked(heap, obj);
|
||||
pthread_mutex_unlock(&heap->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys a heap, the heap must be empty.
|
||||
*/
|
||||
void object_heap_destroy(object_heap_p heap)
|
||||
{
|
||||
object_base_p obj;
|
||||
int bucket_index, obj_index, i;
|
||||
|
||||
/* Check if heap is empty */
|
||||
for (i = 0; i < heap->heap_size; i++) {
|
||||
/* Check if object is not still allocated */
|
||||
bucket_index = i / heap->heap_increment;
|
||||
obj_index = i % heap->heap_increment;
|
||||
obj = (object_base_p)(heap->bucket[bucket_index] + obj_index * heap->object_size);
|
||||
ASSERT(obj->next_free != ALLOCATED);
|
||||
}
|
||||
|
||||
for (i = 0; i < heap->heap_size / heap->heap_increment; i++) {
|
||||
free(heap->bucket[i]);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&heap->mutex);
|
||||
|
||||
free(heap->bucket);
|
||||
heap->bucket = NULL;
|
||||
heap->heap_size = 0;
|
||||
heap->next_free = LAST_FREE;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef OBJECT_HEAP_H
|
||||
#define OBJECT_HEAP_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define OBJECT_HEAP_OFFSET_MASK 0x7F000000
|
||||
#define OBJECT_HEAP_ID_MASK 0x00FFFFFF
|
||||
|
||||
typedef struct object_base *object_base_p;
|
||||
typedef struct object_heap *object_heap_p;
|
||||
|
||||
struct object_base {
|
||||
int id;
|
||||
int next_free;
|
||||
};
|
||||
|
||||
struct object_heap {
|
||||
pthread_mutex_t mutex;
|
||||
int object_size;
|
||||
int id_offset;
|
||||
int next_free;
|
||||
int heap_size;
|
||||
int heap_increment;
|
||||
void **bucket;
|
||||
int num_buckets;
|
||||
};
|
||||
|
||||
typedef int object_heap_iterator;
|
||||
|
||||
/*
|
||||
* Return 0 on success, -1 on error
|
||||
*/
|
||||
int object_heap_init(object_heap_p heap, int object_size, int id_offset);
|
||||
|
||||
/*
|
||||
* Allocates an object
|
||||
* Returns the object ID on success, returns -1 on error
|
||||
*/
|
||||
int object_heap_allocate(object_heap_p heap);
|
||||
|
||||
/*
|
||||
* Lookup an allocated object by object ID
|
||||
* Returns a pointer to the object on success, returns NULL on error
|
||||
*/
|
||||
object_base_p object_heap_lookup(object_heap_p heap, int id);
|
||||
|
||||
/*
|
||||
* Iterate over all objects in the heap.
|
||||
* Returns a pointer to the first object on the heap, returns NULL if heap is empty.
|
||||
*/
|
||||
object_base_p object_heap_first(object_heap_p heap, object_heap_iterator *iter);
|
||||
|
||||
/*
|
||||
* Iterate over all objects in the heap.
|
||||
* Returns a pointer to the next object on the heap, returns NULL if heap is empty.
|
||||
*/
|
||||
object_base_p object_heap_next(object_heap_p heap, object_heap_iterator *iter);
|
||||
|
||||
/*
|
||||
* Frees an object
|
||||
*/
|
||||
void object_heap_free(object_heap_p heap, object_base_p obj);
|
||||
|
||||
/*
|
||||
* Destroys a heap, the heap must be empty.
|
||||
*/
|
||||
void object_heap_destroy(object_heap_p heap);
|
||||
|
||||
#endif /* OBJECT_HEAP_H */
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "picture.h"
|
||||
#include "buffer.h"
|
||||
#include "context.h"
|
||||
#include "surface.h"
|
||||
#include "va_config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
/*
|
||||
* A Picture is an encoded input frame made of several buffers. A single input
|
||||
* can contain slice data, headers and IQ matrix. Each Picture is assigned a
|
||||
* request ID when created and each corresponding buffer might be turned into a
|
||||
* v4l buffers or extended control when rendered. Finally they are submitted to
|
||||
* kernel space when reaching EndPicture.
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_BeginPicture(VADriverContextP ctx, VAContextID context,
|
||||
VASurfaceID render_target)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_context_p obj_context;
|
||||
object_surface_p obj_surface;
|
||||
|
||||
obj_context = CONTEXT(context);
|
||||
assert(obj_context);
|
||||
|
||||
obj_surface = SURFACE(render_target);
|
||||
assert(obj_surface);
|
||||
|
||||
if(obj_surface->status == VASurfaceRendering)
|
||||
sunxi_cedrus_SyncSurface(ctx, render_target);
|
||||
|
||||
obj_surface->status = VASurfaceRendering;
|
||||
obj_surface->request = (obj_context->num_rendered_surfaces)%INPUT_BUFFERS_NB+1;
|
||||
obj_surface->input_buf_index = obj_context->num_rendered_surfaces%INPUT_BUFFERS_NB;
|
||||
obj_context->num_rendered_surfaces ++;
|
||||
|
||||
obj_context->current_render_target = obj_surface->base.id;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_RenderPicture(VADriverContextP ctx, VAContextID context,
|
||||
VABufferID *buffers, int num_buffers)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_context_p obj_context;
|
||||
object_surface_p obj_surface;
|
||||
object_config_p obj_config;
|
||||
int i;
|
||||
|
||||
obj_context = CONTEXT(context);
|
||||
assert(obj_context);
|
||||
|
||||
obj_config = CONFIG(obj_context->config_id);
|
||||
if (NULL == obj_config)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
obj_surface = SURFACE(obj_context->current_render_target);
|
||||
assert(obj_surface);
|
||||
|
||||
/* verify that we got valid buffer references */
|
||||
for(i = 0; i < num_buffers; i++)
|
||||
{
|
||||
object_buffer_p obj_buffer = BUFFER(buffers[i]);
|
||||
assert(obj_buffer);
|
||||
if (NULL == obj_buffer)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_EndPicture(VADriverContextP ctx, VAContextID context)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_context_p obj_context;
|
||||
object_surface_p obj_surface;
|
||||
struct v4l2_buffer out_buf, cap_buf;
|
||||
struct v4l2_plane plane[1];
|
||||
struct v4l2_plane planes[2];
|
||||
struct v4l2_ext_control ctrl;
|
||||
struct v4l2_ext_controls extCtrls;
|
||||
object_config_p obj_config;
|
||||
|
||||
obj_context = CONTEXT(context);
|
||||
assert(obj_context);
|
||||
|
||||
obj_surface = SURFACE(obj_context->current_render_target);
|
||||
assert(obj_surface);
|
||||
|
||||
obj_config = CONFIG(obj_context->config_id);
|
||||
if (NULL == obj_config)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
memset(&(out_buf), 0, sizeof(out_buf));
|
||||
out_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
out_buf.memory = V4L2_MEMORY_MMAP;
|
||||
out_buf.index = obj_surface->input_buf_index;
|
||||
out_buf.length = 1;
|
||||
out_buf.m.planes = plane;
|
||||
out_buf.request = obj_surface->request;
|
||||
|
||||
switch(obj_config->profile) {
|
||||
default:
|
||||
out_buf.m.planes[0].bytesused = 0;
|
||||
ctrl.id = V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR;
|
||||
ctrl.ptr = NULL;
|
||||
ctrl.size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&(cap_buf), 0, sizeof(cap_buf));
|
||||
cap_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
cap_buf.memory = V4L2_MEMORY_MMAP;
|
||||
cap_buf.index = obj_surface->output_buf_index;
|
||||
cap_buf.length = 2;
|
||||
cap_buf.m.planes = planes;
|
||||
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_QUERYBUF, &cap_buf)==0);
|
||||
|
||||
extCtrls.controls = &ctrl;
|
||||
extCtrls.count = 1;
|
||||
extCtrls.request = obj_surface->request;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_S_EXT_CTRLS, &extCtrls)==0);
|
||||
|
||||
if(ioctl(driver_data->mem2mem_fd, VIDIOC_QBUF, &cap_buf)) {
|
||||
obj_surface->status = VASurfaceSkipped;
|
||||
sunxi_cedrus_msg("Error when queuing output: %s\n", strerror(errno));
|
||||
return VA_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
if(ioctl(driver_data->mem2mem_fd, VIDIOC_QBUF, &out_buf)) {
|
||||
obj_surface->status = VASurfaceSkipped;
|
||||
sunxi_cedrus_msg("Error when queuing input: %s\n", strerror(errno));
|
||||
ioctl(driver_data->mem2mem_fd, VIDIOC_DQBUF, &cap_buf);
|
||||
return VA_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* For now, assume that we are done with rendering right away */
|
||||
obj_context->current_render_target = -1;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PICTURE_H_
|
||||
#define _PICTURE_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
|
||||
VAStatus sunxi_cedrus_BeginPicture(VADriverContextP ctx, VAContextID context,
|
||||
VASurfaceID render_target);
|
||||
|
||||
VAStatus sunxi_cedrus_RenderPicture(VADriverContextP ctx, VAContextID context,
|
||||
VABufferID *buffers, int num_buffers);
|
||||
|
||||
VAStatus sunxi_cedrus_EndPicture(VADriverContextP ctx, VAContextID context);
|
||||
|
||||
#endif /* _PICTURE_H_ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "subpicture.h"
|
||||
|
||||
/*
|
||||
* Subpictures aren't supported yet
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_QuerySubpictureFormats(VADriverContextP ctx,
|
||||
VAImageFormat *format_list, unsigned int *flags,
|
||||
unsigned int *num_formats)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_CreateSubpicture(VADriverContextP ctx, VAImageID image,
|
||||
VASubpictureID *subpicture)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_DestroySubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureImage(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VAImageID image)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpicturePalette(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, unsigned char *palette)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureChromakey(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, unsigned int chromakey_min,
|
||||
unsigned int chromakey_max, unsigned int chromakey_mask)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureGlobalAlpha(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, float global_alpha)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_AssociateSubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VASurfaceID *target_surfaces,
|
||||
int num_surfaces, short src_x, short src_y,
|
||||
unsigned short src_width, unsigned short src_height,
|
||||
short dest_x, short dest_y, unsigned short dest_width,
|
||||
unsigned short dest_height, unsigned int flags)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
VAStatus sunxi_cedrus_DeassociateSubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VASurfaceID *target_surfaces,
|
||||
int num_surfaces)
|
||||
{ return VA_STATUS_SUCCESS; }
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _SUBPICTURE_H_
|
||||
#define _SUBPICTURE_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
VAStatus sunxi_cedrus_QuerySubpictureFormats(VADriverContextP ctx,
|
||||
VAImageFormat *format_list, unsigned int *flags,
|
||||
unsigned int *num_formats);
|
||||
|
||||
VAStatus sunxi_cedrus_CreateSubpicture(VADriverContextP ctx, VAImageID image,
|
||||
VASubpictureID *subpicture);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroySubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture);
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureImage(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VAImageID image);
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpicturePalette(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, unsigned char *palette);
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureChromakey(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, unsigned int chromakey_min,
|
||||
unsigned int chromakey_max, unsigned int chromakey_mask);
|
||||
|
||||
VAStatus sunxi_cedrus_SetSubpictureGlobalAlpha(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, float global_alpha);
|
||||
|
||||
VAStatus sunxi_cedrus_AssociateSubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VASurfaceID *target_surfaces,
|
||||
int num_surfaces, short src_x, short src_y,
|
||||
unsigned short src_width, unsigned short src_height,
|
||||
short dest_x, short dest_y, unsigned short dest_width,
|
||||
unsigned short dest_height, unsigned int flags);
|
||||
|
||||
VAStatus sunxi_cedrus_DeassociateSubpicture(VADriverContextP ctx,
|
||||
VASubpictureID subpicture, VASurfaceID *target_surfaces,
|
||||
int num_surfaces);
|
||||
|
||||
#endif /* _SUBPICTURE_H_ */
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "buffer.h"
|
||||
#include "context.h"
|
||||
#include "image.h"
|
||||
#include "picture.h"
|
||||
#include "subpicture.h"
|
||||
#include "surface.h"
|
||||
#include "va_config.h"
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
/* We need to use stderr if we want to be heard */
|
||||
void sunxi_cedrus_msg(const char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
fprintf(stderr, "sunxi_cedrus_drv_video: ");
|
||||
va_start(args, msg);
|
||||
vfprintf(stderr, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Free memory and close v4l device */
|
||||
VAStatus sunxi_cedrus_Terminate(VADriverContextP ctx)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_buffer_p obj_buffer;
|
||||
object_config_p obj_config;
|
||||
object_heap_iterator iter;
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type);
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
ioctl(driver_data->mem2mem_fd, VIDIOC_STREAMOFF, &type);
|
||||
|
||||
close(driver_data->mem2mem_fd);
|
||||
|
||||
/* Clean up left over buffers */
|
||||
obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
|
||||
while (obj_buffer)
|
||||
{
|
||||
sunxi_cedrus_msg("vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
|
||||
sunxi_cedrus_destroy_buffer(driver_data, obj_buffer);
|
||||
obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
|
||||
}
|
||||
|
||||
object_heap_destroy(&driver_data->buffer_heap);
|
||||
object_heap_destroy(&driver_data->surface_heap);
|
||||
object_heap_destroy(&driver_data->context_heap);
|
||||
|
||||
/* Clean up configIDs */
|
||||
obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
|
||||
while (obj_config)
|
||||
{
|
||||
object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
|
||||
obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
|
||||
}
|
||||
object_heap_destroy(&driver_data->config_heap);
|
||||
|
||||
free(ctx->pDriverData);
|
||||
ctx->pDriverData = NULL;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Only expose the init function */
|
||||
VAStatus __attribute__((visibility("default")))
|
||||
VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
|
||||
|
||||
/* Setup a bunch of function pointers for VA */
|
||||
VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
|
||||
{
|
||||
struct VADriverVTable * const vtable = ctx->vtable;
|
||||
struct sunxi_cedrus_driver_data *driver_data;
|
||||
struct v4l2_capability cap;
|
||||
|
||||
ctx->version_major = VA_MAJOR_VERSION;
|
||||
ctx->version_minor = VA_MINOR_VERSION;
|
||||
ctx->max_profiles = SUNXI_CEDRUS_MAX_PROFILES;
|
||||
ctx->max_entrypoints = SUNXI_CEDRUS_MAX_ENTRYPOINTS;
|
||||
ctx->max_attributes = SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES;
|
||||
ctx->max_image_formats = SUNXI_CEDRUS_MAX_IMAGE_FORMATS;
|
||||
ctx->max_subpic_formats = SUNXI_CEDRUS_MAX_SUBPIC_FORMATS;
|
||||
ctx->max_display_attributes = SUNXI_CEDRUS_MAX_DISPLAY_ATTRIBUTES;
|
||||
ctx->str_vendor = SUNXI_CEDRUS_STR_VENDOR;
|
||||
|
||||
vtable->vaTerminate = sunxi_cedrus_Terminate;
|
||||
vtable->vaQueryConfigEntrypoints = sunxi_cedrus_QueryConfigEntrypoints;
|
||||
vtable->vaQueryConfigProfiles = sunxi_cedrus_QueryConfigProfiles;
|
||||
vtable->vaQueryConfigEntrypoints = sunxi_cedrus_QueryConfigEntrypoints;
|
||||
vtable->vaQueryConfigAttributes = sunxi_cedrus_QueryConfigAttributes;
|
||||
vtable->vaCreateConfig = sunxi_cedrus_CreateConfig;
|
||||
vtable->vaDestroyConfig = sunxi_cedrus_DestroyConfig;
|
||||
vtable->vaGetConfigAttributes = sunxi_cedrus_GetConfigAttributes;
|
||||
vtable->vaCreateSurfaces = sunxi_cedrus_CreateSurfaces;
|
||||
vtable->vaDestroySurfaces = sunxi_cedrus_DestroySurfaces;
|
||||
vtable->vaCreateContext = sunxi_cedrus_CreateContext;
|
||||
vtable->vaDestroyContext = sunxi_cedrus_DestroyContext;
|
||||
vtable->vaCreateBuffer = sunxi_cedrus_CreateBuffer;
|
||||
vtable->vaBufferSetNumElements = sunxi_cedrus_BufferSetNumElements;
|
||||
vtable->vaMapBuffer = sunxi_cedrus_MapBuffer;
|
||||
vtable->vaUnmapBuffer = sunxi_cedrus_UnmapBuffer;
|
||||
vtable->vaDestroyBuffer = sunxi_cedrus_DestroyBuffer;
|
||||
vtable->vaBeginPicture = sunxi_cedrus_BeginPicture;
|
||||
vtable->vaRenderPicture = sunxi_cedrus_RenderPicture;
|
||||
vtable->vaEndPicture = sunxi_cedrus_EndPicture;
|
||||
vtable->vaSyncSurface = sunxi_cedrus_SyncSurface;
|
||||
vtable->vaQuerySurfaceStatus = sunxi_cedrus_QuerySurfaceStatus;
|
||||
vtable->vaPutSurface = sunxi_cedrus_PutSurface;
|
||||
vtable->vaQueryImageFormats = sunxi_cedrus_QueryImageFormats;
|
||||
vtable->vaCreateImage = sunxi_cedrus_CreateImage;
|
||||
vtable->vaDeriveImage = sunxi_cedrus_DeriveImage;
|
||||
vtable->vaDestroyImage = sunxi_cedrus_DestroyImage;
|
||||
vtable->vaSetImagePalette = sunxi_cedrus_SetImagePalette;
|
||||
vtable->vaGetImage = sunxi_cedrus_GetImage;
|
||||
vtable->vaPutImage = sunxi_cedrus_PutImage;
|
||||
vtable->vaQuerySubpictureFormats = sunxi_cedrus_QuerySubpictureFormats;
|
||||
vtable->vaCreateSubpicture = sunxi_cedrus_CreateSubpicture;
|
||||
vtable->vaDestroySubpicture = sunxi_cedrus_DestroySubpicture;
|
||||
vtable->vaSetSubpictureImage = sunxi_cedrus_SetSubpictureImage;
|
||||
vtable->vaSetSubpictureChromakey = sunxi_cedrus_SetSubpictureChromakey;
|
||||
vtable->vaSetSubpictureGlobalAlpha = sunxi_cedrus_SetSubpictureGlobalAlpha;
|
||||
vtable->vaAssociateSubpicture = sunxi_cedrus_AssociateSubpicture;
|
||||
vtable->vaDeassociateSubpicture = sunxi_cedrus_DeassociateSubpicture;
|
||||
vtable->vaQueryDisplayAttributes = sunxi_cedrus_QueryDisplayAttributes;
|
||||
vtable->vaGetDisplayAttributes = sunxi_cedrus_GetDisplayAttributes;
|
||||
vtable->vaSetDisplayAttributes = sunxi_cedrus_SetDisplayAttributes;
|
||||
vtable->vaLockSurface = sunxi_cedrus_LockSurface;
|
||||
vtable->vaUnlockSurface = sunxi_cedrus_UnlockSurface;
|
||||
vtable->vaBufferInfo = sunxi_cedrus_BufferInfo;
|
||||
|
||||
driver_data = (struct sunxi_cedrus_driver_data *) malloc(sizeof(*driver_data));
|
||||
ctx->pDriverData = (void *) driver_data;
|
||||
|
||||
assert(object_heap_init(&driver_data->config_heap,
|
||||
sizeof(struct object_config), CONFIG_ID_OFFSET)==0);
|
||||
assert(object_heap_init(&driver_data->context_heap,
|
||||
sizeof(struct object_context), CONTEXT_ID_OFFSET)==0);
|
||||
assert(object_heap_init(&driver_data->surface_heap,
|
||||
sizeof(struct object_surface), SURFACE_ID_OFFSET)==0);
|
||||
assert(object_heap_init(&driver_data->buffer_heap,
|
||||
sizeof(struct object_buffer), BUFFER_ID_OFFSET)==0);
|
||||
assert(object_heap_init(&driver_data->image_heap,
|
||||
sizeof(struct object_image), IMAGE_ID_OFFSET)==0);
|
||||
|
||||
driver_data->mem2mem_fd = open("/dev/video0", O_RDWR | O_NONBLOCK, 0);
|
||||
assert(driver_data->mem2mem_fd >= 0);
|
||||
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_QUERYCAP, &cap)==0);
|
||||
if (!(cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE))
|
||||
{
|
||||
sunxi_cedrus_msg("/dev/video0 does not support m2m_mplane\n");
|
||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _SUNXI_CEDRUS_DRV_VIDEO_H_
|
||||
#define _SUNXI_CEDRUS_DRV_VIDEO_H_
|
||||
|
||||
#include <va/va.h>
|
||||
#include "object_heap.h"
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#define INIT_DRIVER_DATA struct sunxi_cedrus_driver_data * const driver_data = (struct sunxi_cedrus_driver_data *) ctx->pDriverData;
|
||||
|
||||
#define SUNXI_CEDRUS_STR_VENDOR "Sunxi Cedrus Driver 1.0"
|
||||
|
||||
#define SUNXI_CEDRUS_MAX_PROFILES 11
|
||||
#define SUNXI_CEDRUS_MAX_ENTRYPOINTS 5
|
||||
#define SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES 10
|
||||
#define SUNXI_CEDRUS_MAX_IMAGE_FORMATS 10
|
||||
#define SUNXI_CEDRUS_MAX_SUBPIC_FORMATS 4
|
||||
#define SUNXI_CEDRUS_MAX_DISPLAY_ATTRIBUTES 4
|
||||
|
||||
void sunxi_cedrus_msg(const char *msg, ...);
|
||||
|
||||
struct sunxi_cedrus_driver_data {
|
||||
struct object_heap config_heap;
|
||||
struct object_heap context_heap;
|
||||
struct object_heap surface_heap;
|
||||
struct object_heap buffer_heap;
|
||||
struct object_heap image_heap;
|
||||
char *luma_bufs[VIDEO_MAX_FRAME];
|
||||
char *chroma_bufs[VIDEO_MAX_FRAME];
|
||||
unsigned int num_dst_bufs;
|
||||
int mem2mem_fd;
|
||||
};
|
||||
|
||||
#endif /* _SUNXI_CEDRUS_DRV_VIDEO_H_ */
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "surface.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/*
|
||||
* A Surface is an internal data structure never handled by the VA's user
|
||||
* containing the output of a rendering. Usualy, a bunch of surfaces are created
|
||||
* at the begining of decoding and they are then used alternatively. When
|
||||
* created, a surface is assigned a corresponding v4l capture buffer and it is
|
||||
* kept until the end of decoding. Syncing a surface waits for the v4l buffer to
|
||||
* be available and then dequeue it.
|
||||
*
|
||||
* Note: since a Surface is kept private from the VA's user, it can ask to
|
||||
* directly render a Surface on screen in an X Drawable. Some kind of
|
||||
* implementation is available in PutSurface but this is only for development
|
||||
* purpose.
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_CreateSurfaces(VADriverContextP ctx, int width,
|
||||
int height, int format, int num_surfaces, VASurfaceID *surfaces)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
int i;
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_plane planes[2];
|
||||
struct v4l2_create_buffers create_bufs;
|
||||
struct v4l2_format fmt;
|
||||
|
||||
/* We only support one format */
|
||||
if (VA_RT_FORMAT_YUV420 != format)
|
||||
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
|
||||
|
||||
/* Set format for capture */
|
||||
memset(&(fmt), 0, sizeof(fmt));
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
fmt.fmt.pix_mp.width = width;
|
||||
fmt.fmt.pix_mp.height = height;
|
||||
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_SUNXI;
|
||||
fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
|
||||
fmt.fmt.pix_mp.num_planes = 2;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_S_FMT, &fmt)==0);
|
||||
|
||||
memset (&create_bufs, 0, sizeof (struct v4l2_create_buffers));
|
||||
create_bufs.count = num_surfaces;
|
||||
create_bufs.memory = V4L2_MEMORY_MMAP;
|
||||
create_bufs.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_G_FMT, &create_bufs.format)==0);
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_CREATE_BUFS, &create_bufs)==0);
|
||||
driver_data->num_dst_bufs = create_bufs.count;
|
||||
|
||||
for (i = 0; i < create_bufs.count; i++)
|
||||
{
|
||||
int surfaceID = object_heap_allocate(&driver_data->surface_heap);
|
||||
object_surface_p obj_surface = SURFACE(surfaceID);
|
||||
if (NULL == obj_surface)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
break;
|
||||
}
|
||||
obj_surface->surface_id = surfaceID;
|
||||
surfaces[i] = surfaceID;
|
||||
|
||||
memset(&(buf), 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = create_bufs.index + i;
|
||||
buf.length = 2;
|
||||
buf.m.planes = planes;
|
||||
|
||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_QUERYBUF, &buf)==0);
|
||||
|
||||
driver_data->luma_bufs[buf.index] = mmap(NULL, buf.m.planes[0].length,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
driver_data->mem2mem_fd, buf.m.planes[0].m.mem_offset);
|
||||
assert(driver_data->luma_bufs[buf.index] != MAP_FAILED);
|
||||
|
||||
driver_data->chroma_bufs[buf.index] = mmap(NULL, buf.m.planes[1].length,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
driver_data->mem2mem_fd, buf.m.planes[1].m.mem_offset);
|
||||
assert(driver_data->chroma_bufs[buf.index] != MAP_FAILED);
|
||||
|
||||
obj_surface->input_buf_index = 0;
|
||||
obj_surface->output_buf_index = create_bufs.index + i;
|
||||
|
||||
obj_surface->width = width;
|
||||
obj_surface->height = height;
|
||||
obj_surface->status = VASurfaceReady;
|
||||
}
|
||||
|
||||
/* Error recovery */
|
||||
if (VA_STATUS_SUCCESS != vaStatus)
|
||||
{
|
||||
/* surfaces[i-1] was the last successful allocation */
|
||||
for(; i--;)
|
||||
{
|
||||
object_surface_p obj_surface = SURFACE(surfaces[i]);
|
||||
surfaces[i] = VA_INVALID_SURFACE;
|
||||
assert(obj_surface);
|
||||
object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
|
||||
}
|
||||
}
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DestroySurfaces(VADriverContextP ctx,
|
||||
VASurfaceID *surface_list, int num_surfaces)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
int i;
|
||||
for(i = num_surfaces; i--;)
|
||||
{
|
||||
object_surface_p obj_surface = SURFACE(surface_list[i]);
|
||||
assert(obj_surface);
|
||||
object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
|
||||
}
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_SyncSurface(VADriverContextP ctx,
|
||||
VASurfaceID render_target)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
object_surface_p obj_surface;
|
||||
struct v4l2_buffer buf;
|
||||
struct v4l2_plane plane[1];
|
||||
fd_set read_fds;
|
||||
struct timeval tv = {0, 300000};
|
||||
|
||||
obj_surface = SURFACE(render_target);
|
||||
assert(obj_surface);
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(driver_data->mem2mem_fd, &read_fds);
|
||||
if(obj_surface->status != VASurfaceSkipped)
|
||||
select(driver_data->mem2mem_fd + 1, &read_fds, NULL, NULL, &tv);
|
||||
else
|
||||
return VA_STATUS_ERROR_UNKNOWN;
|
||||
|
||||
memset(&(buf), 0, sizeof(buf));
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = obj_surface->input_buf_index;
|
||||
buf.length = 1;
|
||||
buf.m.planes = plane;
|
||||
|
||||
if(ioctl(driver_data->mem2mem_fd, VIDIOC_DQBUF, &buf)) {
|
||||
sunxi_cedrus_msg("Error when dequeuing input: %s\n", strerror(errno));
|
||||
return VA_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
memset(&(buf), 0, sizeof(buf));
|
||||
struct v4l2_plane planes[2];
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = obj_surface->output_buf_index;
|
||||
buf.length = 2;
|
||||
buf.m.planes = planes;
|
||||
|
||||
obj_surface->status = VASurfaceReady;
|
||||
|
||||
if(ioctl(driver_data->mem2mem_fd, VIDIOC_DQBUF, &buf)) {
|
||||
sunxi_cedrus_msg("Error when dequeuing output: %s\n", strerror(errno));
|
||||
return VA_STATUS_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_QuerySurfaceStatus(VADriverContextP ctx,
|
||||
VASurfaceID render_target, VASurfaceStatus *status)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_surface_p obj_surface;
|
||||
|
||||
obj_surface = SURFACE(render_target);
|
||||
assert(obj_surface);
|
||||
|
||||
*status = obj_surface->status;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
/* WARNING: This is for development purpose only!!! */
|
||||
VAStatus sunxi_cedrus_PutSurface(VADriverContextP ctx, VASurfaceID surface,
|
||||
void *draw, short srcx, short srcy, unsigned short srcw,
|
||||
unsigned short srch, short destx, short desty,
|
||||
unsigned short destw, unsigned short desth,
|
||||
VARectangle *cliprects, unsigned int number_cliprects,
|
||||
unsigned int flags)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
GC gc;
|
||||
Display *display;
|
||||
const XID xid = (XID)(uintptr_t)draw;
|
||||
XColor xcolor;
|
||||
int screen;
|
||||
Colormap cm;
|
||||
int colorratio = 65535 / 255;
|
||||
int x, y;
|
||||
object_surface_p obj_surface;
|
||||
|
||||
obj_surface = SURFACE(surface);
|
||||
assert(obj_surface);
|
||||
|
||||
display = XOpenDisplay(getenv("DISPLAY"));
|
||||
if (display == NULL) {
|
||||
sunxi_cedrus_msg("Cannot connect to X server\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sunxi_cedrus_msg("warning: using vaPutSurface with sunxi-cedrus is not recommended\n");
|
||||
screen = DefaultScreen(display);
|
||||
gc = XCreateGC(display, RootWindow(display, screen), 0, NULL);
|
||||
XSync(display, False);
|
||||
|
||||
cm = DefaultColormap(display, screen);
|
||||
xcolor.flags = DoRed | DoGreen | DoBlue;
|
||||
|
||||
for(x=destx; x < destx+destw; x++) {
|
||||
for(y=desty; y < desty+desth; y++) {
|
||||
char lum = driver_data->luma_bufs[obj_surface->output_buf_index][x+srcw*y];
|
||||
xcolor.red = xcolor.green = xcolor.blue = lum*colorratio;
|
||||
XAllocColor(display, cm, &xcolor);
|
||||
XSetForeground(display, gc, xcolor.pixel);
|
||||
XDrawPoint(display, xid, gc, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
XFlush(display);
|
||||
XCloseDisplay(display);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_LockSurface(VADriverContextP ctx, VASurfaceID surface,
|
||||
unsigned int *fourcc, unsigned int *luma_stride,
|
||||
unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
|
||||
unsigned int *luma_offset, unsigned int *chroma_u_offset,
|
||||
unsigned int *chroma_v_offset, unsigned int *buffer_name,
|
||||
void **buffer)
|
||||
{ return VA_STATUS_ERROR_UNIMPLEMENTED; }
|
||||
|
||||
VAStatus sunxi_cedrus_UnlockSurface(VADriverContextP ctx, VASurfaceID surface)
|
||||
{ return VA_STATUS_ERROR_UNIMPLEMENTED; }
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _SURFACES_H_
|
||||
#define _SURFACES_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
|
||||
#define SURFACE(id) ((object_surface_p) object_heap_lookup(&driver_data->surface_heap, id))
|
||||
#define SURFACE_ID_OFFSET 0x04000000
|
||||
|
||||
struct object_surface {
|
||||
struct object_base base;
|
||||
VASurfaceID surface_id;
|
||||
uint32_t request;
|
||||
uint32_t input_buf_index;
|
||||
uint32_t output_buf_index;
|
||||
int width;
|
||||
int height;
|
||||
VAStatus status;
|
||||
};
|
||||
|
||||
typedef struct object_surface *object_surface_p;
|
||||
|
||||
VAStatus sunxi_cedrus_CreateSurfaces(VADriverContextP ctx, int width,
|
||||
int height, int format, int num_surfaces, VASurfaceID *surfaces);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroySurfaces(VADriverContextP ctx,
|
||||
VASurfaceID *surface_list, int num_surfaces);
|
||||
|
||||
VAStatus sunxi_cedrus_SyncSurface(VADriverContextP ctx,
|
||||
VASurfaceID render_target);
|
||||
|
||||
VAStatus sunxi_cedrus_QuerySurfaceStatus(VADriverContextP ctx,
|
||||
VASurfaceID render_target, VASurfaceStatus *status);
|
||||
|
||||
VAStatus sunxi_cedrus_PutSurface(VADriverContextP ctx, VASurfaceID surface,
|
||||
void *draw, short srcx, short srcy, unsigned short srcw,
|
||||
unsigned short srch, short destx, short desty,
|
||||
unsigned short destw, unsigned short desth,
|
||||
VARectangle *cliprects, unsigned int number_cliprects,
|
||||
unsigned int flags);
|
||||
|
||||
VAStatus sunxi_cedrus_LockSurface(VADriverContextP ctx, VASurfaceID surface,
|
||||
unsigned int *fourcc, unsigned int *luma_stride,
|
||||
unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
|
||||
unsigned int *luma_offset, unsigned int *chroma_u_offset,
|
||||
unsigned int *chroma_v_offset, unsigned int *buffer_name,
|
||||
void **buffer);
|
||||
|
||||
VAStatus sunxi_cedrus_UnlockSurface(VADriverContextP ctx, VASurfaceID surface);
|
||||
|
||||
#endif /* _SURFACES_H_ */
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Jens Kuske <jenskuske@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The Sunxi Video Engine outputs buffers in a specific format similar to NV12
|
||||
* but with "tiles" of size 32x32. This code converts the data from this tiled
|
||||
* format to two NV12 planes.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
|
||||
#endif
|
||||
|
||||
#ifndef __aarch64__
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
.arch armv7-a
|
||||
.fpu neon
|
||||
.thumb
|
||||
|
||||
.macro thumb_function fname
|
||||
.global \fname
|
||||
#ifdef __ELF__
|
||||
.hidden \fname
|
||||
.type \fname, %function
|
||||
#endif
|
||||
.thumb_func
|
||||
\fname:
|
||||
.endm
|
||||
|
||||
.macro end_function fname
|
||||
#ifdef __ELF__
|
||||
.size \fname, .-\fname
|
||||
#endif
|
||||
.endm
|
||||
|
||||
SRC .req r0
|
||||
DST .req r1
|
||||
PITCH .req r2
|
||||
CNT .req r3
|
||||
TLINE .req r4
|
||||
HEIGHT .req r5
|
||||
REST .req r6
|
||||
NTILES .req r7
|
||||
TMPSRC .req r8
|
||||
DST2 .req r9
|
||||
TSIZE .req r12
|
||||
NEXTLIN .req lr
|
||||
|
||||
thumb_function tiled_to_planar
|
||||
push {r4, r5, r6, r7, r8, lr}
|
||||
ldr HEIGHT, [sp, #24]
|
||||
add NEXTLIN, r3, #31
|
||||
lsrs NTILES, r3, #5
|
||||
bic NEXTLIN, NEXTLIN, #31
|
||||
and REST, r3, #31
|
||||
lsl NEXTLIN, NEXTLIN, #5
|
||||
subs PITCH, r2, r3
|
||||
movs TLINE, #32
|
||||
rsb NEXTLIN, NEXTLIN, #32
|
||||
mov TSIZE, #1024
|
||||
|
||||
/* y loop */
|
||||
1: cbz NTILES, 3f
|
||||
mov CNT, NTILES
|
||||
|
||||
/* x loop complete tiles */
|
||||
2: pld [SRC, TSIZE]
|
||||
vld1.8 {d0 - d3}, [SRC :256], TSIZE
|
||||
subs CNT, #1
|
||||
vst1.8 {d0 - d3}, [DST]!
|
||||
bne 2b
|
||||
|
||||
3: cbnz REST, 4f
|
||||
|
||||
/* fix up dest pointer if pitch != width */
|
||||
7: add DST, PITCH
|
||||
|
||||
/* fix up src pointer at end of line */
|
||||
subs TLINE, #1
|
||||
itee ne
|
||||
addne SRC, NEXTLIN
|
||||
subeq SRC, #992
|
||||
moveq TLINE, #32
|
||||
|
||||
subs HEIGHT, #1
|
||||
bne 1b
|
||||
pop {r4, r5, r6, r7, r8, pc}
|
||||
|
||||
/* partly copy last tile of line */
|
||||
4: mov TMPSRC, SRC
|
||||
tst REST, #16
|
||||
beq 5f
|
||||
vld1.8 {d0 - d1}, [TMPSRC :128]!
|
||||
vst1.8 {d0 - d1}, [DST]!
|
||||
5: add SRC, TSIZE
|
||||
ands CNT, REST, #15
|
||||
beq 7b
|
||||
6: vld1.8 {d0[0]}, [TMPSRC]!
|
||||
subs CNT, #1
|
||||
vst1.8 {d0[0]}, [DST]!
|
||||
bne 6b
|
||||
b 7b
|
||||
end_function tiled_to_planar
|
||||
|
||||
thumb_function tiled_deinterleave_to_planar
|
||||
push {r4, r5, r6, r7, r8, r9, lr}
|
||||
mov DST2, r2
|
||||
ldr HEIGHT, [sp, #32]
|
||||
ldr r4, [sp, #28]
|
||||
add NEXTLIN, r4, #31
|
||||
lsrs NTILES, r4, #5
|
||||
bic NEXTLIN, NEXTLIN, #31
|
||||
ubfx REST, r4, #1, #4
|
||||
lsl NEXTLIN, NEXTLIN, #5
|
||||
sub PITCH, r3, r4, lsr #1
|
||||
movs TLINE, #32
|
||||
rsb NEXTLIN, NEXTLIN, #32
|
||||
mov TSIZE, #1024
|
||||
|
||||
/* y loop */
|
||||
1: cbz NTILES, 3f
|
||||
mov CNT, NTILES
|
||||
|
||||
/* x loop complete tiles */
|
||||
2: pld [SRC, TSIZE]
|
||||
vld2.8 {d0 - d3}, [SRC :256], TSIZE
|
||||
subs CNT, #1
|
||||
vst1.8 {d0 - d1}, [DST]!
|
||||
vst1.8 {d2 - d3}, [DST2]!
|
||||
bne 2b
|
||||
|
||||
3: cbnz REST, 4f
|
||||
|
||||
/* fix up dest pointer if pitch != width */
|
||||
7: add DST, PITCH
|
||||
add DST2, PITCH
|
||||
|
||||
/* fix up src pointer at end of line */
|
||||
subs TLINE, #1
|
||||
itee ne
|
||||
addne SRC, NEXTLIN
|
||||
subeq SRC, #992
|
||||
moveq TLINE, #32
|
||||
|
||||
subs HEIGHT, #1
|
||||
bne 1b
|
||||
pop {r4, r5, r6, r7, r8, r9, pc}
|
||||
|
||||
/* partly copy last tile of line */
|
||||
4: mov TMPSRC, SRC
|
||||
tst REST, #8
|
||||
beq 5f
|
||||
vld2.8 {d0 - d1}, [TMPSRC :128]!
|
||||
vst1.8 {d0}, [DST]!
|
||||
vst1.8 {d1}, [DST2]!
|
||||
5: add SRC, TSIZE
|
||||
ands CNT, REST, #7
|
||||
beq 7b
|
||||
6: vld2.8 {d0[0], d1[0]}, [TMPSRC]!
|
||||
subs CNT, #1
|
||||
vst1.8 {d0[0]}, [DST]!
|
||||
vst1.8 {d1[0]}, [DST2]!
|
||||
bne 6b
|
||||
b 7b
|
||||
end_function tiled_deinterleave_to_planar
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Jens Kuske <jenskuske@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TILED_YUV_H__
|
||||
#define __TILED_YUV_H__
|
||||
|
||||
void tiled_to_planar(void *src, void *dst, unsigned int dst_pitch,
|
||||
unsigned int width, unsigned int height);
|
||||
|
||||
void tiled_deinterleave_to_planar(void *src, void *dst1, void *dst2,
|
||||
unsigned int dst_pitch,
|
||||
unsigned int width, unsigned int height);
|
||||
|
||||
#endif
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sunxi_cedrus_drv_video.h"
|
||||
#include "va_config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
/*
|
||||
* This file provides generalities to VA's user regarding the file formats
|
||||
* supported by the v4l driver. It uses VIDIOC_ENUM_FMT to make the
|
||||
* correspondence between v4l and VA video formats.
|
||||
*/
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigProfiles(VADriverContextP ctx,
|
||||
VAProfile *profile_list, int *num_profiles)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
int i = 0;
|
||||
struct v4l2_fmtdesc vid_fmtdesc;
|
||||
memset(&vid_fmtdesc, 0, sizeof(vid_fmtdesc));
|
||||
vid_fmtdesc.index = 0;
|
||||
vid_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
||||
|
||||
while(ioctl(driver_data->mem2mem_fd, VIDIOC_ENUM_FMT, &vid_fmtdesc) == 0)
|
||||
{
|
||||
vid_fmtdesc.index++;
|
||||
}
|
||||
|
||||
assert(i <= SUNXI_CEDRUS_MAX_PROFILES);
|
||||
*num_profiles = i;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigEntrypoints(VADriverContextP ctx,
|
||||
VAProfile profile, VAEntrypoint *entrypoint_list,
|
||||
int *num_entrypoints)
|
||||
{
|
||||
switch (profile) {
|
||||
default:
|
||||
*num_entrypoints = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(*num_entrypoints <= SUNXI_CEDRUS_MAX_ENTRYPOINTS);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_GetConfigAttributes(VADriverContextP ctx,
|
||||
VAProfile profile, VAEntrypoint entrypoint,
|
||||
VAConfigAttrib *attrib_list, int num_attribs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_attribs; i++)
|
||||
{
|
||||
switch (attrib_list[i].type)
|
||||
{
|
||||
case VAConfigAttribRTFormat:
|
||||
attrib_list[i].value = VA_RT_FORMAT_YUV420;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Do nothing */
|
||||
attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_update_attribute(object_config_p obj_config,
|
||||
VAConfigAttrib *attrib)
|
||||
{
|
||||
int i;
|
||||
/* Check existing attributes */
|
||||
for(i = 0; obj_config->attrib_count < i; i++)
|
||||
{
|
||||
if (obj_config->attrib_list[i].type == attrib->type)
|
||||
{
|
||||
/* Update existing attribute */
|
||||
obj_config->attrib_list[i].value = attrib->value;
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
if (obj_config->attrib_count < SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES)
|
||||
{
|
||||
i = obj_config->attrib_count;
|
||||
obj_config->attrib_list[i].type = attrib->type;
|
||||
obj_config->attrib_list[i].value = attrib->value;
|
||||
obj_config->attrib_count++;
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_CreateConfig(VADriverContextP ctx, VAProfile profile,
|
||||
VAEntrypoint entrypoint, VAConfigAttrib *attrib_list,
|
||||
int num_attribs, VAConfigID *config_id)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus;
|
||||
int configID;
|
||||
object_config_p obj_config;
|
||||
int i;
|
||||
|
||||
/* Validate profile & entrypoint */
|
||||
switch (profile) {
|
||||
default:
|
||||
vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (VA_STATUS_SUCCESS != vaStatus)
|
||||
return vaStatus;
|
||||
|
||||
configID = object_heap_allocate(&driver_data->config_heap);
|
||||
obj_config = CONFIG(configID);
|
||||
if (NULL == obj_config)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
obj_config->profile = profile;
|
||||
obj_config->entrypoint = entrypoint;
|
||||
obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
|
||||
obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
|
||||
obj_config->attrib_count = 1;
|
||||
|
||||
for(i = 0; i < num_attribs; i++)
|
||||
{
|
||||
vaStatus = sunxi_cedrus_update_attribute(obj_config, &(attrib_list[i]));
|
||||
if (VA_STATUS_SUCCESS != vaStatus)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Error recovery */
|
||||
if (VA_STATUS_SUCCESS != vaStatus)
|
||||
object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
|
||||
else
|
||||
*config_id = configID;
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus;
|
||||
object_config_p obj_config;
|
||||
|
||||
obj_config = CONFIG(config_id);
|
||||
if (NULL == obj_config)
|
||||
{
|
||||
vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigAttributes(VADriverContextP ctx,
|
||||
VAConfigID config_id, VAProfile *profile,
|
||||
VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list,
|
||||
int *num_attribs)
|
||||
{
|
||||
INIT_DRIVER_DATA
|
||||
VAStatus vaStatus = VA_STATUS_SUCCESS;
|
||||
object_config_p obj_config;
|
||||
int i;
|
||||
|
||||
obj_config = CONFIG(config_id);
|
||||
assert(obj_config);
|
||||
|
||||
*profile = obj_config->profile;
|
||||
*entrypoint = obj_config->entrypoint;
|
||||
*num_attribs = obj_config->attrib_count;
|
||||
for(i = 0; i < obj_config->attrib_count; i++)
|
||||
attrib_list[i] = obj_config->attrib_list[i];
|
||||
|
||||
return vaStatus;
|
||||
}
|
||||
|
||||
/* sunxi-cedrus doesn't support display attributes */
|
||||
VAStatus sunxi_cedrus_QueryDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int *num_attributes)
|
||||
{ return VA_STATUS_ERROR_UNKNOWN; }
|
||||
|
||||
VAStatus sunxi_cedrus_GetDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int num_attributes)
|
||||
{ return VA_STATUS_ERROR_UNKNOWN; }
|
||||
|
||||
VAStatus sunxi_cedrus_SetDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int num_attributes)
|
||||
{ return VA_STATUS_ERROR_UNKNOWN; }
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Florent Revest, <florent.revest@free-electrons.com>
|
||||
* 2007 Intel Corporation. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#include <va/va_backend.h>
|
||||
|
||||
#include "object_heap.h"
|
||||
|
||||
#define CONFIG(id) ((object_config_p) object_heap_lookup(&driver_data->config_heap, id))
|
||||
#define CONFIG_ID_OFFSET 0x01000000
|
||||
|
||||
struct object_config {
|
||||
struct object_base base;
|
||||
VAProfile profile;
|
||||
VAEntrypoint entrypoint;
|
||||
VAConfigAttrib attrib_list[SUNXI_CEDRUS_MAX_CONFIG_ATTRIBUTES];
|
||||
int attrib_count;
|
||||
};
|
||||
|
||||
typedef struct object_config *object_config_p;
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigProfiles(VADriverContextP ctx,
|
||||
VAProfile *profile_list, int *num_profiles);
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigEntrypoints(VADriverContextP ctx,
|
||||
VAProfile profile, VAEntrypoint *entrypoint_list,
|
||||
int *num_entrypoints);
|
||||
|
||||
VAStatus sunxi_cedrus_GetConfigAttributes(VADriverContextP ctx,
|
||||
VAProfile profile, VAEntrypoint entrypoint,
|
||||
VAConfigAttrib *attrib_list, int num_attribs);
|
||||
|
||||
VAStatus sunxi_cedrus_update_attribute(object_config_p obj_config,
|
||||
VAConfigAttrib *attrib);
|
||||
|
||||
VAStatus sunxi_cedrus_CreateConfig(VADriverContextP ctx, VAProfile profile,
|
||||
VAEntrypoint entrypoint, VAConfigAttrib *attrib_list,
|
||||
int num_attribs, VAConfigID *config_id);
|
||||
|
||||
VAStatus sunxi_cedrus_DestroyConfig(VADriverContextP ctx, VAConfigID config_id);
|
||||
|
||||
VAStatus sunxi_cedrus_QueryConfigAttributes(VADriverContextP ctx,
|
||||
VAConfigID config_id, VAProfile *profile,
|
||||
VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list,
|
||||
int *num_attribs);
|
||||
|
||||
VAStatus sunxi_cedrus_QueryDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int *num_attributes);
|
||||
|
||||
VAStatus sunxi_cedrus_GetDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int num_attributes);
|
||||
|
||||
VAStatus sunxi_cedrus_SetDisplayAttributes (VADriverContextP ctx,
|
||||
VADisplayAttribute *attr_list, int num_attributes);
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
Reference in New Issue
Block a user