st/omx: initial OpenMAX support v3

Featuring a full grown MPEG2 and H264 decoder and a couple of hundred bugs.

v2 (Leo): fix an error for pic_order_cnt_type 1
v3 (Leo): implement support for field decoding

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Leo Liu <leo.liu@amd.com>
This commit is contained in:
Christian König 2013-08-05 11:41:27 -06:00
parent c9b941ff1b
commit 15e39ca28a
14 changed files with 2421 additions and 2 deletions

View file

@ -589,6 +589,11 @@ AC_ARG_ENABLE([vdpau],
[enable vdpau library @<:@default=auto@:>@])], [enable vdpau library @<:@default=auto@:>@])],
[enable_vdpau="$enableval"], [enable_vdpau="$enableval"],
[enable_vdpau=auto]) [enable_vdpau=auto])
AC_ARG_ENABLE([omx],
[AS_HELP_STRING([--enable-omx],
[enable OpenMAX library @<:@default=no@:>@])],
[enable_omx="$enableval"],
[enable_omx=no])
AC_ARG_ENABLE([opencl], AC_ARG_ENABLE([opencl],
[AS_HELP_STRING([--enable-opencl], [AS_HELP_STRING([--enable-opencl],
[enable OpenCL library NOTE: Enabling this option will also enable [enable OpenCL library NOTE: Enabling this option will also enable
@ -661,6 +666,7 @@ if test "x$enable_opengl" = xno -a \
"x$enable_xa" = xno -a \ "x$enable_xa" = xno -a \
"x$enable_xvmc" = xno -a \ "x$enable_xvmc" = xno -a \
"x$enable_vdpau" = xno -a \ "x$enable_vdpau" = xno -a \
"x$enable_omx" = xno -a \
"x$enable_opencl" = xno; then "x$enable_opencl" = xno; then
AC_MSG_ERROR([at least one API should be enabled]) AC_MSG_ERROR([at least one API should be enabled])
fi fi
@ -1306,6 +1312,10 @@ if test -n "$with_gallium_drivers"; then
if test "x$enable_vdpau" = xauto; then if test "x$enable_vdpau" = xauto; then
PKG_CHECK_EXISTS([vdpau], [enable_vdpau=yes], [enable_vdpau=no]) PKG_CHECK_EXISTS([vdpau], [enable_vdpau=yes], [enable_vdpau=no])
fi fi
if test "x$enable_omx" = xauto; then
PKG_CHECK_EXISTS([libomxil-bellagio], [enable_omx=yes], [enable_omx=no])
fi
fi fi
if test "x$enable_xvmc" = xyes; then if test "x$enable_xvmc" = xyes; then
@ -1320,6 +1330,12 @@ if test "x$enable_vdpau" = xyes; then
fi fi
AM_CONDITIONAL(HAVE_ST_VDPAU, test "x$enable_vdpau" = xyes) AM_CONDITIONAL(HAVE_ST_VDPAU, test "x$enable_vdpau" = xyes)
if test "x$enable_omx" = xyes; then
PKG_CHECK_MODULES([OMX], [libomxil-bellagio >= 0.0 x11-xcb xcb-dri2 >= 1.8])
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS omx"
fi
AM_CONDITIONAL(HAVE_ST_OMX, test "x$enable_omx" = xyes)
dnl dnl
dnl OpenCL configuration dnl OpenCL configuration
dnl dnl
@ -1653,6 +1669,13 @@ AC_ARG_WITH([vdpau-libdir],
[VDPAU_LIB_INSTALL_DIR='${libdir}/vdpau']) [VDPAU_LIB_INSTALL_DIR='${libdir}/vdpau'])
AC_SUBST([VDPAU_LIB_INSTALL_DIR]) AC_SUBST([VDPAU_LIB_INSTALL_DIR])
AC_ARG_WITH([omx-libdir],
[AS_HELP_STRING([--with-omx-libdir=DIR],
[directory for the OMX libraries])],
[OMX_LIB_INSTALL_DIR="$withval"],
[OMX_LIB_INSTALL_DIR=`$PKG_CONFIG --variable=pluginsdir libomxil-bellagio`])
AC_SUBST([OMX_LIB_INSTALL_DIR])
dnl Directory for OpenCL libs dnl Directory for OpenCL libs
AC_ARG_WITH([opencl-libdir], AC_ARG_WITH([opencl-libdir],
[AS_HELP_STRING([--with-opencl-libdir=DIR], [AS_HELP_STRING([--with-opencl-libdir=DIR],
@ -1683,6 +1706,9 @@ gallium_check_st() {
if test "x$enable_vdpau" = xyes && test "x$5" != x; then if test "x$enable_vdpau" = xyes && test "x$5" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5" GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5"
fi fi
if test "x$enable_omx" = xyes && test "x$6" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $7"
fi
} }
gallium_require_llvm() { gallium_require_llvm() {
@ -1780,7 +1806,7 @@ if test "x$with_gallium_drivers" != x; then
if test "x$enable_opencl" = xyes; then if test "x$enable_opencl" = xyes; then
LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser" LLVM_COMPONENTS="${LLVM_COMPONENTS} bitreader asmparser"
fi fi
gallium_check_st "radeon/drm" "r600/dri" "" "r600/xvmc" "r600/vdpau" gallium_check_st "radeon/drm" "r600/dri" "" "r600/xvmc" "r600/vdpau" "r600/omx"
DRICOMMON_NEED_LIBDRM=yes DRICOMMON_NEED_LIBDRM=yes
;; ;;
xradeonsi) xradeonsi)
@ -1789,7 +1815,7 @@ if test "x$with_gallium_drivers" != x; then
gallium_require_drm_loader gallium_require_drm_loader
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi" GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
radeon_llvm_check radeon_llvm_check
gallium_check_st "radeon/drm" "radeonsi/dri" "" "" "radeonsi/vdpau" gallium_check_st "radeon/drm" "radeonsi/dri" "" "" "radeonsi/vdpau" "radeonsi/omx"
DRICOMMON_NEED_LIBDRM=yes DRICOMMON_NEED_LIBDRM=yes
;; ;;
xnouveau) xnouveau)
@ -2003,6 +2029,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/state_trackers/gbm/Makefile src/gallium/state_trackers/gbm/Makefile
src/gallium/state_trackers/glx/xlib/Makefile src/gallium/state_trackers/glx/xlib/Makefile
src/gallium/state_trackers/osmesa/Makefile src/gallium/state_trackers/osmesa/Makefile
src/gallium/state_trackers/omx/Makefile
src/gallium/state_trackers/vdpau/Makefile src/gallium/state_trackers/vdpau/Makefile
src/gallium/state_trackers/vega/Makefile src/gallium/state_trackers/vega/Makefile
src/gallium/state_trackers/xa/Makefile src/gallium/state_trackers/xa/Makefile
@ -2021,9 +2048,11 @@ AC_CONFIG_FILES([Makefile
src/gallium/targets/osmesa/osmesa.pc src/gallium/targets/osmesa/osmesa.pc
src/gallium/targets/pipe-loader/Makefile src/gallium/targets/pipe-loader/Makefile
src/gallium/targets/radeonsi/dri/Makefile src/gallium/targets/radeonsi/dri/Makefile
src/gallium/targets/radeonsi/omx/Makefile
src/gallium/targets/radeonsi/vdpau/Makefile src/gallium/targets/radeonsi/vdpau/Makefile
src/gallium/targets/r300/dri/Makefile src/gallium/targets/r300/dri/Makefile
src/gallium/targets/r600/dri/Makefile src/gallium/targets/r600/dri/Makefile
src/gallium/targets/r600/omx/Makefile
src/gallium/targets/r600/vdpau/Makefile src/gallium/targets/r600/vdpau/Makefile
src/gallium/targets/r600/xvmc/Makefile src/gallium/targets/r600/xvmc/Makefile
src/gallium/targets/libgl-xlib/Makefile src/gallium/targets/libgl-xlib/Makefile

View file

@ -60,3 +60,7 @@ endif
if HAVE_CLOVER if HAVE_CLOVER
SUBDIRS += clover SUBDIRS += clover
endif endif
if HAVE_ST_OMX
SUBDIRS += omx
endif

View file

@ -0,0 +1,35 @@
# Copyright © 2012 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (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
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
$(GALLIUM_CFLAGS) \
$(OMX_CFLAGS)
noinst_LTLIBRARIES = libomxtracker.la
libomxtracker_la_SOURCES = \
entrypoint.c \
vid_dec.c \
vid_dec_mpeg12.c \
vid_dec_h264.c

View file

@ -0,0 +1,100 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#include <assert.h>
#include <string.h>
#include <X11/Xlib.h>
#include "os/os_thread.h"
#include "util/u_memory.h"
#include "entrypoint.h"
#include "vid_dec.h"
pipe_static_mutex(omx_lock);
static Display *omx_display = NULL;
static struct vl_screen *omx_screen = NULL;
static unsigned omx_usecount = 0;
int omx_component_library_Setup(stLoaderComponentType **stComponents)
{
OMX_ERRORTYPE r;
if (stComponents == NULL)
return 1;
r = vid_dec_LoaderComponent(stComponents[0]);
if (r != OMX_ErrorNone)
return r;
return 1;
}
struct vl_screen *omx_get_screen(void)
{
pipe_mutex_lock(omx_lock);
if (!omx_display) {
omx_display = XOpenDisplay(NULL);
if (!omx_display) {
pipe_mutex_unlock(omx_lock);
return NULL;
}
}
if (!omx_screen) {
omx_screen = vl_screen_create(omx_display, 0);
if (!omx_screen) {
pipe_mutex_unlock(omx_lock);
return NULL;
}
}
++omx_usecount;
pipe_mutex_unlock(omx_lock);
return omx_screen;
}
void omx_put_screen(void)
{
pipe_mutex_lock(omx_lock);
if ((--omx_usecount) == 0) {
vl_screen_destroy(omx_screen);
XCloseDisplay(omx_display);
omx_screen = NULL;
omx_display = NULL;
}
pipe_mutex_unlock(omx_lock);
}

View file

@ -0,0 +1,46 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#ifndef OMX_ENTRYPOINT_H
#define OMX_ENTRYPOINT_H
#include <bellagio/st_static_component_loader.h>
#include "vl/vl_winsys.h"
extern int omx_component_library_Setup(stLoaderComponentType **stComponents);
struct vl_screen *omx_get_screen(void);
void omx_put_screen(void);
#endif

View file

@ -0,0 +1,584 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#include <assert.h>
#include <OMX_Video.h>
/* bellagio defines a DEBUG macro that we don't want */
#ifndef DEBUG
#include <bellagio/omxcore.h>
#undef DEBUG
#else
#include <bellagio/omxcore.h>
#endif
#include <bellagio/omx_base_video_port.h>
#include "pipe/p_screen.h"
#include "pipe/p_video_codec.h"
#include "util/u_memory.h"
#include "util/u_surface.h"
#include "vl/vl_vlc.h"
#include "entrypoint.h"
#include "vid_dec.h"
static OMX_ERRORTYPE vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING name);
static OMX_ERRORTYPE vid_dec_Destructor(OMX_COMPONENTTYPE *comp);
static OMX_ERRORTYPE vid_dec_SetParameter(OMX_HANDLETYPE handle, OMX_INDEXTYPE idx, OMX_PTR param);
static OMX_ERRORTYPE vid_dec_GetParameter(OMX_HANDLETYPE handle, OMX_INDEXTYPE idx, OMX_PTR param);
static OMX_ERRORTYPE vid_dec_MessageHandler(OMX_COMPONENTTYPE *comp, internalRequestMessageType *msg);
static OMX_ERRORTYPE vid_dec_DecodeBuffer(omx_base_PortType *port, OMX_BUFFERHEADERTYPE *buf);
static OMX_ERRORTYPE vid_dec_FreeDecBuffer(omx_base_PortType *port, OMX_U32 idx, OMX_BUFFERHEADERTYPE *buf);
static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input, OMX_BUFFERHEADERTYPE* output);
static void vid_dec_name(char str[OMX_MAX_STRINGNAME_SIZE])
{
snprintf(str, OMX_MAX_STRINGNAME_SIZE, OMX_VID_DEC_BASE_NAME, driver_descriptor.name);
}
static void vid_dec_name_mpeg2(char str[OMX_MAX_STRINGNAME_SIZE])
{
snprintf(str, OMX_MAX_STRINGNAME_SIZE, OMX_VID_DEC_MPEG2_NAME, driver_descriptor.name);
}
static void vid_dec_name_avc(char str[OMX_MAX_STRINGNAME_SIZE])
{
snprintf(str, OMX_MAX_STRINGNAME_SIZE, OMX_VID_DEC_AVC_NAME, driver_descriptor.name);
}
OMX_ERRORTYPE vid_dec_LoaderComponent(stLoaderComponentType *comp)
{
comp->componentVersion.s.nVersionMajor = 0;
comp->componentVersion.s.nVersionMinor = 0;
comp->componentVersion.s.nRevision = 0;
comp->componentVersion.s.nStep = 1;
comp->name_specific_length = 2;
comp->name = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
if (comp->name == NULL)
goto error;
comp->name_specific = CALLOC(comp->name_specific_length, sizeof(char *));
if (comp->name_specific == NULL)
goto error;
comp->name_specific[0] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
if (comp->name_specific[0] == NULL)
goto error;
comp->name_specific[1] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
if (comp->name_specific[1] == NULL)
goto error;
comp->role_specific = CALLOC(comp->name_specific_length, sizeof(char *));
if (comp->role_specific == NULL)
goto error;
comp->role_specific[0] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
if (comp->role_specific[0] == NULL)
goto error;
comp->role_specific[1] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
if (comp->role_specific[1] == NULL)
goto error;
vid_dec_name(comp->name);
vid_dec_name_mpeg2(comp->name_specific[0]);
vid_dec_name_avc(comp->name_specific[1]);
strcpy(comp->role_specific[0], OMX_VID_DEC_MPEG2_ROLE);
strcpy(comp->role_specific[1], OMX_VID_DEC_AVC_ROLE);
comp->constructor = vid_dec_Constructor;
return OMX_ErrorNone;
error:
FREE(comp->name);
if (comp->name_specific) {
FREE(comp->name_specific[0]);
FREE(comp->name_specific[1]);
FREE(comp->name_specific);
}
if (comp->role_specific) {
FREE(comp->role_specific[0]);
FREE(comp->role_specific[1]);
FREE(comp->role_specific);
}
return OMX_ErrorInsufficientResources;
}
static OMX_ERRORTYPE vid_dec_Constructor(OMX_COMPONENTTYPE *comp, OMX_STRING name)
{
char tmpstr[OMX_MAX_STRINGNAME_SIZE];
vid_dec_PrivateType *priv;
omx_base_video_PortType *port;
struct pipe_screen *screen;
OMX_ERRORTYPE r;
int i;
assert(!comp->pComponentPrivate);
priv = comp->pComponentPrivate = CALLOC(1, sizeof(vid_dec_PrivateType));
if (!priv)
return OMX_ErrorInsufficientResources;
r = omx_base_filter_Constructor(comp, name);
if (r)
return r;
priv->profile = PIPE_VIDEO_PROFILE_UNKNOWN;
vid_dec_name_mpeg2(tmpstr);
if (!strcmp(name, tmpstr))
priv->profile = PIPE_VIDEO_PROFILE_MPEG2_MAIN;
vid_dec_name_avc(tmpstr);
if (!strcmp(name, tmpstr))
priv->profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
priv->BufferMgmtCallback = vid_dec_FrameDecoded;
priv->messageHandler = vid_dec_MessageHandler;
priv->destructor = vid_dec_Destructor;
comp->SetParameter = vid_dec_SetParameter;
comp->GetParameter = vid_dec_GetParameter;
priv->screen = omx_get_screen();
if (!priv->screen)
return OMX_ErrorInsufficientResources;
screen = priv->screen->pscreen;
priv->pipe = screen->context_create(screen, priv->screen);
if (!priv->pipe)
return OMX_ErrorInsufficientResources;
priv->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
priv->sPortTypesParam[OMX_PortDomainVideo].nPorts = 2;
priv->ports = CALLOC(2, sizeof(omx_base_PortType *));
if (!priv->ports)
return OMX_ErrorInsufficientResources;
for (i = 0; i < 2; ++i) {
priv->ports[i] = CALLOC(1, sizeof(omx_base_video_PortType));
if (!priv->ports[i])
return OMX_ErrorInsufficientResources;
base_video_port_Constructor(comp, &priv->ports[i], i, i == 0);
}
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
strcpy(port->sPortParam.format.video.cMIMEType,"video/MPEG2");
port->sPortParam.nBufferCountMin = 8;
port->sPortParam.nBufferCountActual = 8;
port->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
port->sPortParam.format.video.nFrameWidth = 176;
port->sPortParam.format.video.nFrameHeight = 144;
port->sPortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
port->sVideoParam.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
port->Port_SendBufferFunction = vid_dec_DecodeBuffer;
port->Port_FreeBuffer = vid_dec_FreeDecBuffer;
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
port->sPortParam.nBufferCountActual = 8;
port->sPortParam.nBufferCountMin = 4;
port->sPortParam.format.video.nFrameWidth = 176;
port->sPortParam.format.video.nFrameHeight = 144;
port->sPortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
port->sVideoParam.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
return OMX_ErrorNone;
}
static OMX_ERRORTYPE vid_dec_Destructor(OMX_COMPONENTTYPE *comp)
{
vid_dec_PrivateType* priv = comp->pComponentPrivate;
int i;
if (priv->ports) {
for (i = 0; i < priv->sPortTypesParam[OMX_PortDomainVideo].nPorts; ++i) {
if(priv->ports[i])
priv->ports[i]->PortDestructor(priv->ports[i]);
}
FREE(priv->ports);
priv->ports=NULL;
}
if (priv->pipe)
priv->pipe->destroy(priv->pipe);
if (priv->screen)
omx_put_screen();
omx_base_filter_Destructor(comp);
return OMX_ErrorNone;
}
static OMX_ERRORTYPE vid_dec_SetParameter(OMX_HANDLETYPE handle, OMX_INDEXTYPE idx, OMX_PTR param)
{
OMX_COMPONENTTYPE *comp = handle;
vid_dec_PrivateType *priv = comp->pComponentPrivate;
OMX_ERRORTYPE r;
if (!param)
return OMX_ErrorBadParameter;
switch(idx) {
case OMX_IndexParamPortDefinition: {
OMX_PARAM_PORTDEFINITIONTYPE *def = param;
r = omx_base_component_SetParameter(handle, idx, param);
if (r)
return r;
if (def->nPortIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) {
omx_base_video_PortType *port;
unsigned framesize = def->format.video.nFrameWidth * def->format.video.nFrameHeight;
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
port->sPortParam.nBufferSize = framesize * 512 / (16*16);
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
port->sPortParam.format.video.nFrameWidth = def->format.video.nFrameWidth;
port->sPortParam.format.video.nFrameHeight = def->format.video.nFrameHeight;
port->sPortParam.format.video.nStride = def->format.video.nFrameWidth;
port->sPortParam.format.video.nSliceHeight = def->format.video.nFrameHeight;
port->sPortParam.nBufferSize = framesize*3/2;
priv->callbacks->EventHandler(comp, priv->callbackData, OMX_EventPortSettingsChanged,
OMX_BASE_FILTER_OUTPUTPORT_INDEX, 0, NULL);
}
break;
}
case OMX_IndexParamStandardComponentRole: {
OMX_PARAM_COMPONENTROLETYPE *role = param;
r = checkHeader(param, sizeof(OMX_PARAM_COMPONENTROLETYPE));
if (r)
return r;
if (!strcmp((char *)role->cRole, OMX_VID_DEC_MPEG2_ROLE)) {
priv->profile = PIPE_VIDEO_PROFILE_MPEG2_MAIN;
} else if (!strcmp((char *)role->cRole, OMX_VID_DEC_AVC_ROLE)) {
priv->profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
} else {
return OMX_ErrorBadParameter;
}
break;
}
case OMX_IndexParamVideoPortFormat: {
OMX_VIDEO_PARAM_PORTFORMATTYPE *format = param;
omx_base_video_PortType *port;
r = checkHeader(param, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
if (r)
return r;
if (format->nPortIndex > 1)
return OMX_ErrorBadPortIndex;
port = (omx_base_video_PortType *)priv->ports[format->nPortIndex];
memcpy(&port->sVideoParam, format, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
break;
}
default:
return omx_base_component_SetParameter(handle, idx, param);
}
return OMX_ErrorNone;
}
static OMX_ERRORTYPE vid_dec_GetParameter(OMX_HANDLETYPE handle, OMX_INDEXTYPE idx, OMX_PTR param)
{
OMX_COMPONENTTYPE *comp = handle;
vid_dec_PrivateType *priv = comp->pComponentPrivate;
OMX_ERRORTYPE r;
if (!param)
return OMX_ErrorBadParameter;
switch(idx) {
case OMX_IndexParamStandardComponentRole: {
OMX_PARAM_COMPONENTROLETYPE *role = param;
r = checkHeader(param, sizeof(OMX_PARAM_COMPONENTROLETYPE));
if (r)
return r;
if (priv->profile == PIPE_VIDEO_PROFILE_MPEG2_MAIN)
strcpy((char *)role->cRole, OMX_VID_DEC_MPEG2_ROLE);
else if (priv->profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH)
strcpy((char *)role->cRole, OMX_VID_DEC_AVC_ROLE);
break;
}
case OMX_IndexParamVideoInit:
r = checkHeader(param, sizeof(OMX_PORT_PARAM_TYPE));
if (r)
return r;
memcpy(param, &priv->sPortTypesParam[OMX_PortDomainVideo], sizeof(OMX_PORT_PARAM_TYPE));
break;
case OMX_IndexParamVideoPortFormat: {
OMX_VIDEO_PARAM_PORTFORMATTYPE *format = param;
omx_base_video_PortType *port;
r = checkHeader(param, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
if (r)
return r;
if (format->nPortIndex > 1)
return OMX_ErrorBadPortIndex;
port = (omx_base_video_PortType *)priv->ports[format->nPortIndex];
memcpy(format, &port->sVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
break;
}
default:
return omx_base_component_GetParameter(handle, idx, param);
}
return OMX_ErrorNone;
}
static OMX_ERRORTYPE vid_dec_MessageHandler(OMX_COMPONENTTYPE* comp, internalRequestMessageType *msg)
{
vid_dec_PrivateType* priv = comp->pComponentPrivate;
if (msg->messageType == OMX_CommandStateSet) {
if ((msg->messageParam == OMX_StateIdle ) && (priv->state == OMX_StateLoaded)) {
struct pipe_video_codec templat = {};
omx_base_video_PortType *port;
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
templat.profile = priv->profile;
templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
templat.width = port->sPortParam.format.video.nFrameWidth;
templat.height = port->sPortParam.format.video.nFrameHeight;
templat.max_references = 2;
templat.expect_chunked_decode = true;
priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);
if (priv->profile == PIPE_VIDEO_PROFILE_MPEG2_MAIN)
vid_dec_mpeg12_Init(priv);
else if (priv->profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH)
vid_dec_h264_Init(priv);
} else if ((msg->messageParam == OMX_StateLoaded) && (priv->state == OMX_StateIdle)) {
if (priv->shadow) {
priv->shadow->destroy(priv->shadow);
priv->shadow = NULL;
}
if (priv->codec) {
priv->codec->destroy(priv->codec);
priv->codec = NULL;
}
}
}
return omx_base_component_MessageHandler(comp, msg);
}
void vid_dec_NeedTarget(vid_dec_PrivateType *priv)
{
struct pipe_video_buffer templat = {};
omx_base_video_PortType *port;
port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
if (!priv->target) {
templat.buffer_format = PIPE_FORMAT_NV12;
templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
templat.width = port->sPortParam.format.video.nFrameWidth;
templat.height = port->sPortParam.format.video.nFrameHeight;
templat.interlaced = false;
priv->target = priv->pipe->create_video_buffer(priv->pipe, &templat);
}
}
static void vid_dec_FreeInputPortPrivate(OMX_BUFFERHEADERTYPE *buf)
{
struct pipe_video_buffer *vbuf = buf->pInputPortPrivate;
if (!vbuf)
return;
vbuf->destroy(vbuf);
buf->pInputPortPrivate = NULL;
}
static OMX_ERRORTYPE vid_dec_DecodeBuffer(omx_base_PortType *port, OMX_BUFFERHEADERTYPE *buf)
{
OMX_COMPONENTTYPE* comp = port->standCompContainer;
vid_dec_PrivateType *priv = comp->pComponentPrivate;
unsigned i = priv->num_in_buffers++;
OMX_ERRORTYPE r;
priv->in_buffers[i] = buf;
priv->sizes[i] = buf->nFilledLen;
priv->inputs[i] = buf->pBuffer;
while (priv->num_in_buffers > (!!(buf->nFlags & OMX_BUFFERFLAG_EOS) ? 0 : 1)) {
bool eos = !!(priv->in_buffers[0]->nFlags & OMX_BUFFERFLAG_EOS);
unsigned min_bits_left = eos ? 32 : MAX2(buf->nFilledLen * 8, 32);
struct vl_vlc vlc;
vl_vlc_init(&vlc, priv->num_in_buffers, priv->inputs, priv->sizes);
if (priv->slice)
priv->bytes_left = vl_vlc_bits_left(&vlc) / 8;
while (vl_vlc_bits_left(&vlc) > min_bits_left) {
priv->Decode(priv, &vlc, min_bits_left);
vl_vlc_fillbits(&vlc);
}
if (priv->slice) {
unsigned bytes = priv->bytes_left - vl_vlc_bits_left(&vlc) / 8;
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1, &priv->slice, &bytes);
if (priv->num_in_buffers)
priv->slice = priv->inputs[1];
else
priv->slice = NULL;
}
if (eos && priv->frame_started)
priv->EndFrame(priv);
if (priv->frame_finished) {
priv->frame_finished = false;
priv->in_buffers[0]->nFilledLen = priv->in_buffers[0]->nAllocLen;
r = base_port_SendBufferFunction(port, priv->in_buffers[0]);
} else if (eos) {
vid_dec_FreeInputPortPrivate(priv->in_buffers[0]);
priv->in_buffers[0]->nFilledLen = priv->in_buffers[0]->nAllocLen;
r = base_port_SendBufferFunction(port, priv->in_buffers[0]);
} else {
priv->in_buffers[0]->nFilledLen = 0;
r = port->ReturnBufferFunction(port, priv->in_buffers[0]);
}
if (--priv->num_in_buffers) {
unsigned delta = (min_bits_left - vl_vlc_bits_left(&vlc)) / 8;
priv->in_buffers[0] = priv->in_buffers[1];
priv->sizes[0] = priv->sizes[1] - delta;
priv->inputs[0] = priv->inputs[1] + delta;
}
if (r)
return r;
}
return OMX_ErrorNone;
}
static OMX_ERRORTYPE vid_dec_FreeDecBuffer(omx_base_PortType *port, OMX_U32 idx, OMX_BUFFERHEADERTYPE *buf)
{
vid_dec_FreeInputPortPrivate(buf);
return base_port_FreeBuffer(port, idx, buf);
}
static void vid_dec_FillOutput(vid_dec_PrivateType *priv, struct pipe_video_buffer *buf,
OMX_BUFFERHEADERTYPE* output)
{
omx_base_PortType *port = priv->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
OMX_VIDEO_PORTDEFINITIONTYPE *def = &port->sPortParam.format.video;
struct pipe_sampler_view **views;
struct pipe_transfer *transfer;
struct pipe_box box = { };
uint8_t *src, *dst;
views = buf->get_sampler_view_planes(buf);
dst = output->pBuffer;
box.width = def->nFrameWidth;
box.height = def->nFrameHeight;
box.depth = 1;
src = priv->pipe->transfer_map(priv->pipe, views[0]->texture, 0,
PIPE_TRANSFER_READ, &box, &transfer);
util_copy_rect(dst, views[0]->texture->format, def->nStride, 0, 0,
box.width, box.height, src, transfer->stride, 0, 0);
pipe_transfer_unmap(priv->pipe, transfer);
dst = ((uint8_t*)output->pBuffer) + (def->nStride * box.height);
box.width = def->nFrameWidth / 2;
box.height = def->nFrameHeight / 2;
src = priv->pipe->transfer_map(priv->pipe, views[1]->texture, 0,
PIPE_TRANSFER_READ, &box, &transfer);
util_copy_rect(dst, views[1]->texture->format, def->nStride, 0, 0,
box.width, box.height, src, transfer->stride, 0, 0);
pipe_transfer_unmap(priv->pipe, transfer);
output->nFilledLen = output->nAllocLen;
}
static void vid_dec_FrameDecoded(OMX_COMPONENTTYPE *comp, OMX_BUFFERHEADERTYPE* input,
OMX_BUFFERHEADERTYPE* output)
{
vid_dec_PrivateType *priv = comp->pComponentPrivate;
bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS);
if (!input->pInputPortPrivate)
input->pInputPortPrivate = priv->Flush(priv);
if (input->pInputPortPrivate)
vid_dec_FillOutput(priv, input->pInputPortPrivate, output);
if (eos && input->pInputPortPrivate)
vid_dec_FreeInputPortPrivate(input);
else
input->nFilledLen = 0;
}

View file

@ -0,0 +1,119 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#ifndef OMX_VID_DEC_H
#define OMX_VID_DEC_H
#include <X11/Xlib.h>
#include <string.h>
#include <OMX_Types.h>
#include <OMX_Component.h>
#include <OMX_Core.h>
#include <bellagio/st_static_component_loader.h>
#include <bellagio/omx_base_filter.h>
#include "pipe/p_video_state.h"
#include "state_tracker/drm_driver.h"
#include "os/os_thread.h"
#include "util/u_double_list.h"
#define OMX_VID_DEC_BASE_NAME "OMX.%s.video_decoder"
#define OMX_VID_DEC_MPEG2_NAME "OMX.%s.video_decoder.mpeg2"
#define OMX_VID_DEC_MPEG2_ROLE "video_decoder.mpeg2"
#define OMX_VID_DEC_AVC_NAME "OMX.%s.video_decoder.avc"
#define OMX_VID_DEC_AVC_ROLE "video_decoder.avc"
struct vl_vlc;
DERIVEDCLASS(vid_dec_PrivateType, omx_base_filter_PrivateType)
#define vid_dec_PrivateType_FIELDS omx_base_filter_PrivateType_FIELDS \
enum pipe_video_profile profile; \
struct vl_screen *screen; \
struct pipe_context *pipe; \
struct pipe_video_codec *codec; \
void (*Decode)(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left); \
void (*EndFrame)(vid_dec_PrivateType *priv); \
struct pipe_video_buffer *(*Flush)(vid_dec_PrivateType *priv); \
struct pipe_video_buffer *target, *shadow; \
union { \
struct { \
uint8_t intra_matrix[64]; \
uint8_t non_intra_matrix[64]; \
} mpeg12; \
struct { \
unsigned nal_ref_idc; \
bool IdrPicFlag; \
unsigned idr_pic_id; \
unsigned pic_order_cnt_lsb; \
unsigned pic_order_cnt_msb; \
unsigned delta_pic_order_cnt_bottom; \
unsigned delta_pic_order_cnt[2]; \
unsigned prevFrameNumOffset; \
struct pipe_h264_sps sps[32]; \
struct pipe_h264_pps pps[256]; \
struct list_head dpb_list; \
unsigned dpb_num; \
} h264; \
} codec_data; \
union { \
struct pipe_picture_desc base; \
struct pipe_mpeg12_picture_desc mpeg12; \
struct pipe_h264_picture_desc h264; \
} picture; \
unsigned num_in_buffers; \
OMX_BUFFERHEADERTYPE *in_buffers[2]; \
const void *inputs[2]; \
unsigned sizes[2]; \
bool frame_finished; \
bool frame_started; \
unsigned bytes_left; \
const void *slice;
ENDCLASS(vid_dec_PrivateType)
OMX_ERRORTYPE vid_dec_LoaderComponent(stLoaderComponentType *comp);
/* used by MPEG12 and H264 implementation */
void vid_dec_NeedTarget(vid_dec_PrivateType *priv);
/* vid_dec_mpeg12.c */
void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv);
/* vid_dec_h264.c */
void vid_dec_h264_Init(vid_dec_PrivateType *priv);
#endif

View file

@ -0,0 +1,980 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#include "pipe/p_video_codec.h"
#include "util/u_memory.h"
#include "vl/vl_rbsp.h"
#include "entrypoint.h"
#include "vid_dec.h"
#define DPB_MAX_SIZE 5
struct dpb_list {
struct list_head list;
struct pipe_video_buffer *buffer;
unsigned poc;
};
static const uint8_t Default_4x4_Intra[16] = {
6, 13, 13, 20, 20, 20, 28, 28,
28, 28, 32, 32, 32, 37, 37, 42
};
static const uint8_t Default_4x4_Inter[16] = {
10, 14, 14, 20, 20, 20, 24, 24,
24, 24, 27, 27, 27, 30, 30, 34
};
static const uint8_t Default_8x8_Intra[64] = {
6, 10, 10, 13, 11, 13, 16, 16,
16, 16, 18, 18, 18, 18, 18, 23,
23, 23, 23, 23, 23, 25, 25, 25,
25, 25, 25, 25, 27, 27, 27, 27,
27, 27, 27, 27, 29, 29, 29, 29,
29, 29, 29, 31, 31, 31, 31, 31,
31, 33, 33, 33, 33, 33, 36, 36,
36, 36, 38, 38, 38, 40, 40, 42
};
static const uint8_t Default_8x8_Inter[64] = {
9, 13, 13, 15, 13, 15, 17, 17,
17, 17, 19, 19, 19, 19, 19, 21,
21, 21, 21, 21, 21, 22, 22, 22,
22, 22, 22, 22, 24, 24, 24, 24,
24, 24, 24, 24, 25, 25, 25, 25,
25, 25, 25, 27, 27, 27, 27, 27,
27, 28, 28, 28, 28, 28, 30, 30,
30, 30, 32, 32, 32, 33, 33, 35
};
static void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv);
static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv);
void vid_dec_h264_Init(vid_dec_PrivateType *priv)
{
priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
priv->Decode = vid_dec_h264_Decode;
priv->EndFrame = vid_dec_h264_EndFrame;
priv->Flush = vid_dec_h264_Flush;
LIST_INITHEAD(&priv->codec_data.h264.dpb_list);
priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
}
static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv)
{
//TODO: sane buffer handling
if (priv->frame_started)
return;
vid_dec_NeedTarget(priv);
priv->picture.h264.num_ref_frames = priv->picture.h264.pps->sps->max_num_ref_frames;
priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
priv->frame_started = true;
}
static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv)
{
struct dpb_list *entry, *result = NULL;
struct pipe_video_buffer *buf;
/* search for the lowest poc and break on zeros */
LIST_FOR_EACH_ENTRY(entry, &priv->codec_data.h264.dpb_list, list) {
if (result && entry->poc == 0)
break;
if (!result || entry->poc < result->poc)
result = entry;
}
if (!result)
return NULL;
buf = result->buffer;
--priv->codec_data.h264.dpb_num;
LIST_DEL(&result->list);
FREE(result);
return buf;
}
static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv)
{
struct dpb_list *entry;
struct pipe_video_buffer *tmp;
bool top_field_first;
if (!priv->frame_started)
return;
priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
priv->frame_started = false;
// TODO: implement frame number handling
priv->picture.h264.frame_num_list[0] = priv->picture.h264.frame_num;
priv->picture.h264.field_order_cnt_list[0][0] = priv->picture.h264.frame_num;
priv->picture.h264.field_order_cnt_list[0][1] = priv->picture.h264.frame_num;
top_field_first = priv->picture.h264.field_order_cnt[0] < priv->picture.h264.field_order_cnt[1];
if (priv->picture.h264.field_pic_flag && priv->picture.h264.bottom_field_flag != top_field_first)
return;
/* add the decoded picture to the dpb list */
entry = CALLOC_STRUCT(dpb_list);
if (!entry)
return;
entry->buffer = priv->target;
entry->poc = MIN2(priv->picture.h264.field_order_cnt[0], priv->picture.h264.field_order_cnt[1]);
LIST_ADDTAIL(&entry->list, &priv->codec_data.h264.dpb_list);
++priv->codec_data.h264.dpb_num;
priv->target = NULL;
priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
if (priv->codec_data.h264.dpb_num <= DPB_MAX_SIZE)
return;
tmp = priv->in_buffers[0]->pInputPortPrivate;
priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv);
priv->target = tmp;
priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL;
}
static void vui_parameters(struct vl_rbsp *rbsp)
{
// TODO
}
static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned sizeOfScalingList,
const uint8_t *defaultList, const uint8_t *fallbackList)
{
unsigned lastScale = 8, nextScale = 8;
unsigned i;
/* (pic|seq)_scaling_list_present_flag[i] */
if (!vl_rbsp_u(rbsp, 1)) {
if (fallbackList)
memcpy(scalingList, fallbackList, sizeOfScalingList);
return;
}
for (i = 0; i < sizeOfScalingList; ++i ) {
if (nextScale != 0) {
signed delta_scale = vl_rbsp_se(rbsp);
nextScale = (lastScale + delta_scale + 256) % 256;
if (i == 0 && nextScale == 0) {
memcpy(scalingList, defaultList, sizeOfScalingList);
return;
}
}
scalingList[i] = nextScale == 0 ? lastScale : nextScale;
lastScale = scalingList[i];
}
}
static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
{
unsigned id = vl_rbsp_ue(rbsp);
if (id >= Elements(priv->codec_data.h264.sps))
return NULL; /* invalid seq_parameter_set_id */
return &priv->codec_data.h264.sps[id];
}
static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
{
struct pipe_h264_sps *sps;
unsigned profile_idc;
unsigned i;
/* Sequence parameter set */
profile_idc = vl_rbsp_u(rbsp, 8);
/* constraint_set0_flag */
vl_rbsp_u(rbsp, 1);
/* constraint_set1_flag */
vl_rbsp_u(rbsp, 1);
/* constraint_set2_flag */
vl_rbsp_u(rbsp, 1);
/* constraint_set3_flag */
vl_rbsp_u(rbsp, 1);
/* constraint_set4_flag */
vl_rbsp_u(rbsp, 1);
/* constraint_set5_flag */
vl_rbsp_u(rbsp, 1);
/* reserved_zero_2bits */
vl_rbsp_u(rbsp, 2);
/* level_idc */
vl_rbsp_u(rbsp, 8);
sps = seq_parameter_set_id(priv, rbsp);
if (!sps)
return;
memset(sps, 0, sizeof(*sps));
memset(sps->ScalingList4x4, 16, sizeof(sps->ScalingList4x4));
memset(sps->ScalingList8x8, 16, sizeof(sps->ScalingList8x8));
if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 ||
profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 ||
profile_idc == 128 || profile_idc == 138) {
sps->chroma_format_idc = vl_rbsp_ue(rbsp);
if (sps->chroma_format_idc == 3)
sps->separate_colour_plane_flag = vl_rbsp_u(rbsp, 1);
sps->bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);
sps->bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);
/* qpprime_y_zero_transform_bypass_flag */
vl_rbsp_u(rbsp, 1);
sps->seq_scaling_matrix_present_flag = vl_rbsp_u(rbsp, 1);
if (sps->seq_scaling_matrix_present_flag) {
scaling_list(rbsp, sps->ScalingList4x4[0], 16, Default_4x4_Intra, Default_4x4_Intra);
scaling_list(rbsp, sps->ScalingList4x4[1], 16, Default_4x4_Intra, sps->ScalingList4x4[0]);
scaling_list(rbsp, sps->ScalingList4x4[2], 16, Default_4x4_Intra, sps->ScalingList4x4[1]);
scaling_list(rbsp, sps->ScalingList4x4[3], 16, Default_4x4_Inter, Default_4x4_Inter);
scaling_list(rbsp, sps->ScalingList4x4[4], 16, Default_4x4_Inter, sps->ScalingList4x4[3]);
scaling_list(rbsp, sps->ScalingList4x4[5], 16, Default_4x4_Inter, sps->ScalingList4x4[4]);
scaling_list(rbsp, sps->ScalingList8x8[0], 64, Default_8x8_Intra, Default_8x8_Intra);
scaling_list(rbsp, sps->ScalingList8x8[1], 64, Default_8x8_Inter, Default_8x8_Inter);
if (sps->chroma_format_idc == 3) {
scaling_list(rbsp, sps->ScalingList8x8[2], 64, Default_8x8_Intra, sps->ScalingList8x8[0]);
scaling_list(rbsp, sps->ScalingList8x8[3], 64, Default_8x8_Inter, sps->ScalingList8x8[1]);
scaling_list(rbsp, sps->ScalingList8x8[4], 64, Default_8x8_Intra, sps->ScalingList8x8[2]);
scaling_list(rbsp, sps->ScalingList8x8[5], 64, Default_8x8_Inter, sps->ScalingList8x8[3]);
}
}
} else if (profile_idc == 183)
sps->chroma_format_idc = 0;
else
sps->chroma_format_idc = 1;
sps->log2_max_frame_num_minus4 = vl_rbsp_ue(rbsp);
sps->pic_order_cnt_type = vl_rbsp_ue(rbsp);
if (sps->pic_order_cnt_type == 0)
sps->log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);
else {
sps->delta_pic_order_always_zero_flag = vl_rbsp_u(rbsp, 1);
sps->offset_for_non_ref_pic = vl_rbsp_se(rbsp);
sps->offset_for_top_to_bottom_field = vl_rbsp_se(rbsp);
sps->num_ref_frames_in_pic_order_cnt_cycle = vl_rbsp_ue(rbsp);
for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
sps->offset_for_ref_frame[i] = vl_rbsp_se(rbsp);
}
sps->max_num_ref_frames = vl_rbsp_ue(rbsp);
/* gaps_in_frame_num_value_allowed_flag */
vl_rbsp_u(rbsp, 1);
/* pic_width_in_mbs_minus1 */
vl_rbsp_ue(rbsp);
/* pic_height_in_map_units_minus1 */
vl_rbsp_ue(rbsp);
sps->frame_mbs_only_flag = vl_rbsp_u(rbsp, 1);
if (!sps->frame_mbs_only_flag)
sps->mb_adaptive_frame_field_flag = vl_rbsp_u(rbsp, 1);
sps->direct_8x8_inference_flag = vl_rbsp_u(rbsp, 1);
/* frame_cropping_flag */
if (vl_rbsp_u(rbsp, 1)) {
/* frame_crop_left_offset */
vl_rbsp_ue(rbsp);
/* frame_crop_right_offset */
vl_rbsp_ue(rbsp);
/* frame_crop_top_offset */
vl_rbsp_ue(rbsp);
/* frame_crop_bottom_offset */
vl_rbsp_ue(rbsp);
}
/* vui_parameters_present_flag */
if (vl_rbsp_u(rbsp, 1))
vui_parameters(rbsp);
}
static struct pipe_h264_pps *pic_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
{
unsigned id = vl_rbsp_ue(rbsp);
if (id >= Elements(priv->codec_data.h264.pps))
return NULL; /* invalid pic_parameter_set_id */
return &priv->codec_data.h264.pps[id];
}
static void picture_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
{
struct pipe_h264_sps *sps;
struct pipe_h264_pps *pps;
unsigned i;
pps = pic_parameter_set_id(priv, rbsp);
if (!pps)
return;
memset(pps, 0, sizeof(*pps));
sps = pps->sps = seq_parameter_set_id(priv, rbsp);
if (!sps)
return;
memcpy(pps->ScalingList4x4, sps->ScalingList4x4, sizeof(pps->ScalingList4x4));
memcpy(pps->ScalingList8x8, sps->ScalingList8x8, sizeof(pps->ScalingList8x8));
pps->entropy_coding_mode_flag = vl_rbsp_u(rbsp, 1);
pps->bottom_field_pic_order_in_frame_present_flag = vl_rbsp_u(rbsp, 1);
pps->num_slice_groups_minus1 = vl_rbsp_ue(rbsp);
if (pps->num_slice_groups_minus1 > 0) {
pps->slice_group_map_type = vl_rbsp_ue(rbsp);
if (pps->slice_group_map_type == 0) {
for (i = 0; i <= pps->num_slice_groups_minus1; ++i)
/* run_length_minus1[i] */
vl_rbsp_ue(rbsp);
} else if (pps->slice_group_map_type == 2) {
for (i = 0; i <= pps->num_slice_groups_minus1; ++i) {
/* top_left[i] */
vl_rbsp_ue(rbsp);
/* bottom_right[i] */
vl_rbsp_ue(rbsp);
}
} else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
/* slice_group_change_direction_flag */
vl_rbsp_u(rbsp, 1);
pps->slice_group_change_rate_minus1 = vl_rbsp_ue(rbsp);
} else if (pps->slice_group_map_type == 6) {
unsigned pic_size_in_map_units_minus1;
pic_size_in_map_units_minus1 = vl_rbsp_ue(rbsp);
for (i = 0; i <= pic_size_in_map_units_minus1; ++i)
/* slice_group_id[i] */
vl_rbsp_u(rbsp, log2(pps->num_slice_groups_minus1 + 1));
}
}
pps->num_ref_idx_l0_default_active_minus1 = vl_rbsp_ue(rbsp);
pps->num_ref_idx_l1_default_active_minus1 = vl_rbsp_ue(rbsp);
pps->weighted_pred_flag = vl_rbsp_u(rbsp, 1);
pps->weighted_bipred_idc = vl_rbsp_u(rbsp, 2);
pps->pic_init_qp_minus26 = vl_rbsp_se(rbsp);
/* pic_init_qs_minus26 */
vl_rbsp_se(rbsp);
pps->chroma_qp_index_offset = vl_rbsp_se(rbsp);
pps->deblocking_filter_control_present_flag = vl_rbsp_u(rbsp, 1);
pps->constrained_intra_pred_flag = vl_rbsp_u(rbsp, 1);
pps->redundant_pic_cnt_present_flag = vl_rbsp_u(rbsp, 1);
if (vl_rbsp_more_data(rbsp)) {
pps->transform_8x8_mode_flag = vl_rbsp_u(rbsp, 1);
/* pic_scaling_matrix_present_flag */
if (vl_rbsp_u(rbsp, 1)) {
scaling_list(rbsp, pps->ScalingList4x4[0], 16, Default_4x4_Intra,
sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Intra);
scaling_list(rbsp, pps->ScalingList4x4[1], 16, Default_4x4_Intra, pps->ScalingList4x4[0]);
scaling_list(rbsp, pps->ScalingList4x4[2], 16, Default_4x4_Intra, pps->ScalingList4x4[1]);
scaling_list(rbsp, pps->ScalingList4x4[3], 16, Default_4x4_Inter,
sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Inter);
scaling_list(rbsp, pps->ScalingList4x4[4], 16, Default_4x4_Inter, pps->ScalingList4x4[3]);
scaling_list(rbsp, pps->ScalingList4x4[5], 16, Default_4x4_Inter, pps->ScalingList4x4[4]);
if (pps->transform_8x8_mode_flag) {
scaling_list(rbsp, pps->ScalingList8x8[0], 64, Default_8x8_Intra,
sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Intra);
scaling_list(rbsp, pps->ScalingList8x8[1], 64, Default_8x8_Inter,
sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Inter);
if (sps->chroma_format_idc == 3) {
scaling_list(rbsp, pps->ScalingList8x8[2], 64, Default_8x8_Intra, pps->ScalingList8x8[0]);
scaling_list(rbsp, pps->ScalingList8x8[3], 64, Default_8x8_Inter, pps->ScalingList8x8[1]);
scaling_list(rbsp, pps->ScalingList8x8[4], 64, Default_8x8_Intra, pps->ScalingList8x8[2]);
scaling_list(rbsp, pps->ScalingList8x8[5], 64, Default_8x8_Inter, pps->ScalingList8x8[3]);
}
}
}
pps->second_chroma_qp_index_offset = vl_rbsp_se(rbsp);
}
}
static void ref_pic_list_mvc_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
{
// TODO
assert(0);
}
static void ref_pic_list_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
enum pipe_h264_slice_type slice_type)
{
unsigned modification_of_pic_nums_idc;
if (slice_type != 2 && slice_type != 4) {
/* ref_pic_list_modification_flag_l0 */
if (vl_rbsp_u(rbsp, 1)) {
do {
modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
if (modification_of_pic_nums_idc == 0 ||
modification_of_pic_nums_idc == 1)
/* abs_diff_pic_num_minus1 */
vl_rbsp_ue(rbsp);
else if (modification_of_pic_nums_idc == 2)
/* long_term_pic_num */
vl_rbsp_ue(rbsp);
} while (modification_of_pic_nums_idc != 3);
}
}
if (slice_type == 1) {
/* ref_pic_list_modification_flag_l1 */
if (vl_rbsp_u(rbsp, 1)) {
do {
modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
if (modification_of_pic_nums_idc == 0 ||
modification_of_pic_nums_idc == 1)
/* abs_diff_pic_num_minus1 */
vl_rbsp_ue(rbsp);
else if (modification_of_pic_nums_idc == 2)
/* long_term_pic_num */
vl_rbsp_ue(rbsp);
} while (modification_of_pic_nums_idc != 3);
}
}
}
static void pred_weight_table(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
struct pipe_h264_sps *sps, enum pipe_h264_slice_type slice_type)
{
unsigned ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;
unsigned i, j;
/* luma_log2_weight_denom */
vl_rbsp_ue(rbsp);
if (ChromaArrayType != 0)
/* chroma_log2_weight_denom */
vl_rbsp_ue(rbsp);
for (i = 0; i <= priv->picture.h264.num_ref_idx_l0_active_minus1; ++i) {
/* luma_weight_l0_flag */
if (vl_rbsp_u(rbsp, 1)) {
/* luma_weight_l0[i] */
vl_rbsp_se(rbsp);
/* luma_offset_l0[i] */
vl_rbsp_se(rbsp);
}
if (ChromaArrayType != 0) {
/* chroma_weight_l0_flag */
if (vl_rbsp_u(rbsp, 1)) {
for (j = 0; j < 2; ++j) {
/* chroma_weight_l0[i][j] */
vl_rbsp_se(rbsp);
/* chroma_offset_l0[i][j] */
vl_rbsp_se(rbsp);
}
}
}
}
if (slice_type == 1) {
for (i = 0; i <= priv->picture.h264.num_ref_idx_l1_active_minus1; ++i) {
/* luma_weight_l1_flag */
if (vl_rbsp_u(rbsp, 1)) {
/* luma_weight_l1[i] */
vl_rbsp_se(rbsp);
/* luma_offset_l1[i] */
vl_rbsp_se(rbsp);
}
if (ChromaArrayType != 0) {
/* chroma_weight_l1_flag */
if (vl_rbsp_u(rbsp, 1)) {
for (j = 0; j < 2; ++j) {
/* chroma_weight_l1[i][j] */
vl_rbsp_se(rbsp);
/* chroma_offset_l1[i][j] */
vl_rbsp_se(rbsp);
}
}
}
}
}
}
static void dec_ref_pic_marking(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
bool IdrPicFlag)
{
unsigned memory_management_control_operation;
if (IdrPicFlag) {
/* no_output_of_prior_pics_flag */
vl_rbsp_u(rbsp, 1);
/* long_term_reference_flag */
vl_rbsp_u(rbsp, 1);
} else {
/* adaptive_ref_pic_marking_mode_flag */
if (vl_rbsp_u(rbsp, 1)) {
do {
memory_management_control_operation = vl_rbsp_ue(rbsp);
if (memory_management_control_operation == 1 ||
memory_management_control_operation == 3)
/* difference_of_pic_nums_minus1 */
vl_rbsp_ue(rbsp);
if (memory_management_control_operation == 2)
/* long_term_pic_num */
vl_rbsp_ue(rbsp);
if (memory_management_control_operation == 3 ||
memory_management_control_operation == 6)
/* long_term_frame_idx */
vl_rbsp_ue(rbsp);
if (memory_management_control_operation == 4)
/* max_long_term_frame_idx_plus1 */
vl_rbsp_ue(rbsp);
} while (memory_management_control_operation != 0);
}
}
}
static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
unsigned nal_ref_idc, unsigned nal_unit_type)
{
enum pipe_h264_slice_type slice_type;
struct pipe_h264_pps *pps;
struct pipe_h264_sps *sps;
unsigned frame_num, prevFrameNum;
bool IdrPicFlag = nal_unit_type == 5;
if (IdrPicFlag != priv->codec_data.h264.IdrPicFlag)
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.IdrPicFlag = IdrPicFlag;
/* first_mb_in_slice */
vl_rbsp_ue(rbsp);
slice_type = vl_rbsp_ue(rbsp) % 5;
pps = pic_parameter_set_id(priv, rbsp);
if (!pps)
return;
sps = pps->sps;
if (!sps)
return;
if (pps != priv->picture.h264.pps)
vid_dec_h264_EndFrame(priv);
priv->picture.h264.pps = pps;
if (sps->separate_colour_plane_flag == 1 )
/* colour_plane_id */
vl_rbsp_u(rbsp, 2);
frame_num = vl_rbsp_u(rbsp, sps->log2_max_frame_num_minus4 + 4);
if (frame_num != priv->picture.h264.frame_num)
vid_dec_h264_EndFrame(priv);
prevFrameNum = priv->picture.h264.frame_num;
priv->picture.h264.frame_num = frame_num;
priv->picture.h264.field_pic_flag = 0;
priv->picture.h264.bottom_field_flag = 0;
if (!sps->frame_mbs_only_flag) {
unsigned field_pic_flag = vl_rbsp_u(rbsp, 1);
if (!field_pic_flag && field_pic_flag != priv->picture.h264.field_pic_flag)
vid_dec_h264_EndFrame(priv);
priv->picture.h264.field_pic_flag = field_pic_flag;
if (priv->picture.h264.field_pic_flag) {
unsigned bottom_field_flag = vl_rbsp_u(rbsp, 1);
if (bottom_field_flag != priv->picture.h264.bottom_field_flag);
vid_dec_h264_EndFrame(priv);
priv->picture.h264.bottom_field_flag = bottom_field_flag;
}
}
if (IdrPicFlag) {
unsigned idr_pic_id = vl_rbsp_ue(rbsp);
if (idr_pic_id != priv->codec_data.h264.idr_pic_id)
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.idr_pic_id = idr_pic_id;
}
if (sps->pic_order_cnt_type == 0) {
unsigned log2_max_pic_order_cnt_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
unsigned max_pic_order_cnt_lsb = 1 << log2_max_pic_order_cnt_lsb;
unsigned pic_order_cnt_lsb = vl_rbsp_u(rbsp, log2_max_pic_order_cnt_lsb);
unsigned pic_order_cnt_msb;
if (pic_order_cnt_lsb != priv->codec_data.h264.pic_order_cnt_lsb)
vid_dec_h264_EndFrame(priv);
if ((pic_order_cnt_lsb < priv->codec_data.h264.pic_order_cnt_lsb) &&
(priv->codec_data.h264.pic_order_cnt_lsb - pic_order_cnt_lsb) >= (max_pic_order_cnt_lsb / 2))
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb + max_pic_order_cnt_lsb;
else if ((pic_order_cnt_lsb > priv->codec_data.h264.pic_order_cnt_lsb) &&
(pic_order_cnt_lsb - priv->codec_data.h264.pic_order_cnt_lsb) > (max_pic_order_cnt_lsb / 2))
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb - max_pic_order_cnt_lsb;
else
pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb;
priv->codec_data.h264.pic_order_cnt_msb = pic_order_cnt_msb;
priv->codec_data.h264.pic_order_cnt_lsb = pic_order_cnt_lsb;
if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
unsigned delta_pic_order_cnt_bottom = vl_rbsp_se(rbsp);
if (delta_pic_order_cnt_bottom != priv->codec_data.h264.delta_pic_order_cnt_bottom)
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom;
}
priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;
priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb;
if (!priv->picture.h264.field_pic_flag)
priv->picture.h264.field_order_cnt[1] += priv->codec_data.h264.delta_pic_order_cnt_bottom;
} else if (sps->pic_order_cnt_type == 1) {
unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
unsigned FrameNumOffset, absFrameNum, expectedPicOrderCnt;
if (!sps->delta_pic_order_always_zero_flag) {
unsigned delta_pic_order_cnt[2];
delta_pic_order_cnt[0] = vl_rbsp_se(rbsp);
if (delta_pic_order_cnt[0] != priv->codec_data.h264.delta_pic_order_cnt[0])
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.delta_pic_order_cnt[0] = delta_pic_order_cnt[0];
if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
delta_pic_order_cnt[1] = vl_rbsp_se(rbsp);
if (delta_pic_order_cnt[1] != priv->codec_data.h264.delta_pic_order_cnt[1])
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.delta_pic_order_cnt[1] = delta_pic_order_cnt[1];
}
}
if (IdrPicFlag)
FrameNumOffset = 0;
else if (prevFrameNum > frame_num)
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
else
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
absFrameNum = FrameNumOffset + frame_num;
else
absFrameNum = 0;
if (nal_ref_idc == 0 && absFrameNum > 0)
absFrameNum = absFrameNum - 1;
if (absFrameNum > 0) {
unsigned picOrderCntCycleCnt = (absFrameNum - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;
unsigned frameNumInPicOrderCntCycle = (absFrameNum - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;
signed ExpectedDeltaPerPicOrderCntCycle = 0;
unsigned i;
for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
ExpectedDeltaPerPicOrderCntCycle += sps->offset_for_ref_frame[i];
expectedPicOrderCnt = picOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle;
for (i = 0; i <= frameNumInPicOrderCntCycle; ++i)
expectedPicOrderCnt += sps->offset_for_ref_frame[i];
} else
expectedPicOrderCnt = 0;
if (nal_ref_idc == 0)
expectedPicOrderCnt += sps->offset_for_non_ref_pic;
if (!priv->picture.h264.field_pic_flag) {
priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt[0] +
sps->offset_for_top_to_bottom_field + priv->codec_data.h264.delta_pic_order_cnt[1];
} else if (!priv->picture.h264.bottom_field_flag)
priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
else
priv->picture.h264.field_order_cnt[1] = expectedPicOrderCnt + sps->offset_for_top_to_bottom_field +
priv->codec_data.h264.delta_pic_order_cnt[0];
} else if (sps->pic_order_cnt_type == 2) {
unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
unsigned FrameNumOffset, tempPicOrderCnt;
if (IdrPicFlag)
FrameNumOffset = 0;
else if (prevFrameNum > frame_num)
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
else
FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
if (IdrPicFlag)
tempPicOrderCnt = 0;
else if (nal_ref_idc == 0)
tempPicOrderCnt = 2 * (FrameNumOffset + frame_num) - 1;
else
tempPicOrderCnt = 2 * (FrameNumOffset + frame_num);
if (!priv->picture.h264.field_pic_flag) {
priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
} else if (!priv->picture.h264.bottom_field_flag)
priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
else
priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
}
if (pps->redundant_pic_cnt_present_flag)
/* redundant_pic_cnt */
vl_rbsp_ue(rbsp);
if (slice_type == PIPE_H264_SLICE_TYPE_B)
/* direct_spatial_mv_pred_flag */
vl_rbsp_u(rbsp, 1);
priv->picture.h264.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1;
priv->picture.h264.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1;
if (slice_type == PIPE_H264_SLICE_TYPE_P ||
slice_type == PIPE_H264_SLICE_TYPE_SP ||
slice_type == PIPE_H264_SLICE_TYPE_B) {
/* num_ref_idx_active_override_flag */
if (vl_rbsp_u(rbsp, 1)) {
priv->picture.h264.num_ref_idx_l0_active_minus1 = vl_rbsp_ue(rbsp);
if (slice_type == PIPE_H264_SLICE_TYPE_B)
priv->picture.h264.num_ref_idx_l1_active_minus1 = vl_rbsp_ue(rbsp);
}
}
if (nal_unit_type == 20 || nal_unit_type == 21)
ref_pic_list_mvc_modification(priv, rbsp);
else
ref_pic_list_modification(priv, rbsp, slice_type);
if ((pps->weighted_pred_flag && (slice_type == PIPE_H264_SLICE_TYPE_P || slice_type == PIPE_H264_SLICE_TYPE_SP)) ||
(pps->weighted_bipred_idc == 1 && slice_type == PIPE_H264_SLICE_TYPE_B))
pred_weight_table(priv, rbsp, sps, slice_type);
if (nal_ref_idc != 0)
dec_ref_pic_marking(priv, rbsp, IdrPicFlag);
if (pps->entropy_coding_mode_flag && slice_type != PIPE_H264_SLICE_TYPE_I && slice_type != PIPE_H264_SLICE_TYPE_SI)
/* cabac_init_idc */
vl_rbsp_ue(rbsp);
/* slice_qp_delta */
vl_rbsp_se(rbsp);
if (slice_type == PIPE_H264_SLICE_TYPE_SP || slice_type == PIPE_H264_SLICE_TYPE_SI) {
if (slice_type == PIPE_H264_SLICE_TYPE_SP)
/* sp_for_switch_flag */
vl_rbsp_u(rbsp, 1);
/*slice_qs_delta */
vl_rbsp_se(rbsp);
}
if (pps->deblocking_filter_control_present_flag) {
unsigned disable_deblocking_filter_idc = vl_rbsp_ue(rbsp);
if (disable_deblocking_filter_idc != 1) {
/* slice_alpha_c0_offset_div2 */
vl_rbsp_se(rbsp);
/* slice_beta_offset_div2 */
vl_rbsp_se(rbsp);
}
}
if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
/* slice_group_change_cycle */
vl_rbsp_u(rbsp, 2);
}
static void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
{
unsigned nal_ref_idc, nal_unit_type;
if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
return;
if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
vl_vlc_eatbits(vlc, 8);
return;
}
if (priv->slice) {
unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1, &priv->slice, &bytes);
priv->slice = NULL;
}
vl_vlc_eatbits(vlc, 24);
/* forbidden_zero_bit */
vl_vlc_eatbits(vlc, 1);
nal_ref_idc = vl_vlc_get_uimsbf(vlc, 2);
if (nal_ref_idc != priv->codec_data.h264.nal_ref_idc &&
(nal_ref_idc * priv->codec_data.h264.nal_ref_idc) == 0)
vid_dec_h264_EndFrame(priv);
priv->codec_data.h264.nal_ref_idc = nal_ref_idc;
nal_unit_type = vl_vlc_get_uimsbf(vlc, 5);
if (nal_unit_type != 1 && nal_unit_type != 5)
vid_dec_h264_EndFrame(priv);
if (nal_unit_type == 7) {
struct vl_rbsp rbsp;
vl_rbsp_init(&rbsp, vlc, ~0);
seq_parameter_set(priv, &rbsp);
} else if (nal_unit_type == 8) {
struct vl_rbsp rbsp;
vl_rbsp_init(&rbsp, vlc, ~0);
picture_parameter_set(priv, &rbsp);
} else if (nal_unit_type == 1 || nal_unit_type == 5) {
/* Coded slice of a non-IDR or IDR picture */
unsigned bits = vl_vlc_valid_bits(vlc);
unsigned bytes = bits / 8 + 4;
struct vl_rbsp rbsp;
uint8_t buf[8];
const void *ptr = buf;
unsigned i;
buf[0] = 0x0;
buf[1] = 0x0;
buf[2] = 0x1;
buf[3] = (nal_ref_idc << 5) | nal_unit_type;
for (i = 4; i < bytes; ++i)
buf[i] = vl_vlc_peekbits(vlc, bits) >> ((bytes - i - 1) * 8);
priv->bytes_left = (vl_vlc_bits_left(vlc) - bits) / 8;
priv->slice = vlc->data;
vl_rbsp_init(&rbsp, vlc, 128);
slice_header(priv, &rbsp, nal_ref_idc, nal_unit_type);
vid_dec_h264_BeginFrame(priv);
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1, &ptr, &bytes);
}
/* resync to byte boundary */
vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
}

View file

@ -0,0 +1,367 @@
/**************************************************************************
*
* Copyright 2013 Advanced Micro Devices, Inc.
* 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
**************************************************************************/
/*
* Authors:
* Christian König <christian.koenig@amd.com>
*
*/
#include "pipe/p_video_codec.h"
#include "vl/vl_vlc.h"
#include "vl/vl_zscan.h"
#include "vid_dec.h"
static uint8_t default_intra_matrix[64] = {
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 19, 22, 22, 22, 22, 26,
26, 27, 22, 26, 26, 27, 29, 24,
27, 27, 29, 32, 27, 29, 29, 32,
35, 29, 34, 34, 35, 40, 34, 34,
37, 40, 48, 37, 38, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
static uint8_t default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
};
static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv);
static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv);
void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv)
{
priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG2_MAIN;
priv->picture.mpeg12.intra_matrix = default_intra_matrix;
priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
priv->Decode = vid_dec_mpeg12_Decode;
priv->EndFrame = vid_dec_mpeg12_EndFrame;
priv->Flush = vid_dec_mpeg12_Flush;
}
static void BeginFrame(vid_dec_PrivateType *priv)
{
if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {
priv->picture.mpeg12.ref[0] = priv->picture.mpeg12.ref[1];
priv->picture.mpeg12.ref[1] = NULL;
}
if (priv->target == priv->picture.mpeg12.ref[0]) {
struct pipe_video_buffer *tmp = priv->target;
priv->target = priv->shadow;
priv->shadow = tmp;
}
vid_dec_NeedTarget(priv);
priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
priv->frame_started = true;
}
static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv)
{
struct pipe_video_buffer *done;
priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
priv->frame_started = false;
if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {
priv->picture.mpeg12.ref[1] = priv->target;
done = priv->picture.mpeg12.ref[0];
if (!done) {
priv->target = NULL;
return;
}
} else
done = priv->target;
priv->frame_finished = true;
priv->target = priv->in_buffers[0]->pInputPortPrivate;
priv->in_buffers[0]->pInputPortPrivate = done;
}
static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv)
{
struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];
priv->picture.mpeg12.ref[1] = NULL;
return result;
}
static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
{
uint8_t code;
unsigned i;
if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
return;
if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
vl_vlc_eatbits(vlc, 8);
return;
}
if (priv->slice) {
unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1, &priv->slice, &bytes);
priv->slice = NULL;
}
vl_vlc_eatbits(vlc, 24);
code = vl_vlc_get_uimsbf(vlc, 8);
if (priv->frame_started && (code == 0x00 || code > 0xAF))
vid_dec_mpeg12_EndFrame(priv);
if (code == 0xB3) {
/* sequence header code */
vl_vlc_fillbits(vlc);
/* horizontal_size_value */
vl_vlc_get_uimsbf(vlc, 12);
/* vertical_size_value */
vl_vlc_get_uimsbf(vlc, 12);
/* aspect_ratio_information */
vl_vlc_get_uimsbf(vlc, 4);
/* frame_rate_code */
vl_vlc_get_uimsbf(vlc, 4);
vl_vlc_fillbits(vlc);
/* bit_rate_value */
vl_vlc_get_uimsbf(vlc, 18);
/* marker_bit */
vl_vlc_get_uimsbf(vlc, 1);
/* vbv_buffer_size_value */
vl_vlc_get_uimsbf(vlc, 10);
/* constrained_parameters_flag */
vl_vlc_get_uimsbf(vlc, 1);
vl_vlc_fillbits(vlc);
/* load_intra_quantiser_matrix */
if (vl_vlc_get_uimsbf(vlc, 1)) {
/* intra_quantiser_matrix */
priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
for (i = 0; i < 64; ++i) {
priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
vl_vlc_fillbits(vlc);
}
} else
priv->picture.mpeg12.intra_matrix = default_intra_matrix;
/* load_non_intra_quantiser_matrix */
if (vl_vlc_get_uimsbf(vlc, 1)) {
/* non_intra_quantiser_matrix */
priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
for (i = 0; i < 64; ++i) {
priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
vl_vlc_fillbits(vlc);
}
} else
priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
} else if (code == 0x00) {
/* picture start code */
vl_vlc_fillbits(vlc);
/* temporal_reference */
vl_vlc_get_uimsbf(vlc, 10);
priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);
/* vbv_delay */
vl_vlc_get_uimsbf(vlc, 16);
vl_vlc_fillbits(vlc);
if (priv->picture.mpeg12.picture_coding_type == 2 ||
priv->picture.mpeg12.picture_coding_type == 3) {
priv->picture.mpeg12.full_pel_forward_vector = vl_vlc_get_uimsbf(vlc, 1);
/* forward_f_code */
priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0];
} else {
priv->picture.mpeg12.full_pel_forward_vector = 0;
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
}
if (priv->picture.mpeg12.picture_coding_type == 3) {
priv->picture.mpeg12.full_pel_backward_vector = vl_vlc_get_uimsbf(vlc, 1);
/* backward_f_code */
priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
priv->picture.mpeg12.f_code[1][1] = priv->picture.mpeg12.f_code[1][0];
} else {
priv->picture.mpeg12.full_pel_backward_vector = 0;
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
}
/* extra_bit_picture */
while (vl_vlc_get_uimsbf(vlc, 1)) {
/* extra_information_picture */
vl_vlc_get_uimsbf(vlc, 8);
vl_vlc_fillbits(vlc);
}
} else if (code == 0xB5) {
/* extension start code */
vl_vlc_fillbits(vlc);
/* extension_start_code_identifier */
switch (vl_vlc_get_uimsbf(vlc, 4)) {
case 0x3: /* quant matrix extension */
/* load_intra_quantiser_matrix */
if (vl_vlc_get_uimsbf(vlc, 1)) {
/* intra_quantiser_matrix */
priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
for (i = 0; i < 64; ++i) {
priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
vl_vlc_fillbits(vlc);
}
} else
priv->picture.mpeg12.intra_matrix = default_intra_matrix;
/* load_non_intra_quantiser_matrix */
if (vl_vlc_get_uimsbf(vlc, 1)) {
/* non_intra_quantiser_matrix */
priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
for (i = 0; i < 64; ++i) {
priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
vl_vlc_fillbits(vlc);
}
} else
priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;
break;
case 0x8: /* picture coding extension */
priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
priv->picture.mpeg12.f_code[0][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
priv->picture.mpeg12.f_code[1][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
priv->picture.mpeg12.intra_dc_precision = vl_vlc_get_uimsbf(vlc, 2);
priv->picture.mpeg12.picture_structure = vl_vlc_get_uimsbf(vlc, 2);
priv->picture.mpeg12.top_field_first = vl_vlc_get_uimsbf(vlc, 1);
priv->picture.mpeg12.frame_pred_frame_dct = vl_vlc_get_uimsbf(vlc, 1);
priv->picture.mpeg12.concealment_motion_vectors = vl_vlc_get_uimsbf(vlc, 1);
priv->picture.mpeg12.q_scale_type = vl_vlc_get_uimsbf(vlc, 1);
priv->picture.mpeg12.intra_vlc_format = vl_vlc_get_uimsbf(vlc, 1);
priv->picture.mpeg12.alternate_scan = vl_vlc_get_uimsbf(vlc, 1);
/* repeat_first_field */
vl_vlc_get_uimsbf(vlc, 1);
/* chroma_420_type */
vl_vlc_get_uimsbf(vlc, 1);
vl_vlc_fillbits(vlc);
/* progressive_frame */
vl_vlc_get_uimsbf(vlc, 1);
/* composite_display_flag */
if (vl_vlc_get_uimsbf(vlc, 1)) {
/* v_axis */
vl_vlc_get_uimsbf(vlc, 1);
/* field_sequence */
vl_vlc_get_uimsbf(vlc, 3);
/* sub_carrier */
vl_vlc_get_uimsbf(vlc, 1);
/* burst_amplitude */
vl_vlc_get_uimsbf(vlc, 7);
/* sub_carrier_phase */
vl_vlc_get_uimsbf(vlc, 8);
}
break;
}
} else if (code <= 0xAF) {
/* slice start */
unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;
uint8_t buf[12];
const void *ptr = buf;
unsigned i;
if (!priv->frame_started)
BeginFrame(priv);
buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = 0x01;
buf[3] = code;
for (i = 4; i < bytes; ++i)
buf[i] = vl_vlc_get_uimsbf(vlc, 8);
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1, &ptr, &bytes);
priv->bytes_left = vl_vlc_bits_left(vlc) / 8;
priv->slice = vlc->data;
} else if (code == 0xB2) {
/* user data start */
} else if (code == 0xB4) {
/* sequence error */
} else if (code == 0xB7) {
/* sequence end */
} else if (code == 0xB8) {
/* group start */
} else if (code >= 0xB9) {
/* system start */
} else {
/* reserved */
}
/* resync to byte boundary */
vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
}

View file

@ -84,6 +84,10 @@ endif
if HAVE_ST_VDPAU if HAVE_ST_VDPAU
SUBDIRS += r600/vdpau SUBDIRS += r600/vdpau
endif endif
if HAVE_ST_OMX
SUBDIRS += r600/omx
endif
endif endif
if HAVE_GALLIUM_RADEONSI if HAVE_GALLIUM_RADEONSI
@ -94,6 +98,10 @@ endif
if HAVE_ST_VDPAU if HAVE_ST_VDPAU
SUBDIRS += radeonsi/vdpau SUBDIRS += radeonsi/vdpau
endif endif
if HAVE_ST_OMX
SUBDIRS += radeonsi/omx
endif
endif endif
if HAVE_GALLIUM_NOUVEAU if HAVE_GALLIUM_NOUVEAU

View file

@ -0,0 +1,77 @@
# Copyright © 2012 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (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
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
$(GALLIUM_CFLAGS) \
$(PTHREAD_CFLAGS) \
$(LIBDRM_CFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/gallium/drivers \
-I$(top_srcdir)/src/gallium/winsys
omxdir = $(OMX_LIB_INSTALL_DIR)
omx_LTLIBRARIES = libomx_r600.la
EXPORTS = '^(omx_component_library_Setup|radeon_drm_winsys_create)$$'
libomx_r600_la_SOURCES = \
drm_target.c \
$(top_srcdir)/src/gallium/auxiliary/vl/vl_winsys_dri.c
libomx_r600_la_LDFLAGS = \
-module \
-export-symbols-regex $(EXPORTS) \
-shared \
-no-undefined
libomx_r600_la_LIBADD = \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
$(top_builddir)/src/gallium/drivers/r600/libr600.la \
$(top_builddir)/src/gallium/state_trackers/omx/libomxtracker.la \
$(top_builddir)/src/gallium/winsys/radeon/drm/libradeonwinsys.la \
$(top_builddir)/src/gallium/drivers/trace/libtrace.la \
$(GALLIUM_DRI_LIB_DEPS) \
$(OMX_LIBS) \
$(LIBDRM_LIBS) \
$(RADEON_LIBS) \
-lstdc++
if HAVE_MESA_LLVM
libomx_r600_la_LINK = $(CXXLINK) $(libomx_r600_la_LDFLAGS)
# Mention a dummy pure C++ file to trigger generation of the $(LINK) variable
nodist_EXTRA_libomx_r600_la_SOURCES = dummy-cpp.cpp
libomx_r600_la_LDFLAGS += $(LLVM_LDFLAGS)
libomx_r600_la_LIBADD += $(LLVM_LIBS)
else
libomx_r600_la_LINK = $(LINK) $(libomx_r600_la_LDFLAGS)
# Mention a dummy pure C file to trigger generation of the $(LINK) variable
nodist_EXTRA_libomx_r600_la_SOURCES = dummy-c.c
endif
# Provide compatibility with scripts for the old Mesa build system for
# a while by putting a link to the driver into /lib of the build tree.
all-local: libomx_r600.la
$(MKDIR_P) $(top_builddir)/$(LIB_DIR)/gallium
ln -f .libs/libomx_r600.so* $(top_builddir)/$(LIB_DIR)/gallium/

View file

@ -0,0 +1 @@
../common/drm_target.c

View file

@ -0,0 +1,68 @@
# Copyright © 2012 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (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
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
$(GALLIUM_CFLAGS) \
$(PTHREAD_CFLAGS) \
$(LIBDRM_CFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/gallium/drivers \
-I$(top_srcdir)/src/gallium/winsys
omxdir = $(OMX_LIB_INSTALL_DIR)
omx_LTLIBRARIES = libomx_radeonsi.la
EXPORTS = '^(omx_component_library_Setup|radeon_drm_winsys_create)$$'
libomx_radeonsi_la_SOURCES = \
drm_target.c \
$(top_srcdir)/src/gallium/auxiliary/vl/vl_winsys_dri.c
libomx_radeonsi_la_LDFLAGS = \
-module \
-export-symbols-regex $(EXPORTS) \
-shared \
-no-undefined
libomx_radeonsi_la_LIBADD = \
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
$(top_builddir)/src/gallium/drivers/radeonsi/libradeonsi.la \
$(top_builddir)/src/gallium/state_trackers/omx/libomxtracker.la \
$(top_builddir)/src/gallium/winsys/radeon/drm/libradeonwinsys.la \
$(top_builddir)/src/gallium/drivers/trace/libtrace.la \
$(GALLIUM_DRI_LIB_DEPS) \
$(OMX_LIBS) \
$(LIBDRM_LIBS) \
$(RADEON_LIBS)
if HAVE_MESA_LLVM
libomx_radeonsi_la_LDFLAGS += $(LLVM_LDFLAGS)
libomx_radeonsi_la_LIBADD += $(LLVM_LIBS)
endif
# Provide compatibility with scripts for the old Mesa build system for
# a while by putting a link to the driver into /lib of the build tree.
all-local: libomx_radeonsi.la
$(MKDIR_P) $(top_builddir)/$(LIB_DIR)/gallium
ln -f .libs/libomx_radeonsi.so* $(top_builddir)/$(LIB_DIR)/gallium/

View file

@ -0,0 +1 @@
../common/drm_target.c